@@ -536,7 +536,7 @@ pub(crate) enum Opt {
536536 Note on Rollbacks and the `/etc` Directory:
537537
538538 When you perform a rollback (e.g., with `bootc rollback`), any
539- changes made to files in the `/etc` directory won’ t carry over
539+ changes made to files in the `/etc` directory won' t carry over
540540 to the rolled-back deployment. The `/etc` files will revert
541541 to their state from that previous deployment instead.
542542
@@ -715,6 +715,54 @@ pub(crate) fn require_root(is_container: bool) -> Result<()> {
715715 Ok ( ( ) )
716716}
717717
718+ /// Check if a deployment can perform a soft reboot
719+ fn can_perform_soft_reboot ( deployment : Option < & crate :: spec:: BootEntry > ) -> bool {
720+ deployment. map ( |d| d. soft_reboot_capable ) . unwrap_or ( false )
721+ }
722+
723+ /// Prepare and execute a soft reboot for the given deployment
724+ #[ context( "Preparing soft reboot" ) ]
725+ fn prepare_soft_reboot (
726+ sysroot : & crate :: store:: Storage ,
727+ deployment : & ostree:: Deployment ,
728+ ) -> Result < ( ) > {
729+ let cancellable = ostree:: gio:: Cancellable :: NONE ;
730+ sysroot
731+ . sysroot
732+ . deployment_prepare_next_root ( deployment, false , cancellable)
733+ . context ( "Failed to prepare soft-reboot" ) ?;
734+ Ok ( ( ) )
735+ }
736+
737+ /// Perform a soft reboot for a staged deployment
738+ #[ context( "Soft reboot staged deployment" ) ]
739+ fn soft_reboot_staged ( sysroot : & crate :: store:: Storage ) -> Result < ( ) > {
740+ println ! ( "Staged deployment is soft-reboot capable, performing soft-reboot..." ) ;
741+
742+ let deployments_list = sysroot. deployments ( ) ;
743+ let staged_deployment = deployments_list
744+ . iter ( )
745+ . find ( |d| d. is_staged ( ) )
746+ . ok_or_else ( || anyhow:: anyhow!( "Failed to find staged deployment" ) ) ?;
747+
748+ prepare_soft_reboot ( sysroot, staged_deployment) ?;
749+ Ok ( ( ) )
750+ }
751+
752+ /// Perform a soft reboot for a rollback deployment
753+ #[ context( "Soft reboot rollback deployment" ) ]
754+ fn soft_reboot_rollback ( sysroot : & crate :: store:: Storage ) -> Result < ( ) > {
755+ println ! ( "Rollback deployment is soft-reboot capable, performing soft-reboot..." ) ;
756+
757+ let deployments_list = sysroot. deployments ( ) ;
758+ let target_deployment = deployments_list
759+ . first ( )
760+ . ok_or_else ( || anyhow:: anyhow!( "No deployments found after rollback" ) ) ?;
761+
762+ prepare_soft_reboot ( sysroot, target_deployment) ?;
763+ Ok ( ( ) )
764+ }
765+
718766/// A few process changes that need to be made for writing.
719767/// IMPORTANT: This may end up re-executing the current process,
720768/// so anything that happens before this should be idempotent.
@@ -835,6 +883,9 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
835883 println ! ( "Staged update present, not changed." ) ;
836884
837885 if opts. apply {
886+ if can_perform_soft_reboot ( host. status . staged . as_ref ( ) ) {
887+ soft_reboot_staged ( sysroot) ?;
888+ }
838889 crate :: reboot:: reboot ( ) ?;
839890 }
840891 } else if booted_unchanged {
@@ -931,6 +982,13 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
931982 sysroot. update_mtime ( ) ?;
932983
933984 if opts. apply {
985+ // Get updated status to check for soft-reboot capability
986+ let ( _updated_deployments, updated_host) =
987+ crate :: status:: get_status ( sysroot, Some ( & booted_deployment) ) ?;
988+
989+ if can_perform_soft_reboot ( updated_host. status . staged . as_ref ( ) ) {
990+ soft_reboot_staged ( sysroot) ?;
991+ }
934992 crate :: reboot:: reboot ( ) ?;
935993 }
936994
@@ -941,10 +999,22 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
941999#[ context( "Rollback" ) ]
9421000async fn rollback ( opts : RollbackOpts ) -> Result < ( ) > {
9431001 let sysroot = & get_storage ( ) . await ?;
944- crate :: deploy:: rollback ( sysroot) . await ?;
9451002
9461003 if opts. apply {
1004+ // Get status before rollback to check soft-reboot capability
1005+ let ( _booted_deployment, _deployments, host) =
1006+ crate :: status:: get_status_require_booted ( sysroot) ?;
1007+ let can_soft_reboot = can_perform_soft_reboot ( host. status . rollback . as_ref ( ) ) ;
1008+
1009+ // Perform the rollback
1010+ crate :: deploy:: rollback ( sysroot) . await ?;
1011+
1012+ if can_soft_reboot {
1013+ soft_reboot_rollback ( sysroot) ?;
1014+ }
9471015 crate :: reboot:: reboot ( ) ?;
1016+ } else {
1017+ crate :: deploy:: rollback ( sysroot) . await ?;
9481018 }
9491019
9501020 Ok ( ( ) )
0 commit comments