Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions crates/openshell-driver-docker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use bollard::models::{
ContainerCreateBody, ContainerState, ContainerStateStatusEnum, ContainerSummary,
ContainerSummaryStateEnum, ContainerWaitResponse, CreateImageInfo, DeviceRequest, HealthConfig,
HealthStatusEnum, HostConfig, Mount, MountTmpfsOptions, MountTypeEnum, MountVolumeOptions,
ProgressDetail, SystemInfo, VolumeCreateRequest,
ProgressDetail, SystemInfo, SystemVersion, VolumeCreateRequest,
};
use bollard::query_parameters::{
CreateContainerOptionsBuilder, CreateImageOptions, DownloadFromContainerOptionsBuilder,
Expand Down Expand Up @@ -917,9 +917,12 @@ impl DockerComputeDriver {
.map_err(|err| {
Error::execution(format!("failed to create Docker client: {err}"))
})?;
docker.version().await.map_err(|err| {
let version = docker.version().await.map_err(|err| {
Error::execution(format!("failed to query Docker daemon version: {err}"))
})?;
if let Some(warning) = unsupported_docker_engine_warning(&version) {
warn!("{warning}");
}
let info = docker.info().await.map_err(|err| {
Error::execution(format!("failed to query Docker daemon info: {err}"))
})?;
Expand Down Expand Up @@ -6033,6 +6036,31 @@ fn docker_cdi_gpu_inventory(info: &SystemInfo) -> CdiGpuInventory {
)
}

/// Oldest Docker Engine major version the driver is supported on.
const MIN_DOCKER_ENGINE_MAJOR: u64 = 28;

/// Warn text when the daemon is a Docker Engine older than the supported
/// minimum. Older engines fail sandbox bundle staging with opaque errors.
fn unsupported_docker_engine_warning(version: &SystemVersion) -> Option<String> {
let engine = version
.components
.iter()
.flatten()
.find(|component| component.name == "Engine")?;
let major: u64 = engine
.version
.split(|c: char| !c.is_ascii_digit())
.next()?
.parse()
.ok()?;
(major < MIN_DOCKER_ENGINE_MAJOR).then(|| {
format!(
"Docker Engine {} is older than the supported minimum {MIN_DOCKER_ENGINE_MAJOR}.0; sandbox creation may fail. See the support matrix in the OpenShell docs.",
engine.version
)
})
}

fn docker_info_reports_wsl2(info: &SystemInfo) -> bool {
[
info.kernel_version.as_deref(),
Expand Down
32 changes: 32 additions & 0 deletions crates/openshell-driver-docker/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3274,6 +3274,38 @@ fn driver_default_gpu_selection_consumes_distinct_devices_for_creates() {
);
}

fn engine_version(name: &str, version: &str) -> SystemVersion {
SystemVersion {
components: Some(vec![bollard::models::SystemVersionComponents {
name: name.to_string(),
version: version.to_string(),
details: None,
}]),
..Default::default()
}
}

#[test]
fn warns_on_docker_engine_older_than_minimum() {
let warning = unsupported_docker_engine_warning(&engine_version("Engine", "26.1.5+dfsg1"))
.expect("old engine warns");
assert!(warning.contains("26.1.5+dfsg1"), "{warning}");
assert!(warning.contains("28.0"), "{warning}");
}

#[test]
fn no_warning_for_supported_unknown_or_other_engines() {
for version in [
engine_version("Engine", "28.0.0"),
engine_version("Engine", "29.9.3"),
engine_version("Engine", "garbage"),
engine_version("Other Engine", "5.8.2"),
SystemVersion::default(),
] {
assert!(unsupported_docker_engine_warning(&version).is_none());
}
}

#[test]
fn docker_info_reports_wsl2_from_kernel_version() {
let info = SystemInfo {
Expand Down
Loading