Skip to content

Commit 8fb489f

Browse files
authored
Merge pull request #717 from cgwalters/install-etc-writable
install: Ensure /etc/containers is writable
2 parents a9cd10f + bffa15c commit 8fb489f

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

lib/src/install.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,42 @@ fn ensure_var() -> Result<()> {
992992
Ok(())
993993
}
994994

995+
/// Unfortunately today podman requires that /etc be writable for
996+
/// `/etc/containers/networks`. Detect the situation where it's not
997+
/// (the main usual cause will be how bootc-image-builder runs us
998+
/// via a custom bwrap container today) and work around it by
999+
/// mounting a writable transient overlayfs.
1000+
#[context("Ensuring writable /etc")]
1001+
fn ensure_writable_etc_containers() -> Result<()> {
1002+
let etc_containers = Utf8Path::new("/etc/containers");
1003+
// If there's no /etc/containers, nothing to do
1004+
if !etc_containers.try_exists()? {
1005+
return Ok(());
1006+
}
1007+
if rustix::fs::access(etc_containers.as_std_path(), rustix::fs::Access::WRITE_OK).is_ok() {
1008+
return Ok(());
1009+
}
1010+
// Create a tempdir for the overlayfs upper; right now this is leaked,
1011+
// but in the case we care about it's into a tmpfs allocated only while
1012+
// we're running (equivalent to PrivateTmp=yes), so it's not
1013+
// really a leak.
1014+
let td = tempfile::tempdir_in("/tmp")?.into_path();
1015+
let td: &Utf8Path = (td.as_path()).try_into()?;
1016+
let upper = &td.join("upper");
1017+
let work = &td.join("work");
1018+
std::fs::create_dir(upper)?;
1019+
std::fs::create_dir(work)?;
1020+
let opts = format!("lowerdir={etc_containers},workdir={work},upperdir={upper}");
1021+
Task::new(
1022+
&format!("Mount transient overlayfs for {etc_containers}"),
1023+
"mount",
1024+
)
1025+
.args(["-t", "overlay", "overlay", "-o", opts.as_str()])
1026+
.arg(etc_containers)
1027+
.run()?;
1028+
Ok(())
1029+
}
1030+
9951031
/// We want to have proper /tmp and /var/tmp without requiring the caller to set them up
9961032
/// in advance by manually specifying them via `podman run -v /tmp:/tmp` etc.
9971033
/// Unfortunately, it's quite complex right now to "gracefully" dynamically reconfigure
@@ -1177,6 +1213,7 @@ async fn prepare_install(
11771213

11781214
ensure_var()?;
11791215
setup_tmp_mounts()?;
1216+
ensure_writable_etc_containers()?;
11801217

11811218
// Even though we require running in a container, the mounts we create should be specific
11821219
// to this process, so let's enter a private mountns to avoid leaking them.

0 commit comments

Comments
 (0)