diff --git a/crates/openshell-core/src/driver_utils.rs b/crates/openshell-core/src/driver_utils.rs index 09fb82dce..9e4411b2a 100644 --- a/crates/openshell-core/src/driver_utils.rs +++ b/crates/openshell-core/src/driver_utils.rs @@ -36,6 +36,42 @@ pub const LABEL_SANDBOX_NAMESPACE: &str = "openshell.ai/sandbox-namespace"; /// path used when building the `openshell-sandbox` image layer. pub const SUPERVISOR_IMAGE_BINARY_PATH: &str = "/openshell-sandbox"; +/// Directory inside sandbox containers where the supervisor binary is mounted. +/// +/// Compute drivers that side-load the supervisor into a shared volume mount +/// the binary here so the sandbox container can execute it from a fixed path. +pub const SUPERVISOR_CONTAINER_DIR: &str = "/opt/openshell/bin"; + +/// Full path to the supervisor binary inside sandbox containers. +/// +/// Equals `SUPERVISOR_CONTAINER_DIR + "/openshell-sandbox"`. Use this when +/// the full executable path is needed (Docker entrypoint, Podman entrypoint, +/// VM rootfs injection). Use `SUPERVISOR_CONTAINER_DIR` when only the +/// directory mount-point is needed (Kubernetes emptyDir volume mount). +pub const SUPERVISOR_CONTAINER_BINARY: &str = "/opt/openshell/bin/openshell-sandbox"; + +// --------------------------------------------------------------------------- +// In-container mount paths for guest TLS materials and the sandbox token. +// +// All container-based drivers (Docker, Podman, Kubernetes) mount the gateway's +// mTLS client credentials at these fixed paths inside every sandbox container. +// The supervisor reads these paths on startup to establish its gRPC-over-mTLS +// connection back to the gateway. The paths must remain stable across driver +// versions since the supervisor binary is built and packaged separately. +// --------------------------------------------------------------------------- + +/// Container-side mount path for the guest mTLS CA certificate. +pub const TLS_CA_MOUNT_PATH: &str = "/etc/openshell/tls/client/ca.crt"; + +/// Container-side mount path for the guest mTLS client certificate. +pub const TLS_CERT_MOUNT_PATH: &str = "/etc/openshell/tls/client/tls.crt"; + +/// Container-side mount path for the guest mTLS client private key. +pub const TLS_KEY_MOUNT_PATH: &str = "/etc/openshell/tls/client/tls.key"; + +/// Container-side mount path for the per-sandbox JWT token. +pub const SANDBOX_TOKEN_MOUNT_PATH: &str = "/etc/openshell/auth/sandbox.jwt"; + /// Return the XDG state path for a driver's sandbox JWT token file. /// /// The resulting path is `$XDG_STATE_HOME/openshell/[/]//sandbox.jwt`. diff --git a/crates/openshell-driver-docker/src/lib.rs b/crates/openshell-driver-docker/src/lib.rs index 11ffab7d6..49bd3d3f6 100644 --- a/crates/openshell-driver-docker/src/lib.rs +++ b/crates/openshell-driver-docker/src/lib.rs @@ -59,11 +59,11 @@ const WATCH_BUFFER: usize = 128; const WATCH_POLL_INTERVAL: Duration = Duration::from_secs(2); const WATCH_POLL_MAX_BACKOFF: Duration = Duration::from_secs(30); -const SUPERVISOR_MOUNT_PATH: &str = "/opt/openshell/bin/openshell-sandbox"; -const TLS_CA_MOUNT_PATH: &str = "/etc/openshell/tls/client/ca.crt"; -const TLS_CERT_MOUNT_PATH: &str = "/etc/openshell/tls/client/tls.crt"; -const TLS_KEY_MOUNT_PATH: &str = "/etc/openshell/tls/client/tls.key"; -const SANDBOX_TOKEN_MOUNT_PATH: &str = "/etc/openshell/auth/sandbox.jwt"; +const SUPERVISOR_MOUNT_PATH: &str = openshell_core::driver_utils::SUPERVISOR_CONTAINER_BINARY; +const TLS_CA_MOUNT_PATH: &str = openshell_core::driver_utils::TLS_CA_MOUNT_PATH; +const TLS_CERT_MOUNT_PATH: &str = openshell_core::driver_utils::TLS_CERT_MOUNT_PATH; +const TLS_KEY_MOUNT_PATH: &str = openshell_core::driver_utils::TLS_KEY_MOUNT_PATH; +const SANDBOX_TOKEN_MOUNT_PATH: &str = openshell_core::driver_utils::SANDBOX_TOKEN_MOUNT_PATH; const SANDBOX_COMMAND: &str = "sleep infinity"; const SUPERVISOR_PATH: &str = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; const HOST_OPENSHELL_INTERNAL: &str = "host.openshell.internal"; diff --git a/crates/openshell-driver-kubernetes/src/driver.rs b/crates/openshell-driver-kubernetes/src/driver.rs index 583f3cb99..ba20b0725 100644 --- a/crates/openshell-driver-kubernetes/src/driver.rs +++ b/crates/openshell-driver-kubernetes/src/driver.rs @@ -769,7 +769,7 @@ fn extract_image_size(message: &str) -> Option { } /// Path where the supervisor binary is mounted inside the agent container. -const SUPERVISOR_MOUNT_PATH: &str = "/opt/openshell/bin"; +const SUPERVISOR_MOUNT_PATH: &str = openshell_core::driver_utils::SUPERVISOR_CONTAINER_DIR; /// Name of the volume used to side-load the supervisor binary. const SUPERVISOR_VOLUME_NAME: &str = "openshell-supervisor-bin"; diff --git a/crates/openshell-driver-podman/src/container.rs b/crates/openshell-driver-podman/src/container.rs index cdf074619..f3aceb9bf 100644 --- a/crates/openshell-driver-podman/src/container.rs +++ b/crates/openshell-driver-podman/src/container.rs @@ -46,11 +46,16 @@ const CONTAINER_PREFIX: &str = "openshell-sandbox-"; /// Volume name prefix. const VOLUME_PREFIX: &str = "openshell-sandbox-"; -/// Container-side mount paths for client TLS materials. -const TLS_CA_MOUNT_PATH: &str = "/etc/openshell/tls/client/ca.crt"; -const TLS_CERT_MOUNT_PATH: &str = "/etc/openshell/tls/client/tls.crt"; -const TLS_KEY_MOUNT_PATH: &str = "/etc/openshell/tls/client/tls.key"; -const SANDBOX_TOKEN_MOUNT_PATH: &str = "/etc/openshell/auth/sandbox.jwt"; +/// Container-side mount paths for client TLS materials and the sandbox token. +const TLS_CA_MOUNT_PATH: &str = openshell_core::driver_utils::TLS_CA_MOUNT_PATH; +const TLS_CERT_MOUNT_PATH: &str = openshell_core::driver_utils::TLS_CERT_MOUNT_PATH; +const TLS_KEY_MOUNT_PATH: &str = openshell_core::driver_utils::TLS_KEY_MOUNT_PATH; +const SANDBOX_TOKEN_MOUNT_PATH: &str = openshell_core::driver_utils::SANDBOX_TOKEN_MOUNT_PATH; + +/// Directory inside sandbox containers where the supervisor binary is mounted. +const SUPERVISOR_MOUNT_DIR: &str = openshell_core::driver_utils::SUPERVISOR_CONTAINER_DIR; +/// Full path to the supervisor binary inside sandbox containers. +const SUPERVISOR_BINARY_PATH: &str = openshell_core::driver_utils::SUPERVISOR_CONTAINER_BINARY; /// Build a Podman container name from the sandbox name. #[must_use] @@ -443,7 +448,7 @@ pub fn build_container_spec_with_token( // /opt/openshell/bin/openshell-sandbox. image_volumes: vec![ImageVolume { source: config.supervisor_image.clone(), - destination: "/opt/openshell/bin".into(), + destination: SUPERVISOR_MOUNT_DIR.into(), rw: false, }], hostname: format!("sandbox-{}", sandbox.name), @@ -451,9 +456,9 @@ pub fn build_container_spec_with_token( // directly. Sandbox images (e.g. the community base image) set // ENTRYPOINT ["/bin/bash"], and Podman's `command` field only // overrides CMD — which gets appended as args to the entrypoint. - // Without this, the container would run `/bin/bash /opt/openshell/bin/openshell-sandbox` - // and bash would fail trying to interpret the binary as a script. - entrypoint: vec!["/opt/openshell/bin/openshell-sandbox".into()], + // Without this, the container would run the entrypoint binary with + // the supervisor path as an argument instead of executing it directly. + entrypoint: vec![SUPERVISOR_BINARY_PATH.into()], command: vec![], // Force the supervisor to run as root (UID 0). Sandbox images may // set a non-root USER directive (e.g. `USER sandbox`), but the @@ -1162,7 +1167,7 @@ mod tests { ); assert_eq!( vol["destination"].as_str(), - Some("/opt/openshell/bin"), + Some(SUPERVISOR_MOUNT_DIR), "image volume destination should be /opt/openshell/bin" ); assert_eq!( diff --git a/crates/openshell-driver-vm/src/rootfs.rs b/crates/openshell-driver-vm/src/rootfs.rs index 904ed8cd3..d59e7b4b9 100644 --- a/crates/openshell-driver-vm/src/rootfs.rs +++ b/crates/openshell-driver-vm/src/rootfs.rs @@ -14,7 +14,7 @@ const SUPERVISOR: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/openshell-sa const UMOCI: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/umoci.zst")); const ROOTFS_VARIANT_MARKER: &str = ".openshell-rootfs-variant"; const SANDBOX_GUEST_INIT_PATH: &str = "/srv/openshell-vm-sandbox-init.sh"; -const SANDBOX_SUPERVISOR_PATH: &str = "/opt/openshell/bin/openshell-sandbox"; +const SANDBOX_SUPERVISOR_PATH: &str = openshell_core::driver_utils::SUPERVISOR_CONTAINER_BINARY; const SANDBOX_UMOCI_PATH: &str = "/opt/openshell/bin/umoci"; const SANDBOX_OWNER_NORMALIZED_MARKER: &str = "/opt/openshell/.sandbox-owner-normalized"; const ROOTFS_IMAGE_MIN_SIZE_BYTES: u64 = 512 * 1024 * 1024;