feat(ctl): add umwelt-ctl update #6
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/ctl-update"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds
umwelt-ctl update— one command that refreshes a host after a code change: the local install, every provisioned remote server, and (opt-in) the running sandboxes.Today a rollout means re-running
remote-installby hand for each server and knowing which of them were provisioned with--egress. This is that, once.The command
updateupdate --allupdate headlessupdate --restartupdate --all --restartNames and
--alltogether are an error. A named run never touches the local planes. Every restart is the gracefulshutdown, never--hard.--forceoverrides the up-to-date skip without regenerating a server's base config.Per-server state
[[server]]gains an optionalremote_dir/config/egressrecord, written byremote-installon every install; absent keys mean today's defaults, so existing registries keep working. An entry with no record is probed once over admin ssh — the[egress]verdict from the server's own config, the install directory recovered from its managedauthorized_keysrelay path — and the answer is written, so the next update is cheap.remote-statususes the recorded directory too. Up-to-date servers are skipped by their tree digest, and one server's failure never stops the others.Remote restarts stop a server's running agents over admin ssh through the tree already pushed there (
ctl.py stop <sid>, graceful), using the server's own session prefix. The next call relaunches them on the new tree; the local cached transport self-heals.Notes
ctl.pyhad to join the reduced-push manifest (nothing else in a pushed tree can send that shutdown), which changes the tree digest — so the firstupdatere-pushes every provisioned server. Intended for a code change, but it is a full re-push._verify_server_floor(used by the install verify andremote-status) is still bound to the default install root, so a non-default--remote-dirserver has its egress artifacts under-checked.Testing
1123 passed, 3 skipped(baseline 1073). 32 new tests inumwelt/tests/test_ctl_update.pyplus additions totest_remotes.py,test_provision.py,test_ctl_remote.py. Every new test is hermetic — no ssh, no podman, no network — through the injectedrun; the generated ssh snippets are additionally executed for real undersh -cagainst temp directories. Docs updated inCONFIGURATION.mdandAGENTS.md.`_remote_agents_command` globbed `$XDG_RUNTIME_DIR/{prefix}-*.sock` with the *local* effective prefix (`load_prefix(config)`), so a host whose own `session_prefix` differs from the server's looked for a glob that server does not have: it reported "no running agents" and `--restart` silently left the remote agents alone - exactly the per-remote knowledge this command exists to remove. The snippet now reads the server's prefix out of the server's own config (the same file the stop command names, defaulting to the install dir's umwelt.toml that remote-install.sh generated) with `umwelt` as the fallback, and reports it, so "no running agents" names the glob that server actually has. `_remote_agents_command` loses its `prefix` argument, `_restart_remote_agents` no longer takes the local prefix, and the local enumeration keeps `load_prefix(config)`.