diff options
| -rw-r--r-- | src/build.rs | 7 | ||||
| -rw-r--r-- | tests/build.rs | 30 |
2 files changed, 35 insertions, 2 deletions
diff --git a/src/build.rs b/src/build.rs index 994b793..1fd7720 100644 --- a/src/build.rs +++ b/src/build.rs @@ -70,7 +70,7 @@ impl<I: PackageInstaller, B: InitramfsBuilder> BuildExecutor<I, B> { anyhow::anyhow!("package installer did not create rootfs: {}", rootfs.display()), ); } - RootfsFinalization::new( + if let Err(error) = RootfsFinalization::new( Vec::new(), InitrdOem::new( plan.spec().boot.initrd_features.iter().cloned(), @@ -78,7 +78,10 @@ impl<I: PackageInstaller, B: InitramfsBuilder> BuildExecutor<I, B> { ), Vec::new(), ) - .apply(&rootfs)?; + .apply(&rootfs) + { + return Self::fail_and_remove_workspace(workspace, error); + } let initramfs_request = match InitramfsRequest::discover(&rootfs) { Ok(request) => request, diff --git a/tests/build.rs b/tests/build.rs index cae79b0..a0a75b8 100644 --- a/tests/build.rs +++ b/tests/build.rs @@ -39,6 +39,18 @@ impl PackageInstaller for RootfslessInstaller { } } +struct RootfsFinalizationFailingInstaller; + +impl PackageInstaller for RootfsFinalizationFailingInstaller { + fn install(&self, request: &PackageRequest) -> anyhow::Result<()> { + let rootfs = request.workdir().join("chroot"); + fs::create_dir_all(rootfs.join("boot"))?; + fs::write(rootfs.join("boot/vmlinuz-6.12.0-rt1"), "kernel")?; + fs::write(rootfs.join("etc"), "not a directory")?; + Ok(()) + } +} + struct FailingInitramfsBuilder; impl InitramfsBuilder for FailingInitramfsBuilder { @@ -218,6 +230,24 @@ fn removes_the_new_workspace_when_the_installer_does_not_create_a_rootfs() { } #[test] +fn removes_the_new_workspace_when_rootfs_finalization_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(RootfsFinalizationFailingInstaller, FixtureInitramfsBuilder); + 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 rootfs finalization must fail the build"); + + 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")) |