Skip to content

Treat a host that is in use or leaving as unfit to hold an etcd vote #220

Description

@Mearman

The role controller's decision (scripts/fleet-role.jq) swaps a voter out only when it is unfit on round trip, WAL fsync, backend commit or readiness. A host that is about to leave is just as unfit for a vote, and nothing says so.

Change: read the presence label (the presence agent issue). A voter that is in use or leaving is unfit, with a reason that names the state, and a standby that is not available is never a fit candidate. The existing swap does the rest: snapshot, runner wait, learner promotion, gates, removal, rollback. The leaving host keeps its vote until the swap finishes, within the swap's own budgets. A host with no presence label is judged as before.

The controller stays in dry run unless the owner turns that off, and the cluster-wide gates and the cooldown after a membership change apply unchanged.

Validation: a mesh scenario in which a voter's presence flips to leaving and the swap runs to completion with the votes never below the target; a scenario in which no standby is fit and the voter stays; unit tests over the decision for each presence value. Each change is broken once to see a test fail.

Depends on the presence agent and on the voter swap controller (#218). Part of the presence-driven regrading epic (#223).

Design input (4 November 2026): a Mac that serves a model runs its node VM and its model server from the same unified memory, so a presence yield frees more than the vote. A yield that stops the VM also stops the voter inside it, and the cluster has one voter fewer until the VM returns. Resizing the VM needs a stop and a start, so a resize and a presence stop are the same operation. Placement has to be told what each yield frees (the VM, the model server, the voter), not a single figure per host.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions