Skip to content

refactor(driver-sdk): carve out the driver SDK and container-runtime crate - #5405

Open
elezar wants to merge 5 commits into
mainfrom
refactor/5383-carve-out-driver-sdk/elezar
Open

elezar wants to merge 5 commits into
mainfrom
refactor/5383-carve-out-driver-sdk/elezar

Conversation

@elezar

@elezar elezar commented Nov 9, 2026

Copy link
Copy Markdown
Member

Summary

Splits the code that the Docker, Podman, and VM drivers share with core into a thin openshell-driver-sdk crate and a desktop-only openshell-container-runtime crate. openshell-core re-exports every SDK item, so each item has one definition and no public path changes. This is the first implementation step of RFC 0022 / #5200.

Related Issue

Closes #5383

Changes

  • Add crates/openshell-driver-sdk. It depends only on workspace crates and crates.io (never on openshell-core). It owns the generated compute-driver proto closure (options, extension, datamodel, sandbox, compute_driver), the git-derived VERSION, and the items classified as SDK below.
  • Add crates/openshell-container-runtime for items used only by the desktop drivers. It depends on the SDK, never on core.
  • openshell-core re-exports the SDK modules and items. Its build refers to the moved protos through prost extern_path, so openshell_core::proto::... types are the same types. FILE_DESCRIPTOR_SET still covers every proto.
  • openshell-isolation-interface and the shared constants in openshell-sandbox-backend and openshell-policy now re-export the SDK definitions.
  • The Docker, Podman, and VM drivers import from the SDK and the container-runtime crate and no longer name openshell_core. The compiler proves the classification: nothing core-only is used by them directly.
  • Core features jwt, otel, clap, and telemetry forward to the SDK. driver-extraction is removed because the tar and cache helpers it gated are desktop-only and now live unconditionally in the container-runtime crate.
  • Move the sha2 allowance in deny.toml and CRYPTO.md from openshell-isolation-interface to openshell-driver-sdk, where that code now lives. No exception is added or widened.
  • Update the architecture tables in AGENTS.md and CONTRIBUTING.md and add READMEs for the new crates.

Classification table

Legend: SDK = used by something that stays in core (gateway, supervisor, Kubernetes driver, sandbox) and by the desktop drivers; desktop = used only by the Docker, Podman, and VM drivers; core-only = not used by the desktop drivers. Usage was traced from what the three drivers compile against, item by item including use groups, and then checked for users outside the drivers. SDK = openshell-driver-sdk, CR = openshell-container-runtime.

