Run, stop and remove every Container through EnsureContainer#1696

merged1
rpc-simplify/r6-ensure
rpc-simplify/r7-ensure-callers
openedOct 13, 2026byNNick
View on GitHubGitHub import enabledPR last imported 21d ago

This is the seventh and last PR of the Machine RPC catalog simplification. It moves every caller onto EnsureContainer and deletes the seven verbs it replaces: CreateContainer, StartContainer, MarkContainerStopping, StopContainer, RemoveContainer, GetContainerObservations and GetIngressProxyConfig, along with the Ingress capability group.

What changes

  • The deploy executor sends wants.
    • A new Container is Running{New}, then the health wait.
    • A replace removes the old Container with Gone{Id, DEFAULT}.
    • A failed new Container is removed with Gone{Key, NONE}. This is skipped on Conflict, and for Global keys, which could name an earlier attempt's Container.
    • Hooks use no drain.
    • StopFirst stops the old Container first and removes it once the new one is healthy, so a failed new Container can hand the slot back.
  • The withdrawal chain and the observations barrier are gone. The Machine that stops a Container drains behind its ingress first. A one-slot replace goes from 9 Container calls and 3 polls of every Machine to 2 calls and none. The planning reads before them don't change: on 2 Machines, verify measured 14 RPCs for one replace, 11 of them reads and 1 the health poll.
  • Every new Container has a creation key, so a resent create finds the Container a lost reply made.
    • A Global slot keeps today's key exactly, so its Docker name survives the upgrade.
    • A replicated slot or pre-deploy hook gets {run}:{plan hash}:{op index}.
      • Cloud's run is the Deployment id, so an Inngest retry finds its own Containers.
      • The CLI's is a fresh id per run. A CLI run that crashes and is run again leaves the first Container for the next deploy to prune.
    • A move gets move:{old}.
  • ployz service stop, start and restart send Stopped, Running and Stopped-then-Running. Stop keeps the user's signal and grace period. In Cloud, a leg a crashed step already sent is sent again and its answer recorded, instead of reading unknown.
  • The SDK's stop_one, start_one and remove_one send wants. Their napi names and TypeScript signatures don't change. remove_one now removes anonymous Volumes too, as does removing a Global slot.
  • A refused want maps to one error code:
    • not found → NotFound;
    • not participating → Unavailable;
    • invalid ingress → InvalidArgument;
    • not eligible, slot occupied, volumes not prepared → Conflict;
    • image pull failed → Internal.
  • Cloud gates deploys and service actions with serverSupports.
    • A Deployment that would touch a Server known to lack EnsureContainer fails before it runs, with "Deploys need a newer Ployz on web-1".
    • A stop or start on such a Server fails that leg with "web-1 needs a newer Ployz to stop it". A Server whose capability read unknown and then refused gets the same line.
    • A Drain of such a Server, or one that would move a Container while any services Server lacks it, refuses before anything turns off: "Drains need a newer Ployz on web-1".
    • An unknown capability attempts the call. No Cloud code compares versions.
  • The deploy progress JSON loses its barrier and wait_error fields.
  • core/DESIGN.md names the seven verbs as removed under rule 6, with no shim.
  • docs/user changes.
    • Stopping or restarting the same Service from the CLI and from Cloud at once can now leave it either running or stopped.
    • The text about a stop waiting on every proxy is gone. A stopping replica is marked so every web Server stops sending it requests, and it stops a few seconds later.
    • The version-skew notes cover the Drain refusal, and a CLI ployz drain of a v0.2.4 Server: services turn off, then the drain refuses, and a rerun after upgrading recovers.

Who notices

Cloud ships when this merges. Until the release, and until the three live Servers are upgraded:

  • a Cloud deploy that touches a v0.2.4 Server fails before it runs, with "Deploys need a newer Ployz on ";
  • a Cloud stop or start on one fails that leg;
  • a Cloud Drain that would touch one refuses before anything turns off.

The installed v0.2.4 CLI keeps deploying through its own verbs. After the release, the new CLI refuses a deploy to a v0.2.4 daemon, naming ployz.container.ensure.v1, before it changes anything.

This PR is a draft until the top of the stack is verified end to end.

Checks

16 successful · 1 skipped
All checks passed
03f9273

Added 1 commit

  • Run, stop and remove every Container through EnsureContainer03f9273
Synced from GitHub

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

yaml
1reviews:
2 auto_review:
3 drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.