Repository navigation
feat(supervisor): add independent application listener and endpoints - #4936
TaylorMutch wants to merge 2 commits into
Conversation
|
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-4936.docs.buildwithfern.com/openshell |
6969959 to
a1cae53
Compare
a816fa1 to
dfb34da
Compare
Signed-off-by: Taylor Mutch <taylormutch@gmail.com>
dfb34da to
d94fb6a
Compare
Compatibility review (advisory)New or updated breaking changes; see the full report for all findings. 1. rust-sdk — No explicit risk acceptance foundThe SDK-reachable raw::proto::SandboxConfigSnapshot and GetSandboxConfigResponse structs gain a required service_routes field, invalidating previously exhaustive literals and patterns.
2. typescript-sdk — No explicit risk acceptance foundRegenerated SandboxConfigSnapshot and GetSandboxConfigResponse types gain a required serviceRoutes array in the public raw entry point.
Review details
Advisory review; publication gates are unchanged. |
Signed-off-by: Taylor Mutch <taylormutch@gmail.com>
|
/ok to test d46a19f |
|
Label |
Summary
Add an opt-in supervisor TLS listener for declared HTTP and WebSocket services. Application traffic connects directly to the owning supervisor and sandbox loopback connector, bypassing the gateway.
Related Issue
Closes #4666. Part of RFC 0017.
Changes
Release Notes
The application listener remains opt-in and disabled by default.
Application listener request flow
This PR adds an opt-in TLS listener on the supervisor. The gateway supplies
configuration, while application traffic reaches declared sandbox services
through the selected sandbox instance's connector.
flowchart TB subgraph Configuration["Configuration and deployment"] SETTINGS["Operator enables app listener<br/>Domain, port, TLS Secret"] KUBE["Kubernetes driver / Helm<br/>Configure supervisor port and mount TLS material"] DECLARE["Sandbox service declaration<br/>Example: web → port 8080"] GW["OpenShell gateway<br/>Include service allowlist in sandbox configuration"] SETTINGS --> KUBE DECLARE --> GW end subgraph HOST["Supervisor process — dedicated or shared"] TLS["One process-level TLS listener<br/>Example: Pod IP:8443"] ROUTER["SNI dispatcher<br/>Select sandbox instance"] subgraph INSTANCE["Selected sandbox instance"] CONFIG["Apply accepted configuration<br/>Install routes and renew freshness"] CHECK["Validate installed route and freshness<br/>Require HTTP Host to match TLS SNI"] PROXY["HTTP/1.1 or WebSocket proxy<br/>Apply limits and sanitize headers"] CONNECTOR["This instance's<br/>BoundaryLoopbackConnector"] CONFIG -.->|"Route table and validity"| CHECK CHECK -->|"Accepted"| PROXY PROXY --> CONNECTOR end TLS --> ROUTER ROUTER --> CHECK OTHER["Other sandbox instances<br/>Separate routes, connectors and lifetimes"] ROUTER -->|"Other SNI hostname"| OTHER REVOKE["Route removed or changed,<br/>configuration rejected, freshness expires,<br/>or instance stops"] CONFIG -.-> REVOKE REVOKE -.->|"Reject affected traffic<br/>Close affected active streams"| PROXY end subgraph SANDBOX["Selected sandbox"] APP["Application<br/>127.0.0.1:8080"] end CLIENT["Client<br/>team--demo--web.apps.example.com"] EDGE["Externally configured ingress / proxy<br/>or direct connection"] KUBE -.->|"Startup configuration"| TLS GW -->|"Existing configuration push / poll"| CONFIG CLIENT --> EDGE EDGE -->|"TLS with application SNI"| TLS CONNECTOR -->|"Connect to declared loopback port"| APPinstances. Each retains its own connector, limits, and lifetime.
through successful configuration delivery or an accepted live push session.
Withdrawal or expiry also closes affected streams.
supervisors expose individual Pod endpoints without a shared application
Service; callers must target the owning member.
ingress for authentication. Gateway-mediated authentication is separate.
Advertisements, discovery, authoritative public URLs, the sandbox proxy, and
HTTPRoute reconciliation are outside this PR. The ingress box represents
infrastructure configured externally at this stage. Addresses and ports are
illustrative.
Automated Kubernetes listener checks
mise run e2e:kubernetes:app-listenerdeploys an isolated Helm release withmatching branch images, ephemeral TLS material and in-cluster clients, then
removes its test resources. It needs neither discovery nor the reference proxy.
The
test:e2eCI lane now runs four cases: dedicated push, dedicated poll,shared graceful takeover and shared abrupt takeover. These jobs use the existing
Kubernetes reusable workflow, enable pinned Calico in kind to verify NetworkPolicy
denial, upload failure evidence, and contribute to
Core E2E result.Coverage includes HTTP/WebSockets, verified application TLS, SNI/Host validation,
header handling, named/unnamed routes, dedicated Service DNS/EndpointSlices,
quiet-session freshness, selective withdrawal, gateway-outage expiry/recovery,
workload identity/memory preservation through shared-owner changes, and disabled
listener compatibility with gateway-mediated application access.
Local validation passed on the Helm/k3d development environment, including the
new task for dedicated polling and abrupt shared takeover. The dedicated-push
task also passed end to end on a fresh kind cluster with the same Calico setup
used by CI. Python lint/type/format, workflow lint, Markdown and license checks
passed. Remote CI results are tracked in this PR's checks.
Testing
fdce6ef26: 2,557 server tests passed (34 ignored), 279 supervisor tests, 310 Kubernetes driver tests, 8 proxy tests, full Go SDK CI, and 431 gateway + 6 workspace + 6 proxy Helm tests. All eight PR layers independently passed locked Rust compilation with test targets. Repository pre-commit passed withSETUPTOOLS_SCM_PRETEND_VERSION_FOR_OPENSHELL=0.0.0; plain invocation hits an existing main-branch setuptools-scm failure parsing tagsdk/go/v0.1.6. The final advance to main9f1cdb4efchanges onlytests/suites/features/Cargo.lockin each validated layer. Live HA qualification was not rerun for this rebase.Qualification limits
Live HA validation exercised supervisor process/Pod loss on a local k3d cluster. Whole-node failure, real network partitions, metric-driven HPA, sustained production load, and published release artifacts remain unqualified. Grant-file projection contributes to revocation propagation time. Main now includes #4842 for gateway-mediated hashed hostnames. Direct application-listener/discovery hostnames remain readable; extending hashed naming to that path and installation-status presentation (#4670) remain separate work.
The example Kubernetes HTTPRoute controller is a deferred compatibility POC outside this stack.
Checklist
Draft stack: #4936 → #4940 → #4941 → #4956 → #4963 → #4964 → #4957 → #4958.