summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rootfs.rs16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/rootfs.rs b/src/rootfs.rs
index 9246aa8..ea7d87b 100644
--- a/src/rootfs.rs
+++ b/src/rootfs.rs
@@ -173,8 +173,7 @@ fn copy_entry(
if let Some(parent) = output.parent() {
fs::create_dir_all(parent)?;
}
- fs::copy(source, &output)
- .with_context(|| format!("copy {} to {}", source.display(), output.display()))?;
+ replace_with_file(source, &output)?;
fs::set_permissions(&output, metadata.permissions())?;
manifest.record(destination);
} else {
@@ -213,6 +212,19 @@ fn enable_service(rootfs: &Path, service: &ServiceName, manifest: &mut MutationM
Ok(())
}
+fn replace_with_file(source: &Path, output: &Path) -> Result<()> {
+ match fs::symlink_metadata(output) {
+ Ok(metadata) if metadata.file_type().is_dir() => {
+ bail!("cannot replace directory with file: {}", 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())),
+ }
+ fs::copy(source, output).with_context(|| format!("copy {} to {}", source.display(), output.display()))?;
+ Ok(())
+}
+
fn replace_with_symlink(target: &Path, output: &Path) -> Result<()> {
match fs::symlink_metadata(output) {
Ok(metadata) if metadata.file_type().is_dir() => {