@@ -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" ;
@@ -375,8 +377,6 @@ async fn deploy(
375
377
image : & ImageState ,
376
378
origin : & glib:: KeyFile ,
377
379
) -> Result < Deployment > {
378
- let stateroot = Some ( stateroot) ;
379
- let mut opts = ostree:: SysrootDeployTreeOpts :: default ( ) ;
380
380
// Compute the kernel argument overrides. In practice today this API is always expecting
381
381
// a merge deployment. The kargs code also always looks at the booted root (which
382
382
// is a distinct minor issue, but not super important as right now the install path
@@ -386,26 +386,49 @@ async fn deploy(
386
386
} else {
387
387
None
388
388
} ;
389
- // Because the C API expects a Vec<&str>, we need to generate a new Vec<>
390
- // that borrows.
391
- let override_kargs = override_kargs
392
- . as_deref ( )
393
- . map ( |v| v. iter ( ) . map ( |s| s. as_str ( ) ) . collect :: < Vec < _ > > ( ) ) ;
394
- if let Some ( kargs) = override_kargs. as_deref ( ) {
395
- opts. override_kernel_argv = Some ( & kargs) ;
396
- }
397
- // Copy to move into thread
398
- let cancellable = gio:: Cancellable :: NONE ;
399
- return sysroot
400
- . stage_tree_with_options (
401
- stateroot,
402
- image. ostree_commit . as_str ( ) ,
403
- Some ( origin) ,
404
- merge_deployment,
405
- & opts,
406
- cancellable,
407
- )
408
- . 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)
409
432
}
410
433
411
434
#[ context( "Generating origin" ) ]
0 commit comments