feat(updates): bootstrap host updater installs - #839
Conversation
🔐 Codex Security Review
Review SummaryOverall Risk: NONE FindingsNo concrete security, correctness, or reliability defects were found in the changed hunks. NotesBash syntax and diff-integrity checks passed. Functional shell tests could not run because the review environment’s temporary filesystem is read-only. Generated by Codex Security Review | |
f031dd7 to
1ed35a3
Compare
455254a to
d79c649
Compare
d79c649 to
faa6e55
Compare
faa6e55 to
1e46cc9
Compare
1e46cc9 to
83cc576
Compare
83cc576 to
15d9faf
Compare
8ff8e73 to
f9a6056
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f9a60566a3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: edd1075934
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ${privilege[@]+"${privilege[@]}"} systemctl disable --now \ | ||
| proto-fleet-updater.service >/dev/null 2>&1 || true |
There was a problem hiding this comment.
Disable runtime-enabled updater units with --runtime
When the existing service has UnitFileState=enabled-runtime, this plain systemctl disable --now edits only persistent unit links; the /run/systemd/system/...wants link remains, so the following state check still sees enabled-runtime and aborts every installer upgrade after stopping the updater. Fresh evidence beyond the earlier runtime-restoration finding is that systemctl --root left the unit runtime-enabled after this exact command, while systemctl --help says --runtime applies enable/disable changes “temporarily until next reboot.” The same unqualified disable in disable_direct_run_updater and prepare_host_updater_removal blocks fallback or leaves a stale link, so select runtime disablement for this state in all three lifecycle paths.
AGENTS.md reference: AGENTS.md:L141-L144
Useful? React with 👍 / 👎.
| if ! load_state=$(systemctl show --property=LoadState --value \ | ||
| proto-fleet-updater.service 2>/dev/null); then |
There was a problem hiding this comment.
Fall back when no systemd manager is reachable
On a Linux host where systemctl and /run/systemd/system exist but the manager bus is unavailable, such as a container or chroot exposing that runtime path, this query returns nonzero and marks cleanup failed before checking whether any updater artifact exists. Fresh evidence beyond the earlier runner fallback finding is that the installer therefore aborts a clean manual install before extraction instead of reaching the documented no-systemd copy-command fallback; systemctl --help describes show as querying units/jobs or the manager, and a no-manager invocation returns status 1. Detect manager availability before this query and treat it as unsupported when no updater artifacts need reconciliation.
AGENTS.md reference: AGENTS.md:L141-L144
Useful? React with 👍 / 👎.
Reviewable diff: +907/-32 across 6 files (excludes generated, test, and story files).
Summary
Bootstraps the packaged host updater on supported Linux/systemd installations with rootful Docker, then exposes only its secured Unix socket to Fleet. Unsupported hosts and any bootstrap path that cannot reach a verified safe state explicitly retain the existing copy-command experience.
Stack: #841 → #842 → #843 → #844 → #845 → #835 → #836 → #837 → #838 → #839 → #840. This is 5/6 of the one-click phase. All ancestors are merged, so this diff is directly against
main; those PRs provide release discovery, capability reporting, the privileged updater, and the server trigger path. This PR installs and connects that updater, while #840 adds the operator-facing one-click action. Manual upgrades remain available throughout.How it works
The installer validates the requested release name, downloads the bundle and matching SHA-256 sidecar into a private temporary directory, checks the exact filename and digest, and captures any legacy optional-overlay choices before replacing the deployment. On a compatible host it installs the updater binary, root-only environment, and systemd unit; verifies root and the installer use the same Docker daemon; and waits up to 60 seconds for an authenticated request over the Unix socket to succeed. Only then does
run-fleet.shpersistENABLE_ONE_CLICK_UPDATES=trueand layer the socket-only Compose overlay. Every unsupported or safely recoverable failure persistsfalse; cleanup uncertainty aborts the install. Uninstall stops and verifies the service before touching Docker, then removes exact updater files, state, runtime sockets, and hash-named staging directories.flowchart LR I["Installer"] --> D["Private bundle download"] D --> V["Validate version, sidecar name, and SHA-256"] V --> H{"Compatible systemd and rootful Docker host?"} H -->|"yes"| S["Install service and verify Unix-socket readiness"] S --> O["Persist enabled state and layer updater socket"] H -->|"no or safe fallback"| M["Persist disabled state and keep copy command"] O --> F["Start Fleet"] M --> FsequenceDiagram participant I as Installer participant G as GitHub Releases participant U as Host updater service participant R as run-fleet participant F as fleet-api I->>G: Download bundle and checksum sidecar I->>I: Verify exact asset digest and migrate legacy flags I->>U: Install, enable, restart I->>U: Poll status over secured Unix socket alt updater is ready I->>R: Enable one-click overlay R->>F: Start with read-only socket mount else unsupported or safely disabled I->>R: Disable one-click overlay R->>F: Start with manual fallback only endAreas of the code involved
deployment-files/install.shdeployment-files/run-fleet.shdeployment-files/uninstall.shdeployment-files/README.md,README.md.github/workflows/deployment-config-checks.ymlKey technical decisions & trade-offs
Testing & validation
bash -nvalidation for installer, runner, uninstaller, and deployment test scripts../deployment-files/tests/test-install-overlay-migration.sh./deployment-files/tests/test-profiles.sh./deployment-files/ha/tests/test-profile.sh./deployment-files/tests/test-run-fleet-upgrade.shgit diff --check origin/main..HEAD