Skip to content

Commit fde5568

Browse files
committed
fix(vm): look for e2fsprogs tools in /usr/sbin and /sbin
The VM driver only checked PATH and the Homebrew e2fsprogs dirs for mke2fs, e2fsck and debugfs. On Linux these live in /usr/sbin or /sbin, which usually isn't on a regular user's PATH, so provisioning failed with "mke2fs not found" even with e2fsprogs installed. Add /usr/local/sbin, /usr/sbin and /sbin to the search list. macOS behavior is unchanged. Closes #3400 Signed-off-by: natedemoss <ndemoss28@gmail.com>
1 parent fa0bfa4 commit fde5568

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

‎crates/openshell-driver-vm/src/rootfs.rs‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,8 +1053,17 @@ fn run_debugfs(image_path: &Path, command: &str) -> Result<(), String> {
10531053
))
10541054
}
10551055

1056+
/// Resolve the places an e2fsprogs binary may live, starting with `PATH`.
1057+
///
1058+
/// Distributions install `mke2fs`, `e2fsck`, and `debugfs` under `/usr/sbin`
1059+
/// or `/sbin`, which most Linux hosts leave out of a non-root user's `PATH`,
1060+
/// so those directories are probed explicitly. Homebrew keeps e2fsprogs
1061+
/// keg-only on macOS, so its prefixes are probed as well.
10561062
fn e2fs_tool_candidates(tool: &str) -> Vec<PathBuf> {
10571063
let mut candidates = vec![PathBuf::from(tool)];
1064+
for dir in ["/usr/local/sbin", "/usr/sbin", "/sbin"] {
1065+
candidates.push(Path::new(dir).join(tool));
1066+
}
10581067
for root in ["/opt/homebrew/opt/e2fsprogs", "/usr/local/opt/e2fsprogs"] {
10591068
candidates.push(Path::new(root).join("sbin").join(tool));
10601069
candidates.push(Path::new(root).join("bin").join(tool));
@@ -1585,6 +1594,20 @@ mod tests {
15851594
assert_eq!(debugfs_quote_argument("/tmp/bad\npath"), None);
15861595
}
15871596

1597+
#[test]
1598+
fn e2fs_tool_candidates_probe_path_then_system_sbin_directories() {
1599+
let candidates = e2fs_tool_candidates("mke2fs");
1600+
1601+
assert_eq!(candidates.first(), Some(&PathBuf::from("mke2fs")));
1602+
for expected in ["/usr/local/sbin/mke2fs", "/usr/sbin/mke2fs", "/sbin/mke2fs"] {
1603+
assert!(
1604+
candidates.contains(&PathBuf::from(expected)),
1605+
"expected {expected} in {candidates:?}"
1606+
);
1607+
}
1608+
assert!(candidates.contains(&PathBuf::from("/opt/homebrew/opt/e2fsprogs/sbin/mke2fs")));
1609+
}
1610+
15881611
#[test]
15891612
fn formatter_candidates_preserve_executed_failure_over_missing_fallback() {
15901613
let candidates = vec![PathBuf::from("mke2fs"), PathBuf::from("missing")];

0 commit comments

Comments
 (0)