summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crates/common/src/types.rs1
-rw-r--r--crates/driver/src/driver.rs4
-rw-r--r--crates/runner/src/init.rs24
-rw-r--r--crates/runner/src/paths.rs5
-rw-r--r--crates/runner/src/tar.rs28
-rw-r--r--crates/runner/src/task.rs46
6 files changed, 54 insertions, 54 deletions
diff --git a/crates/common/src/types.rs b/crates/common/src/types.rs
index 336b131..222c79f 100644
--- a/crates/common/src/types.rs
+++ b/crates/common/src/types.rs
@@ -38,6 +38,7 @@ pub struct Task {
pub label: String,
pub command: String,
pub workdir: String,
+ pub rootfs: ArchiveHash,
pub inherit: Vec<LayerHash>,
pub depends: HashSet<Dependency>,
pub outputs: HashMap<String, String>,
diff --git a/crates/driver/src/driver.rs b/crates/driver/src/driver.rs
index e3dc407..84262ac 100644
--- a/crates/driver/src/driver.rs
+++ b/crates/driver/src/driver.rs
@@ -298,14 +298,16 @@ impl<'ctx> Driver<'ctx> {
format!("Failed to evaluate command template for task {}", task_ref)
})?;
+ let rootfs = self.state.ctx.get_rootfs();
let task = Task {
label: format!("{:#}", task_ref),
command,
workdir: paths::TASK_WORKDIR.to_string(),
+ rootfs: rootfs.0,
inherit: inherit_chain,
depends: task_deps,
outputs: task_output,
- pins: HashMap::new(),
+ pins: HashMap::from([rootfs.clone()]),
};
Ok(Some(runner.spawn(&task)))
diff --git a/crates/runner/src/init.rs b/crates/runner/src/init.rs
index ad37cf0..ede8fd8 100644
--- a/crates/runner/src/init.rs
+++ b/crates/runner/src/init.rs
@@ -1,29 +1,8 @@
-use std::fs::File;
-
use nix::mount::{self, MsFlags};
use common::error::*;
-use super::{tar, util::fs};
-use crate::paths;
-
-fn prepare_rootfs(path: &str) -> Result<()> {
- tar::unpack(File::open(paths::ROOTFS_ARCHIVE)?, path)
- .context("Unpacking build container rootfs failed")?;
-
- mount::mount::<_, _, str, str>(Some(path), path, None, MsFlags::MS_BIND, None)
- .context("Failed to bind mount container rootfs")?;
- mount::mount::<str, _, str, str>(
- None,
- path,
- None,
- MsFlags::MS_REMOUNT | MsFlags::MS_BIND | MsFlags::MS_RDONLY,
- None,
- )
- .context("Failed to mount container rootfs read-only")?;
-
- Ok(())
-}
+use crate::{paths, util::fs};
fn prepare_dev(path: &str) -> Result<()> {
fs::mkdir(path)?;
@@ -83,7 +62,6 @@ pub fn init_runner() -> Result<()> {
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)?;
prepare_dev(paths::DEV_DIR)?;
Ok(())
diff --git a/crates/runner/src/paths.rs b/crates/runner/src/paths.rs
index b46d1bb..7af1e3a 100644
--- a/crates/runner/src/paths.rs
+++ b/crates/runner/src/paths.rs
@@ -5,7 +5,6 @@
//! ```text
//! build/
//! ├── build.lock
-//! ├── rootfs.tar
//! ├── downloads/
//! │   └── ...
//! ├── state/
@@ -27,7 +26,6 @@
//! │   └── ...
//! └── tmp/ # temporary files (cleaned on start)
//!    ├── dev/ # container /dev
-//!    ├── rootfs/ # unpacked rootfs.tar
//!    ├── depends/ # unpacked dependencies
//!    └── task/
//!    └── <input hash>/
@@ -40,14 +38,11 @@
use common::string_hash::*;
-pub const ROOTFS_ARCHIVE: &str = "build/rootfs.tar";
-
pub const DOWNLOADS_DIR: &str = "build/downloads";
pub const PIN_DIR: &str = "build/pinned";
pub const TMP_DIR: &str = "build/tmp";
pub const DEV_DIR: &str = "build/tmp/dev";
-pub const ROOTFS_DIR: &str = "build/tmp/rootfs";
pub const DEPENDS_TMP_DIR: &str = "build/tmp/depends";
pub const TASK_TMP_DIR: &str = "build/tmp/task";
diff --git a/crates/runner/src/tar.rs b/crates/runner/src/tar.rs
index 32d8e8d..10cac92 100644
--- a/crates/runner/src/tar.rs
+++ b/crates/runner/src/tar.rs
@@ -11,7 +11,7 @@ use nix::{
sys::wait,
};
-use common::error::*;
+use common::{error::*, string_hash::ArchiveHash};
use super::{
ns,
@@ -19,12 +19,28 @@ use super::{
};
use crate::paths;
-pub fn pack<W: Write, P: AsRef<Path>>(archive: &mut W, source: P) -> Result<()> {
+pub fn pack<W: Write, P: AsRef<Path>>(
+ rootfs_hash: &ArchiveHash,
+ archive: &mut W,
+ source: P,
+) -> Result<()> {
+ let rootfs = paths::depend_dir(rootfs_hash);
+ let _rootfs_mount = fs::mount(&rootfs, &rootfs, None, MsFlags::MS_BIND, None)
+ .with_context(|| format!("Failed to bind mount rootfs to {:?}", rootfs))?;
+ mount::mount::<str, str, str, str>(
+ None,
+ &rootfs,
+ None,
+ MsFlags::MS_REMOUNT | MsFlags::MS_BIND | MsFlags::MS_RDONLY,
+ None,
+ )
+ .context("Failed to mount container rootfs read-only")?;
+
let (mut piper, pipew) = fs::pipe()?;
let exec_tar = || -> Result<()> {
- // We are in our own mount namespace, so mounting into the shared ROOTFS_DIR is fine
- let dev_target = paths::join(&[paths::ROOTFS_DIR, "dev"]);
+ // We are in our own mount namespace, so mounting into the shared rootfs is fine
+ let dev_target = paths::join(&[&rootfs, "dev"]);
mount::mount::<_, _, str, str>(
Some(paths::DEV_DIR),
dev_target.as_str(),
@@ -32,7 +48,7 @@ pub fn pack<W: Write, P: AsRef<Path>>(archive: &mut W, source: P) -> Result<()>
MsFlags::MS_BIND | MsFlags::MS_REC,
None,
)?;
- let mount_target = paths::join(&[paths::ROOTFS_DIR, paths::TASK_BUILDDIR]);
+ let mount_target = paths::join(&[&rootfs, paths::TASK_BUILDDIR]);
mount::mount::<_, _, str, str>(
Some(source.as_ref()),
mount_target.as_str(),
@@ -41,7 +57,7 @@ pub fn pack<W: Write, P: AsRef<Path>>(archive: &mut W, source: P) -> Result<()>
None,
)?;
- ns::pivot_root(paths::ROOTFS_DIR);
+ ns::pivot_root(&rootfs);
let err = Command::new("tar")
.args(&[
diff --git a/crates/runner/src/task.rs b/crates/runner/src/task.rs
index c43fc2f..8981d13 100644
--- a/crates/runner/src/task.rs
+++ b/crates/runner/src/task.rs
@@ -51,6 +51,7 @@ fn input_hash(task: &Task) -> InputHash {
struct HashInput<'a> {
pub command: &'a str,
pub workdir: &'a str,
+ pub rootfs: &'a ArchiveHash,
pub inherit: &'a [LayerHash],
pub depends: HashMap<DependencyHash, &'a Dependency>,
pub outputs: &'a HashMap<String, String>,
@@ -58,6 +59,7 @@ fn input_hash(task: &Task) -> InputHash {
let input = HashInput {
command: &task.command,
workdir: &task.workdir,
+ rootfs: &task.rootfs,
inherit: &task.inherit,
depends: task
.depends
@@ -180,22 +182,27 @@ fn check_conflicts(
Ok(())
}
-fn init_task_rootfs(input_hash: &InputHash, depends: &DependMap) -> Result<Stack<fs::Mount>> {
+fn init_task_rootfs(input_hash: &InputHash, task: &Task) -> Result<Stack<fs::Mount>> {
let task_tmp_dir = paths::task_tmp_dir(input_hash);
let mount_target = paths::join(&[&task_tmp_dir, paths::TASK_TMP_ROOTFS_SUBDIR]);
+ let rootfs = paths::depend_dir(&task.rootfs);
+
+ let depends = unpack_dependencies(input_hash, task).context("Failed to unpack dependencies")?;
let mut mounts = Stack::new();
mounts.push(
- fs::mount(
- paths::ROOTFS_DIR,
- &mount_target,
- None,
- MsFlags::MS_BIND,
- None,
- )
- .with_context(|| format!("Failed to bind mount rootfs to {:?}", mount_target))?,
+ fs::mount(rootfs, &mount_target, None, MsFlags::MS_BIND, None)
+ .with_context(|| format!("Failed to bind mount rootfs to {:?}", mount_target))?,
);
+ mount::mount::<str, str, str, str>(
+ None,
+ &mount_target,
+ None,
+ MsFlags::MS_REMOUNT | MsFlags::MS_BIND | MsFlags::MS_RDONLY,
+ None,
+ )
+ .context("Failed to mount container rootfs read-only")?;
let (mut dirs, mut files) = get_contents(&mount_target, "")?;
@@ -209,11 +216,11 @@ fn init_task_rootfs(input_hash: &InputHash, depends: &DependMap) -> Result<Stack
)));
}
- let dep_target = mount_target.clone() + path;
+ let dep_target = mount_target.clone() + &path;
let dep_paths: Box<[_]> = dep_hashes.iter().map(paths::depend_dir).collect();
for dep in dep_paths.iter() {
- let (dep_dirs, dep_files) = get_contents(dep, path)?;
+ let (dep_dirs, dep_files) = get_contents(dep, &path)?;
check_conflicts(&dirs, &files, &dep_dirs, &dep_files)?;
dirs.extend(dep_dirs);
files.extend(dep_files);
@@ -306,6 +313,8 @@ fn unpack_dependency(task: &Task, hash: &ArchiveHash) -> Result<()> {
fn unpack_dependencies(input_hash: &InputHash, task: &Task) -> Result<DependMap> {
let task_tmp_dir = paths::task_tmp_dir(input_hash);
+ unpack_dependency(task, &task.rootfs)?;
+
let mut ret = DependMap::new();
for dep in &task.depends {
@@ -330,7 +339,7 @@ fn unpack_dependencies(input_hash: &InputHash, task: &Task) -> Result<DependMap>
Ok(ret)
}
-fn collect_output(input_hash: &InputHash, path: &str) -> Result<Option<ArchiveHash>> {
+fn collect_output(input_hash: &InputHash, task: &Task, path: &str) -> Result<Option<ArchiveHash>> {
let source = paths::join(&[&paths::task_tmp_dir(input_hash), path]);
if !Path::new(&source).is_dir() {
return Ok(None);
@@ -344,7 +353,7 @@ fn collect_output(input_hash: &InputHash, path: &str) -> Result<Option<ArchiveHa
let writer = TeeWriter::new(file, hasher);
let mut buffered_writer = BufWriter::with_capacity(16 * 1024 * 1024, writer);
- super::tar::pack(&mut buffered_writer, &source)?;
+ super::tar::pack(&task.rootfs, &mut buffered_writer, &source)?;
let writer = buffered_writer.into_inner()?;
let (file, hasher) = writer.into_inner();
@@ -364,7 +373,7 @@ fn collect_outputs(input_hash: &InputHash, task: &Task) -> Result<HashMap<String
let mut ret = HashMap::new();
for (name, path) in &task.outputs {
- if let Some(hash) = collect_output(input_hash, path)? {
+ if let Some(hash) = collect_output(input_hash, task, path)? {
ret.insert(name.clone(), hash);
}
}
@@ -374,9 +383,8 @@ fn collect_outputs(input_hash: &InputHash, task: &Task) -> Result<HashMap<String
fn run_task(input_hash: &InputHash, task: &Task, jobserver: &mut Jobserver) -> Result<()> {
let _workdir_mount = init_task(input_hash, task).context("Failed to initialize task")?;
- let depends = unpack_dependencies(input_hash, task).context("Failed to unpack dependencies")?;
let _rootfs_mounts =
- init_task_rootfs(input_hash, &depends).context("Failed to initialize task rootfs")?;
+ init_task_rootfs(input_hash, task).context("Failed to initialize task rootfs")?;
let task_tmp_dir = paths::task_tmp_dir(input_hash);
let rootfs = paths::join(&[&task_tmp_dir, paths::TASK_TMP_ROOTFS_SUBDIR]);
@@ -475,7 +483,7 @@ fn run_task(input_hash: &InputHash, task: &Task, jobserver: &mut Jobserver) -> R
Ok(())
}
-fn hash_layer(input_hash: &InputHash) -> Result<Option<LayerHash>> {
+fn hash_layer(input_hash: &InputHash, task: &Task) -> Result<Option<LayerHash>> {
let task_state_dir = paths::task_state_dir(input_hash);
let task_layer_dir = paths::join(&[&task_state_dir, paths::TASK_STATE_LAYER_SUBDIR]);
@@ -487,7 +495,7 @@ fn hash_layer(input_hash: &InputHash) -> Result<Option<LayerHash>> {
let hasher = LayerHasher::new();
let mut buffered_writer = BufWriter::with_capacity(16 * 1024 * 1024, hasher);
- tar::pack(&mut buffered_writer, &task_layer_dir)?;
+ tar::pack(&task.rootfs, &mut buffered_writer, &task_layer_dir)?;
let hasher = buffered_writer.into_inner()?;
Ok(Some(LayerHash(StringHash(hasher.finalize().into()))))
@@ -529,7 +537,7 @@ fn run_and_hash_task(
let outputs = collect_outputs(input_hash, task)?;
- let layer = hash_layer(input_hash)?;
+ let layer = hash_layer(input_hash, task)?;
move_layer(input_hash, &layer)?;
Ok(TaskOutput {