unshare: mount proc differently depending on root privileges
This commit is contained in:
+55
-1
@@ -134,7 +134,12 @@ impl EphemeralContextGuard {
|
||||
|
||||
// Create device nodes in the chroot
|
||||
log::debug!("Creating device nodes in chroot...");
|
||||
Self::create_device_nodes(chroot_path, ctx_for_devices)?;
|
||||
Self::create_device_nodes(chroot_path, ctx_for_devices.clone())?;
|
||||
|
||||
// Bind mount /proc from host into chroot (before entering unshare namespace)
|
||||
// This allows /proc to work in containers where mounting inside unshare fails
|
||||
log::debug!("Bind-mounting /proc into chroot...");
|
||||
Self::bind_mount_proc(chroot_path, ctx_for_devices)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -286,6 +291,43 @@ impl EphemeralContextGuard {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Bind mount /proc from host into the chroot
|
||||
/// This is done before entering the unshare namespace, so it works in containers
|
||||
fn bind_mount_proc(
|
||||
chroot_path: &Path,
|
||||
ctx: Arc<context::Context>,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let proc_path = chroot_path.join("proc");
|
||||
|
||||
// Ensure /proc directory exists in chroot
|
||||
fs::create_dir_all(&proc_path)?;
|
||||
|
||||
// Check if we're running as root
|
||||
let is_root = crate::utils::root::is_root()?;
|
||||
|
||||
// Bind mount host's /proc into chroot (with sudo if not root)
|
||||
let mut cmd = ctx.command(if is_root { "mount" } else { "sudo" });
|
||||
if !is_root {
|
||||
cmd.arg("mount");
|
||||
}
|
||||
let status = cmd
|
||||
.arg("--bind")
|
||||
.arg("/proc")
|
||||
.arg(proc_path.to_string_lossy().to_string())
|
||||
.status()?;
|
||||
|
||||
if !status.success() {
|
||||
log::warn!(
|
||||
"Could not bind-mount /proc into chroot at {}. Some packages may not install correctly.",
|
||||
proc_path.display()
|
||||
);
|
||||
} else {
|
||||
log::debug!("Bind-mounted /proc into chroot at {}", proc_path.display());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Mark the build as successful, which will trigger chroot cleanup on drop
|
||||
pub fn mark_build_successful(&mut self) {
|
||||
self.build_succeeded = true;
|
||||
@@ -310,6 +352,18 @@ impl Drop for EphemeralContextGuard {
|
||||
// Check if we're running as root to avoid unnecessary sudo
|
||||
let is_root = crate::utils::root::is_root().unwrap_or(false);
|
||||
|
||||
// Unmount /proc from chroot before removing (ignore errors)
|
||||
let proc_path = self.chroot_path.join("proc");
|
||||
let _ = if is_root {
|
||||
self.base_ctx.command("umount").arg(&proc_path).status()
|
||||
} else {
|
||||
self.base_ctx
|
||||
.command("sudo")
|
||||
.arg("umount")
|
||||
.arg(&proc_path)
|
||||
.status()
|
||||
};
|
||||
|
||||
let result = if is_root {
|
||||
self.base_ctx
|
||||
.command("rm")
|
||||
|
||||
Reference in New Issue
Block a user