From d486a774540c27ba8c06f8cdd3a95326cbdb0028 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 20 Jun 2021 20:57:15 +0200 Subject: executor: generate and print task output information --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + src/executor.rs | 35 +++++++++++++++++++++++++++++------ src/recipe.rs | 2 +- src/runner/runc.rs | 2 +- src/runner/runc/run.rs | 6 +++--- src/types.rs | 35 +++++++++++++++++++++++++++++++---- 7 files changed, 76 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 971fa43..9c353d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,6 +161,15 @@ dependencies = [ "wasi 0.10.2+wasi-snapshot-preview1", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + [[package]] name = "iovec" version = "0.1.4" @@ -427,6 +436,7 @@ dependencies = [ name = "rebel" version = "0.1.0" dependencies = [ + "hex", "ipc-channel", "libc", "nix", diff --git a/Cargo.toml b/Cargo.toml index dd9f7fe..074267d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +hex = { version = "0.4.3", features = ["std", "serde"] } ipc-channel = { git = "https://github.com/servo/ipc-channel.git" } libc = "0.2.84" nix = "0.21.0" diff --git a/src/executor.rs b/src/executor.rs index c616c0b..350acc3 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -7,7 +7,7 @@ pub struct Executor<'a> { tasks: &'a TaskMap, tasks_blocked: HashSet, tasks_runnable: Vec, - tasks_done: HashSet, + tasks_done: HashMap, rdeps: HashMap>, } @@ -17,7 +17,7 @@ impl<'a> Executor<'a> { tasks, tasks_blocked: HashSet::new(), tasks_runnable: Vec::new(), - tasks_done: HashSet::new(), + tasks_done: HashMap::new(), rdeps: HashMap::new(), }; @@ -44,17 +44,39 @@ impl<'a> Executor<'a> { task_def .depends .iter() - .all(|dep| self.tasks_done.contains(dep)) + .all(|dep| self.tasks_done.contains_key(dep)) + } + + fn task_deps(&self, task: &TaskRef) -> HashMap { + let task_def = self.tasks.get(&task).expect("Invalid TaskRef"); + task_def + .depends + .iter() + .map(|dep| { + ( + dep.clone(), + self.tasks_done + .get(dep) + .expect("Invalid dependency") + .output_hash, + ) + }) + .collect() } fn run_one(&mut self, runner: &impl runner::Runner) -> runner::Result<()> { let task = self.tasks_runnable.pop().expect("No runnable tasks left"); + let task_deps = self.task_deps(&task); - let _hash = runner.run(self.tasks, &task)?; + let hash = runner.run(self.tasks, &task)?; + let output = TaskOutput { + task_ref: task.clone(), + depends: task_deps, + output_hash: hash, + }; let rdeps = self.rdeps.get(&task); - - self.tasks_done.insert(task); + self.tasks_done.insert(task, output); for rdep in rdeps.unwrap_or(&Vec::new()) { if !self.tasks_blocked.contains(rdep) { @@ -75,6 +97,7 @@ impl<'a> Executor<'a> { } assert!(self.tasks_blocked.is_empty(), "No runnable tasks left"); + println!("{}", serde_json::to_string_pretty(&self.tasks_done)?); Ok(()) } } diff --git a/src/recipe.rs b/src/recipe.rs index 20bca6d..f088e9b 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -6,7 +6,7 @@ use crate::types::*; #[derive(Clone, Debug, Deserialize)] pub struct Recipe { - pub tasks: HashMap, + pub tasks: HashMap, } #[derive(Debug)] diff --git a/src/runner/runc.rs b/src/runner/runc.rs index ae61013..9725d92 100644 --- a/src/runner/runc.rs +++ b/src/runner/runc.rs @@ -15,7 +15,7 @@ use crate::util::ipc::CheckDisconnect; #[derive(Debug, Deserialize, Serialize)] struct Request( TaskRef, - Task, + TaskDef, ipc::IpcSender>, ); diff --git a/src/runner/runc/run.rs b/src/runner/runc/run.rs index dc62159..9eb5bc0 100644 --- a/src/runner/runc/run.rs +++ b/src/runner/runc/run.rs @@ -69,7 +69,7 @@ fn output_filename(task: TaskRef) -> PathBuf { Path::new("build/state").join(format!("{}.tar", task)) } -fn collect_output(task: TaskRef, task_def: Task) -> Result { +fn collect_output(task: TaskRef, task_def: TaskDef) -> Result { let file = util::unix::create_as( output_filename(task), Some(unshare::BUILD_UID), @@ -83,10 +83,10 @@ fn collect_output(task: TaskRef, task_def: Task) -> Result Result { +pub fn handle_task(task: TaskRef, task_def: TaskDef) -> Result { init_task()?; spec::generate_spec(task_def.run.as_str()) diff --git a/src/types.rs b/src/types.rs index afee0e3..3cf4826 100644 --- a/src/types.rs +++ b/src/types.rs @@ -5,7 +5,7 @@ use std::collections::HashMap; pub type TaskRef = String; #[derive(Clone, Debug, Deserialize, Serialize)] -pub struct Task { +pub struct TaskDef { #[serde(default)] pub depends: Vec, #[serde(default)] @@ -14,13 +14,40 @@ pub struct Task { } #[derive(Debug, Default)] -pub struct TaskMap(pub HashMap); +pub struct TaskMap(pub HashMap); impl TaskMap { - pub fn get(&self, task: &TaskRef) -> Option<&Task> { + pub fn get(&self, task: &TaskRef) -> Option<&TaskDef> { self.0.get(task) } } +#[derive(Clone, Copy, Debug)] +pub struct StringHash(pub [u8; 32]); + +impl Serialize for StringHash { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + hex::serde::serialize(self.0, serializer) + } +} +impl<'de> Deserialize<'de> for StringHash { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Ok(StringHash(hex::serde::deserialize(deserializer)?)) + } +} + pub type OutputHasher = Sha256; -pub type OutputHash = [u8; 32]; +pub type OutputHash = StringHash; + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct TaskOutput { + pub task_ref: TaskRef, + pub depends: HashMap, + pub output_hash: OutputHash, +} -- cgit v1.2.3