Item Current location Category Destination
Generated compute_driver.proto types and clients/servers, proto::{compute,extension,sandbox,datamodel} openshell-core::proto SDK SDK proto (core refers to them by extern_path and re-exports)
VERSION openshell-core SDK SDK (own build.rs; core re-exports)
compute::ComputeDriver openshell-core::compute SDK SDK
SandboxSessionId, SandboxGenerationId openshell-core SDK SDK
Error, Result, ComputeDriverError openshell-core::error SDK SDK
NetworkSupervisorTrustBundle, MAX_NETWORK_SUPERVISOR_TRUST_BUNDLE_BYTES openshell-core::network_trust SDK (gateway and every driver) SDK
NETWORK_SUPERVISOR_TRUST_GENERATION_KEY, ..._NONE openshell-core::network_trust desktop (Podman only) CR network_trust
sandbox_env::* (env names, OtlpProtocol, OtlpExport, SupervisorOtlp, SupervisorOtlpArgs, MainProcessConfig, UID/GID defaults, OTLP relay) openshell-core::sandbox_env SDK (supervisor, sandbox, Kubernetes driver, server) SDK sandbox_env, whole module (see Notes)
jwt::{CredentialEpoch, SandboxLaunchAuthentication, SecretJwt, SessionRotation, SessionVerificationKey, SupervisorAuthBundle, ...} openshell-core::jwt SDK SDK jwt (feature jwt)
jwt::parse_exp_secs openshell-core::jwt core-only stays in core
extension_protocol::* openshell-core SDK SDK
external_driver_socket::* openshell-core SDK SDK
container_paths::* (incl. SSH_SOCKET_PATH, VM_GUEST_*, NETNS_MOUNT_ROOT) openshell-core SDK / desktop mix SDK, whole module (see Notes)
driver_mounts::* openshell-core SDK / desktop mix SDK, whole module (see Notes)
e2fsprogs::{resolve, preflight} openshell-core SDK (gateway preflight, VM driver) SDK
driver_utils: labels, CONDITION_{EXITED,STOPPED,RUNTIME_RESTART}, SUPERVISOR_EXIT_WORKSPACE_VALIDATION_FAILED, mount paths used by Kubernetes, upstream-proxy parsing/reading, sandbox_log_level, validate_guest_spiffe_tcp_endpoint openshell-core::driver_utils SDK SDK driver_utils
driver_utils: LABEL_SANDBOX_NAMESPACE, CONDITION_WORKSPACE_VALIDATION_FAILED, WORKSPACE_VALIDATION_FAILED_MESSAGE, SANDBOX_RUNTIME_IMAGE_BINARY_PATH, PROXY_CA_MOUNT_PATH, PROVIDER_SPIFFE_WORKLOAD_API_SOCKET_MOUNT_DIR, validate_provider_spiffe_unix_socket, projected_provider_spiffe_socket_path, sandbox_token_path, supervisor_image_tag, supervisor_image_should_refresh, extract_first_tar_entry, write_cache_binary_atomic, supervisor_cache_path, temp_extract_container_name, validate_linux_elf_binary openshell-core::driver_utils desktop CR driver_utils
gpu::{effective_driver_gpu_count, driver_gpu_requirements} openshell-core::gpu SDK (Kubernetes driver, MXC) SDK gpu
gpu::{CdiGpuInventory, CdiGpuDefaultSelector, CdiGpuSelectionError, validate_cdi_*, validate_specific_gpu_device_request} openshell-core::gpu desktop CR gpu
gpu::{sandbox_gpu_requested, sandbox_gpu_count} openshell-core::gpu core-only (server) stays in core gpu
resource_admission::{ResourceAdmissionConfig, DriverAdmissionConfig, check_sandbox_driver_config, check_driver_config} openshell-core SDK SDK
resource_admission::{CONFIG_USED_LABEL, IDENTITIES_LABEL, check_config_provenance} openshell-core desktop CR resource_admission
config::{AppArmorProfile, ImagePullPolicy, UpstreamProxyConfig, DEFAULT_SERVER_PORT, DEFAULT_STOP_TIMEOUT_SECS, SANDBOX_RUNTIME_IMAGE_ENV, SUPERVISOR_IMAGE_ENV, default_sandbox_runtime_image, default_supervisor_image, resolve_supervisor_image_tag} openshell-core::config SDK SDK config
config::{DEFAULT_SSH_PORT, DEFAULT_SANDBOX_PIDS_LIMIT, default_sandbox_pids_limit, CDI_GPU_DEVICE_ALL} openshell-core::config desktop CR config
config::Config and gateway/server/auth tables openshell-core::config core-only stays in core
proto_struct::{json_object_to_struct, struct_to_json_value, struct_to_json_object, value_to_json, json_value_to_proto} openshell-core SDK SDK
proto_struct::deserialize_optional_non_empty_string_list openshell-core desktop CR proto_struct
paths::{xdg_state_dir, xdg_data_dir, create_dir_restricted, set_dir_owner_only, set_file_owner_only, is_posix_absolute} openshell-core::paths SDK SDK paths
other paths::* openshell-core::paths core-only stays in core
net::{set_tcp_nodelay_best_effort, connect_tcp_nodelay_best_effort} openshell-core::net SDK SDK net
SSRF helpers in net openshell-core::net core-only stays in core
time::*, progress::*, image::* openshell-core SDK (Kubernetes driver, CLI, gateway) SDK
settings::parse_bool_like openshell-core::settings SDK (CLI, TUI) SDK settings
other settings::* openshell-core::settings core-only stays in core
telemetry::enabled_env_value openshell-core::telemetry SDK (Kubernetes driver) SDK telemetry (feature telemetry)
other telemetry::* openshell-core::telemetry core-only stays in core
local_api_socket::* openshell-core desktop CR local_api_socket
policy::* (sandbox policy conversion used by the Isolation Backend contract), isolation_registration::* openshell-core SDK (closure of the contract types) SDK
contract::{BackendError, ProvisioningEvidence, ResolvedWorkloadIdentity, ...}, AgentSpec openshell-isolation-interface SDK SDK isolation_interface; crate re-exports
BACKEND_NAME, GPU_RESOURCE_CLAIM, ALLOW_EXTRA_SUPPLEMENTARY_GROUPS_RESOURCE_CLAIM, SUPERVISOR_CA_RUNTIME_ROOT, SUPERVISOR_CA_RUNTIME_DIR openshell-sandbox-backend SDK SDK isolation_interface; crate re-exports
boundary_protocol::{BoundaryConfig, BoundaryListener, GatewayVerificationKey, SandboxRuntimeDescriptor, SandboxTls*, SandboxTransport, generate_sandbox_tls_material} openshell-sandbox-backend SDK (sandbox, supervisor, Kubernetes driver) deferred, stays in place; see Notes
MIN_SANDBOX_UID, MAX_SANDBOX_UID openshell-policy SDK (policy validation, VM driver) SDK policy; openshell-policy re-exports
ComputeDriverTracing, DriverTracingConfig, InProcessRpcTracer, compute_driver_rpc_layer, install_driver_tracing, rpc::*, ErrorStatusGuard, record_error_result, current_trace_context_environment, layer_excluding_target_prefixes, TracedGrpcStream openshell-otel SDK category (Kubernetes driver, MXC, server) stays in openshell-otel (see Notes)

