@@ -26,6 +26,7 @@ use camino::Utf8PathBuf;
26
26
use cap_std:: fs:: { Dir , MetadataExt } ;
27
27
use cap_std_ext:: cap_std;
28
28
use cap_std_ext:: cap_std:: fs_utf8:: DirEntry as DirEntryUtf8 ;
29
+ use cap_std_ext:: cap_tempfile:: TempDir ;
29
30
use cap_std_ext:: cmdext:: CapStdExtCommandExt ;
30
31
use cap_std_ext:: prelude:: CapStdExtDirExt ;
31
32
use chrono:: prelude:: * ;
@@ -322,6 +323,7 @@ pub(crate) struct State {
322
323
pub ( crate ) root_ssh_authorized_keys : Option < String > ,
323
324
/// The root filesystem of the running container
324
325
pub ( crate ) container_root : Dir ,
326
+ pub ( crate ) tempdir : TempDir ,
325
327
}
326
328
327
329
impl State {
@@ -342,6 +344,7 @@ impl State {
342
344
343
345
#[ context( "Finalizing state" ) ]
344
346
pub ( crate ) fn consume ( self ) -> Result < ( ) > {
347
+ self . tempdir . close ( ) ?;
345
348
// If we had invoked `setenforce 0`, then let's re-enable it.
346
349
if let SELinuxFinalState :: Enabled ( Some ( guard) ) = self . selinux_state {
347
350
guard. consume ( ) ?;
@@ -1001,7 +1004,7 @@ fn ensure_var() -> Result<()> {
1001
1004
/// via a custom bwrap container today) and work around it by
1002
1005
/// mounting a writable transient overlayfs.
1003
1006
#[ context( "Ensuring writable /etc" ) ]
1004
- fn ensure_writable_etc_containers ( ) -> Result < ( ) > {
1007
+ fn ensure_writable_etc_containers ( tempdir : & Dir ) -> Result < ( ) > {
1005
1008
let etc_containers = Utf8Path :: new ( "/etc/containers" ) ;
1006
1009
// If there's no /etc/containers, nothing to do
1007
1010
if !etc_containers. try_exists ( ) ? {
@@ -1010,24 +1013,18 @@ fn ensure_writable_etc_containers() -> Result<()> {
1010
1013
if rustix:: fs:: access ( etc_containers. as_std_path ( ) , rustix:: fs:: Access :: WRITE_OK ) . is_ok ( ) {
1011
1014
return Ok ( ( ) ) ;
1012
1015
}
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 (
1025
1021
& format ! ( "Mount transient overlayfs for {etc_containers}" ) ,
1026
1022
"mount" ,
1027
1023
)
1028
1024
. 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 ( ) ?;
1031
1028
Ok ( ( ) )
1032
1029
}
1033
1030
@@ -1214,9 +1211,14 @@ async fn prepare_install(
1214
1211
verify_target_fetch ( & target_imgref) . await ?;
1215
1212
}
1216
1213
1214
+ // A bit of basic global state setup
1217
1215
ensure_var ( ) ?;
1218
1216
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) ?;
1220
1222
1221
1223
// Even though we require running in a container, the mounts we create should be specific
1222
1224
// to this process, so let's enter a private mountns to avoid leaking them.
@@ -1260,6 +1262,7 @@ async fn prepare_install(
1260
1262
install_config,
1261
1263
root_ssh_authorized_keys,
1262
1264
container_root : rootfs,
1265
+ tempdir,
1263
1266
} ) ;
1264
1267
1265
1268
Ok ( state)
0 commit comments