@@ -11,7 +11,7 @@ pub(crate) mod config;
1111pub ( crate ) mod osconfig;
1212
1313use std:: io:: Write ;
14- use std:: os:: fd:: { AsFd , OwnedFd } ;
14+ use std:: os:: fd:: AsFd ;
1515use std:: os:: unix:: process:: CommandExt ;
1616use std:: path:: Path ;
1717use std:: process:: Command ;
@@ -24,9 +24,9 @@ use anyhow::{anyhow, Context, Result};
2424use camino:: Utf8Path ;
2525use camino:: Utf8PathBuf ;
2626use cap_std:: fs:: { Dir , MetadataExt } ;
27+ use cap_std:: fs_utf8:: Dir as DirUtf8 ;
2728use cap_std_ext:: cap_std;
2829use cap_std_ext:: cap_std:: fs_utf8:: DirEntry as DirEntryUtf8 ;
29- use cap_std_ext:: cmdext:: CapStdExtCommandExt ;
3030use cap_std_ext:: prelude:: CapStdExtDirExt ;
3131use chrono:: prelude:: * ;
3232use clap:: ValueEnum ;
@@ -42,6 +42,7 @@ use serde::{Deserialize, Serialize};
4242
4343use self :: baseline:: InstallBlockDeviceOpts ;
4444use crate :: containerenv:: ContainerExecutionInfo ;
45+ use crate :: imgstorage:: Storage ;
4546use crate :: mount:: Filesystem ;
4647use crate :: spec:: ImageReference ;
4748use crate :: task:: Task ;
@@ -548,8 +549,11 @@ pub(crate) fn print_configuration() -> Result<()> {
548549 serde_json:: to_writer ( stdout, & install_config) . map_err ( Into :: into)
549550}
550551
551- #[ context( "Creating ostree deployment" ) ]
552- async fn initialize_ostree_root ( state : & State , root_setup : & RootSetup ) -> Result < ostree:: Sysroot > {
552+ #[ context( "Creating system root" ) ]
553+ async fn initialize_ostree_root (
554+ state : & State ,
555+ root_setup : & RootSetup ,
556+ ) -> Result < ( ostree:: Sysroot , crate :: imgstorage:: Storage ) > {
553557 let sepolicy = state. load_policy ( ) ?;
554558 let sepolicy = sepolicy. as_ref ( ) ;
555559 // Load a fd for the mounted target physical root
@@ -594,6 +598,16 @@ async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result
594598 . cwd ( rootfs_dir) ?
595599 . run ( ) ?;
596600
601+ let sysroot = ostree:: Sysroot :: new ( Some ( & gio:: File :: for_path ( rootfs) ) ) ;
602+ sysroot. load ( cancellable) ?;
603+ let sysroot_dir = DirUtf8 :: reopen_dir ( & crate :: utils:: sysroot_fd ( & sysroot) ) ?;
604+
605+ let tmp_run = cap_std_ext:: cap_tempfile:: utf8:: TempDir :: new ( cap_std:: ambient_authority ( ) ) ?;
606+ sysroot_dir
607+ . create_dir_all ( Utf8Path :: new ( crate :: imgstorage:: SUBPATH ) . parent ( ) . unwrap ( ) )
608+ . context ( "creating bootc dir" ) ?;
609+ let imgstore = crate :: imgstorage:: Storage :: create ( & sysroot_dir, & * tmp_run) ?;
610+
597611 // Bootstrap the initial labeling of the /ostree directory as usr_t
598612 if let Some ( policy) = sepolicy {
599613 let ostree_dir = rootfs_dir. open_dir ( "ostree" ) ?;
@@ -606,9 +620,7 @@ async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result
606620 ) ?;
607621 }
608622
609- let sysroot = ostree:: Sysroot :: new ( Some ( & gio:: File :: for_path ( rootfs) ) ) ;
610- sysroot. load ( cancellable) ?;
611- Ok ( sysroot)
623+ Ok ( ( sysroot, imgstore) )
612624}
613625
614626#[ context( "Creating ostree deployment" ) ]
@@ -1271,14 +1283,14 @@ async fn install_with_sysroot(
12711283 state : & State ,
12721284 rootfs : & RootSetup ,
12731285 sysroot : & ostree:: Sysroot ,
1286+ imgstore : & Storage ,
12741287 boot_uuid : & str ,
12751288 bound_images : & [ crate :: boundimage:: ResolvedBoundImage ] ,
12761289) -> Result < ( ) > {
12771290 let sysroot = SysrootLock :: new_from_sysroot ( & sysroot) . await ?;
12781291 // And actually set up the container in that root, returning a deployment and
12791292 // the aleph state (see below).
1280- let ( deployment, aleph) = install_container ( state, rootfs, & sysroot) . await ?;
1281- let stateroot = deployment. osname ( ) ;
1293+ let ( _deployment, aleph) = install_container ( state, rootfs, & sysroot) . await ?;
12821294 // Write the aleph data that captures the system state at the time of provisioning for aid in future debugging.
12831295 rootfs
12841296 . rootfs_fd
@@ -1301,53 +1313,11 @@ async fn install_with_sysroot(
13011313 tracing:: debug!( "Installed bootloader" ) ;
13021314
13031315 tracing:: debug!( "Perfoming post-deployment operations" ) ;
1304- if !bound_images. is_empty ( ) {
1305- // TODO: We shouldn't hardcode the overlay driver for source or
1306- // target, but we currently need to in order to reference the location.
1307- // For this one, containers-storage: is actually the *host*'s /var/lib/containers
1308- // which we are accessing directly.
1309- let storage_src = "containers-storage:" ;
1310- // TODO: We only do this dance to initialize `/var` at install time if
1311- // there are bound images today; it minimizes side effects.
1312- // However going forward we really do need to handle a separate /var partition...
1313- // and to do that we may in the general case need to run the `var.mount`
1314- // target from the new root.
1315- // Probably the best fix is for us to switch bound images to use the bootc storage.
1316- let varpath = format ! ( "ostree/deploy/{stateroot}/var" ) ;
1317- let var = rootfs
1318- . rootfs_fd
1319- . open_dir ( & varpath)
1320- . with_context ( || format ! ( "Opening {varpath}" ) ) ?;
1321-
1322- // The skopeo API expects absolute paths, so we make a temporary bind
1323- let tmp_dest_var_abs = tempfile:: tempdir ( ) ?;
1324- let tmp_dest_var_abs: & Utf8Path = tmp_dest_var_abs. path ( ) . try_into ( ) ?;
1325- let mut t = Task :: new ( "Mounting deployment /var" , "mount" )
1326- . args ( [ "--bind" , "/proc/self/fd/3" ] )
1327- . arg ( tmp_dest_var_abs) ;
1328- t. cmd . take_fd_n ( Arc :: new ( OwnedFd :: from ( var) ) , 3 ) ;
1329- t. run ( ) ?;
1330-
1331- // And an ephemeral place for the transient state
1332- let tmp_runroot = tempfile:: tempdir ( ) ?;
1333- let tmp_runroot: & Utf8Path = tmp_runroot. path ( ) . try_into ( ) ?;
1334-
1335- // The destination (target stateroot) + container storage dest
1336- let storage_dest = & format ! (
1337- "containers-storage:[overlay@{tmp_dest_var_abs}/lib/containers/storage+{tmp_runroot}]"
1338- ) ;
1339-
1340- // Now copy each bound image from the host's container storage into the target.
1341- for image in bound_images {
1342- let image = image. image . as_str ( ) ;
1343- Task :: new ( format ! ( "Copying image to target: {}" , image) , "skopeo" )
1344- . arg ( "copy" )
1345- . arg ( format ! ( "{storage_src}{image}" ) )
1346- . arg ( format ! ( "{storage_dest}{image}" ) )
1347- . run ( ) ?;
1348- }
1316+ // Now copy each bound image from the host's container storage into the target.
1317+ for image in bound_images {
1318+ let image = image. image . as_str ( ) ;
1319+ imgstore. pull_from_host_storage ( image) ?;
13491320 }
1350-
13511321 Ok ( ( ) )
13521322}
13531323
@@ -1397,10 +1367,18 @@ async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup) -> Re
13971367
13981368 // Initialize the ostree sysroot (repo, stateroot, etc.)
13991369 {
1400- let sysroot = initialize_ostree_root ( state, rootfs) . await ?;
1401- install_with_sysroot ( state, rootfs, & sysroot, & boot_uuid, & bound_images) . await ?;
1402- // We must drop the sysroot here in order to close any open file
1403- // descriptors.
1370+ let ( sysroot, imgstore) = initialize_ostree_root ( state, rootfs) . await ?;
1371+ install_with_sysroot (
1372+ state,
1373+ rootfs,
1374+ & sysroot,
1375+ & imgstore,
1376+ & boot_uuid,
1377+ & bound_images,
1378+ )
1379+ . await ?;
1380+ // We must drop the sysroot and imgstore here in order to close any
1381+ // open file descriptors.
14041382 }
14051383
14061384 // Finalize mounted filesystems
0 commit comments