From 49027941676c9d814d26c53a80fd22d2b81b57fe Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Thu, 7 May 2026 15:34:24 -0700 Subject: [PATCH 1/2] wip --- install-dev.sh | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/install-dev.sh b/install-dev.sh index b0cf88f07..edacd2b8d 100755 --- a/install-dev.sh +++ b/install-dev.sh @@ -227,10 +227,26 @@ find_deb_asset() { _arch="$2" awk -v arch="$_arch" ' - $2 ~ "^\\*?openshell_.*_" arch "\\.deb$" { - sub("^\\*", "", $2) - print $2 - exit + { + name = $2 + sub("^\\*", "", name) + + if (name == "openshell-dev-" arch ".deb") { + selected = name + found = 1 + exit + } + + if (fallback == "" && name ~ "^openshell_.*_" arch "\\.deb$") { + fallback = name + } + } + END { + if (found) { + print selected + } else if (fallback != "") { + print fallback + } } ' "$_checksums" } From fea087b11cb6c4665654f50fbc4ea1663db6337c Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Thu, 7 May 2026 16:00:04 -0700 Subject: [PATCH 2/2] fix(gateway): detect Docker socket for driver auto-detection --- crates/openshell-core/src/config.rs | 90 ++++++++++++++++++++-- crates/openshell-server/src/cli.rs | 4 +- docs/reference/sandbox-compute-drivers.mdx | 2 +- 3 files changed, 88 insertions(+), 8 deletions(-) diff --git a/crates/openshell-core/src/config.rs b/crates/openshell-core/src/config.rs index 1ec06677b..3f0d34b0f 100644 --- a/crates/openshell-core/src/config.rs +++ b/crates/openshell-core/src/config.rs @@ -6,7 +6,9 @@ use serde::{Deserialize, Serialize}; use std::fmt; use std::net::SocketAddr; -use std::path::PathBuf; +#[cfg(unix)] +use std::os::unix::fs::FileTypeExt; +use std::path::{Path, PathBuf}; use std::process::Command; use std::str::FromStr; @@ -108,8 +110,8 @@ pub fn detect_driver() -> Option { return Some(ComputeDriverKind::Podman); } - // Docker: check if docker binary is available - if is_binary_available("docker") { + // Docker: check if the CLI is available or a local Docker socket exists. + if is_docker_available() { return Some(ComputeDriverKind::Docker); } @@ -124,6 +126,55 @@ fn is_binary_available(name: &str) -> bool { .is_ok_and(|output| output.status.success()) } +fn is_docker_available() -> bool { + is_binary_available("docker") || docker_socket_available() +} + +fn docker_socket_available() -> bool { + docker_socket_candidates() + .iter() + .any(|path| is_unix_socket(path)) +} + +fn docker_socket_candidates() -> Vec { + let mut candidates = Vec::new(); + + if let Ok(host) = std::env::var("DOCKER_HOST") + && let Some(path) = docker_host_unix_socket_path(&host) + { + candidates.push(path); + } + + candidates.push(PathBuf::from("/var/run/docker.sock")); + + if let Some(home) = std::env::var_os("HOME") { + candidates.push(PathBuf::from(home).join(".docker/run/docker.sock")); + } + + if let Some(runtime_dir) = std::env::var_os("XDG_RUNTIME_DIR") { + candidates.push(PathBuf::from(runtime_dir).join("docker.sock")); + } + + candidates +} + +fn docker_host_unix_socket_path(host: &str) -> Option { + let path = host.trim().strip_prefix("unix://")?; + (!path.is_empty()).then(|| PathBuf::from(path)) +} + +#[cfg(unix)] +fn is_unix_socket(path: &Path) -> bool { + path.metadata() + .is_ok_and(|metadata| metadata.file_type().is_socket()) +} + +#[cfg(not(unix))] +fn is_unix_socket(path: &Path) -> bool { + let _ = path; + false +} + /// Server configuration. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Config { @@ -563,8 +614,13 @@ const fn default_ssh_session_ttl_secs() -> u64 { #[cfg(test)] mod tests { - use super::{ComputeDriverKind, Config, detect_driver}; + use super::{ + ComputeDriverKind, Config, detect_driver, docker_host_unix_socket_path, is_unix_socket, + }; use std::net::SocketAddr; + #[cfg(unix)] + use std::os::unix::net::UnixListener; + use std::path::PathBuf; #[test] fn compute_driver_kind_parses_supported_values() { @@ -614,12 +670,36 @@ mod tests { #[test] fn detect_driver_returns_none_without_k8s_env_or_binaries() { // When KUBERNETES_SERVICE_HOST is not set and no docker/podman binaries - // are available, detect_driver should return None. + // or Docker socket are available, detect_driver should return None. // This test may pass or fail depending on the test environment, // but it documents the expected behavior. let _ = detect_driver(); // Returns Some or None based on environment } + #[test] + fn docker_host_unix_socket_path_parses_unix_hosts() { + assert_eq!( + docker_host_unix_socket_path("unix:///var/run/docker.sock"), + Some(PathBuf::from("/var/run/docker.sock")) + ); + assert_eq!(docker_host_unix_socket_path("tcp://127.0.0.1:2375"), None); + assert_eq!(docker_host_unix_socket_path("unix://"), None); + } + + #[cfg(unix)] + #[test] + fn is_unix_socket_detects_socket_files() { + let temp_dir = tempfile::tempdir().expect("create temp dir"); + let socket_path = temp_dir.path().join("docker.sock"); + let _listener = UnixListener::bind(&socket_path).expect("bind unix socket"); + + assert!(is_unix_socket(&socket_path)); + + let regular_file = temp_dir.path().join("not-a-socket"); + std::fs::write(®ular_file, b"not a socket").expect("write regular file"); + assert!(!is_unix_socket(®ular_file)); + } + #[test] #[allow(unsafe_code)] // std::env::set_var/remove_var require unsafe in Rust 2024 fn detect_driver_prefers_kubernetes_when_k8s_env_is_set() { diff --git a/crates/openshell-server/src/cli.rs b/crates/openshell-server/src/cli.rs index 6eb1ab2db..ccc08cf2b 100644 --- a/crates/openshell-server/src/cli.rs +++ b/crates/openshell-server/src/cli.rs @@ -67,8 +67,8 @@ struct Args { /// `kubernetes,podman`. The configuration format is future-proofed for /// multiple drivers, but the gateway currently requires exactly one. /// When unset, the gateway auto-detects the driver based on the runtime - /// environment (Kubernetes → Podman → Docker). VM is never auto-detected - /// and requires explicit configuration. + /// environment (Kubernetes → Podman → Docker CLI or socket). VM is never + /// auto-detected and requires explicit configuration. #[arg( long, alias = "driver", diff --git a/docs/reference/sandbox-compute-drivers.mdx b/docs/reference/sandbox-compute-drivers.mdx index cc78b3b80..4db867135 100644 --- a/docs/reference/sandbox-compute-drivers.mdx +++ b/docs/reference/sandbox-compute-drivers.mdx @@ -22,7 +22,7 @@ openshell-gateway --drivers docker You can also set the driver with `OPENSHELL_DRIVERS`. Supported values are `docker`, `podman`, `kubernetes`, and `vm`. -When `--drivers` and `OPENSHELL_DRIVERS` are unset, the gateway auto-detects Kubernetes, then Podman, then Docker. The VM driver is never auto-detected; configure it explicitly with `--drivers vm`. +When `--drivers` and `OPENSHELL_DRIVERS` are unset, the gateway auto-detects Kubernetes, then Podman, then Docker by CLI availability or a local Unix socket. The VM driver is never auto-detected; configure it explicitly with `--drivers vm`. Common gateway options: