Skip to content

Commit

Permalink
Remove SELinux labels when using macOS and podman.
Browse files Browse the repository at this point in the history
Currently, podman does not support SELinux labels due to how they mount volumes. This causes the build to fail, with `lsetxattr` being unsupported.

The relevant podman issue is [here](containers/podman#13631), and the description of the issue and volume mounts is [here](containers/podman#13631 (comment)).

Closes cross-rs#756.
  • Loading branch information
Alexhuszagh committed Jun 5, 2022
1 parent 6a7fa09 commit da65450
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Fixed

- #757 - fixed bind mounts on podman by removing SELinux labels.
- #727 - add `PKG_CONFIG_PATH` to all `*-linux-gnu` images.
- #722 - boolean environment variables are evaluated as truthy or falsey.
- #720 - add android runner to preload `libc++_shared.so`.
Expand Down
64 changes: 53 additions & 11 deletions src/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ 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<bool> {
fn get_engine_type(ce: std::path::PathBuf, verbose: bool) -> Result<(bool, bool)> {
let stdout = Command::new(ce)
.arg("--help")
.run_and_get_stdout(verbose)?
.to_lowercase();

Ok(stdout.contains("docker") && !stdout.contains("emulate"))
let is_docker = stdout.contains("docker") && !stdout.contains("emulate");
let is_podman = stdout.contains("podman");
Ok((is_docker, is_podman))
}

fn get_container_engine() -> Result<std::path::PathBuf, which::Error> {
Expand Down Expand Up @@ -76,6 +78,33 @@ fn validate_env_var(var: &str) -> Result<(&str, Option<&str>)> {
Ok((key, value))
}

// NOTE: podman on macos does not currently support SELinux labels
// https://github.com/containers/podman/issues/13631
struct BindMount {
is_podman: bool,
}

impl BindMount {
fn create<T, U>(&self, src: T, dst: U, private: bool, readonly: bool) -> String
where
T: std::fmt::Display,
U: std::fmt::Display,
{
let mut opts = vec![];
if private && !(self.is_podman && cfg!(target_os = "macos")) {
opts.push("Z")
}
if readonly {
opts.push("ro")
}
if opts.is_empty() {
format!("{}:{}", src, dst)
} else {
format!("{}:{}:{}", src, dst, opts.join(","))
}
}
}

#[allow(clippy::too_many_arguments)] // TODO: refactor
pub fn run(
target: &Target,
Expand Down Expand Up @@ -137,7 +166,8 @@ 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)?;
let (is_docker, is_podman) = get_engine_type(get_container_engine().unwrap(), verbose)?;
let mount = BindMount { is_podman };

for ref var in config.env_passthrough(target)? {
validate_env_var(var)?;
Expand Down Expand Up @@ -175,7 +205,7 @@ pub fn run(
}
docker.args(&[
"-v",
&format!("{}:{}", host_path.display(), mount_path.display()),
&mount.create(host_path.display(), mount_path.display(), false, false),
]);
docker.args(&["-e", &format!("{}={}", var, mount_path.display())]);
env_volumes = true;
Expand Down Expand Up @@ -229,21 +259,33 @@ pub fn run(
"-e",
&format!("CROSS_RUNNER={}", runner.unwrap_or_default()),
])
.args(&["-v", &format!("{}:/xargo:Z", xargo_dir.display())])
.args(&["-v", &format!("{}:/cargo:Z", cargo_dir.display())])
.args(&[
"-v",
&mount.create("/xargo", xargo_dir.display(), true, false),
])
.args(&[
"-v",
&mount.create("/cargo", cargo_dir.display(), true, false),
])
// Prevent `bin` from being mounted inside the Docker container.
.args(&["-v", "/cargo/bin"]);
if env_volumes {
docker.args(&[
"-v",
&format!("{}:{}:Z", host_root.display(), mount_root.display()),
&mount.create(host_root.display(), mount_root.display(), true, false),
]);
} else {
docker.args(&["-v", &format!("{}:/project:Z", host_root.display())]);
docker.args(&[
"-v",
&mount.create("/project", host_root.display(), true, false),
]);
}
docker
.args(&["-v", &format!("{}:/rust:Z,ro", sysroot.display())])
.args(&["-v", &format!("{}:/target:Z", target_dir.display())]);
.args(&["-v", &mount.create("/rust", sysroot.display(), true, true)])
.args(&[
"-v",
&mount.create("/target", target_dir.display(), true, false),
]);

if env_volumes {
docker.args(&["-w", &mount_root.display().to_string()]);
Expand All @@ -256,7 +298,7 @@ pub fn run(
if let Some(nix_store) = nix_store_dir {
docker.args(&[
"-v",
&format!("{}:{}:Z", nix_store.display(), nix_store.display()),
&mount.create(nix_store.display(), nix_store.display(), true, false),
]);
}

Expand Down

0 comments on commit da65450

Please sign in to comment.