summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2023-09-02 08:48:40 +0300
committerLars Wirzenius <liw@liw.fi>2023-09-02 08:49:00 +0300
commit40f225d8471d874b7a28c12df266c94506a49e34 (patch)
tree996a173b91d7954380f16413883ce0deb84761cf
parentf89bcc3784c86e719ee2118a9d4f8aece4f4bdc2 (diff)
downloadambient-run-40f225d8471d874b7a28c12df266c94506a49e34.tar.gz
feat: allow build to export artifacts
Sponsored-by: author
-rw-r--r--ambient-run.md31
-rw-r--r--src/bin/ambient-run.rs3
-rw-r--r--src/project.rs9
-rw-r--r--src/qemu.rs16
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 =