Skip to content

Commit ae54417

Browse files
committed
Support rootless docker.
Adds support for rootless docker, and manually overriding rootless/rootful container engines through the `CROSS_ROOTLESS_CONTAINER_ENGINE` environment variable. If not set, it will use the default mode for the container engine (rootful for docker, rootless for everything else). ```bash \# use the defaults cross run ... \# auto-select if using rootless (the default) CROSS_ROOTLESS_CONTAINER_ENGINE=auto cross run ... \# always use rootful mode CROSS_ROOTLESS_CONTAINER_ENGINE=0 cross run ... \# always use rootless mode CROSS_ROOTLESS_CONTAINER_ENGINE=1 cross run ... ``` Closes #889.
1 parent f059d1a commit ae54417

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased] - ReleaseDate
99

10+
### Added
11+
12+
- #890 - support rootless docker via the `CROSS_ROOTLESS_CONTAINER_ENGINE` environment variable.
13+
1014
### Changed
1115

1216
- #869 - ensure cargo configuration environment variable flags are passed to the docker container.

src/docker/shared.rs

+56-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{env, fs};
66
use super::custom::Dockerfile;
77
use super::engine::*;
88
use crate::cargo::{cargo_metadata_with_args, CargoMetadata};
9-
use crate::config::Config;
9+
use crate::config::{bool_from_envvar, Config};
1010
use crate::errors::*;
1111
use crate::extensions::{CommandExt, SafeCommand};
1212
use crate::file::{self, write_file, PathExt, ToUtf8};
@@ -399,8 +399,17 @@ pub(crate) fn group_id() -> String {
399399
}
400400

401401
pub(crate) fn docker_user_id(docker: &mut Command, engine_type: EngineType) {
402-
// We need to specify the user for Docker, but not for Podman.
403-
if engine_type == EngineType::Docker {
402+
// by default, docker runs as root so we need to specify the user
403+
// so the resulting file permissions are for the current user.
404+
// since we can have rootless docker, we provide an override.
405+
let is_rootless = env::var("CROSS_ROOTLESS_CONTAINER_ENGINE")
406+
.ok()
407+
.and_then(|s| match s.as_ref() {
408+
"auto" => None,
409+
b => Some(bool_from_envvar(b)),
410+
})
411+
.unwrap_or_else(|| engine_type != EngineType::Docker);
412+
if !is_rootless {
404413
docker.args(&["--user", &format!("{}:{}", user_id(), group_id(),)]);
405414
}
406415
}
@@ -648,6 +657,50 @@ pub fn path_hash(path: &Path) -> Result<String> {
648657
#[cfg(test)]
649658
mod tests {
650659
use super::*;
660+
use crate::id;
661+
662+
#[test]
663+
fn test_docker_user_id() {
664+
let var = "CROSS_ROOTLESS_CONTAINER_ENGINE";
665+
let old = env::var(var);
666+
env::remove_var(var);
667+
668+
let rootful = format!("\"engine\" \"--user\" \"{}:{}\"", id::user(), id::group());
669+
let rootless = "\"engine\"".to_string();
670+
671+
let test = |engine, expected| {
672+
let mut cmd = Command::new("engine");
673+
docker_user_id(&mut cmd, engine);
674+
assert_eq!(expected, &format!("{cmd:?}"));
675+
};
676+
test(EngineType::Docker, &rootful);
677+
test(EngineType::Podman, &rootless);
678+
test(EngineType::PodmanRemote, &rootless);
679+
test(EngineType::Other, &rootless);
680+
681+
env::set_var(var, "0");
682+
test(EngineType::Docker, &rootful);
683+
test(EngineType::Podman, &rootful);
684+
test(EngineType::PodmanRemote, &rootful);
685+
test(EngineType::Other, &rootful);
686+
687+
env::set_var(var, "1");
688+
test(EngineType::Docker, &rootless);
689+
test(EngineType::Podman, &rootless);
690+
test(EngineType::PodmanRemote, &rootless);
691+
test(EngineType::Other, &rootless);
692+
693+
env::set_var(var, "auto");
694+
test(EngineType::Docker, &rootful);
695+
test(EngineType::Podman, &rootless);
696+
test(EngineType::PodmanRemote, &rootless);
697+
test(EngineType::Other, &rootless);
698+
699+
match old {
700+
Ok(v) => env::set_var(var, v),
701+
Err(_) => env::remove_var(var),
702+
}
703+
}
651704

652705
mod mount_finder {
653706
use super::*;

0 commit comments

Comments
 (0)