Skip to content

Commit a816fa1

Browse files
committed
feat(supervisor): add independent application listener and endpoints
Signed-off-by: Taylor Mutch <taylormutch@gmail.com>
1 parent e5adf6f commit a816fa1

41 files changed

Lines changed: 2891 additions & 106 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.agents/skills/helm-dev-environment/SKILL.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,3 +608,14 @@ for dependencies still declared in `Chart.yaml`.
608608
| `deploy/kube/manifests/envoy-gateway-openshell.yaml` | GatewayClass and BackendTrafficPolicy for Envoy Gateway (`mise run helm:gateway:apply`) |
609609
| `tasks/scripts/helm-k3s-local.sh` | k3d cluster create/delete/start/stop/status |
610610
| `tasks/scripts/keycloak-k8s-setup.sh` | Keycloak deploy, realm import, and development TLS trust anchor |
611+
612+
## App listener fixture
613+
614+
The opt-in `deploy/helm/openshell/ci/values-app-listener.yaml` enables the
615+
supervisor listener at port 9443 without discovery or a proxy. Provision the
616+
operator TLS Secret and an ingress-client NetworkPolicy first. Follow
617+
`e2e/kubernetes/app-listener/README.md` for direct in-cluster verification,
618+
shared-member selection, and the HA follow-up checks. Keep the fixture disabled
619+
in default profiles. Shared supervisors expose app ports on their Pod IPs
620+
without a shared app Service. Select the member owning the sandbox; automatic
621+
owner selection belongs to the later discovery API.

‎Cargo.lock‎

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! Driver-independent application listener configuration.
5+
6+
use serde::{Deserialize, Serialize};
7+
8+
/// Explicitly enabled application ingress. Deployment details such as TLS
9+
/// Secret names belong to the driver, not to this common configuration.
10+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
11+
#[serde(default, deny_unknown_fields)]
12+
pub struct AppListenerConfig {
13+
pub enabled: bool,
14+
pub port: u16,
15+
pub domain: String,
16+
}
17+
18+
impl Default for AppListenerConfig {
19+
fn default() -> Self {
20+
Self {
21+
enabled: false,
22+
port: 8443,
23+
domain: String::new(),
24+
}
25+
}
26+
}
27+
28+
impl AppListenerConfig {
29+
pub fn validate(&self) -> Result<(), String> {
30+
if !self.enabled {
31+
return Ok(());
32+
}
33+
if self.port < 1024 {
34+
return Err("supervisor.app_listener.port must be at least 1024".into());
35+
}
36+
if self.domain.len() > 253
37+
|| !self.domain.split('.').all(|label| {
38+
!label.is_empty()
39+
&& label.len() <= 63
40+
&& !label.starts_with('-')
41+
&& !label.ends_with('-')
42+
&& label
43+
.bytes()
44+
.all(|b| b.is_ascii_lowercase() || b.is_ascii_digit() || b == b'-')
45+
})
46+
{
47+
return Err("supervisor.app_listener.domain must be a lowercase DNS name".into());
48+
}
49+
Ok(())
50+
}
51+
}
52+
53+
#[cfg(test)]
54+
mod tests {
55+
use super::*;
56+
57+
#[test]
58+
fn only_explicit_enablement_requires_a_valid_endpoint() {
59+
assert!(!AppListenerConfig::default().enabled);
60+
assert!(AppListenerConfig::default().validate().is_ok());
61+
let mut config = AppListenerConfig {
62+
enabled: true,
63+
..Default::default()
64+
};
65+
assert!(config.validate().is_err());
66+
config.domain = "services.example.com".into();
67+
assert!(config.validate().is_ok());
68+
config.port = 0;
69+
assert!(config.validate().is_err());
70+
}
71+
}

‎crates/openshell-core/src/config.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ pub struct Config {
332332

333333
/// Browser-facing sandbox service routing configuration.
334334
pub service_routing: ServiceRoutingConfig,
335+
pub supervisor_app_listener: crate::app_listener::AppListenerConfig,
335336
}
336337

337338
/// Browser-facing sandbox service routing configuration.
@@ -953,6 +954,7 @@ impl Config {
953954
grpc_rate_limit_requests: None,
954955
grpc_rate_limit_window_secs: None,
955956
service_routing: ServiceRoutingConfig::default(),
957+
supervisor_app_listener: crate::app_listener::AppListenerConfig::default(),
956958
}
957959
}
958960

‎crates/openshell-core/src/grpc_client.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,7 @@ pub struct CachedOpenShellClient {
17411741
/// Settings poll result returned by [`CachedOpenShellClient::poll_settings`].
17421742
#[derive(Clone, Debug)]
17431743
pub struct SettingsPollResult {
1744+
pub service_routes: Vec<crate::proto::SandboxServiceRoute>,
17441745
pub configuration_instance_id: String,
17451746
pub configuration_admitted: bool,
17461747
pub configuration_error: String,
@@ -1768,6 +1769,7 @@ pub struct SettingsPollResult {
17681769

17691770
fn settings_poll_result(inner: crate::proto::GetSandboxConfigResponse) -> SettingsPollResult {
17701771
SettingsPollResult {
1772+
service_routes: inner.service_routes,
17711773
configuration_instance_id: inner.configuration_instance_id,
17721774
configuration_admitted: inner.configuration_admitted,
17731775
configuration_error: inner.configuration_error,
@@ -1797,6 +1799,7 @@ fn settings_poll_result(inner: crate::proto::GetSandboxConfigResponse) -> Settin
17971799
impl From<crate::proto::SandboxConfigSnapshot> for SettingsPollResult {
17981800
fn from(snapshot: crate::proto::SandboxConfigSnapshot) -> Self {
17991801
settings_poll_result(crate::proto::GetSandboxConfigResponse {
1802+
service_routes: snapshot.service_routes,
18001803
policy: snapshot.policy,
18011804
version: snapshot.version,
18021805
policy_hash: snapshot.policy_hash,

‎crates/openshell-core/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//! - Build version metadata
1111
1212
pub mod activity;
13+
pub mod app_listener;
1314
pub mod auth;
1415
pub mod config;
1516
pub mod container_paths;

0 commit comments

Comments
 (0)