@@ -45,6 +45,7 @@ use serde::{Deserialize, Serialize};
4545
4646use self :: baseline:: InstallBlockDeviceOpts ;
4747use crate :: boundimage:: { BoundImage , ResolvedBoundImage } ;
48+ use crate :: cli:: ProgressOptions ;
4849use crate :: containerenv:: ContainerExecutionInfo ;
4950use crate :: lsm;
5051use crate :: mount:: Filesystem ;
@@ -220,6 +221,10 @@ pub(crate) struct InstallToDiskOpts {
220221 #[ serde( flatten) ]
221222 pub ( crate ) config_opts : InstallConfigOpts ,
222223
224+ #[ clap( flatten) ]
225+ #[ serde( flatten) ]
226+ pub ( crate ) progress_opts : ProgressOptions ,
227+
223228 /// Instead of targeting a block device, write to a file via loopback.
224229 #[ clap( long) ]
225230 #[ serde( default ) ]
@@ -299,6 +304,9 @@ pub(crate) struct InstallToFilesystemOpts {
299304
300305 #[ clap( flatten) ]
301306 pub ( crate ) config_opts : InstallConfigOpts ,
307+
308+ #[ clap( flatten) ]
309+ pub ( crate ) progress_opts : ProgressOptions ,
302310}
303311
304312#[ derive( Debug , Clone , clap:: Parser , PartialEq , Eq ) ]
@@ -316,6 +324,9 @@ pub(crate) struct InstallToExistingRootOpts {
316324 #[ clap( flatten) ]
317325 pub ( crate ) config_opts : InstallConfigOpts ,
318326
327+ #[ clap( flatten) ]
328+ pub ( crate ) progress_opts : ProgressOptions ,
329+
319330 /// Accept that this is a destructive action and skip a warning timer.
320331 #[ clap( long) ]
321332 pub ( crate ) acknowledge_destructive : bool ,
@@ -355,6 +366,7 @@ pub(crate) struct State {
355366 pub ( crate ) host_is_container : bool ,
356367 /// The root filesystem of the running container
357368 pub ( crate ) container_root : Dir ,
369+ pub ( crate ) progress : ProgressWriter ,
358370 pub ( crate ) tempdir : TempDir ,
359371}
360372
@@ -739,7 +751,7 @@ async fn install_container(
739751 & spec_imgref,
740752 Some ( & state. target_imgref ) ,
741753 false ,
742- ProgressWriter :: default ( ) ,
754+ state . progress . clone ( ) ,
743755 )
744756 . await ?;
745757 repo. set_disable_fsync ( false ) ;
@@ -1159,6 +1171,7 @@ async fn prepare_install(
11591171 config_opts : InstallConfigOpts ,
11601172 source_opts : InstallSourceOpts ,
11611173 target_opts : InstallTargetOpts ,
1174+ progress_opts : ProgressOptions ,
11621175) -> Result < Arc < State > > {
11631176 tracing:: trace!( "Preparing install" ) ;
11641177 let rootfs = cap_std:: fs:: Dir :: open_ambient_dir ( "/" , cap_std:: ambient_authority ( ) )
@@ -1273,6 +1286,8 @@ async fn prepare_install(
12731286 . map ( |p| std:: fs:: read_to_string ( p) . with_context ( || format ! ( "Reading {p}" ) ) )
12741287 . transpose ( ) ?;
12751288
1289+ let progress = progress_opts. try_into ( ) ?;
1290+
12761291 // Create our global (read-only) state which gets wrapped in an Arc
12771292 // so we can pass it to worker threads too. Right now this just
12781293 // combines our command line options along with some bind mounts from the host.
@@ -1285,6 +1300,7 @@ async fn prepare_install(
12851300 root_ssh_authorized_keys,
12861301 container_root : rootfs,
12871302 tempdir,
1303+ progress,
12881304 host_is_container,
12891305 } ) ;
12901306
@@ -1471,7 +1487,13 @@ pub(crate) async fn install_to_disk(mut opts: InstallToDiskOpts) -> Result<()> {
14711487 } else if !target_blockdev_meta. file_type ( ) . is_block_device ( ) {
14721488 anyhow:: bail!( "Not a block device: {}" , block_opts. device) ;
14731489 }
1474- let state = prepare_install ( opts. config_opts , opts. source_opts , opts. target_opts ) . await ?;
1490+ let state = prepare_install (
1491+ opts. config_opts ,
1492+ opts. source_opts ,
1493+ opts. target_opts ,
1494+ opts. progress_opts ,
1495+ )
1496+ . await ?;
14751497
14761498 // This is all blocking stuff
14771499 let ( mut rootfs, loopback) = {
@@ -1652,7 +1674,13 @@ pub(crate) async fn install_to_filesystem(
16521674 // IMPORTANT: and hence anything that is done before MUST BE IDEMPOTENT.
16531675 // IMPORTANT: In practice, we should only be gathering information before this point,
16541676 // IMPORTANT: and not performing any mutations at all.
1655- let state = prepare_install ( opts. config_opts , opts. source_opts , opts. target_opts ) . await ?;
1677+ let state = prepare_install (
1678+ opts. config_opts ,
1679+ opts. source_opts ,
1680+ opts. target_opts ,
1681+ opts. progress_opts ,
1682+ )
1683+ . await ?;
16561684 // And the last bit of state here is the fsopts, which we also destructure now.
16571685 let mut fsopts = opts. filesystem_opts ;
16581686
@@ -1878,6 +1906,7 @@ pub(crate) async fn install_to_existing_root(opts: InstallToExistingRootOpts) ->
18781906 source_opts : opts. source_opts ,
18791907 target_opts : opts. target_opts ,
18801908 config_opts : opts. config_opts ,
1909+ progress_opts : opts. progress_opts ,
18811910 } ;
18821911
18831912 install_to_filesystem ( opts, true ) . await
0 commit comments