@@ -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
@@ -1174,6 +1185,7 @@ async fn prepare_install(
11741185    config_opts :  InstallConfigOpts , 
11751186    source_opts :  InstallSourceOpts , 
11761187    target_opts :  InstallTargetOpts , 
1188+     _prog :  ProgressWriter , 
11771189)  -> Result < Arc < State > >  { 
11781190    tracing:: trace!( "Preparing install" ) ; 
11791191    let  rootfs = cap_std:: fs:: Dir :: open_ambient_dir ( "/" ,  cap_std:: ambient_authority ( ) ) 
@@ -1335,10 +1347,11 @@ async fn install_with_sysroot(
13351347    bound_images :  BoundImages , 
13361348    has_ostree :  bool , 
13371349    imgstore :  & crate :: imgstorage:: Storage , 
1350+     prog :  ProgressWriter , 
13381351)  -> Result < ( ) >  { 
13391352    // And actually set up the container in that root, returning a deployment and 
13401353    // 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 ?; 
13421355    // Write the aleph data that captures the system state at the time of provisioning for aid in future debugging. 
13431356    rootfs
13441357        . physical_root 
@@ -1420,6 +1433,7 @@ async fn install_to_filesystem_impl(
14201433    state :  & State , 
14211434    rootfs :  & mut  RootSetup , 
14221435    cleanup :  Cleanup , 
1436+     prog :  ProgressWriter , 
14231437)  -> Result < ( ) >  { 
14241438    if  matches ! ( state. selinux_state,  SELinuxFinalState :: ForceTargetDisabled )  { 
14251439        rootfs. kargs . push ( "selinux=0" . to_string ( ) ) ; 
@@ -1461,6 +1475,7 @@ async fn install_to_filesystem_impl(
14611475            bound_images, 
14621476            has_ostree, 
14631477            & imgstore, 
1478+             prog, 
14641479        ) 
14651480        . await ?; 
14661481
@@ -1496,6 +1511,7 @@ fn installation_complete() {
14961511#[ context( "Installing to disk" ) ]  
14971512#[ cfg( feature = "install-to-disk" ) ]  
14981513pub ( crate )  async  fn  install_to_disk ( mut  opts :  InstallToDiskOpts )  -> Result < ( ) >  { 
1514+     let  prog:  ProgressWriter  = opts. progress . try_into ( ) ?; 
14991515    let  mut  block_opts = opts. block_opts ; 
15001516    let  target_blockdev_meta = block_opts
15011517        . device 
@@ -1517,7 +1533,13 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
15171533    }  else  if  !target_blockdev_meta. file_type ( ) . is_block_device ( )  { 
15181534        anyhow:: bail!( "Not a block device: {}" ,  block_opts. device) ; 
15191535    } 
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 ?; 
15211543
15221544    // This is all blocking stuff 
15231545    let  ( mut  rootfs,  loopback)  = { 
@@ -1538,7 +1560,7 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
15381560        ( rootfs,  loopback_dev) 
15391561    } ; 
15401562
1541-     install_to_filesystem_impl ( & state,  & mut  rootfs,  Cleanup :: Skip ) . await ?; 
1563+     install_to_filesystem_impl ( & state,  & mut  rootfs,  Cleanup :: Skip ,  prog ) . await ?; 
15421564
15431565    // Drop all data about the root except the bits we need to ensure any file descriptors etc. are closed. 
15441566    let  ( root_path,  luksdev)  = rootfs. into_storage ( ) ; 
@@ -1720,12 +1742,19 @@ pub(crate) async fn install_to_filesystem(
17201742    targeting_host_root :  bool , 
17211743    cleanup :  Cleanup , 
17221744)  -> Result < ( ) >  { 
1745+     let  prog:  ProgressWriter  = opts. progress . try_into ( ) ?; 
17231746    // Gather global state, destructuring the provided options. 
17241747    // IMPORTANT: We might re-execute the current process in this function (for SELinux among other things) 
17251748    // IMPORTANT: and hence anything that is done before MUST BE IDEMPOTENT. 
17261749    // IMPORTANT: In practice, we should only be gathering information before this point, 
17271750    // 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 ?; 
17291758    // And the last bit of state here is the fsopts, which we also destructure now. 
17301759    let  mut  fsopts = opts. filesystem_opts ; 
17311760
@@ -1924,7 +1953,7 @@ pub(crate) async fn install_to_filesystem(
19241953        skip_finalize, 
19251954    } ; 
19261955
1927-     install_to_filesystem_impl ( & state,  & mut  rootfs,  cleanup) . await ?; 
1956+     install_to_filesystem_impl ( & state,  & mut  rootfs,  cleanup,  prog ) . await ?; 
19281957
19291958    // Drop all data about the root except the path to ensure any file descriptors etc. are closed. 
19301959    drop ( rootfs) ; 
@@ -1952,6 +1981,7 @@ pub(crate) async fn install_to_existing_root(opts: InstallToExistingRootOpts) ->
19521981        source_opts :  opts. source_opts , 
19531982        target_opts :  opts. target_opts , 
19541983        config_opts :  opts. config_opts , 
1984+         progress :  opts. progress , 
19551985    } ; 
19561986
19571987    install_to_filesystem ( opts,  true ,  cleanup) . await 
0 commit comments