forge
ExploreLog in

Tahinli/forge

public
0 watching
★ 0
1.9 KiB
1//! Removing a tree whose files are owned by subordinate ids, through the `__sandbox-rm` helper.
2//! The tests skip when the host can't provide subuid mode or `unshare --map-auto`.
3
4use std::fs;
5use std::path::Path;
6use std::process::{Command, Stdio};
7
8use forge_runner::sandbox::idmap::{IdMap, UsernsMode, remove_tree};
9
10#[test]
11fn remove_tree_deletes_files_owned_by_subordinate_ids() {
12 let map = match IdMap::resolve(UsernsMode::Subuid) {
13 Ok(map) => map,
14 Err(e) => {
15 eprintln!("skipping: {e}");
16 return;
17 }
18 };
19 let dir = tempfile::tempdir().expect("tempdir");
20 let job = dir.path().join("job");
21 fs::create_dir_all(job.join("sub")).expect("create job dir");
22 let file = job.join("sub/f");
23 fs::write(&file, b"x").expect("write file");
24 // Give the file to container uid 1000, which is a subordinate id on the host.
25 let chown = Command::new("unshare")
26 .args(["--map-auto", "--map-root-user", "chown", "1000:1000"])
27 .arg(&file)
28 .stdout(Stdio::null())
29 .stderr(Stdio::null())
30 .status();
31 if !chown.is_ok_and(|s| s.success()) {
32 eprintln!("skipping: unshare --map-auto cannot chown");
33 return;
34 }
35
36 let exe = Path::new(env!("CARGO_BIN_EXE_forge-runner"));
37 remove_tree(&map, &job, exe).expect("remove_tree");
38 assert!(!job.exists(), "{} should be gone", job.display());
39}
40
41#[test]
42fn remove_tree_treats_a_missing_path_as_done() {
43 let dir = tempfile::tempdir().expect("tempdir");
44 let missing = dir.path().join("missing");
45 let exe = Path::new(env!("CARGO_BIN_EXE_forge-runner"));
46 remove_tree(&IdMap::single(), &missing, exe).expect("single mode");
47 let map = IdMap {
48 uid: 1000,
49 gid: 1000,
50 sub_uid: Some((524288, 65536)),
51 sub_gid: Some((524288, 65536)),
52 };
53 remove_tree(&map, &missing, exe).expect("subuid mode");
54}