Notes on choices

  • Generated protos moved. Items such as DriverSandboxSpec are used by every driver and by the gateway, so they are SDK items. The closure of compute_driver.proto is small (options, extension, datamodel, sandbox), so it moved whole. This is what the issue's import-path count missed: almost every other SDK item depends on these types.
  • Modules moved whole although part of a module is core-only. sandbox_env, container_paths, driver_mounts, time, progress, image, error, e2fsprogs, and isolation_interface form one protocol or policy that the supervisor, the Kubernetes driver, and the desktop drivers all read, and the unused remainder is small or checks against the rest of the module (for example CONTROL_ROOTS in container_paths is the collision list that driver_mounts validates against). Splitting them would put one rule in two crates and bring back the drift the RFC warns about. Items in these modules that only the desktop drivers use (VM_GUEST_*, NETNS_MOUNT_ROOT, DEFAULT_SANDBOX_GID, SelinuxLabel, AppArmorProfile::oci_security_opt) are called out here rather than moved. AppArmorProfile::oci_security_opt is an inherent method and has to stay with its type.
  • Modules split at item level where the split was clean: driver_utils, gpu, resource_admission, config, proto_struct, network_trust, paths, net, settings, telemetry, jwt.
  • NetworkSupervisorTrustBundle and MAX_NETWORK_SUPERVISOR_TRUST_BUNDLE_BYTES are SDK: the gateway validates against the limit and every driver receives the bundle. The Podman-only generation labels beside them are desktop.
  • Deferred: openshell-sandbox-backend::boundary_protocol. Its items are SDK items (the sandbox, supervisor, and Kubernetes driver use them), but the module is 2k lines and depends on protobuf wire helpers, route-handle validation in runtime_routed, and the generated sandbox.backend.v1 and sandbox.protocol.v1 protos. Moving it needs a second proto split and a split of the wire helpers, so it belongs in its own change. Until then the Docker, Podman, and VM drivers still depend on openshell-sandbox-backend (and through it on core). It needs a follow-up issue.
  • openshell-otel stays in place. The tracing items are SDK-category, but the crate is already independent of core and the drivers already depend on it directly. Re-exporting it from the SDK would pull the OpenTelemetry stack into every SDK consumer.
  • telemetry::enabled_env_value keeps its behavior: it reports "false" when the telemetry feature is off. The feature flows from core to the SDK, so a build that enables core telemetry still enables it here.

