Skip to content

Commit 917e969

Browse files
committed
M3.14: wire ComputeDriverKind::Substrate dispatch into gateway compute runtime
The M3 scaffold (commit 0390bcd) added the `Substrate` enum variant and the driver crate, but parked the gateway-side instantiation behind a placeholder error: "openshell-driver-substrate is a scaffold; runtime wiring lands in M3." M3.1 through M3.13 then built out the driver crate (client, RPCs, kube-rs materialization, JWT, TLS, live tests, ActorTemplate synthesis). This change replaces the placeholder with the real wiring so `compute_drivers = ["substrate"]` in `gateway.toml` actually instantiates `SubstrateComputeDriver` and routes every `ComputeDriver` RPC through it. Three pieces: - `openshell-server/Cargo.toml`: depend on `openshell-driver-substrate` (one line; mirrors the docker/kubernetes/podman pattern). - `openshell-server/src/compute/mod.rs`: add `ComputeRuntime::new_substrate`. The substrate driver implements `ComputeDriver` directly with the same `WatchStream` type `SharedComputeDriver` expects, so no `ComputeDriverService`-style adapter is needed (kubernetes wraps because its internal API surface differs from the gRPC trait). - `openshell-server/src/lib.rs`: replace the placeholder `Substrate => Err(...)` arm with a real `ComputeRuntime::new_substrate(...)` call, and add `substrate_config_from_file()` mirroring `kubernetes_config_from_file()` to parse `[openshell.drivers.substrate]` via the driver's `Deserialize` impl. Test plan: - `cargo check --release -p openshell-server --bin openshell-gateway` completes in 2m 03s without warnings. - End-to-end validation lands in the helpdesk demo (`dims/openshell-driver-substrate/examples/helpdesk/`), which switches from `kubectl apply` + atenet curl to driving every sandbox lifecycle call through `gateway.create_sandbox` / `stop_sandbox` / `delete_sandbox` / `list_sandboxes`. That work is filed separately. Signed-off-by: Davanum Srinivas <dsrinivas@nvidia.com>
1 parent 10fdc9b commit 917e969

4 files changed

Lines changed: 93 additions & 6 deletions

File tree

Cargo.lock

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/openshell-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ openshell-core = { path = "../openshell-core" }
2020
openshell-driver-docker = { path = "../openshell-driver-docker" }
2121
openshell-driver-kubernetes = { path = "../openshell-driver-kubernetes" }
2222
openshell-driver-podman = { path = "../openshell-driver-podman" }
23+
openshell-driver-substrate = { path = "../openshell-driver-substrate" }
2324
openshell-ocsf = { path = "../openshell-ocsf" }
2425
openshell-policy = { path = "../openshell-policy" }
2526
openshell-providers = { path = "../openshell-providers" }

