diff --git a/src/context/unshare.rs b/src/context/unshare.rs index 8b80c6a..48bbaad 100644 --- a/src/context/unshare.rs +++ b/src/context/unshare.rs @@ -207,11 +207,39 @@ impl UnshareDriver { cmd.arg("-w").arg(dir); } - cmd.arg("--").arg("bash").arg("-c").arg(format!( - "mount -t proc proc /proc; mkdir /dev/pts; mount -t devpts devpts /dev/pts; touch /dev/ptmx; mount --bind /dev/pts/ptmx /dev/ptmx; {} {}", - program, - args.iter().map(|a| format!("\"{a}\"")).collect::>().join(" ") - )); + // Check if we're running as root to determine how to mount /proc + // --mount-proc requires root privileges, otherwise we try mounting inside the namespace + let is_root = crate::utils::root::is_root().unwrap_or(false); + + if is_root { + cmd.arg("--mount-proc"); + } + + // Build the bash command: set up /dev/pts and run the program + // When not root, also try to mount /proc inside the namespace (may fail in containers) + let proc_mount_cmd = if is_root { + // /proc is already mounted by --mount-proc + String::new() + } else { + // Try to mount /proc, continue with warning if it fails + "mkdir -p /proc; mount -t proc proc /proc 2>/dev/null || echo 'Warning: Could not mount /proc, some packages may not install correctly'; ".to_string() + }; + + let program_args = args + .iter() + .map(|a| format!("\"{a}\"")) + .collect::>() + .join(" "); + + cmd.arg("--") + .arg("bash") + .arg("-c") + .arg(format!( + "{}mkdir -p /dev/pts; mount -t devpts devpts /dev/pts 2>/dev/null || true; touch /dev/ptmx; mount --bind /dev/pts/ptmx /dev/ptmx 2>/dev/null || true; {} {}", + proc_mount_cmd, + program, + program_args + )); cmd }