@@ -19,11 +19,13 @@ use ostree_ext::oci_spec::image::{Descriptor, Digest};
19
19
use ostree_ext:: ostree:: Deployment ;
20
20
use ostree_ext:: ostree:: { self , Sysroot } ;
21
21
use ostree_ext:: sysroot:: SysrootLock ;
22
+ use ostree_ext:: tokio_util:: spawn_blocking_cancellable_flatten;
22
23
23
24
use crate :: spec:: ImageReference ;
24
25
use crate :: spec:: { BootOrder , HostSpec } ;
25
26
use crate :: status:: labels_of_config;
26
27
use crate :: store:: Storage ;
28
+ use crate :: utils:: async_task_with_spinner;
27
29
28
30
// TODO use https://github.com/ostreedev/ostree-rs-ext/pull/493/commits/afc1837ff383681b947de30c0cefc70080a4f87a
29
31
const BASE_IMAGE_PREFIX : & str = "ostree/container/baseimage/bootc" ;
@@ -211,12 +213,14 @@ async fn handle_layer_progress_print(
211
213
let elapsed = end. duration_since ( start) ;
212
214
let persec = total_read as f64 / elapsed. as_secs_f64 ( ) ;
213
215
let persec = indicatif:: HumanBytes ( persec as u64 ) ;
214
- println ! (
216
+ if let Err ( e ) = bar . println ( & format ! (
215
217
"Fetched layers: {} in {} ({}/s)" ,
216
218
indicatif:: HumanBytes ( total_read) ,
217
219
indicatif:: HumanDuration ( elapsed) ,
218
220
persec,
219
- ) ;
221
+ ) ) {
222
+ tracing:: warn!( "writing to stdout: {e}" ) ;
223
+ }
220
224
}
221
225
222
226
/// Wrapper for pulling a container image, wiring up status output.
@@ -373,8 +377,6 @@ async fn deploy(
373
377
image : & ImageState ,
374
378
origin : & glib:: KeyFile ,
375
379
) -> Result < Deployment > {
376
- let stateroot = Some ( stateroot) ;
377
- let mut opts = ostree:: SysrootDeployTreeOpts :: default ( ) ;
378
380
// Compute the kernel argument overrides. In practice today this API is always expecting
379
381
// a merge deployment. The kargs code also always looks at the booted root (which
380
382
// is a distinct minor issue, but not super important as right now the install path
@@ -384,26 +386,49 @@ async fn deploy(
384
386
} else {
385
387
None
386
388
} ;
387
- // Because the C API expects a Vec<&str>, we need to generate a new Vec<>
388
- // that borrows.
389
- let override_kargs = override_kargs
390
- . as_deref ( )
391
- . map ( |v| v. iter ( ) . map ( |s| s. as_str ( ) ) . collect :: < Vec < _ > > ( ) ) ;
392
- if let Some ( kargs) = override_kargs. as_deref ( ) {
393
- opts. override_kernel_argv = Some ( & kargs) ;
394
- }
395
- // Copy to move into thread
396
- let cancellable = gio:: Cancellable :: NONE ;
397
- return sysroot
398
- . stage_tree_with_options (
399
- stateroot,
400
- image. ostree_commit . as_str ( ) ,
401
- Some ( origin) ,
402
- merge_deployment,
403
- & opts,
404
- cancellable,
405
- )
406
- . map_err ( Into :: into) ;
389
+ // Clone all the things to move to worker thread
390
+ let sysroot_clone = sysroot. sysroot . clone ( ) ;
391
+ // ostree::Deployment is incorrently !Send 😢 so convert it to an integer
392
+ let merge_deployment = merge_deployment. map ( |d| d. index ( ) as usize ) ;
393
+ let stateroot = stateroot. to_string ( ) ;
394
+ let ostree_commit = image. ostree_commit . to_string ( ) ;
395
+ // GKeyFile also isn't Send! So we serialize that as a string...
396
+ let origin_data = origin. to_data ( ) ;
397
+ let r = async_task_with_spinner (
398
+ "Deploying" ,
399
+ spawn_blocking_cancellable_flatten ( move |cancellable| -> Result < _ > {
400
+ let sysroot = sysroot_clone;
401
+ let stateroot = Some ( stateroot) ;
402
+ let mut opts = ostree:: SysrootDeployTreeOpts :: default ( ) ;
403
+
404
+ // Because the C API expects a Vec<&str>, we need to generate a new Vec<>
405
+ // that borrows.
406
+ let override_kargs = override_kargs
407
+ . as_deref ( )
408
+ . map ( |v| v. iter ( ) . map ( |s| s. as_str ( ) ) . collect :: < Vec < _ > > ( ) ) ;
409
+ if let Some ( kargs) = override_kargs. as_deref ( ) {
410
+ opts. override_kernel_argv = Some ( & kargs) ;
411
+ }
412
+ let deployments = sysroot. deployments ( ) ;
413
+ let merge_deployment = merge_deployment. map ( |m| & deployments[ m] ) ;
414
+ let origin = glib:: KeyFile :: new ( ) ;
415
+ origin. load_from_data ( & origin_data, glib:: KeyFileFlags :: NONE ) ?;
416
+ let d = sysroot. stage_tree_with_options (
417
+ stateroot. as_deref ( ) ,
418
+ & ostree_commit,
419
+ Some ( & origin) ,
420
+ merge_deployment,
421
+ & opts,
422
+ Some ( cancellable) ,
423
+ ) ?;
424
+ Ok ( d. index ( ) )
425
+ } ) ,
426
+ )
427
+ . await ?;
428
+ // SAFETY: We must have a staged deployment
429
+ let staged = sysroot. staged_deployment ( ) . unwrap ( ) ;
430
+ assert_eq ! ( staged. index( ) , r) ;
431
+ Ok ( staged)
407
432
}
408
433
409
434
#[ context( "Generating origin" ) ]
0 commit comments