Skip to content

Commit 36f8add

Browse files
committed
install: Allocate a global tmpdir
We allocate temporary things in a few places, and it's handy to have a pre-created single directory for the whole install process to use instead of creating individual tempfiles. Signed-off-by: Colin Walters <[email protected]>
1 parent a557143 commit 36f8add

File tree

1 file changed

+19
-16
lines changed

1 file changed

+19
-16
lines changed

lib/src/install.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use camino::Utf8PathBuf;
2626
use cap_std::fs::{Dir, MetadataExt};
2727
use cap_std_ext::cap_std;
2828
use cap_std_ext::cap_std::fs_utf8::DirEntry as DirEntryUtf8;
29+
use cap_std_ext::cap_tempfile::TempDir;
2930
use cap_std_ext::cmdext::CapStdExtCommandExt;
3031
use cap_std_ext::prelude::CapStdExtDirExt;
3132
use chrono::prelude::*;
@@ -322,6 +323,7 @@ pub(crate) struct State {
322323
pub(crate) root_ssh_authorized_keys: Option<String>,
323324
/// The root filesystem of the running container
324325
pub(crate) container_root: Dir,
326+
pub(crate) tempdir: TempDir,
325327
}
326328

327329
impl State {
@@ -342,6 +344,7 @@ impl State {
342344

343345
#[context("Finalizing state")]
344346
pub(crate) fn consume(self) -> Result<()> {
347+
self.tempdir.close()?;
345348
// If we had invoked `setenforce 0`, then let's re-enable it.
346349
if let SELinuxFinalState::Enabled(Some(guard)) = self.selinux_state {
347350
guard.consume()?;
@@ -1001,7 +1004,7 @@ fn ensure_var() -> Result<()> {
10011004
/// via a custom bwrap container today) and work around it by
10021005
/// mounting a writable transient overlayfs.
10031006
#[context("Ensuring writable /etc")]
1004-
fn ensure_writable_etc_containers() -> Result<()> {
1007+
fn ensure_writable_etc_containers(tempdir: &Dir) -> Result<()> {
10051008
let etc_containers = Utf8Path::new("/etc/containers");
10061009
// If there's no /etc/containers, nothing to do
10071010
if !etc_containers.try_exists()? {
@@ -1010,24 +1013,18 @@ fn ensure_writable_etc_containers() -> Result<()> {
10101013
if rustix::fs::access(etc_containers.as_std_path(), rustix::fs::Access::WRITE_OK).is_ok() {
10111014
return Ok(());
10121015
}
1013-
// Create a tempdir for the overlayfs upper; right now this is leaked,
1014-
// but in the case we care about it's into a tmpfs allocated only while
1015-
// we're running (equivalent to PrivateTmp=yes), so it's not
1016-
// really a leak.
1017-
let td = tempfile::tempdir_in("/tmp")?.into_path();
1018-
let td: &Utf8Path = (td.as_path()).try_into()?;
1019-
let upper = &td.join("upper");
1020-
let work = &td.join("work");
1021-
std::fs::create_dir(upper)?;
1022-
std::fs::create_dir(work)?;
1023-
let opts = format!("lowerdir={etc_containers},workdir={work},upperdir={upper}");
1024-
Task::new(
1016+
// Create dirs for the overlayfs upper and work in the install-global tmpdir.
1017+
tempdir.create_dir_all("etc-ovl/upper")?;
1018+
tempdir.create_dir("etc-ovl/work")?;
1019+
let opts = format!("lowerdir={etc_containers},workdir=etc-ovl/work,upperdir=etc-ovl/upper");
1020+
let mut t = Task::new(
10251021
&format!("Mount transient overlayfs for {etc_containers}"),
10261022
"mount",
10271023
)
10281024
.args(["-t", "overlay", "overlay", "-o", opts.as_str()])
1029-
.arg(etc_containers)
1030-
.run()?;
1025+
.arg(etc_containers);
1026+
t.cmd.cwd_dir(tempdir.try_clone()?);
1027+
t.run()?;
10311028
Ok(())
10321029
}
10331030

@@ -1214,9 +1211,14 @@ async fn prepare_install(
12141211
verify_target_fetch(&target_imgref).await?;
12151212
}
12161213

1214+
// A bit of basic global state setup
12171215
ensure_var()?;
12181216
setup_tmp_mounts()?;
1219-
ensure_writable_etc_containers()?;
1217+
// Allocate a temporary directory we can use in various places to avoid
1218+
// creating multiple.
1219+
let tempdir = cap_std_ext::cap_tempfile::TempDir::new(cap_std::ambient_authority())?;
1220+
// And continue to init global state
1221+
ensure_writable_etc_containers(&tempdir)?;
12201222

12211223
// Even though we require running in a container, the mounts we create should be specific
12221224
// to this process, so let's enter a private mountns to avoid leaking them.
@@ -1260,6 +1262,7 @@ async fn prepare_install(
12601262
install_config,
12611263
root_ssh_authorized_keys,
12621264
container_root: rootfs,
1265+
tempdir,
12631266
});
12641267

12651268
Ok(state)

0 commit comments

Comments
 (0)