summaryrefslogtreecommitdiff
path: root/src/rootfs.rs
diff options
context:
space:
mode:
authorHermes Agent <hermes@localhost>2026-08-12 04:18:12 +0000
committerHermes Agent <hermes@localhost>2026-08-12 04:18:12 +0000
commit39a23d9035ab99191e305db3a55a8df1606f63b3 (patch)
treeac48f8d44ce5c884b4694ea88e806e9cb08ee2c6 /src/rootfs.rs
parentfc4e46c41bfb769193159143f6567341cd3e3a51 (diff)
Make rootfs finalization repeatable
Diffstat (limited to 'src/rootfs.rs')
-rw-r--r--src/rootfs.rs21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/rootfs.rs b/src/rootfs.rs
index 06b2557..9246aa8 100644
--- a/src/rootfs.rs
+++ b/src/rootfs.rs
@@ -167,7 +167,7 @@ fn copy_entry(
if let Some(parent) = output.parent() {
fs::create_dir_all(parent)?;
}
- symlink(&target, &output).with_context(|| format!("create symlink {}", output.display()))?;
+ replace_with_symlink(&target, &output)?;
manifest.record(destination);
} else if metadata.file_type().is_file() {
if let Some(parent) = output.parent() {
@@ -204,8 +204,23 @@ fn enable_service(rootfs: &Path, service: &ServiceName, manifest: &mut MutationM
))?;
let output = rootfs.join(destination.as_path());
fs::create_dir_all(output.parent().expect("service path has a parent"))?;
- symlink(format!("/usr/lib/systemd/system/{}", service.0), &output)
- .with_context(|| format!("enable service {}", service.0))?;
+ replace_with_symlink(
+ Path::new(&format!("/usr/lib/systemd/system/{}", service.0)),
+ &output,
+ )
+ .with_context(|| format!("enable service {}", service.0))?;
manifest.record(destination.as_path());
Ok(())
}
+
+fn replace_with_symlink(target: &Path, output: &Path) -> Result<()> {
+ match fs::symlink_metadata(output) {
+ Ok(metadata) if metadata.file_type().is_dir() => {
+ bail!("cannot replace directory with symlink: {}", output.display());
+ }
+ Ok(_) => fs::remove_file(output).with_context(|| format!("replace {}", output.display()))?,
+ Err(error) if error.kind() == std::io::ErrorKind::NotFound => {}
+ Err(error) => return Err(error).with_context(|| format!("inspect {}", output.display())),
+ }
+ symlink(target, output).with_context(|| format!("create symlink {}", output.display()))
+}