@@ -11,7 +11,7 @@ pub(crate) mod config;
11
11
pub ( crate ) mod osconfig;
12
12
13
13
use std:: io:: Write ;
14
- use std:: os:: fd:: { AsFd , OwnedFd } ;
14
+ use std:: os:: fd:: AsFd ;
15
15
use std:: os:: unix:: process:: CommandExt ;
16
16
use std:: path:: Path ;
17
17
use std:: process:: Command ;
@@ -24,9 +24,9 @@ use anyhow::{anyhow, Context, Result};
24
24
use camino:: Utf8Path ;
25
25
use camino:: Utf8PathBuf ;
26
26
use cap_std:: fs:: { Dir , MetadataExt } ;
27
+ use cap_std:: fs_utf8:: Dir as DirUtf8 ;
27
28
use cap_std_ext:: cap_std;
28
29
use cap_std_ext:: cap_std:: fs_utf8:: DirEntry as DirEntryUtf8 ;
29
- use cap_std_ext:: cmdext:: CapStdExtCommandExt ;
30
30
use cap_std_ext:: prelude:: CapStdExtDirExt ;
31
31
use chrono:: prelude:: * ;
32
32
use clap:: ValueEnum ;
@@ -42,6 +42,7 @@ use serde::{Deserialize, Serialize};
42
42
43
43
use self :: baseline:: InstallBlockDeviceOpts ;
44
44
use crate :: containerenv:: ContainerExecutionInfo ;
45
+ use crate :: imgstorage:: Storage ;
45
46
use crate :: mount:: Filesystem ;
46
47
use crate :: spec:: ImageReference ;
47
48
use crate :: task:: Task ;
@@ -548,8 +549,11 @@ pub(crate) fn print_configuration() -> Result<()> {
548
549
serde_json:: to_writer ( stdout, & install_config) . map_err ( Into :: into)
549
550
}
550
551
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 ) > {
553
557
let sepolicy = state. load_policy ( ) ?;
554
558
let sepolicy = sepolicy. as_ref ( ) ;
555
559
// Load a fd for the mounted target physical root
@@ -594,6 +598,16 @@ async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result
594
598
. cwd ( rootfs_dir) ?
595
599
. run ( ) ?;
596
600
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 ( Utf8Path :: new ( crate :: imgstorage:: SUBPATH ) . parent ( ) . unwrap ( ) )
608
+ . context ( "creating bootc dir" ) ?;
609
+ let imgstore = crate :: imgstorage:: Storage :: create ( & sysroot_dir, & * tmp_run) ?;
610
+
597
611
// Bootstrap the initial labeling of the /ostree directory as usr_t
598
612
if let Some ( policy) = sepolicy {
599
613
let ostree_dir = rootfs_dir. open_dir ( "ostree" ) ?;
@@ -606,9 +620,7 @@ async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result
606
620
) ?;
607
621
}
608
622
609
- let sysroot = ostree:: Sysroot :: new ( Some ( & gio:: File :: for_path ( rootfs) ) ) ;
610
- sysroot. load ( cancellable) ?;
611
- Ok ( sysroot)
623
+ Ok ( ( sysroot, imgstore) )
612
624
}
613
625
614
626
#[ context( "Creating ostree deployment" ) ]
@@ -1271,14 +1283,14 @@ async fn install_with_sysroot(
1271
1283
state : & State ,
1272
1284
rootfs : & RootSetup ,
1273
1285
sysroot : & ostree:: Sysroot ,
1286
+ imgstore : & Storage ,
1274
1287
boot_uuid : & str ,
1275
1288
bound_images : & [ crate :: boundimage:: ResolvedBoundImage ] ,
1276
1289
) -> Result < ( ) > {
1277
1290
let sysroot = SysrootLock :: new_from_sysroot ( & sysroot) . await ?;
1278
1291
// And actually set up the container in that root, returning a deployment and
1279
1292
// 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 ?;
1282
1294
// Write the aleph data that captures the system state at the time of provisioning for aid in future debugging.
1283
1295
rootfs
1284
1296
. rootfs_fd
@@ -1301,53 +1313,11 @@ async fn install_with_sysroot(
1301
1313
tracing:: debug!( "Installed bootloader" ) ;
1302
1314
1303
1315
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) ?;
1349
1320
}
1350
-
1351
1321
Ok ( ( ) )
1352
1322
}
1353
1323
@@ -1397,8 +1367,16 @@ async fn install_to_filesystem_impl(state: &State, rootfs: &mut RootSetup) -> Re
1397
1367
1398
1368
// Initialize the ostree sysroot (repo, stateroot, etc.)
1399
1369
{
1400
- let sysroot = initialize_ostree_root ( state, rootfs) . await ?;
1401
- install_with_sysroot ( state, rootfs, & sysroot, & boot_uuid, & bound_images) . await ?;
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 ?;
1402
1380
// We must drop the sysroot here in order to close any open file
1403
1381
// descriptors.
1404
1382
}
0 commit comments