@@ -554,7 +554,7 @@ pub(crate) enum Opt {
554554 Note on Rollbacks and the `/etc` Directory:
555555
556556 When you perform a rollback (e.g., with `bootc rollback`), any
557- changes made to files in the `/etc` directory won’ t carry over
557+ changes made to files in the `/etc` directory won' t carry over
558558 to the rolled-back deployment. The `/etc` files will revert
559559 to their state from that previous deployment instead.
560560
@@ -733,6 +733,40 @@ pub(crate) fn require_root(is_container: bool) -> Result<()> {
733733 Ok ( ( ) )
734734}
735735
736+ /// Check if a deployment can perform a soft reboot
737+ fn can_perform_soft_reboot ( deployment : Option < & crate :: spec:: BootEntry > ) -> bool {
738+ deployment. map ( |d| d. soft_reboot_capable ) . unwrap_or ( false )
739+ }
740+
741+ /// Prepare and execute a soft reboot for the given deployment
742+ #[ context( "Preparing soft reboot" ) ]
743+ fn prepare_soft_reboot (
744+ sysroot : & crate :: store:: Storage ,
745+ deployment : & ostree:: Deployment ,
746+ ) -> Result < ( ) > {
747+ let cancellable = ostree:: gio:: Cancellable :: NONE ;
748+ sysroot
749+ . sysroot
750+ . deployment_set_soft_reboot ( deployment, false , cancellable)
751+ . context ( "Failed to prepare soft-reboot" ) ?;
752+ Ok ( ( ) )
753+ }
754+
755+ /// Perform a soft reboot for a staged deployment
756+ #[ context( "Soft reboot staged deployment" ) ]
757+ fn soft_reboot_staged ( sysroot : & crate :: store:: Storage ) -> Result < ( ) > {
758+ println ! ( "Staged deployment is soft-reboot capable, performing soft-reboot..." ) ;
759+
760+ let deployments_list = sysroot. deployments ( ) ;
761+ let staged_deployment = deployments_list
762+ . iter ( )
763+ . find ( |d| d. is_staged ( ) )
764+ . ok_or_else ( || anyhow:: anyhow!( "Failed to find staged deployment" ) ) ?;
765+
766+ prepare_soft_reboot ( sysroot, staged_deployment) ?;
767+ Ok ( ( ) )
768+ }
769+
736770/// A few process changes that need to be made for writing.
737771/// IMPORTANT: This may end up re-executing the current process,
738772/// so anything that happens before this should be idempotent.
@@ -853,6 +887,9 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
853887 println ! ( "Staged update present, not changed." ) ;
854888
855889 if opts. apply {
890+ if can_perform_soft_reboot ( host. status . staged . as_ref ( ) ) {
891+ soft_reboot_staged ( sysroot) ?;
892+ }
856893 crate :: reboot:: reboot ( ) ?;
857894 }
858895 } else if booted_unchanged {
@@ -949,6 +986,12 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
949986 sysroot. update_mtime ( ) ?;
950987
951988 if opts. apply {
989+ // Get updated status to check for soft-reboot capability
990+ let updated_host = crate :: status:: get_status ( sysroot, Some ( & booted_deployment) ) ?. 1 ;
991+
992+ if can_perform_soft_reboot ( updated_host. status . staged . as_ref ( ) ) {
993+ soft_reboot_staged ( sysroot) ?;
994+ }
952995 crate :: reboot:: reboot ( ) ?;
953996 }
954997
@@ -962,6 +1005,20 @@ async fn rollback(opts: RollbackOpts) -> Result<()> {
9621005 crate :: deploy:: rollback ( sysroot) . await ?;
9631006
9641007 if opts. apply {
1008+ // Get status before rollback to check soft-reboot capability
1009+ let host = crate :: status:: get_status_require_booted ( sysroot) ?. 2 ;
1010+
1011+ if can_perform_soft_reboot ( host. status . rollback . as_ref ( ) ) {
1012+ println ! ( "Rollback deployment is soft-reboot capable, performing soft-reboot..." ) ;
1013+
1014+ let deployments_list = sysroot. deployments ( ) ;
1015+ let target_deployment = deployments_list
1016+ . first ( )
1017+ . ok_or_else ( || anyhow:: anyhow!( "No deployments found after rollback" ) ) ?;
1018+
1019+ prepare_soft_reboot ( sysroot, target_deployment) ?;
1020+ }
1021+
9651022 crate :: reboot:: reboot ( ) ?;
9661023 }
9671024
0 commit comments