feat(updates): bridge Fleet API to host updater - #837
Conversation
🔐 Codex Security Review
Review SummaryOverall Risk: NONE FindingsNo concrete security, correctness, or reliability issues were identified in the changed hunks. NotesThe authoritative diff was structurally valid. Authentication, authorization, version validation, bounded executor communication, sensitive-response redaction, and protobuf compatibility were reviewed. Generated by Codex Security Review | |
3f3e13b to
25b43f7
Compare
25b43f7 to
777cc29
Compare
777cc29 to
715c038
Compare
715c038 to
9cd7725
Compare
9cd7725 to
0e47a53
Compare
0e47a53 to
8e17a87
Compare
c7947bd to
e43e2e7
Compare
e43e2e7 to
3a85af8
Compare
3a85af8 to
0c2c419
Compare
0c2c419 to
15049e3
Compare
15049e3 to
4386fad
Compare
4386fad to
6ffb136
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ffb136618
ℹ️ 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.
Pull request overview
This PR extends the Fleet updates surface to support one-click host upgrades by adding new InstanceUpdateService RPCs (TriggerUpgrade, GetUpgradeStatus) and wiring them through the server updates domain to a bounded Unix-socket HTTP client that talks to the privileged host updater.
Changes:
- Add upgrade trigger + durable upgrade status RPCs to the updates proto contract (plus regenerated bindings).
- Implement server handler + middleware/interceptor policy for the new procedures (session-only, permission-gated, response redaction).
- Add updates-domain executor client + trigger/retry/reconcile logic and activity auditing for confirmed triggers.
Reviewed changes
Copilot reviewed 15 out of 18 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
server/internal/handlers/updates/handler.go |
Adds RPC handler methods for triggering and reading upgrade status; maps domain operation/phase to protobuf. |
server/internal/handlers/updates/handler_test.go |
Adds coverage for upgrade phase enum mapping. |
server/internal/handlers/updates/handler_perms_test.go |
Extends permission-gating tests to the new update RPCs and cancellation-code mapping. |
server/internal/handlers/middleware/rpc_permissions.go |
Classifies new update procedures under instance:update. |
server/internal/handlers/interceptors/config.go |
Adds new procedures to session-only and redacted-response lists. |
server/internal/handlers/interceptors/config_test.go |
Ensures new procedures are session-only and redacted. |
server/internal/domain/updates/service.go |
Implements one-click availability probing, trigger logic with same-ID retry + reconciliation, and durable status retrieval. |
server/internal/domain/updates/service_test.go |
Adds executor fakes and tests for trigger mapping, retry/reconcile semantics, and upgrade status behavior. |
server/internal/domain/updates/executor.go |
Introduces Unix-socket HTTP client with bounded JSON decoding and error typing. |
server/internal/domain/updates/executor_test.go |
Adds integration-style tests around Unix-socket request/response shapes, bounds, and retry behavior. |
server/internal/domain/updates/config.go |
Adds UpdaterSocketPath config and validates it is absolute when set. |
server/internal/domain/updates/config_test.go |
Adds validation coverage for UpdaterSocketPath. |
server/cmd/fleetd/main.go |
Wires activity logging into the updates domain service construction. |
proto/instance/v1/updates.proto |
Adds upgrade RPCs/messages and one_click_available + upgrade phase/operation schema. |
server/generated/grpc/instance/v1/updates.pb.go |
Generated Go protobuf output for the updated updates contract. |
server/generated/grpc/instance/v1/instancev1connect/updates.connect.go |
Generated Connect-RPC bindings for new procedures. |
client/src/protoFleet/features/settings/components/Updates.test.tsx |
Adjusts helper typing for generated message overrides. |
client/src/protoFleet/api/generated/instance/v1/updates_pb.ts |
Generated TS protobuf output for the updated updates contract. |
7c3aa70 to
8f245c1
Compare
Reviewable diff: +537/-27 across 8 files (excludes generated, test, and story files).
Summary
Adds the permission-gated Fleet RPC contract and Unix-socket client that mediate access to the host updater. Trigger requests now use the idempotent operation-ID contract introduced by #836, so Fleet can safely recover from a lost acknowledgement without starting a duplicate upgrade. When the daemon socket is absent, Fleet reports
one_click_available=false, preserving the manual update experience.Stack: #841 → #842 → #843 → #844 → #845 → #835 → #836 → #837 → #838 → #839 → #840. This is 3/6 of the one-click phase; its diff is relative to #836. The parent supplies the privileged updater and accepts both legacy target-only and new ID-bearing requests. Client exposure remains in #838–#840; unsupported hosts continue using the manual flow.
How it works
GetUpdateStatusperforms a bounded status probe and advertises one-click only when the independent executor is reachable.TriggerUpgradere-derives the organization’s currently eligible release, rejects stale or arbitrary targets, creates an operation ID, and sends only that ID plus the validated tag over the Unix socket. A lost or malformed acknowledgement is retried once with the same ID, then reconciled against exact durable status; an unconfirmed outcome remainsUnavailablerather than encouraging a second upgrade path. Confirmed triggers are activity-audited once using a cancellation-detached bounded context.sequenceDiagram participant C as "Future capability-gated client" participant F as "Fleet InstanceUpdateService" participant U as "Host updater from #836" C->>F: "TriggerUpgrade(target)" F->>F: "Authorize and revalidate eligible target" F->>U: "POST operation ID + target" alt "Acknowledgement received" U-->>F: "Durable operation" else "Outcome is ambiguous" F->>U: "Retry same operation ID" F->>U: "GET durable status if still unconfirmed" U-->>F: "Exact operation ID or no confirmation" end F-->>C: "Operation or conservative Unavailable"Areas of the code involved
proto/instance/v1server/generated, client generated APIserver/internal/domain/updatesserver/internal/handlers/updatesserver/internal/handlers/interceptorsserver/internal/handlers/middlewareinstance:updateserver/cmd/fleetdKey technical decisions & trade-offs
Unavailablerather than suggesting the install command, which could launch a second upgrade path.Testing & validation