Moving a role of the host Stado process
Moving a role of the host Stado process
stado placement role move SERVICE --to-host B --reason WHY [--json] moves a
directory service the host Stado process serves — the fleet object API,
stado-object-api — which no profile can carry, since that process runs on
every host and a profile fences and starts units. What the role carries is its
store, ~/.stado/local-storage, which every host's Stado serves its object
API from. Under one transaction it copies the store through this machine
while the store still takes writes, then runs stado storage fence arm on
the route's active host (every write there is refused once the writes in
flight have finished), copies again by content only what changed since, and
puts the copy in place on B, where the tree B held is kept as the move's
backup; in one registry commit it then names
B as the route's active host. B's endpoint becomes the address B's
Stado serves the object API on: the catalog's --bind and --port, a port
the catalog names as $STADO_LISTEN_PORT being the one the service directory
records for B, and a literal port as written,
where every caller's tunnel ends; any standby address of B goes, and so does
the source's endpoint, because the source's Stado now serves only the fenced
copy there: callers on the source resolve the service like any other host's.
A step that fails puts B's tree back and lifts the
source's fence, and the error names any of those that failed too. After the
commit the source's copy stays fenced, <source>'s copy stays fenced by transaction <id>: a write there would be lost to the store that now serves.
A move back to a host an earlier role move left lifts the fence that move
left on its store once the route is switched (destination_fence_lifted in
the receipt), since that store serves again. Both fences are read and armed
on the store path itself (--root ~/.stado/local-storage), whatever storage
the host declares.
When the route's active host is also the registry authority, the store the
role carries holds the registry that authority writes, so once the move
fences it no ordinary registry commit lands. --with-authority, run on B,
moves the authority in the same registry: after the copy, the registry is
read from the authority (reads stand under the fence), the route is switched
and B named the authority in one document (the directory generation
advanced for each), and that document is committed at the authority through
its fence by the move's own transaction (stado registry push - --if-generation <version> --fence-transaction <id>, which a fence of any
other transaction still refuses), so the authority itself serves a registry
naming B and every resolver follows on its next refresh. It is then
installed on B: written into the store just copied there through B's own
object API at the catalog's address, before any resolver routes to it, and
into B's last-known-good copy; a fence an earlier role move left on B's
store is lifted before that write and put back when nothing was committed.
Then B's resolver is brought to the registry it now serves (stado resolver follow without --generation: asked to read now with SIGUSR1, asked again
once it moves to its own store, and waited for on its published state), so
every write after the move goes through the route on B; a resolver that
answers without it is named beside the committed move, never undoing it
(<cause>; B's resolver did not follow the registry that moved <service> here, so this host still resolves the old route; stado resolver follow, run here, brings it forward).
A failure before the commit undoes the move as above; once committed, the
route and the authority stand on B, and a store write the install did not
make is named, not undone (<service> moved to B with the registry authority, and B's copy holds the registry; write it into the store with stado registry pull --last-known-good > registry.json and stado registry push registry.json; receipt: …). The receipt carries the install's receipt as
authority, and the check reports with_authority.
Refused before anything changes: a service the directory does not declare, a
route with no managed_service or one served by another unit (… give it a placement profile and move it with stado placement move), a service
already on B, a destination whose store another kind of transaction
fenced (… which no role move armed, so a store moved there would refuse every write; end that transaction first), a source that holds the registry
authority without --with-authority (<source> holds the registry authority, and <service>'s store holds the registry it writes, so no registry commit can land once the move fences that store; move it with --with-authority, run on B), --with-authority for a source that does not
hold it, --with-authority run anywhere but B (the registry authority is taken on the host that takes it: run this on B, not <host>),
and with --with-authority a source whose installed Stado (the authority's
command) offers no registry push --fence-transaction (<source>: its Stado (<command>) offers no registry push --fence-transaction, so the registry commit through its fence would be refused; deliver a Stado that carries it to <source> before moving the role), a B for which the directory records
no listen port the catalog's $STADO_LISTEN_PORT needs (the service directory records no listen port for the host Stado process (stado) on B, so the address it serves the object API on is not known; publish the destination's directory entry first), a catalog --port that is no port
(the catalog's host Stado process names --port <port>, which is no port),
or a B whose own object API does not
answer a registry read at that address (B's own object API at <address> did not answer a registry read, so the registry could not be written there after the move: <cause>).
Before the source is fenced, the store's size on the source is measured
against the free space on B and on this machine, which the copy passes
through, refused with both figures as a placement move's preflight is.
--check stops there, fencing and changing nothing: <service> can move from <source> to B: …; nothing was fenced or changed, or under --json
{"state": "would_move", "service", "from_host", "to_host", "endpoint", "with_authority"}. --json prints {"state": "moved", "service", "from_host", "to_host", "transaction", "registry_generation", "kept_replaced_store", "unsettled_store", "source_fenced", "destination_fence_lifted", "authority"}. Stado Desktop runs it and its check as
"Move a role of the host Stado process".
Source: this website