summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2021-11-01 23:20:49 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2021-11-01 23:33:45 +0100
commit3123a16b6793a209aa10b4e72b63729ae9a32e99 (patch)
treec22afe45db2e2091fb19e723a046a3fe2ee3c024
parentf6e4529dba0adbf1736687686a0d70e674830a21 (diff)
downloadrebel-3123a16b6793a209aa10b4e72b63729ae9a32e99.tar
rebel-3123a16b6793a209aa10b4e72b63729ae9a32e99.zip
runner: use rootfs passed in Task definition
With this, the rootfs hash is included in the task's input hash, so now the hash covers all significant inputs except for the runner itself.
-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 {