Skip to content

Commit 59ec530

Browse files
Merge #942
942: Use non-canonical paths for mount paths. r=Emilgardis a=Alexhuszagh Symlinks and canonical paths can destroy assumptions about paths: say I have a file at `/tmp/path/to/file` I reference in my crate, and ask to mount `/tmp/path/to` on the container. Currently, on macOS, since `/tmp` is a symlink to `/private/tmp`, the code that expects `/tmp/path/to/file` will fail because in the container it will be mounted at `/private/tmp/path/to/file`. In addition, this fixes `DeviceNS` parsing with drive letters (this previously didn't matter since it never occurred, due to `dunce` canonicalization). This PR also fixes a minor bug where the host root instead of the var names was passed as the environment variable (introduced in #904). Closes #920. Co-authored-by: Alex Huszagh <[email protected]>
2 parents 06690f4 + b3a62ea commit 59ec530

File tree

6 files changed

+169
-131
lines changed

6 files changed

+169
-131
lines changed

.changes/942.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[
2+
{
3+
"description": "use non-canonical paths for mount locations.",
4+
"type": "changed",
5+
"issues": [920]
6+
},
7+
{
8+
"description": "fixed DeviceNS drive parsing in creating WSL-style paths on windows.",
9+
"type": "fixed"
10+
},
11+
{
12+
"description": "fixed the environment variable name for mounted volumes.",
13+
"type": "fixed"
14+
}
15+
]

src/cli.rs

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
33

44
use crate::cargo::Subcommand;
55
use crate::errors::Result;
6-
use crate::file::PathExt;
6+
use crate::file::{absolute_path, PathExt};
77
use crate::rustc::TargetList;
88
use crate::shell::{self, MessageInfo};
99
use crate::Target;
@@ -23,15 +23,6 @@ pub struct Args {
2323
pub color: Option<String>,
2424
}
2525

26-
// Fix for issue #581. target_dir must be absolute.
27-
fn absolute_path(path: PathBuf) -> Result<PathBuf> {
28-
Ok(if path.is_absolute() {
29-
path
30-
} else {
31-
env::current_dir()?.join(path)
32-
})
33-
}
34-
3526
pub fn is_subcommand_list(stdout: &str) -> bool {
3627
stdout.starts_with("Installed Commands:")
3728
}
@@ -151,22 +142,8 @@ fn str_to_owned(arg: &str) -> Result<String> {
151142
Ok(arg.to_owned())
152143
}
153144

154-
#[allow(clippy::needless_return)]
155145
fn store_manifest_path(path: String) -> Result<String> {
156-
let p = Path::new(&path);
157-
if p.is_absolute() {
158-
#[cfg(target_os = "windows")]
159-
{
160-
return p.as_wslpath();
161-
}
162-
#[cfg(not(target_os = "windows"))]
163-
{
164-
use crate::file::ToUtf8;
165-
return p.to_utf8().map(ToOwned::to_owned);
166-
}
167-
} else {
168-
p.as_posix()
169-
}
146+
Path::new(&path).as_posix_relative()
170147
}
171148

172149
fn store_target_dir(_: String) -> Result<String> {

src/docker/local.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::io;
2-
use std::process::ExitStatus;
2+
use std::path::Path;
3+
use std::process::{Command, ExitStatus};
34

45
use super::shared::*;
56
use crate::errors::Result;
@@ -8,6 +9,16 @@ use crate::file::{PathExt, ToUtf8};
89
use crate::shell::{MessageInfo, Stream};
910
use eyre::Context;
1011

12+
// NOTE: host path must be absolute
13+
fn mount(docker: &mut Command, host_path: &Path, absolute_path: &Path, prefix: &str) -> Result<()> {
14+
let mount_path = absolute_path.as_posix_absolute()?;
15+
docker.args(&[
16+
"-v",
17+
&format!("{}:{prefix}{}", host_path.to_utf8()?, mount_path),
18+
]);
19+
Ok(())
20+
}
21+
1122
pub(crate) fn run(
1223
options: DockerOptions,
1324
paths: DockerPaths,
@@ -39,7 +50,7 @@ pub(crate) fn run(
3950
&mut docker,
4051
&options,
4152
&paths,
42-
|docker, val| mount(docker, val, ""),
53+
|docker, host, absolute| mount(docker, host, absolute, ""),
4354
|_| {},
4455
)?;
4556

@@ -81,7 +92,11 @@ pub(crate) fn run(
8192
if let Some(ref nix_store) = dirs.nix_store {
8293
docker.args(&[
8394
"-v",
84-
&format!("{}:{}:Z", nix_store.to_utf8()?, nix_store.as_posix()?),
95+
&format!(
96+
"{}:{}:Z",
97+
nix_store.to_utf8()?,
98+
nix_store.as_posix_absolute()?
99+
),
85100
]);
86101
}
87102

src/docker/remote.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,11 @@ fn create_volume_dir(
168168
// make our parent directory if needed
169169
subcommand_or_exit(engine, "exec")?
170170
.arg(container)
171-
.args(&["sh", "-c", &format!("mkdir -p '{}'", dir.as_posix()?)])
171+
.args(&[
172+
"sh",
173+
"-c",
174+
&format!("mkdir -p '{}'", dir.as_posix_absolute()?),
175+
])
172176
.run_and_get_status(msg_info, false)
173177
}
174178

@@ -183,7 +187,7 @@ fn copy_volume_files(
183187
subcommand_or_exit(engine, "cp")?
184188
.arg("-a")
185189
.arg(src.to_utf8()?)
186-
.arg(format!("{container}:{}", dst.as_posix()?))
190+
.arg(format!("{container}:{}", dst.as_posix_absolute()?))
187191
.run_and_get_status(msg_info, false)
188192
}
189193

@@ -214,7 +218,11 @@ fn container_path_exists(
214218
) -> Result<bool> {
215219
Ok(subcommand_or_exit(engine, "exec")?
216220
.arg(container)
217-
.args(&["bash", "-c", &format!("[[ -d '{}' ]]", path.as_posix()?)])
221+
.args(&[
222+
"bash",
223+
"-c",
224+
&format!("[[ -d '{}' ]]", path.as_posix_absolute()?),
225+
])
218226
.run_and_get_status(msg_info, true)?
219227
.success())
220228
}
@@ -567,7 +575,7 @@ fn read_dir_fingerprint(
567575
let modified = file.metadata()?.modified()?;
568576
let millis = modified.duration_since(epoch)?.as_millis() as u64;
569577
let rounded = epoch + time::Duration::from_millis(millis);
570-
let relpath = file.path().strip_prefix(home)?.as_posix()?;
578+
let relpath = file.path().strip_prefix(home)?.as_posix_relative()?;
571579
map.insert(relpath, rounded);
572580
}
573581
}
@@ -647,7 +655,7 @@ rm \"{PATH}\"
647655
// SAFETY: safe, single-threaded execution.
648656
let mut tempfile = unsafe { temp::TempFile::new()? };
649657
for file in files {
650-
writeln!(tempfile.file(), "{}", dst.join(file).as_posix()?)?;
658+
writeln!(tempfile.file(), "{}", dst.join(file).as_posix_relative()?)?;
651659
}
652660

653661
// need to avoid having hundreds of files on the command, so
@@ -845,11 +853,6 @@ pub fn unique_container_identifier(
845853
Ok(format!("{toolchain_id}-{triple}-{name}-{project_hash}"))
846854
}
847855

848-
fn mount_path(val: &Path) -> Result<String> {
849-
let host_path = file::canonicalize(val)?;
850-
canonicalize_mount_path(&host_path)
851-
}
852-
853856
pub(crate) fn run(
854857
options: DockerOptions,
855858
paths: DockerPaths,
@@ -921,7 +924,7 @@ pub(crate) fn run(
921924
&mut docker,
922925
&options,
923926
&paths,
924-
|_, val| mount_path(val),
927+
|_, _, _| Ok(()),
925928
|(src, dst)| volumes.push((src, dst)),
926929
)
927930
.wrap_err("could not determine mount points")?;
@@ -1100,7 +1103,7 @@ pub(crate) fn run(
11001103
let mut final_args = vec![];
11011104
let mut iter = args.iter().cloned();
11021105
let mut has_target_dir = false;
1103-
let target_dir_string = target_dir.as_posix()?;
1106+
let target_dir_string = target_dir.as_posix_absolute()?;
11041107
while let Some(arg) = iter.next() {
11051108
if arg == "--target-dir" {
11061109
has_target_dir = true;
@@ -1156,7 +1159,11 @@ symlink_recurse \"${{prefix}}\"
11561159
"
11571160
));
11581161
for (src, dst) in to_symlink {
1159-
symlink.push(format!("ln -s \"{}\" \"{}\"", src.as_posix()?, dst));
1162+
symlink.push(format!(
1163+
"ln -s \"{}\" \"{}\"",
1164+
src.as_posix_absolute()?,
1165+
dst
1166+
));
11601167
}
11611168
subcommand_or_exit(engine, "exec")?
11621169
.arg(&container)
@@ -1185,7 +1192,7 @@ symlink_recurse \"${{prefix}}\"
11851192
if !skip_artifacts && container_path_exists(engine, &container, &target_dir, msg_info)? {
11861193
subcommand_or_exit(engine, "cp")?
11871194
.arg("-a")
1188-
.arg(&format!("{container}:{}", target_dir.as_posix()?))
1195+
.arg(&format!("{container}:{}", target_dir.as_posix_absolute()?))
11891196
.arg(
11901197
&dirs
11911198
.target

0 commit comments

Comments
 (0)