@@ -53,6 +53,7 @@ use serde::{Deserialize, Serialize};
5353#[ cfg( feature = "install-to-disk" ) ]
5454use self :: baseline:: InstallBlockDeviceOpts ;
5555use crate :: boundimage:: { BoundImage , ResolvedBoundImage } ;
56+ use crate :: cli:: ProgressOptions ;
5657use crate :: containerenv:: ContainerExecutionInfo ;
5758use crate :: deploy:: { prepare_for_pull, pull_from_prepared, PreparedImportMeta , PreparedPullResult } ;
5859use crate :: lsm;
@@ -242,6 +243,10 @@ pub(crate) struct InstallToDiskOpts {
242243 #[ clap( long) ]
243244 #[ serde( default ) ]
244245 pub ( crate ) via_loopback : bool ,
246+
247+ #[ clap( flatten) ]
248+ #[ serde( flatten) ]
249+ pub ( crate ) progress : ProgressOptions ,
245250}
246251
247252#[ derive( ValueEnum , Debug , Copy , Clone , PartialEq , Eq , Serialize , Deserialize ) ]
@@ -317,6 +322,9 @@ pub(crate) struct InstallToFilesystemOpts {
317322
318323 #[ clap( flatten) ]
319324 pub ( crate ) config_opts : InstallConfigOpts ,
325+
326+ #[ clap( flatten) ]
327+ pub ( crate ) progress : ProgressOptions ,
320328}
321329
322330#[ derive( Debug , Clone , clap:: Parser , PartialEq , Eq ) ]
@@ -348,6 +356,9 @@ pub(crate) struct InstallToExistingRootOpts {
348356 /// via e.g. `-v /:/target`.
349357 #[ clap( default_value = ALONGSIDE_ROOT_MOUNT ) ]
350358 pub ( crate ) root_path : Utf8PathBuf ,
359+
360+ #[ clap( flatten) ]
361+ pub ( crate ) progress : ProgressOptions ,
351362}
352363
353364/// Global state captured from the container.
@@ -755,6 +766,7 @@ async fn install_container(
755766 root_setup : & RootSetup ,
756767 sysroot : & ostree:: Sysroot ,
757768 has_ostree : bool ,
769+ prog : ProgressWriter ,
758770) -> Result < ( ostree:: Deployment , InstallAleph ) > {
759771 let sepolicy = state. load_policy ( ) ?;
760772 let sepolicy = sepolicy. as_ref ( ) ;
@@ -793,15 +805,14 @@ async fn install_container(
793805 let repo = & sysroot. repo ( ) ;
794806 repo. set_disable_fsync ( true ) ;
795807
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+ } ;
805816
806817 repo. set_disable_fsync ( false ) ;
807818
@@ -1335,10 +1346,11 @@ async fn install_with_sysroot(
13351346 bound_images : BoundImages ,
13361347 has_ostree : bool ,
13371348 imgstore : & crate :: imgstorage:: Storage ,
1349+ prog : ProgressWriter ,
13381350) -> Result < ( ) > {
13391351 // And actually set up the container in that root, returning a deployment and
13401352 // 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 ?;
13421354 // Write the aleph data that captures the system state at the time of provisioning for aid in future debugging.
13431355 rootfs
13441356 . physical_root
@@ -1420,6 +1432,7 @@ async fn install_to_filesystem_impl(
14201432 state : & State ,
14211433 rootfs : & mut RootSetup ,
14221434 cleanup : Cleanup ,
1435+ prog : ProgressWriter ,
14231436) -> Result < ( ) > {
14241437 if matches ! ( state. selinux_state, SELinuxFinalState :: ForceTargetDisabled ) {
14251438 rootfs. kargs . push ( "selinux=0" . to_string ( ) ) ;
@@ -1461,6 +1474,7 @@ async fn install_to_filesystem_impl(
14611474 bound_images,
14621475 has_ostree,
14631476 & imgstore,
1477+ prog,
14641478 )
14651479 . await ?;
14661480
@@ -1496,6 +1510,7 @@ fn installation_complete() {
14961510#[ context( "Installing to disk" ) ]
14971511#[ cfg( feature = "install-to-disk" ) ]
14981512pub ( crate ) async fn install_to_disk ( mut opts : InstallToDiskOpts ) -> Result < ( ) > {
1513+ let prog: ProgressWriter = opts. progress . try_into ( ) ?;
14991514 let mut block_opts = opts. block_opts ;
15001515 let target_blockdev_meta = block_opts
15011516 . device
@@ -1517,7 +1532,12 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
15171532 } else if !target_blockdev_meta. file_type ( ) . is_block_device ( ) {
15181533 anyhow:: bail!( "Not a block device: {}" , block_opts. device) ;
15191534 }
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 ?;
15211541
15221542 // This is all blocking stuff
15231543 let ( mut rootfs, loopback) = {
@@ -1538,7 +1558,7 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
15381558 ( rootfs, loopback_dev)
15391559 } ;
15401560
1541- install_to_filesystem_impl ( & state, & mut rootfs, Cleanup :: Skip ) . await ?;
1561+ install_to_filesystem_impl ( & state, & mut rootfs, Cleanup :: Skip , prog ) . await ?;
15421562
15431563 // Drop all data about the root except the bits we need to ensure any file descriptors etc. are closed.
15441564 let ( root_path, luksdev) = rootfs. into_storage ( ) ;
@@ -1720,12 +1740,18 @@ pub(crate) async fn install_to_filesystem(
17201740 targeting_host_root : bool ,
17211741 cleanup : Cleanup ,
17221742) -> Result < ( ) > {
1743+ let prog: ProgressWriter = opts. progress . try_into ( ) ?;
17231744 // Gather global state, destructuring the provided options.
17241745 // IMPORTANT: We might re-execute the current process in this function (for SELinux among other things)
17251746 // IMPORTANT: and hence anything that is done before MUST BE IDEMPOTENT.
17261747 // IMPORTANT: In practice, we should only be gathering information before this point,
17271748 // 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 ?;
17291755 // And the last bit of state here is the fsopts, which we also destructure now.
17301756 let mut fsopts = opts. filesystem_opts ;
17311757
@@ -1924,7 +1950,7 @@ pub(crate) async fn install_to_filesystem(
19241950 skip_finalize,
19251951 } ;
19261952
1927- install_to_filesystem_impl ( & state, & mut rootfs, cleanup) . await ?;
1953+ install_to_filesystem_impl ( & state, & mut rootfs, cleanup, prog ) . await ?;
19281954
19291955 // Drop all data about the root except the path to ensure any file descriptors etc. are closed.
19301956 drop ( rootfs) ;
@@ -1952,6 +1978,7 @@ pub(crate) async fn install_to_existing_root(opts: InstallToExistingRootOpts) ->
19521978 source_opts : opts. source_opts ,
19531979 target_opts : opts. target_opts ,
19541980 config_opts : opts. config_opts ,
1981+ progress : opts. progress ,
19551982 } ;
19561983
19571984 install_to_filesystem ( opts, true , cleanup) . await
0 commit comments