@@ -478,6 +478,27 @@ pub(crate) fn get_base_commit(repo: &ostree::Repo, commit: &str) -> Result<Optio
478478 Ok ( r)
479479}
480480
481+ #[ context( "Loading deployment into kexec" ) ]
482+ async fn kexec_load ( sysroot : & Storage , deployment : & Deployment ) -> Result < ( ) > {
483+ // Clone all the things to move to worker thread
484+ let sysroot = sysroot. sysroot . clone ( ) ;
485+ // ostree::Deployment is incorrently !Send 😢 so convert it to an integer
486+ let deployment_index = deployment. index ( ) as usize ;
487+
488+ async_task_with_spinner (
489+ "Deploying" ,
490+ spawn_blocking_cancellable_flatten ( move |cancellable| -> Result < ( ) > {
491+ let deployments = sysroot. deployments ( ) ;
492+ let deployment = & deployments[ deployment_index] ;
493+
494+ sysroot. deployment_kexec_load ( & deployment, Some ( cancellable) ) ?;
495+ Ok ( ( ) )
496+ } ) ,
497+ )
498+ . await ?;
499+ Ok ( ( ) )
500+ }
501+
481502#[ context( "Writing deployment" ) ]
482503async fn deploy (
483504 sysroot : & Storage ,
@@ -552,6 +573,12 @@ fn origin_from_imageref(imgref: &ImageReference) -> Result<glib::KeyFile> {
552573 Ok ( origin)
553574}
554575
576+ #[ derive( Debug , Clone , Default ) ]
577+ #[ non_exhaustive]
578+ pub ( crate ) struct StageOptions {
579+ pub ( crate ) deploy_kexec : bool ,
580+ }
581+
555582/// Stage (queue deployment of) a fetched container image.
556583#[ context( "Staging" ) ]
557584pub ( crate ) async fn stage (
@@ -560,7 +587,11 @@ pub(crate) async fn stage(
560587 image : & ImageState ,
561588 spec : & RequiredHostSpec < ' _ > ,
562589 prog : ProgressWriter ,
590+ StageOptions { deploy_kexec } : StageOptions ,
563591) -> Result < ( ) > {
592+ let steps_total = 4 + ( deploy_kexec as u64 ) ;
593+ let mut steps = 0 ;
594+
564595 let mut subtask = SubTaskStep {
565596 subtask : "merging" . into ( ) ,
566597 description : "Merging Image" . into ( ) ,
@@ -574,7 +605,7 @@ pub(crate) async fn stage(
574605 id : image. manifest_digest . clone ( ) . as_ref ( ) . into ( ) ,
575606 steps_cached : 0 ,
576607 steps : 0 ,
577- steps_total : 3 ,
608+ steps_total,
578609 subtasks : subtasks
579610 . clone ( )
580611 . into_iter ( )
@@ -590,13 +621,14 @@ pub(crate) async fn stage(
590621 subtask. id = "deploying" . into ( ) ;
591622 subtask. description = "Deploying Image" . into ( ) ;
592623 subtask. completed = false ;
624+ steps += 1 ;
593625 prog. send ( Event :: ProgressSteps {
594626 task : "staging" . into ( ) ,
595627 description : "Deploying Image" . into ( ) ,
596628 id : image. manifest_digest . clone ( ) . as_ref ( ) . into ( ) ,
597629 steps_cached : 0 ,
598- steps : 1 ,
599- steps_total : 3 ,
630+ steps,
631+ steps_total,
600632 subtasks : subtasks
601633 . clone ( )
602634 . into_iter ( )
@@ -620,13 +652,14 @@ pub(crate) async fn stage(
620652 subtask. id = "bound_images" . into ( ) ;
621653 subtask. description = "Pulling Bound Images" . into ( ) ;
622654 subtask. completed = false ;
655+ steps += 1 ;
623656 prog. send ( Event :: ProgressSteps {
624657 task : "staging" . into ( ) ,
625658 description : "Deploying Image" . into ( ) ,
626659 id : image. manifest_digest . clone ( ) . as_ref ( ) . into ( ) ,
627660 steps_cached : 0 ,
628- steps : 1 ,
629- steps_total : 3 ,
661+ steps,
662+ steps_total,
630663 subtasks : subtasks
631664 . clone ( )
632665 . into_iter ( )
@@ -642,13 +675,14 @@ pub(crate) async fn stage(
642675 subtask. id = "cleanup" . into ( ) ;
643676 subtask. description = "Removing old images" . into ( ) ;
644677 subtask. completed = false ;
678+ steps += 1 ;
645679 prog. send ( Event :: ProgressSteps {
646680 task : "staging" . into ( ) ,
647681 description : "Deploying Image" . into ( ) ,
648682 id : image. manifest_digest . clone ( ) . as_ref ( ) . into ( ) ,
649683 steps_cached : 0 ,
650- steps : 2 ,
651- steps_total : 3 ,
684+ steps,
685+ steps_total,
652686 subtasks : subtasks
653687 . clone ( )
654688 . into_iter ( )
@@ -663,15 +697,42 @@ pub(crate) async fn stage(
663697 }
664698 println ! ( " Digest: {}" , image. manifest_digest) ;
665699
700+ if deploy_kexec {
701+ subtask. completed = true ;
702+ subtasks. push ( subtask. clone ( ) ) ;
703+ subtask. subtask = "kexec" . into ( ) ;
704+ subtask. id = "kexec" . into ( ) ;
705+ subtask. description = "Loading image into kexec" . into ( ) ;
706+ subtask. completed = false ;
707+ steps += 1 ;
708+ prog. send ( Event :: ProgressSteps {
709+ task : "staging" . into ( ) ,
710+ description : "Deploying Image" . into ( ) ,
711+ id : image. manifest_digest . clone ( ) . as_ref ( ) . into ( ) ,
712+ steps_cached : 0 ,
713+ steps,
714+ steps_total,
715+ subtasks : subtasks
716+ . clone ( )
717+ . into_iter ( )
718+ . chain ( [ subtask. clone ( ) ] )
719+ . collect ( ) ,
720+ } )
721+ . await ;
722+ crate :: deploy:: kexec_load ( sysroot, & deployment) . await ?;
723+ println ! ( " Next reboot will kexec into this deployment!" ) ;
724+ }
725+
666726 subtask. completed = true ;
667727 subtasks. push ( subtask. clone ( ) ) ;
728+ steps += 1 ;
668729 prog. send ( Event :: ProgressSteps {
669730 task : "staging" . into ( ) ,
670731 description : "Deploying Image" . into ( ) ,
671732 id : image. manifest_digest . clone ( ) . as_ref ( ) . into ( ) ,
672733 steps_cached : 0 ,
673- steps : 3 ,
674- steps_total : 3 ,
734+ steps,
735+ steps_total,
675736 subtasks : subtasks
676737 . clone ( )
677738 . into_iter ( )
0 commit comments