Skip to content

Commit 7297d0d

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 ... \# always use rootful mode CROSS_ROOTLESS_CONTAINER_ENGINE=0 cross run ... \# always use rootless mode CROSS_ROOTLESS_CONTAINER_ENGINE=1 cross run ... ``` Closes cross-rs#889.
1 parent f059d1a commit 7297d0d

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

CHANGELOG.md

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

88
## [Unreleased] - ReleaseDate
99

10+
### Added
11+
- #890 - support rootless docker via the `CROSS_ROOTLESS_CONTAINER_ENGINE` environment variable.
12+
1013
### Changed
1114

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

src/docker/shared.rs

+45-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,13 @@ 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+
.map(|s| bool_from_envvar(&s))
407+
.unwrap_or_else(|_| engine_type != EngineType::Docker);
408+
if !is_rootless {
404409
docker.args(&["--user", &format!("{}:{}", user_id(), group_id(),)]);
405410
}
406411
}
@@ -649,6 +654,43 @@ pub fn path_hash(path: &Path) -> Result<String> {
649654
mod tests {
650655
use super::*;
651656

657+
#[test]
658+
fn test_docker_user_id() {
659+
let var = "CROSS_ROOTLESS_CONTAINER_ENGINE";
660+
let old = env::var(var);
661+
env::remove_var(var);
662+
663+
let rootful = "\"engine\" \"--user\" \"1000:1000\"";
664+
let rootless = "\"engine\"";
665+
666+
let test = |engine, expected| {
667+
let mut cmd = Command::new("engine");
668+
docker_user_id(&mut cmd, engine);
669+
assert_eq!(expected, &format!("{cmd:?}"));
670+
};
671+
test(EngineType::Docker, rootful);
672+
test(EngineType::Podman, rootless);
673+
test(EngineType::PodmanRemote, rootless);
674+
test(EngineType::Other, rootless);
675+
676+
env::set_var(var, "0");
677+
test(EngineType::Docker, rootful);
678+
test(EngineType::Podman, rootful);
679+
test(EngineType::PodmanRemote, rootful);
680+
test(EngineType::Other, rootful);
681+
682+
env::set_var(var, "1");
683+
test(EngineType::Docker, rootless);
684+
test(EngineType::Podman, rootless);
685+
test(EngineType::PodmanRemote, rootless);
686+
test(EngineType::Other, rootless);
687+
688+
match old {
689+
Ok(v) => env::set_var(var, v),
690+
Err(_) => env::remove_var(var),
691+
}
692+
}
693+
652694
mod mount_finder {
653695
use super::*;
654696

0 commit comments

Comments
 (0)