crates/openshell-server/src/compute/mod.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ use openshell_driver_kubernetes::{
3434
use openshell_driver_podman::{
3535
ComputeDriverService as PodmanDriverService, PodmanComputeConfig, PodmanComputeDriver,
3636
};
37+
pub use openshell_driver_substrate::SubstrateComputeConfig;
38+
use openshell_driver_substrate::SubstrateComputeDriver;
3739
use prost::Message;
3840
use std::fmt;
3941
use std::net::SocketAddr;
@@ -347,6 +349,34 @@ impl ComputeRuntime {
347349
.await
348350
}
349351

352+
pub async fn new_substrate(
353+
config: SubstrateComputeConfig,
354+
store: Arc<Store>,
355+
sandbox_index: SandboxIndex,
356+
sandbox_watch_bus: SandboxWatchBus,
357+
tracing_log_bus: TracingLogBus,
358+
supervisor_sessions: Arc<SupervisorSessionRegistry>,
359+
) -> Result<Self, ComputeError> {
360+
// SubstrateComputeDriver directly impls ComputeDriver with the
361+
// same WatchStream type SharedComputeDriver expects, so no
362+
// ComputeDriverService-style adapter is needed.
363+
let driver: SharedComputeDriver = Arc::new(SubstrateComputeDriver::new(config));
364+
Self::from_driver(
365+
driver,
366+
None,
367+
None,
368+
None,
369+
store,
370+
sandbox_index,
371+
sandbox_watch_bus,
372+
tracing_log_bus,
373+
supervisor_sessions,
374+
false,
375+
Vec::new(),
376+
)
377+
.await
378+
}
379+
350380
pub(crate) async fn new_remote_vm(
351381
channel: Channel,
352382
driver_process: Option<Arc<ManagedDriverProcess>>,

crates/openshell-server/src/lib.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub use grpc::OpenShellService;
6363
pub use http::{health_router, http_router, metrics_router, service_http_router};
6464
pub use multiplex::{MultiplexService, MultiplexedService};
6565
use openshell_driver_kubernetes::KubernetesComputeConfig;
66+
use openshell_driver_substrate::SubstrateComputeConfig;
6667
use persistence::Store;
6768
use sandbox_index::SandboxIndex;
6869
use sandbox_watch::SandboxWatchBus;
@@ -757,11 +758,19 @@ async fn build_compute_runtime(
757758
.await
758759
.map_err(|e| Error::execution(format!("failed to create compute runtime: {e}")))
759760
}
760-
ComputeDriverKind::Substrate => Err(Error::execution(
761-
"openshell-driver-substrate is a scaffold; runtime wiring lands in M3. \
762-
See crates/openshell-driver-substrate/README.md and rfc/0005-sandbox-degraded-mode/."
763-
.to_string(),
764-
)),
761+
ComputeDriverKind::Substrate => {
762+
let substrate = substrate_config_from_file(file)?;
763+
ComputeRuntime::new_substrate(
764+
substrate,
765+
store,
766+
sandbox_index,
767+
sandbox_watch_bus,
768+
tracing_log_bus,
769+
supervisor_sessions,
770+
)
771+
.await
772+
.map_err(|e| Error::execution(format!("failed to create compute runtime: {e}")))
773+
}
765774
}
766775
}
767776

@@ -785,6 +794,26 @@ fn kubernetes_config_from_file(
785794
.map_err(|e| Error::config(format!("invalid [openshell.drivers.kubernetes] table: {e}")))
786795
}
787796

797+
/// Build a [`SubstrateComputeConfig`] from the file's
798+
/// `[openshell.drivers.substrate]` table merged with inheritable
799+
/// `[openshell.gateway]` defaults. Falls back to the driver's `Default`
800+
/// when no file is present.
801+
fn substrate_config_from_file(
802+
file: Option<&config_file::ConfigFile>,
803+
) -> Result<SubstrateComputeConfig> {
804+
let Some(file) = file else {
805+
return Ok(SubstrateComputeConfig::default());
806+
};
807+
let merged = config_file::driver_table(
808+
ComputeDriverKind::Substrate,
809+
&file.openshell.gateway,
810+
file.openshell.drivers.get("substrate"),
811+
);
812+
merged
813+
.try_into()
814+
.map_err(|e| Error::config(format!("invalid [openshell.drivers.substrate] table: {e}")))
815+
}
816+
788817
fn kubernetes_config_for_k8s_sa_bootstrap(
789818
file: Option<&config_file::ConfigFile>,
790819
) -> Result<KubernetesComputeConfig> {
@@ -857,7 +886,8 @@ fn configured_compute_driver(config: &Config) -> Result<ComputeDriverKind> {
857886
driver @ (ComputeDriverKind::Kubernetes
858887
| ComputeDriverKind::Vm
859888
| ComputeDriverKind::Docker
860-
| ComputeDriverKind::Podman),
889+
| ComputeDriverKind::Podman
890+
| ComputeDriverKind::Substrate),
861891
] => Ok(*driver),
862892
drivers => Err(Error::config(format!(
863893
"multiple compute drivers are not supported yet; configured drivers: {}",

0 commit comments

Comments
 (0)