@@ -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
@@ -1335,10 +1346,11 @@ async fn install_with_sysroot(
1335
1346
bound_images : BoundImages ,
1336
1347
has_ostree : bool ,
1337
1348
imgstore : & crate :: imgstorage:: Storage ,
1349
+ prog : ProgressWriter ,
1338
1350
) -> Result < ( ) > {
1339
1351
// And actually set up the container in that root, returning a deployment and
1340
1352
// the aleph state (see below).
1341
- let ( _deployment, aleph) = install_container ( state, rootfs, & sysroot, has_ostree) . await ?;
1353
+ let ( _deployment, aleph) = install_container ( state, rootfs, & sysroot, has_ostree, prog ) . await ?;
1342
1354
// Write the aleph data that captures the system state at the time of provisioning for aid in future debugging.
1343
1355
rootfs
1344
1356
. physical_root
@@ -1420,6 +1432,7 @@ async fn install_to_filesystem_impl(
1420
1432
state : & State ,
1421
1433
rootfs : & mut RootSetup ,
1422
1434
cleanup : Cleanup ,
1435
+ prog : ProgressWriter ,
1423
1436
) -> Result < ( ) > {
1424
1437
if matches ! ( state. selinux_state, SELinuxFinalState :: ForceTargetDisabled ) {
1425
1438
rootfs. kargs . push ( "selinux=0" . to_string ( ) ) ;
@@ -1461,6 +1474,7 @@ async fn install_to_filesystem_impl(
1461
1474
bound_images,
1462
1475
has_ostree,
1463
1476
& imgstore,
1477
+ prog,
1464
1478
)
1465
1479
. await ?;
1466
1480
@@ -1496,6 +1510,7 @@ fn installation_complete() {
1496
1510
#[ context( "Installing to disk" ) ]
1497
1511
#[ cfg( feature = "install-to-disk" ) ]
1498
1512
pub ( crate ) async fn install_to_disk ( mut opts : InstallToDiskOpts ) -> Result < ( ) > {
1513
+ let prog: ProgressWriter = opts. progress . try_into ( ) ?;
1499
1514
let mut block_opts = opts. block_opts ;
1500
1515
let target_blockdev_meta = block_opts
1501
1516
. device
@@ -1517,7 +1532,12 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
1517
1532
} else if !target_blockdev_meta. file_type ( ) . is_block_device ( ) {
1518
1533
anyhow:: bail!( "Not a block device: {}" , block_opts. device) ;
1519
1534
}
1520
- let state = prepare_install ( opts. config_opts , opts. source_opts , opts. target_opts ) . await ?;
1535
+ let state = prepare_install (
1536
+ opts. config_opts ,
1537
+ opts. source_opts ,
1538
+ opts. target_opts ,
1539
+ )
1540
+ . await ?;
1521
1541
1522
1542
// This is all blocking stuff
1523
1543
let ( mut rootfs, loopback) = {
@@ -1538,7 +1558,7 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
1538
1558
( rootfs, loopback_dev)
1539
1559
} ;
1540
1560
1541
- install_to_filesystem_impl ( & state, & mut rootfs, Cleanup :: Skip ) . await ?;
1561
+ install_to_filesystem_impl ( & state, & mut rootfs, Cleanup :: Skip , prog ) . await ?;
1542
1562
1543
1563
// Drop all data about the root except the bits we need to ensure any file descriptors etc. are closed.
1544
1564
let ( root_path, luksdev) = rootfs. into_storage ( ) ;
@@ -1720,12 +1740,18 @@ pub(crate) async fn install_to_filesystem(
1720
1740
targeting_host_root : bool ,
1721
1741
cleanup : Cleanup ,
1722
1742
) -> Result < ( ) > {
1743
+ let prog: ProgressWriter = opts. progress . try_into ( ) ?;
1723
1744
// Gather global state, destructuring the provided options.
1724
1745
// IMPORTANT: We might re-execute the current process in this function (for SELinux among other things)
1725
1746
// IMPORTANT: and hence anything that is done before MUST BE IDEMPOTENT.
1726
1747
// IMPORTANT: In practice, we should only be gathering information before this point,
1727
1748
// IMPORTANT: and not performing any mutations at all.
1728
- let state = prepare_install ( opts. config_opts , opts. source_opts , opts. target_opts ) . await ?;
1749
+ let state = prepare_install (
1750
+ opts. config_opts ,
1751
+ opts. source_opts ,
1752
+ opts. target_opts ,
1753
+ )
1754
+ . await ?;
1729
1755
// And the last bit of state here is the fsopts, which we also destructure now.
1730
1756
let mut fsopts = opts. filesystem_opts ;
1731
1757
@@ -1924,7 +1950,7 @@ pub(crate) async fn install_to_filesystem(
1924
1950
skip_finalize,
1925
1951
} ;
1926
1952
1927
- install_to_filesystem_impl ( & state, & mut rootfs, cleanup) . await ?;
1953
+ install_to_filesystem_impl ( & state, & mut rootfs, cleanup, prog ) . await ?;
1928
1954
1929
1955
// Drop all data about the root except the path to ensure any file descriptors etc. are closed.
1930
1956
drop ( rootfs) ;
@@ -1952,6 +1978,7 @@ pub(crate) async fn install_to_existing_root(opts: InstallToExistingRootOpts) ->
1952
1978
source_opts : opts. source_opts ,
1953
1979
target_opts : opts. target_opts ,
1954
1980
config_opts : opts. config_opts ,
1981
+ progress : opts. progress ,
1955
1982
} ;
1956
1983
1957
1984
install_to_filesystem ( opts, true , cleanup) . await
0 commit comments