From 6baac54893bd7eb5eed7c94f67e7e500117d7e19 Mon Sep 17 00:00:00 2001 From: Alex Huszagh Date: Sat, 4 Jun 2022 11:35:18 -0500 Subject: [PATCH] Fix docker detection. Currently, docker detection fails under a few cases: 1. If `podman_docker` is installed, so the filename is docker but the actual executable is podman. 2. If the executable has a suffix, such as `.exe` on Windows, because we check if the executable `ends_with(DOCKER)`. The only reliable way to fix both these issues, IE, if the actual engine is docker and not an alias, and if the executable does not contain a suffix, is to query the container engine. This might not be ideal for performance reasons, but is the only reliable way to fix these issues. Emulated docker will have an output of `Emulate Docker CLI using podman.`, while docker itself will have an output similar to `Docker version 20.10.16, build aa7e414`. Closes #530. Closes #538. --- src/docker.rs | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/docker.rs b/src/docker.rs index 6f9085696..07c21d1d7 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -15,6 +15,17 @@ const CROSS_IMAGE: &str = "ghcr.io/cross-rs"; const DOCKER: &str = "docker"; const PODMAN: &str = "podman"; +// determine if the container engine is docker. this fixes issues with +// any aliases (#530), and doesn't fail if an executable suffix exists. +fn get_is_docker(ce: std::path::PathBuf, verbose: bool) -> Result { + let stdout = Command::new(ce) + .arg("--help") + .run_and_get_stdout(verbose)? + .to_lowercase(); + + Ok(stdout.contains("docker") && !stdout.contains("emulate")) +} + fn get_container_engine() -> Result { if let Ok(ce) = env::var("CROSS_CONTAINER_ENGINE") { which::which(ce) @@ -126,6 +137,7 @@ pub fn run( let runner = config.runner(target)?; let mut docker = docker_command("run")?; + let is_docker = get_is_docker(get_container_engine().unwrap(), verbose)?; for ref var in config.env_passthrough(target)? { validate_env_var(var)?; @@ -179,17 +191,15 @@ pub fn run( } // We need to specify the user for Docker, but not for Podman. - if let Ok(ce) = get_container_engine() { - if ce.ends_with(DOCKER) { - docker.args(&[ - "--user", - &format!( - "{}:{}", - env::var("CROSS_CONTAINER_UID").unwrap_or_else(|_| id::user().to_string()), - env::var("CROSS_CONTAINER_GID").unwrap_or_else(|_| id::group().to_string()), - ), - ]); - } + if is_docker { + docker.args(&[ + "--user", + &format!( + "{}:{}", + env::var("CROSS_CONTAINER_UID").unwrap_or_else(|_| id::user().to_string()), + env::var("CROSS_CONTAINER_GID").unwrap_or_else(|_| id::group().to_string()), + ), + ]); } docker