Repository navigation
Conversation
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
🌿 Preview your docs: https://nvidia-preview-pr-4864.docs.buildwithfern.com/openshell |
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
matthewgrossman
left a comment
There was a problem hiding this comment.
Review of head 06cd2e2 from a multi-agent review panel (security, correctness, API/UX, and scope reviewers, plus a verification and triage step). I checked the one blocking finding against the code by hand. The reviewers read the code but didn't build it or run tests.
Summary: a large but coherent HA feature for #4860. The security reviewer found no new problems with the takeover grants, credential-epoch fencing, or the state preserved during adoption. One correctness issue should be fixed before merge. Everything else is polish or follow-up.
Fix before merge
- A refused pool launch leaves its assignment record and launch material behind, and another replica can later give it a takeover owner (
supervisor_pool.rs:1731).
Small fixes
- A config error message contains runs of spaces (
lib.rs:1876). - The pool/non-pool mismatch errors don't name the setting to change (
controller.rs:1037). - The HA docs don't say what an upgrade does to running sandboxes (
high-availability.mdx).
Follow-ups (fine as separate issues)
- Member freshness and report ordering compare wall-clock times written by different replicas.
- A design record (RFC) for pool ownership, takeover grants, and epoch fencing.
- Decide whether the non-pool shared-supervisor mode stays, since Helm always enables the pool.
Considered and not raised: splitting this ~24k-line PR into smaller PRs. It's one coherent, tested feature, so that's your call.
Details are in the inline comments.
| } | ||
| } | ||
|
|
||
| fn fresh(&self, record: &ObjectRecord) -> bool { |
There was a problem hiding this comment.
Follow-up (non-blocking): cross-replica clock comparisons
fresh() compares this replica's now_ms() with an updated_at_ms that another replica wrote from its own clock. write_member and record_reports also order streams by connected_at_ms from different replicas. With a 15 s TTL, a few seconds of skew between gateway replicas could make a live member look expired, which would trigger an unneeded takeover, or could let a stale stream's report win.
Options: use database time (now() in the UPDATE) for freshness and ordering across both the postgres and sqlite stores, or document a clock-sync requirement for multi-replica gateways. Fine as a follow-up issue.
There was a problem hiding this comment.
Deferred to a follow-up, per the maintainer's decision. This PR retains cross-gateway wall-clock comparisons for membership freshness and stream ordering. A follow-up should use a common time basis for both writing and checking expiry, and avoid ordering competing streams by clocks from different replicas. Leaving this thread unresolved to track that work.
| > **Implementation note ([#4860](https://github.com/NVIDIA/OpenShell/issues/4860)).** | ||
| > The built-in OpenShell runtime adds an explicit, capability-gated exception | ||
| > for highly available shared supervisors | ||
| > (`openshell.sandbox.supervisor-takeover`, protocol 1.1). A replacement |
There was a problem hiding this comment.
Follow-up (non-blocking): design record for pool ownership
This PR adds durable membership and ownership with CAS terms, gateway-signed takeover grants, credential-epoch fencing, a Sandbox Protocol minor bump, and a Helm default change. The RFC side is this short note. A short RFC, or an extension of RFC 0012, recording the trust model, the invariants, and the non-goals (multi-gateway partitions, node loss) would make later changes easier to review. It doesn't need to block this PR.
There was a problem hiding this comment.
Deferred to the existing RFC work in #4377 — RFC 0018: multi-sandbox and HA supervisors, per the maintainer's decision. That RFC should be aligned with the final implementation here, including pool ownership/CAS terms, takeover grants, credential-epoch fencing, trust boundaries, invariants, and the limits of the validated failure scenarios. Leaving this thread unresolved.
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Compatibility review (advisory)New or updated breaking changes; see the full report for all findings. 1. cli — No explicit risk acceptance foundThe existing
2. rust-sdk — No explicit risk acceptance found
Review details
Advisory review; publication gates are unchanged. |
TaylorMutch
left a comment
There was a problem hiding this comment.
Reviewed head abffde246 locally. I found two correctness issues, each reproduced with a focused Rust test against this commit; details and reproduction steps are inline.
Validation: 30 supervisor Helm tests, the render-only 1/2/3-replica scaling check, 13 sandbox authentication tests, and the original 12 supervisor-control tests passed. The two additional regression assertions fail at the expected behavior checks. Temporary source changes were restored. These reproductions exercise the Rust controller and SQLite-backed pool; I did not run live Kubernetes recovery E2Es or PostgreSQL validation.
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Summary
Add high availability for the shared supervisor introduced by #4702. A hash ring places new sandbox generations, while durable ownership and gateway-signed takeover grants let a replacement supervisor adopt existing runtimes, processes, and memory without restarting workloads. Shared supervisors always use pool coordination, including at one replica.
Compute drivers are unchanged from base
9a85667d0. Coordination remains in the gateway and supervisor control layer.Related Issue
Closes #4860
Changes
[openshell.gateway.supervisor_pool]optionally tunes the recovery deadline (60 seconds by default); member identity is required, and configuration errors name the setting to fix. Per-sandbox supervision remains available.supervisor.replicasscales 1 → 2 → 1 without changing gateway configuration or replacing surviving members.Release Notes
Shared supervisors always run as a pool; set
supervisor.replicasto change capacity. One replica has no spare for immediate failover. During takeover, workloads can briefly freeze and existing proxied connections or interactive sessions must reconnect. Workloads terminate if supervision is not restored within the recovery deadline.Testing
0cdfdd3f5: 2,683 passed, 33 skipped across server (test-support), supervisor-control, and supervisor.helm:test, rendered-TOML loader validation, count-independent 1/2/3 renders, Helm lint/docs, affected Clippy with warnings denied, formatting, and Markdown lint passed.b0cb1b0edand supervisor0cdfdd3f5(unchanged by the final gateway log-format follow-up): 1 → 2 → 1 passed (76.27 s), plus all seven helpers. Workload Pod UID/generation/PID/start ticks/in-memory counter and gateway/surviving-supervisor identity stayed unchanged; a new sandbox worked after downscale. The handed-off workload had one transient exec and one network probe failure, with a 4.27 s maximum gap between successful probes (including the 2 s sampling interval); the unaffected workload had no failed probes.abffde246images passed (36.69 s), plus all seven helper tests: direct supervisor SIGKILL, no graceful Leave, expiry-based takeover, preserved workload identity/memory, restored exec/network, and an unaffected workload.0cdfdd3f5(169.90 s) and the log-format follow-upb0cb1b0ed(50.71 s), including workspace/extra-configuration Rust lint, format/license/lockfile, Helm, protobuf, Markdown/Mermaid, Python, and TypeScript checks.Live Kubernetes validation uses one local k3d node. Physical node loss and multi-gateway partitions are not exercised. Cross-replica wall-clock comparisons remain deferred. Aligning the ownership design record with this implementation is deferred to RFC 0018 (#4377); both review threads remain unresolved.
Pool members share the supervisor credential, so declared member identity is within that trust boundary. Identity-bound provider placeholders without stable handles can fail closed after takeover if their provider revision changed. Service discovery adds bounded periodic probes per pool sandbox. A crash between credential creation and candidate staging can leave orphaned material, as in the existing SSH host-key path.
Checklist