Skip to content

Commit

Permalink
Support rootless docker.
Browse files Browse the repository at this point in the history
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 #889.
  • Loading branch information
Alexhuszagh committed Jul 1, 2022
1 parent f059d1a commit c07045f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ This project adheres to [Semantic Versioning](http:https://semver.org/).

## [Unreleased] - ReleaseDate

### Added
- #890 - support rootless docker via the `CROSS_ROOTLESS_CONTAINER_ENGINE` environment variable.

### Changed

- #869 - ensure cargo configuration environment variable flags are passed to the docker container.
Expand Down
49 changes: 46 additions & 3 deletions src/docker/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{env, fs};
use super::custom::Dockerfile;
use super::engine::*;
use crate::cargo::{cargo_metadata_with_args, CargoMetadata};
use crate::config::Config;
use crate::config::{bool_from_envvar, Config};
use crate::errors::*;
use crate::extensions::{CommandExt, SafeCommand};
use crate::file::{self, write_file, PathExt, ToUtf8};
Expand Down Expand Up @@ -399,8 +399,13 @@ pub(crate) fn group_id() -> String {
}

pub(crate) fn docker_user_id(docker: &mut Command, engine_type: EngineType) {
// We need to specify the user for Docker, but not for Podman.
if engine_type == EngineType::Docker {
// by default, docker runs as root so we need to specify the user
// so the resulting file permissions are for the current user.
// since we can have rootless docker, we provide an override.
let is_rootless = env::var("CROSS_ROOTLESS_CONTAINER_ENGINE")
.map(|s| bool_from_envvar(&s))
.unwrap_or_else(|_| engine_type != EngineType::Docker);
if !is_rootless {
docker.args(&["--user", &format!("{}:{}", user_id(), group_id(),)]);
}
}
Expand Down Expand Up @@ -648,6 +653,44 @@ pub fn path_hash(path: &Path) -> Result<String> {
#[cfg(test)]
mod tests {
use super::*;
use crate::id;

#[test]
fn test_docker_user_id() {
let var = "CROSS_ROOTLESS_CONTAINER_ENGINE";
let old = env::var(var);
env::remove_var(var);

let rootful = format!("\"engine\" \"--user\" \"{}:{}\"", id::user(), id::group());
let rootless = "\"engine\"".to_string();

let test = |engine, expected| {
let mut cmd = Command::new("engine");
docker_user_id(&mut cmd, engine);
assert_eq!(expected, &format!("{cmd:?}"));
};
test(EngineType::Docker, &rootful);
test(EngineType::Podman, &rootless);
test(EngineType::PodmanRemote, &rootless);
test(EngineType::Other, &rootless);

env::set_var(var, "0");
test(EngineType::Docker, &rootful);
test(EngineType::Podman, &rootful);
test(EngineType::PodmanRemote, &rootful);
test(EngineType::Other, &rootful);

env::set_var(var, "1");
test(EngineType::Docker, &rootless);
test(EngineType::Podman, &rootless);
test(EngineType::PodmanRemote, &rootless);
test(EngineType::Other, &rootless);

match old {
Ok(v) => env::set_var(var, v),
Err(_) => env::remove_var(var),
}
}

mod mount_finder {
use super::*;
Expand Down

0 comments on commit c07045f

Please sign in to comment.