@@ -53,6 +53,7 @@ use serde::{Deserialize, Serialize};
53
53
#[ cfg( feature = "install-to-disk" ) ]
54
54
use self :: baseline:: InstallBlockDeviceOpts ;
55
55
use crate :: boundimage:: { BoundImage , ResolvedBoundImage } ;
56
+ use crate :: cli:: ProgressOptions ;
56
57
use crate :: containerenv:: ContainerExecutionInfo ;
57
58
use crate :: deploy:: { prepare_for_pull, pull_from_prepared, PreparedImportMeta , PreparedPullResult } ;
58
59
use crate :: lsm;
@@ -242,6 +243,10 @@ pub(crate) struct InstallToDiskOpts {
242
243
#[ clap( long) ]
243
244
#[ serde( default ) ]
244
245
pub ( crate ) via_loopback : bool ,
246
+
247
+ #[ clap( flatten) ]
248
+ #[ serde( flatten) ]
249
+ pub ( crate ) progress : ProgressOptions ,
245
250
}
246
251
247
252
#[ derive( ValueEnum , Debug , Copy , Clone , PartialEq , Eq , Serialize , Deserialize ) ]
@@ -317,6 +322,9 @@ pub(crate) struct InstallToFilesystemOpts {
317
322
318
323
#[ clap( flatten) ]
319
324
pub ( crate ) config_opts : InstallConfigOpts ,
325
+
326
+ #[ clap( flatten) ]
327
+ pub ( crate ) progress : ProgressOptions ,
320
328
}
321
329
322
330
#[ derive( Debug , Clone , clap:: Parser , PartialEq , Eq ) ]
@@ -348,6 +356,9 @@ pub(crate) struct InstallToExistingRootOpts {
348
356
/// via e.g. `-v /:/target`.
349
357
#[ clap( default_value = ALONGSIDE_ROOT_MOUNT ) ]
350
358
pub ( crate ) root_path : Utf8PathBuf ,
359
+
360
+ #[ clap( flatten) ]
361
+ pub ( crate ) progress : ProgressOptions ,
351
362
}
352
363
353
364
/// Global state captured from the container.
@@ -755,6 +766,7 @@ async fn install_container(
755
766
root_setup : & RootSetup ,
756
767
sysroot : & ostree:: Sysroot ,
757
768
has_ostree : bool ,
769
+ prog : ProgressWriter ,
758
770
) -> Result < ( ostree:: Deployment , InstallAleph ) > {
759
771
let sepolicy = state. load_policy ( ) ?;
760
772
let sepolicy = sepolicy. as_ref ( ) ;
@@ -793,15 +805,14 @@ async fn install_container(
793
805
let repo = & sysroot. repo ( ) ;
794
806
repo. set_disable_fsync ( true ) ;
795
807
796
- let pulled_image = match prepare_for_pull ( repo, & spec_imgref, Some ( & state. target_imgref ) )
797
- . await ?
798
- {
799
- PreparedPullResult :: AlreadyPresent ( existing) => existing,
800
- PreparedPullResult :: Ready ( image_meta) => {
801
- check_disk_space ( root_setup. physical_root . as_fd ( ) , & image_meta, & spec_imgref) ?;
802
- pull_from_prepared ( & spec_imgref, false , ProgressWriter :: default ( ) , image_meta) . await ?
803
- }
804
- } ;
808
+ let pulled_image =
809
+ match prepare_for_pull ( repo, & spec_imgref, Some ( & state. target_imgref ) ) . await ? {
810
+ PreparedPullResult :: AlreadyPresent ( existing) => existing,
811
+ PreparedPullResult :: Ready ( image_meta) => {
812
+ check_disk_space ( root_setup. physical_root . as_fd ( ) , & image_meta, & spec_imgref) ?;
813
+ pull_from_prepared ( & spec_imgref, false , prog, image_meta) . await ?
814
+ }
815
+ } ;
805
816
806
817
repo. set_disable_fsync ( false ) ;
807
818
@@ -1174,6 +1185,7 @@ async fn prepare_install(
1174
1185
config_opts : InstallConfigOpts ,
1175
1186
source_opts : InstallSourceOpts ,
1176
1187
target_opts : InstallTargetOpts ,
1188
+ _prog : ProgressWriter ,
1177
1189
) -> Result < Arc < State > > {
1178
1190
tracing:: trace!( "Preparing install" ) ;
1179
1191
let rootfs = cap_std:: fs:: Dir :: open_ambient_dir ( "/" , cap_std:: ambient_authority ( ) )
@@ -1335,10 +1347,11 @@ async fn install_with_sysroot(
1335
1347
bound_images : BoundImages ,
1336
1348
has_ostree : bool ,
1337
1349
imgstore : & crate :: imgstorage:: Storage ,
1350
+ prog : ProgressWriter ,
1338
1351
) -> Result < ( ) > {
1339
1352
// And actually set up the container in that root, returning a deployment and
1340
1353
// the aleph state (see below).
1341
- let ( _deployment, aleph) = install_container ( state, rootfs, & sysroot, has_ostree) . await ?;
1354
+ let ( _deployment, aleph) = install_container ( state, rootfs, & sysroot, has_ostree, prog ) . await ?;
1342
1355
// Write the aleph data that captures the system state at the time of provisioning for aid in future debugging.
1343
1356
rootfs
1344
1357
. physical_root
@@ -1420,6 +1433,7 @@ async fn install_to_filesystem_impl(
1420
1433
state : & State ,
1421
1434
rootfs : & mut RootSetup ,
1422
1435
cleanup : Cleanup ,
1436
+ prog : ProgressWriter ,
1423
1437
) -> Result < ( ) > {
1424
1438
if matches ! ( state. selinux_state, SELinuxFinalState :: ForceTargetDisabled ) {
1425
1439
rootfs. kargs . push ( "selinux=0" . to_string ( ) ) ;
@@ -1461,6 +1475,7 @@ async fn install_to_filesystem_impl(
1461
1475
bound_images,
1462
1476
has_ostree,
1463
1477
& imgstore,
1478
+ prog,
1464
1479
)
1465
1480
. await ?;
1466
1481
@@ -1496,6 +1511,7 @@ fn installation_complete() {
1496
1511
#[ context( "Installing to disk" ) ]
1497
1512
#[ cfg( feature = "install-to-disk" ) ]
1498
1513
pub ( crate ) async fn install_to_disk ( mut opts : InstallToDiskOpts ) -> Result < ( ) > {
1514
+ let prog: ProgressWriter = opts. progress . try_into ( ) ?;
1499
1515
let mut block_opts = opts. block_opts ;
1500
1516
let target_blockdev_meta = block_opts
1501
1517
. device
@@ -1517,7 +1533,13 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
1517
1533
} else if !target_blockdev_meta. file_type ( ) . is_block_device ( ) {
1518
1534
anyhow:: bail!( "Not a block device: {}" , block_opts. device) ;
1519
1535
}
1520
- let state = prepare_install ( opts. config_opts , opts. source_opts , opts. target_opts ) . await ?;
1536
+ let state = prepare_install (
1537
+ opts. config_opts ,
1538
+ opts. source_opts ,
1539
+ opts. target_opts ,
1540
+ prog. clone ( ) ,
1541
+ )
1542
+ . await ?;
1521
1543
1522
1544
// This is all blocking stuff
1523
1545
let ( mut rootfs, loopback) = {
@@ -1538,7 +1560,7 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
1538
1560
( rootfs, loopback_dev)
1539
1561
} ;
1540
1562
1541
- install_to_filesystem_impl ( & state, & mut rootfs, Cleanup :: Skip ) . await ?;
1563
+ install_to_filesystem_impl ( & state, & mut rootfs, Cleanup :: Skip , prog ) . await ?;
1542
1564
1543
1565
// Drop all data about the root except the bits we need to ensure any file descriptors etc. are closed.
1544
1566
let ( root_path, luksdev) = rootfs. into_storage ( ) ;
@@ -1720,12 +1742,19 @@ pub(crate) async fn install_to_filesystem(
1720
1742
targeting_host_root : bool ,
1721
1743
cleanup : Cleanup ,
1722
1744
) -> Result < ( ) > {
1745
+ let prog: ProgressWriter = opts. progress . try_into ( ) ?;
1723
1746
// Gather global state, destructuring the provided options.
1724
1747
// IMPORTANT: We might re-execute the current process in this function (for SELinux among other things)
1725
1748
// IMPORTANT: and hence anything that is done before MUST BE IDEMPOTENT.
1726
1749
// IMPORTANT: In practice, we should only be gathering information before this point,
1727
1750
// IMPORTANT: and not performing any mutations at all.
1728
- let state = prepare_install ( opts. config_opts , opts. source_opts , opts. target_opts ) . await ?;
1751
+ let state = prepare_install (
1752
+ opts. config_opts ,
1753
+ opts. source_opts ,
1754
+ opts. target_opts ,
1755
+ prog. clone ( ) ,
1756
+ )
1757
+ . await ?;
1729
1758
// And the last bit of state here is the fsopts, which we also destructure now.
1730
1759
let mut fsopts = opts. filesystem_opts ;
1731
1760
@@ -1924,7 +1953,7 @@ pub(crate) async fn install_to_filesystem(
1924
1953
skip_finalize,
1925
1954
} ;
1926
1955
1927
- install_to_filesystem_impl ( & state, & mut rootfs, cleanup) . await ?;
1956
+ install_to_filesystem_impl ( & state, & mut rootfs, cleanup, prog ) . await ?;
1928
1957
1929
1958
// Drop all data about the root except the path to ensure any file descriptors etc. are closed.
1930
1959
drop ( rootfs) ;
@@ -1952,6 +1981,7 @@ pub(crate) async fn install_to_existing_root(opts: InstallToExistingRootOpts) ->
1952
1981
source_opts : opts. source_opts ,
1953
1982
target_opts : opts. target_opts ,
1954
1983
config_opts : opts. config_opts ,
1984
+ progress : opts. progress ,
1955
1985
} ;
1956
1986
1957
1987
install_to_filesystem ( opts, true , cleanup) . await
0 commit comments