Skip to content

Commit

Permalink
Change mount paths for cargo, xargo, and the sysroot.
Browse files Browse the repository at this point in the history
Change the mount points from `/cargo`, `/xargo`, and `/rust` to the same paths as on the host, which avoids unnecessary recompilation when `cargo` and `cross` are intermittently used.
  • Loading branch information
Alexhuszagh committed Jul 15, 2022
1 parent 3323536 commit 64448bd
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 84 deletions.
17 changes: 12 additions & 5 deletions .changes/947.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{
"type": "internal",
"description": "resolve symlinks for cargo and xargo home",
"issues": [373]
}
[
{
"type": "internal",
"description": "resolve symlinks for cargo and xargo home",
"issues": [373]
},
{
"type": "fixed",
"description": "mount cargo, xargo, and the sysroot at the same path as on the host to avoid unnecessary recompilation.",
"issues": [551]
}
]
7 changes: 3 additions & 4 deletions src/bin/commands/containers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,23 +430,22 @@ pub fn create_persistent_volume(
docker::remote::copy_volume_container_xargo(
engine,
&container,
&dirs.xargo,
&target,
&dirs,
mount_prefix.as_ref(),
msg_info,
)?;
docker::remote::copy_volume_container_cargo(
engine,
&container,
&dirs.cargo,
&dirs,
mount_prefix.as_ref(),
copy_registry,
msg_info,
)?;
docker::remote::copy_volume_container_rust(
engine,
&container,
&dirs.sysroot,
&dirs,
&target,
mount_prefix.as_ref(),
true,
Expand Down
32 changes: 26 additions & 6 deletions src/docker/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ pub(crate) fn run(

let mut docker = subcommand(engine, "run");
docker_userns(&mut docker);
docker_envvars(&mut docker, &options.config, &options.target, msg_info)?;
docker_envvars(
&mut docker,
&options.config,
dirs,
&options.target,
msg_info,
)?;

docker_mount(
&mut docker,
Expand All @@ -38,17 +44,31 @@ pub(crate) fn run(
.wrap_err("when copying seccomp profile")?;
docker_user_id(&mut docker, engine.kind);

let cargo_mount_path = dirs.cargo_mount_path()?;
docker
.args(&["-v", &format!("{}:/xargo:Z", dirs.xargo.to_utf8()?)])
.args(&["-v", &format!("{}:/cargo:Z", dirs.cargo.to_utf8()?)])
.args(&[
"-v",
&format!("{}:{}:Z", dirs.xargo.to_utf8()?, dirs.xargo_mount_path()?),
])
.args(&[
"-v",
&format!("{}:{cargo_mount_path}:Z", dirs.cargo.to_utf8()?),
])
// Prevent `bin` from being mounted inside the Docker container.
.args(&["-v", "/cargo/bin"]);
.args(&["-v", &format!("{cargo_mount_path}/bin")]);
docker.args(&[
"-v",
&format!("{}:{}:Z", dirs.host_root.to_utf8()?, dirs.mount_root),
]);
docker
.args(&["-v", &format!("{}:/rust:Z,ro", dirs.sysroot.to_utf8()?)])
.args(&[
"-v",
&format!(
"{}:{}:Z,ro",
dirs.sysroot.to_utf8()?,
dirs.sysroot_mount_path()?
),
])
.args(&["-v", &format!("{}:/target:Z", dirs.target.to_utf8()?)]);
docker_cwd(&mut docker, &paths)?;

Expand Down Expand Up @@ -76,7 +96,7 @@ pub(crate) fn run(

docker
.arg(&image)
.args(&["sh", "-c", &format!("PATH=$PATH:/rust/bin {:?}", cmd)])
.args(&["sh", "-c", &build_command(dirs, &cmd)?])
.run_and_get_status(msg_info, false)
.map_err(Into::into)
}
102 changes: 46 additions & 56 deletions src/docker/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,24 +242,19 @@ fn copy_volume_files_nocache(
pub fn copy_volume_container_xargo(
engine: &Engine,
container: &str,
xargo_dir: &Path,
target: &Target,
dirs: &Directories,
mount_prefix: &Path,
msg_info: &mut MessageInfo,
) -> Result<()> {
// only need to copy the rustlib files for our current target.
let triple = target.triple();
let relpath = Path::new("lib").join("rustlib").join(&triple);
let src = xargo_dir.join(&relpath);
let dst = mount_prefix.join("xargo").join(&relpath);
if Path::new(&src).exists() {
let dst = mount_prefix.join(Path::new(&dirs.xargo_mount_path_relative()?));
if dirs.xargo.exists() {
create_volume_dir(
engine,
container,
dst.parent().expect("destination should have a parent"),
msg_info,
)?;
copy_volume_files(engine, container, &src, &dst, msg_info)?;
copy_volume_files(engine, container, &dirs.xargo, &dst, msg_info)?;
}

Ok(())
Expand All @@ -268,23 +263,23 @@ pub fn copy_volume_container_xargo(
pub fn copy_volume_container_cargo(
engine: &Engine,
container: &str,
cargo_dir: &Path,
dirs: &Directories,
mount_prefix: &Path,
copy_registry: bool,
msg_info: &mut MessageInfo,
) -> Result<()> {
let dst = mount_prefix.join("cargo");
let dst = mount_prefix.join(Path::new(&dirs.cargo_mount_path_relative()?));
let copy_registry = env::var("CROSS_REMOTE_COPY_REGISTRY")
.map(|s| bool_from_envvar(&s))
.unwrap_or(copy_registry);

if copy_registry {
copy_volume_files(engine, container, cargo_dir, &dst, msg_info)?;
copy_volume_files(engine, container, &dirs.cargo, &dst, msg_info)?;
} else {
// can copy a limit subset of files: the rest is present.
create_volume_dir(engine, container, &dst, msg_info)?;
for entry in fs::read_dir(cargo_dir)
.wrap_err_with(|| format!("when reading directory {cargo_dir:?}"))?
for entry in fs::read_dir(&dirs.cargo)
.wrap_err_with(|| format!("when reading directory {:?}", dirs.cargo))?
{
let file = entry?;
let basename = file
Expand Down Expand Up @@ -372,17 +367,17 @@ fn warn_symlinks(had_symlinks: bool, msg_info: &mut MessageInfo) -> Result<()> {
fn copy_volume_container_rust_base(
engine: &Engine,
container: &str,
sysroot: &Path,
dirs: &Directories,
mount_prefix: &Path,
msg_info: &mut MessageInfo,
) -> Result<()> {
// the rust toolchain is quite large, but most of it isn't needed
// we need the bin, libexec, and etc directories, and part of the lib directory.
let dst = mount_prefix.join("rust");
let dst = mount_prefix.join(Path::new(&dirs.sysroot_mount_path_relative()?));
let rustlib = Path::new("lib").join("rustlib");
create_volume_dir(engine, container, &dst.join(&rustlib), msg_info)?;
for basename in ["bin", "libexec", "etc"] {
let file = sysroot.join(basename);
let file = dirs.sysroot.join(basename);
copy_volume_files(engine, container, &file, &dst, msg_info)?;
}

Expand All @@ -396,7 +391,7 @@ fn copy_volume_container_rust_base(
let temppath = tempdir.path();
file::create_dir_all(&temppath.join(&rustlib))?;
let mut had_symlinks = copy_dir(
&sysroot.join("lib"),
&dirs.sysroot.join("lib"),
&temppath.join("lib"),
true,
0,
Expand All @@ -405,7 +400,7 @@ fn copy_volume_container_rust_base(

// next, copy the src/etc directories inside rustlib
had_symlinks |= copy_dir(
&sysroot.join(&rustlib),
&dirs.sysroot.join(&rustlib),
&temppath.join(&rustlib),
true,
0,
Expand All @@ -419,21 +414,21 @@ fn copy_volume_container_rust_base(
fn copy_volume_container_rust_manifest(
engine: &Engine,
container: &str,
sysroot: &Path,
dirs: &Directories,
mount_prefix: &Path,
msg_info: &mut MessageInfo,
) -> Result<()> {
// copy over all the manifest files in rustlib
// these are small text files containing names/paths to toolchains
let dst = mount_prefix.join("rust");
let dst = mount_prefix.join(Path::new(&dirs.sysroot_mount_path_relative()?));
let rustlib = Path::new("lib").join("rustlib");

// SAFETY: safe, single-threaded execution.
let tempdir = unsafe { temp::TempDir::new()? };
let temppath = tempdir.path();
file::create_dir_all(&temppath.join(&rustlib))?;
let had_symlinks = copy_dir(
&sysroot.join(&rustlib),
&dirs.sysroot.join(&rustlib),
&temppath.join(&rustlib),
true,
0,
Expand All @@ -448,17 +443,17 @@ fn copy_volume_container_rust_manifest(
pub fn copy_volume_container_rust_triple(
engine: &Engine,
container: &str,
sysroot: &Path,
dirs: &Directories,
triple: &str,
mount_prefix: &Path,
skip_exists: bool,
msg_info: &mut MessageInfo,
) -> Result<()> {
// copy over the files for a specific triple
let dst = mount_prefix.join("rust");
let dst = mount_prefix.join(Path::new(&dirs.sysroot_mount_path_relative()?));
let rustlib = Path::new("lib").join("rustlib");
let dst_rustlib = dst.join(&rustlib);
let src_toolchain = sysroot.join(&rustlib).join(triple);
let src_toolchain = dirs.sysroot.join(&rustlib).join(triple);
let dst_toolchain = dst_rustlib.join(triple);

// skip if the toolchain already exists. for the host toolchain
Expand All @@ -473,7 +468,7 @@ pub fn copy_volume_container_rust_triple(
if !skip && skip_exists {
// this means we have a persistent data volume and we have a
// new target, meaning we might have new manifests as well.
copy_volume_container_rust_manifest(engine, container, sysroot, mount_prefix, msg_info)?;
copy_volume_container_rust_manifest(engine, container, dirs, mount_prefix, msg_info)?;
}

Ok(())
Expand All @@ -482,7 +477,7 @@ pub fn copy_volume_container_rust_triple(
pub fn copy_volume_container_rust(
engine: &Engine,
container: &str,
sysroot: &Path,
dirs: &Directories,
target: &Target,
mount_prefix: &Path,
skip_target: bool,
Expand All @@ -491,12 +486,12 @@ pub fn copy_volume_container_rust(
let target_triple = target.triple();
let image_triple = Host::X86_64UnknownLinuxGnu.triple();

copy_volume_container_rust_base(engine, container, sysroot, mount_prefix, msg_info)?;
copy_volume_container_rust_manifest(engine, container, sysroot, mount_prefix, msg_info)?;
copy_volume_container_rust_base(engine, container, dirs, mount_prefix, msg_info)?;
copy_volume_container_rust_manifest(engine, container, dirs, mount_prefix, msg_info)?;
copy_volume_container_rust_triple(
engine,
container,
sysroot,
dirs,
image_triple,
mount_prefix,
false,
Expand All @@ -506,7 +501,7 @@ pub fn copy_volume_container_rust(
copy_volume_container_rust_triple(
engine,
container,
sysroot,
dirs,
target_triple,
mount_prefix,
false,
Expand Down Expand Up @@ -977,28 +972,14 @@ pub(crate) fn run(
};
let mount_prefix_path = mount_prefix.as_ref();
if let VolumeId::Discard = volume {
copy_volume_container_xargo(
engine,
&container,
&dirs.xargo,
target,
mount_prefix_path,
msg_info,
)
.wrap_err("when copying xargo")?;
copy_volume_container_cargo(
engine,
&container,
&dirs.cargo,
mount_prefix_path,
false,
msg_info,
)
.wrap_err("when copying cargo")?;
copy_volume_container_xargo(engine, &container, dirs, mount_prefix_path, msg_info)
.wrap_err("when copying xargo")?;
copy_volume_container_cargo(engine, &container, dirs, mount_prefix_path, false, msg_info)
.wrap_err("when copying cargo")?;
copy_volume_container_rust(
engine,
&container,
&dirs.sysroot,
dirs,
target,
mount_prefix_path,
false,
Expand All @@ -1010,7 +991,7 @@ pub(crate) fn run(
copy_volume_container_rust_triple(
engine,
&container,
&dirs.sysroot,
dirs,
target.triple(),
mount_prefix_path,
true,
Expand Down Expand Up @@ -1047,9 +1028,18 @@ pub(crate) fn run(
.wrap_err("when copying project")?;

let mut copied = vec![
(&dirs.xargo, mount_prefix_path.join("xargo")),
(&dirs.cargo, mount_prefix_path.join("cargo")),
(&dirs.sysroot, mount_prefix_path.join("rust")),
(
&dirs.xargo,
mount_prefix_path.join(Path::new(&dirs.xargo_mount_path_relative()?)),
),
(
&dirs.cargo,
mount_prefix_path.join(Path::new(&dirs.cargo_mount_path_relative()?)),
),
(
&dirs.sysroot,
mount_prefix_path.join(Path::new(&dirs.sysroot_mount_path_relative()?)),
),
(&dirs.host_root, mount_root.clone()),
];
let mut to_symlink = vec![];
Expand Down Expand Up @@ -1169,10 +1159,10 @@ symlink_recurse \"${{prefix}}\"
// 6. execute our cargo command inside the container
let mut docker = subcommand(engine, "exec");
docker_user_id(&mut docker, engine.kind);
docker_envvars(&mut docker, &options.config, target, msg_info)?;
docker_envvars(&mut docker, &options.config, dirs, target, msg_info)?;
docker_cwd(&mut docker, &paths)?;
docker.arg(&container);
docker.args(&["sh", "-c", &format!("PATH=$PATH:/rust/bin {:?}", cmd)]);
docker.args(&["sh", "-c", &build_command(dirs, &cmd)?]);
bail_container_exited!();
let status = docker
.run_and_get_status(msg_info, false)
Expand Down
Loading

0 comments on commit 64448bd

Please sign in to comment.