Manage nodes
Mission Control manages the estate: which machines exist, which of them are nodes, which versions each one holds, and which is holding the write. This page is the vocabulary. There are five verbs, and only the last one removes anything.
A machine becomes a node
Section titled “A machine becomes a node”| is | where it appears | |
|---|---|---|
| machine | an address you can reach by SSH, holding nothing of ours | the lower list |
| node | Helix on a machine: a home, a release area, perhaps a world | the upper list |
| mode | the role a node plays — replicant, standby, multiplexor, solo — which is what you start it as | on its card |
| environment | where it is running, a name the client chooses (live, test, …) | on its card |
| version | a core and a client bundle together | on its card |
A version is always the pair. The bundle states the core it was built against in its own manifest, so naming one version resolves both halves — which is why you choose an artefact rather than a core tag. A tag alone can only ever set half of it, and half is how a core ends up under a bundle built for something else.
The states, and the verbs between them
Section titled “The states, and the verbs between them”raw ──install <version>──▶ installed ──start [version]──▶ running ◀──uninstall (last)── ◀──────stop────────| verb | what it does | the world |
|---|---|---|
| check | asks a machine what it is, what it holds and what is offered to it. An observation, not a change | untouched |
install <version> | makes a machine hold a version: places the agent if it has none, brings the artefacts in, deploys them | kept |
start [version] | runs it as a role, at a version confirmed here. Joining the cluster is part of starting | kept |
| stop | stops it. It stays a node, with its world and its place in the set | kept |
uninstall <version> | removes that version. The last one takes the node with it | kept, except the last |
Every state is observed, never believed: a card shows what the last check and the live heartbeats actually found, which is why an action re-checks the machine as soon as it finishes.
A previous run still holding the port
Section titled “A previous run still holding the port”A node whose launcher was killed outright — a harness timing a test out, a terminal closed, a machine losing power mid-run — can leave its container running, because nothing can run in a process that has been killed. The next start normally clears it: each run records its container against its launcher, and a later run removes a container whose launcher is gone.
That record can be lost too, though, if whatever cleans up between runs takes the temporary directory with it.
So a single-node start — demo, dev, tuning and a spiral feed — also asks the container runtime what
is holding the ports it is about to publish. A container of this node’s own name is a previous run of
itself, and is removed with a line saying so. Anything else is left strictly alone and the start refuses,
naming what is in the way: it may be another account’s work, another product, or a member of a different
cluster, and none of those are Helix’s to end.
Cluster roles are deliberately excluded. On a machine running a replicant, multiplexor or standby, a
container holding a port may be a live member of the set, and clearing it down would take a node out from under
a running cluster. There, a port conflict is reported and left to you.
This only ever arises on a port you named. An unnamed port is chosen from the free ones at start, so it
cannot collide; what collides is HELIX_PORT, HELIX_PUBLIC_CRUD_PORT, or the MongoDB port once it has been
recorded in a node’s helix.env.
There is no separate “join”
Section titled “There is no separate “join””A node joins the cluster as it starts, because the mode it starts as is what decides its membership — its votes, its priority, and whether it can ever be elected. Those flags apply at the moment it joins and only then, so the node joining is the only thing that can set them correctly.
If a join does not take, the card says so — running, but outside the set. Stop it and start it again. Nothing is lost by restarting a node that is outside the set, because a node outside the set is not replicating.
Getting a version in
Section titled “Getting a version in”A node installs the version the console’s node runs. So the estate converges on one version — and that leaves the question of how a newer one arrives.
A release is pulled, never pushed. Devops gives an account a staging directory beside its release area,
usually a symbolic link to an earlier environment’s release directory, so the artefact names and shapes are
identical by construction. Nothing is pushed into a test or production account by whoever built the release;
the account takes what it has been offered. There is no credential anywhere in this.
~/HelixRuntime/ <stem>/ a node: its launcher, its pins, its storage release/ what this machine holds — shared between the nodes on it staging/ what devops offers this account → usually a symlinkA machine’s card shows both, and the difference between them is what an import does:
Holds: HRA 0.2.15 · core 0.0.14ag [Uninstall]Offered: HRA 0.2.16 · core 0.0.14ah [Import]Importing changes nothing that is running. It copies artefacts into the release area and stops there, so a version can be brought to a live node at no cost and left sitting until somebody chooses it. That is what makes rolling an estate forward node by node, in your own time, free until the moment of choosing.
From a shell on that machine, the same thing:
./helixctl import # what could be taken in./helixctl import helix-hra-0.2.16.tar # take that oneChoosing a version
Section titled “Choosing a version”The version is confirmed when a node starts, which is also why changing it means stopping first: the SPA is served out of the core image, so a browser holding a half-loaded page against a swapped core would be running two versions at once. Mission Control refuses to swap software under a live node for the same reason.
The start control offers every version that machine holds, defaulting to the newest for this cluster’s client — not merely the newest file, since a release area is shared between the nodes on a machine and may hold another client’s bundles. As pinned leaves it on the version it already has, which is every ordinary restart.
Starting at a version pins that core, obtains it — from the machine’s own release area if the archive is there, otherwise the registry — deploys the client, and then starts. Core before bundle, always: a deploy compares the bundle against the core the node already has and refuses first, so a bundle cannot “wait” for a core to arrive later.
Going back is the same act. A rollback is starting at an older version that is still in the release area. The one thing to know is that it can be refused, and by design: once a world has been written by a newer core, an older one will not open it — it stops at boot and names both versions rather than damaging data. The primary’s card shows what the world is stamped at and what the running build reads, so you can see that before you try it.
The writer goes last
Section titled “The writer goes last”Changing the version of the node holding the write takes Mission Control down with it, because the console runs on the writer. So either do that node last, or hand the write over first:
- Step down the writer, which moves both the write and the console to another node.
- Roll the node that is now a secondary.
- Repeat, ending with the node that was the writer.
That is the same order the cluster procedure has always wanted — secondaries first, one handover, the old writer last — and it is one election rather than one per node.
Uninstall
Section titled “Uninstall”The only verb that removes anything, and it has two cases that differ sharply.
| any version | the last one | |
|---|---|---|
| that version’s artefacts | removed | removed |
| its core image | offered to the prune, which keeps anything pinned, in use, or recent | the same |
| the world | kept — you may be rolling back to it | removed, with the node’s storage and home |
| the launcher and the agent | kept | removed |
| the replica set | untouched | left first, so the set never holds an entry for something being destroyed |
| this console’s card | kept | removed |
So a version removal is ordinary and reversible; the last one turns the node back into a machine and cannot be undone. The console says which one you are about to do, in those words, and asks you to confirm the machine’s own name for the second.
Removing the agent is safe. Placing one needs only SSH, so a machine carrying neither agent nor launcher is still reachable and still installable. Leaving it behind would mean a machine we have finished with still answering as a node.
It works on a machine that has died. Leaving the set is a reconfiguration performed by the writer, so it needs no answer from the machine being removed — which matters, because a failed machine that is still a voting member can stop the survivors reaching a majority.
What each state offers
Section titled “What each state offers”| state | what you can do |
|---|---|
| running | Stop · Check · Import · Uninstall a version it is not serving |
| installed, not started | Start <role> at a version · Re-install · Import · Uninstall · Check |
| raw | Install · Check |
| an install that failed | Remove · Check — with the reason it failed |
A node’s mode is not editable. A node is started as something, and the cluster’s view of a member must not be able to disagree with the software actually running there. Changing it is a stop and a start.