diff options
author | Lars Wirzenius <liw@liw.fi> | 2023-09-02 08:48:40 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2023-09-02 08:49:00 +0300 |
commit | 40f225d8471d874b7a28c12df266c94506a49e34 (patch) | |
tree | 996a173b91d7954380f16413883ce0deb84761cf | |
parent | f89bcc3784c86e719ee2118a9d4f8aece4f4bdc2 (diff) | |
download | ambient-run-40f225d8471d874b7a28c12df266c94506a49e34.tar.gz |
feat: allow build to export artifacts
Sponsored-by: author
-rw-r--r-- | ambient-run.md | 31 | ||||
-rw-r--r-- | src/bin/ambient-run.rs | 3 | ||||
-rw-r--r-- | src/project.rs | 9 | ||||
-rw-r--r-- | src/qemu.rs | 16 |
4 files changed, 56 insertions, 3 deletions
diff --git a/ambient-run.md b/ambient-run.md index 1690cce..d143acb 100644 --- a/ambient-run.md +++ b/ambient-run.md @@ -165,6 +165,7 @@ source: . shell: | cargo test image: /my/image.qcow2 +artifact: null ~~~ ### Show per-build configuration @@ -226,6 +227,36 @@ shell: | image: image.qcow2 ~~~ +### Build produces an artifact + +_Requirement:_ The build can produce an artifact. + +_Justification:_ Without this a build can't produce something that can +be used after the build has finished. + +_Stakeholder:_ Lars. + +~~~scenario +given an installed ambient-run +given file artifact-project.yaml +given file foo/README.md from foo-project.yaml +given image file image.qcow2 specified for test suite +when I run ambient-run build artifact-project.yaml --log foo.log +then file foo.tar exists +when I run tar tf foo.tar +then stdout contains "README.md" +~~~ + + +~~~{#artifact-project.yaml .file .yaml} +source: foo +shell: | + #!/bin/bash + tar -cf /dev/vdc . +image: image.qcow2 +artifact: foo.tar +~~~ + ### Build is given dependencies ### Cache is persistent between builds ### Build gets the resources is demands diff --git a/src/bin/ambient-run.rs b/src/bin/ambient-run.rs index e1f1b16..3dc778e 100644 --- a/src/bin/ambient-run.rs +++ b/src/bin/ambient-run.rs @@ -215,7 +215,8 @@ impl BuildCommand { let project = Project::load(&self.filename, config)?; let mut qemu = Qemu::new(&project.image()) .with_shell(project.shell()) - .with_source(&project.source()); + .with_source(&project.source()) + .with_artifact(project.artifact()); if let Some(log) = &self.log { qemu = qemu.with_log(log); } diff --git a/src/project.rs b/src/project.rs index 8a182bc..b381734 100644 --- a/src/project.rs +++ b/src/project.rs @@ -12,6 +12,7 @@ pub struct Project { source: PathBuf, shell: String, image: PathBuf, + artifact: Option<PathBuf>, } impl Project { @@ -43,6 +44,7 @@ impl Project { source: PathBuf::from("."), shell: "".into(), image, + artifact: None, }; project.add_from(filename)?; if project.shell.is_empty() { @@ -68,6 +70,7 @@ impl Project { if let Some(x) = snippet.image { self.image = x; } + self.artifact = snippet.artifact; Ok(()) } @@ -90,6 +93,11 @@ impl Project { pub fn shell(&self) -> &str { self.shell.as_ref() } + + /// Artifact file. + pub fn artifact(&self) -> &Option<PathBuf> { + &self.artifact + } } #[derive(Debug, Deserialize)] @@ -98,6 +106,7 @@ struct ProjectSnippet { source: Option<PathBuf>, shell: Option<String>, image: Option<PathBuf>, + artifact: Option<PathBuf>, } /// Possible errors from configuration file handling. diff --git a/src/qemu.rs b/src/qemu.rs index c48213f..3450101 100644 --- a/src/qemu.rs +++ b/src/qemu.rs @@ -18,6 +18,7 @@ pub struct Qemu { log: Option<PathBuf>, source: PathBuf, shell: Option<String>, + artifact: Option<PathBuf>, } impl Qemu { @@ -48,6 +49,12 @@ impl Qemu { self } + /// Set output artifact filename. + pub fn with_artifact(mut self, artifact: &Option<PathBuf>) -> Self { + self.artifact = artifact.clone(); + self + } + /// Run QEMU in the specified way. pub fn run(&self) -> Result<(), QemuError> { eprintln!("qemu run"); @@ -62,8 +69,13 @@ impl Qemu { copy(OVMF_FD, &vars).map_err(|e| QemuError::Copy(OVMF_FD.into(), e))?; eprintln!("output drive"); - let output_drive = - Self::create_tar_with_size(tmp.path().join("output"), empty.path(), MAX_OUTPUT_SIZE)?; + let output_drive = if let Some(filename) = &self.artifact { + eprintln!("output to {}", filename.display()); + Self::create_tar_with_size(filename.to_path_buf(), empty.path(), MAX_OUTPUT_SIZE)? + } else { + eprintln!("empty output drive"); + Self::create_tar_with_size(tmp.path().join("output"), empty.path(), 0)? + }; eprintln!("cache drive"); let cache_drive = |