summaryrefslogtreecommitdiffstats
path: root/crates/runner/src/init.rs
blob: 07631eaba90451ff1ac63c5ce9769d0684ed59dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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::<str, str, str, str>(Some(&source), &target, None, MsFlags::MS_BIND, None)
			.with_context(|| format!("Failed to bind mount {}", source))?;
	}

	mount::mount::<str, _, str, str>(
		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)?;

	fs::ensure_removed(paths::TMP_DIR)?;
	fs::mkdir(paths::TMP_DIR)?;
	mount::mount::<_, _, str, str>(
		Some(paths::TMP_DIR),
		paths::TMP_DIR,
		None,
		MsFlags::MS_BIND,
		None,
	)
	.context("Failed to bind mount build tmpdir")?;
	mount::mount::<str, _, str, str>(None, paths::TMP_DIR, None, MsFlags::MS_PRIVATE, None)
		.context("Failed to set MS_PRIVATE for build tmpdir")?;

	prepare_rootfs(paths::ROOTFS_DIR)?;

	Ok(())
}