Release Notes

None.

Testing

Ran locally:

  • cargo fmt --all
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test for openshell-driver-sdk, openshell-container-runtime, openshell-core, openshell-isolation-interface, openshell-policy, openshell-sandbox-backend, openshell-driver-docker, openshell-driver-podman (tests moved with their code; no test logic changed)
  • cargo test for openshell-driver-kubernetes, openshell-supervisor, openshell-supervisor-control, openshell-sandbox pass. openshell-driver-vm has 6 failing tests that need mke2fs/debugfs, which are not installed on the machine used (unrelated to this change; not re-run on main). openshell-gateway tests were not run: the host lacks libz3 for linking.
  • cargo check --all-targets for the nested workspaces (tests/*, e2e/rust, examples/*)
  • mise run rust:deny:policy and rust:lockfiles:check (via the pre-commit hook)
  • Unit tests added/updated (tests moved with their code)
  • E2E tests: not run (no sandbox runtime available in this environment)

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated (if applicable)

…proto and VERSION

Move the generated compute-driver proto closure (options, extension,
datamodel, sandbox, compute_driver) and the git-derived build VERSION into
a new openshell-driver-sdk crate. openshell-core refers to the generated
types by extern path and re-exports them, so every path under
openshell_core::proto keeps resolving to the same single definition.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
Move sandbox_session, sandbox_generation, time, progress, image,
external_driver_socket, jwt (session tokens), extension_protocol,
network_trust and the compute driver trait into openshell-driver-sdk, and
re-export each from openshell-core so existing paths keep working.

Add openshell-container-runtime for desktop-only code and move the Podman
destination-trust generation markers there. parse_exp_secs stays in core
because only core uses it.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
…een SDK and desktop crate

Move sandbox_env, container_paths, driver_mounts, e2fsprogs, and the shared
half of driver_utils and paths into openshell-driver-sdk. Move the
desktop-only half of driver_utils and local_api_socket into
openshell-container-runtime, and point the Docker and Podman drivers at it.
openshell-core re-exports the SDK modules so existing paths keep resolving.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
…d config

Move the items shared with core into openshell-driver-sdk and the
desktop-only items (CDI GPU selection, resource-admission provenance labels,
the string-list serde helper, and the Docker/Podman config defaults) into
openshell-container-runtime. Core-only items stay in openshell-core, which
re-exports the SDK items. Point the Docker, Podman, and VM drivers at the
new paths.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
…m the desktop drivers

Move the Isolation Backend contract types, the policy conversion they depend
on, the backend registration types, and the shared constants into
openshell-driver-sdk, with openshell-isolation-interface,
openshell-sandbox-backend, and openshell-policy re-exporting them. Move the
remaining shared helpers (net, settings, telemetry env value) into the SDK.

The Docker, Podman, and VM drivers now import from the SDK and
openshell-container-runtime and no longer name openshell-core. Move the
sha2 allowance in deny.toml and CRYPTO.md from openshell-isolation-interface
to openshell-driver-sdk, where that code now lives, and document the new
crates.

Signed-off-by: Evan Lezar <elezar@nvidia.com>
@elezar elezar added area:gateway Gateway server and control-plane work area:drivers and removed area:gateway Gateway server and control-plane work labels Nov 9, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: carve out the driver SDK and container-runtime crate

1 participant