summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHermes Agent <hermes@localhost>2026-08-12 07:14:29 +0000
committerHermes Agent <hermes@localhost>2026-08-12 07:14:29 +0000
commite5338d823d5e9b2042bbba482c0f629762bbe163 (patch)
tree73f516a6007e46f43a74c2936685b3c59151e334
parente09ee680abd286d25604c2242fa3e128fbdeed69 (diff)
Clean workspace after initramfs failure
-rw-r--r--src/build.rs15
-rw-r--r--tests/build.rs27
2 files changed, 41 insertions, 1 deletions
diff --git a/src/build.rs b/src/build.rs
index 305c059..e6ddf14 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -77,7 +77,14 @@ impl<I: PackageInstaller, B: InitramfsBuilder> BuildExecutor<I, B> {
)
.apply(&rootfs)?;
- let initrd = self.initramfs_builder.build(&InitramfsRequest::discover(&rootfs)?)?;
+ let initramfs_request = match InitramfsRequest::discover(&rootfs) {
+ Ok(request) => request,
+ Err(error) => return Self::fail_and_remove_workspace(workspace, error),
+ };
+ let initrd = match self.initramfs_builder.build(&initramfs_request) {
+ Ok(initrd) => initrd,
+ Err(error) => return Self::fail_and_remove_workspace(workspace, error),
+ };
std::fs::create_dir_all(parent)
.with_context(|| format!("create artifact directory {}", parent.display()))?;
self.tar_writer.write(&rootfs, artifact)?;
@@ -98,6 +105,12 @@ impl<I: PackageInstaller, B: InitramfsBuilder> BuildExecutor<I, B> {
initrd: Some(initrd),
})
}
+
+ fn fail_and_remove_workspace<T>(workspace: &Path, error: anyhow::Error) -> Result<T> {
+ std::fs::remove_dir_all(workspace)
+ .with_context(|| format!("remove failed workspace {}", workspace.display()))?;
+ Err(error)
+ }
}
#[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/tests/build.rs b/tests/build.rs
index dc9443c..987811a 100644
--- a/tests/build.rs
+++ b/tests/build.rs
@@ -31,6 +31,14 @@ impl PackageInstaller for FailingInstaller {
}
}
+struct FailingInitramfsBuilder;
+
+impl InitramfsBuilder for FailingInitramfsBuilder {
+ fn build(&mut self, _request: &InitramfsRequest) -> anyhow::Result<InitramfsResult> {
+ anyhow::bail!("simulated initramfs build failure")
+ }
+}
+
#[derive(Default)]
struct FixtureInitramfsBuilder;
@@ -181,3 +189,22 @@ fn removes_the_new_workspace_when_package_installation_fails() {
assert!(!workspace.exists(), "failed build must not leave a workspace");
assert!(!artifact.exists());
}
+
+#[test]
+fn removes_the_new_workspace_when_initramfs_build_fails() {
+ let fixture = tempdir().expect("fixture directory");
+ let spec = ImageSpec::load(std::path::Path::new("profiles/alt-controller.toml"))
+ .expect("load controller spec");
+ let plan = BuildPlan::compile(spec).expect("compile build plan");
+ let mut executor = BuildExecutor::new(FixtureInstaller::default(), FailingInitramfsBuilder);
+ let workspace = fixture.path().join("work");
+ let artifact = fixture.path().join("image.tar");
+
+ let error = executor
+ .execute(&plan, &workspace, "profiles/apt.conf", &artifact)
+ .expect_err("failed initramfs build must fail the build");
+
+ assert!(error.to_string().contains("simulated initramfs build failure"));
+ assert!(!workspace.exists(), "failed build must not leave a workspace");
+ assert!(!artifact.exists());
+}