use std::fs::File; use nix::mount::{self, MsFlags}; use common::error::*; use super::{tar, util::fs}; use crate::paths; fn prepare_rootfs(rootfs: &str) -> Result<()> { tar::unpack(File::open(paths::ROOTFS_ARCHIVE)?, rootfs) .context("Unpacking build container rootfs failed")?; mount::mount::<_, _, str, str>(Some(rootfs), rootfs, None, MsFlags::MS_BIND, None) .context("Failed to bind mount container rootfs")?; for dir in ["pts", "shm"] { fs::mkdir(paths::join(&[rootfs, "dev", dir]))?; } for (link, target) in [ ("fd", "/proc/self/fd"), ("stdin", "/proc/self/fd/0"), ("stdout", "/proc/self/fd/1"), ("stderr", "/proc/self/fd/2"), ("ptmx", "pts/ptmx"), ] { let path = paths::join(&[rootfs, "dev", link]); std::os::unix::fs::symlink(target, &path) .with_context(|| format!("Failed to create link {}", path))?; } for dev in ["null", "zero", "full", "random", "urandom", "tty"] { let source = paths::join(&["/dev", dev]); let target = paths::join(&[rootfs, "dev", dev]); fs::create(&target)?; mount::mount::(Some(&source), &target, None, MsFlags::MS_BIND, None) .with_context(|| format!("Failed to bind mount {}", source))?; } mount::mount::( None, rootfs, None, MsFlags::MS_REMOUNT | MsFlags::MS_BIND | MsFlags::MS_RDONLY, None, ) .context("Failed to mount container rootfs read-only")?; Ok(()) } pub fn init_runner() -> Result<()> { fs::mkdir(paths::LAYER_STATE_DIR)?; fs::mkdir(paths::OUTPUT_STATE_DIR)?; mount::mount::<_, _, _, str>( Some("buildtmp"), paths::TMP_DIR, Some("tmpfs"), MsFlags::empty(), None, ) .context("Mounting build tmpfs failed")?; mount::mount::(None, paths::TMP_DIR, None, MsFlags::MS_PRIVATE, None) .context("Failed to set MS_PRIVATE for build tmpfs")?; prepare_rootfs(paths::ROOTFS_DIR)?; Ok(()) }