@@ -536,7 +536,7 @@ pub(crate) enum Opt {
536
536
Note on Rollbacks and the `/etc` Directory:
537
537
538
538
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
540
540
to the rolled-back deployment. The `/etc` files will revert
541
541
to their state from that previous deployment instead.
542
542
@@ -715,6 +715,54 @@ pub(crate) fn require_root(is_container: bool) -> Result<()> {
715
715
Ok ( ( ) )
716
716
}
717
717
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
+
718
766
/// A few process changes that need to be made for writing.
719
767
/// IMPORTANT: This may end up re-executing the current process,
720
768
/// so anything that happens before this should be idempotent.
@@ -835,6 +883,9 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
835
883
println ! ( "Staged update present, not changed." ) ;
836
884
837
885
if opts. apply {
886
+ if can_perform_soft_reboot ( host. status . staged . as_ref ( ) ) {
887
+ soft_reboot_staged ( sysroot) ?;
888
+ }
838
889
crate :: reboot:: reboot ( ) ?;
839
890
}
840
891
} else if booted_unchanged {
@@ -931,6 +982,13 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
931
982
sysroot. update_mtime ( ) ?;
932
983
933
984
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
+ }
934
992
crate :: reboot:: reboot ( ) ?;
935
993
}
936
994
@@ -941,10 +999,22 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
941
999
#[ context( "Rollback" ) ]
942
1000
async fn rollback ( opts : RollbackOpts ) -> Result < ( ) > {
943
1001
let sysroot = & get_storage ( ) . await ?;
944
- crate :: deploy:: rollback ( sysroot) . await ?;
945
1002
946
1003
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
+ }
947
1015
crate :: reboot:: reboot ( ) ?;
1016
+ } else {
1017
+ crate :: deploy:: rollback ( sysroot) . await ?;
948
1018
}
949
1019
950
1020
Ok ( ( ) )
0 commit comments