@@ -6,7 +6,6 @@ use std::ffi::{CString, OsStr, OsString};
6
6
use std:: io:: Seek ;
7
7
use std:: os:: unix:: process:: CommandExt ;
8
8
use std:: process:: Command ;
9
- use std:: sync:: Arc ;
10
9
11
10
use anyhow:: { ensure, Context , Result } ;
12
11
use camino:: Utf8PathBuf ;
@@ -28,8 +27,8 @@ use serde::{Deserialize, Serialize};
28
27
29
28
use crate :: deploy:: RequiredHostSpec ;
30
29
use crate :: install:: {
31
- open_composefs_repo , setup_composefs_bls_boot, setup_composefs_uki_boot, write_composefs_state,
32
- BootType , BootSetupType ,
30
+ pull_composefs_repo , setup_composefs_bls_boot, setup_composefs_uki_boot, write_composefs_state,
31
+ BootSetupType , BootType ,
33
32
} ;
34
33
use crate :: lints;
35
34
use crate :: progress_jsonl:: { ProgressWriter , RawProgressFd } ;
@@ -38,11 +37,6 @@ use crate::spec::ImageReference;
38
37
use crate :: status:: composefs_deployment_status;
39
38
use crate :: utils:: sigpolicy_from_opt;
40
39
41
- use ostree_ext:: composefs_boot:: BootOps ;
42
- use ostree_ext:: composefs_oci:: {
43
- image:: create_filesystem as create_composefs_filesystem, pull as composefs_oci_pull,
44
- } ;
45
-
46
40
/// Shared progress options
47
41
#[ derive( Debug , Parser , PartialEq , Eq ) ]
48
42
pub ( crate ) struct ProgressOptions {
@@ -773,44 +767,21 @@ async fn upgrade_composefs(_opts: UpgradeOpts) -> Result<()> {
773
767
. as_ref ( )
774
768
. ok_or_else ( || anyhow:: anyhow!( "No image source specified" ) ) ?;
775
769
776
- let booted_image = host
777
- . status
778
- . booted
779
- . ok_or ( anyhow:: anyhow!( "Could not find booted image" ) ) ?
780
- . image
781
- . ok_or ( anyhow:: anyhow!( "Could not find booted image" ) ) ?;
782
-
783
- tracing:: debug!( "booted_image: {booted_image:#?}" ) ;
784
- tracing:: debug!( "imgref: {imgref:#?}" ) ;
785
-
786
- let digest = booted_image
787
- . digest ( )
788
- . context ( "Getting digest for booted image" ) ?;
770
+ // let booted_image = host
771
+ // .status
772
+ // .booted
773
+ // .ok_or(anyhow::anyhow!("Could not find booted image"))?
774
+ // .image
775
+ // .ok_or(anyhow::anyhow!("Could not find booted image"))?;
789
776
790
- let rootfs_dir = cap_std:: fs:: Dir :: open_ambient_dir ( "/sysroot" , cap_std:: ambient_authority ( ) ) ?;
777
+ // tracing::debug!("booted_image: {booted_image:#?}");
778
+ // tracing::debug!("imgref: {imgref:#?}");
791
779
792
- let repo = open_composefs_repo ( & rootfs_dir) . context ( "Opening compoesfs repo" ) ?;
780
+ // let digest = booted_image
781
+ // .digest()
782
+ // .context("Getting digest for booted image")?;
793
783
794
- let ( id, verity) = composefs_oci_pull (
795
- & Arc :: new ( repo) ,
796
- & format ! ( "{}:{}" , imgref. transport, imgref. image) ,
797
- None ,
798
- )
799
- . await
800
- . context ( "Pulling composefs repo" ) ?;
801
-
802
- tracing:: debug!(
803
- "id = {id}, verity = {verity}" ,
804
- id = hex:: encode( id) ,
805
- verity = verity. to_hex( )
806
- ) ;
807
-
808
- let repo = open_composefs_repo ( & rootfs_dir) ?;
809
- let mut fs = create_composefs_filesystem ( & repo, digest. digest ( ) , None )
810
- . context ( "Failed to create composefs filesystem" ) ?;
811
-
812
- let entries = fs. transform_for_boot ( & repo) ?;
813
- let id = fs. commit_image ( & repo, None ) ?;
784
+ let ( repo, entries, id) = pull_composefs_repo ( & imgref. transport , & imgref. image ) . await ?;
814
785
815
786
let Some ( entry) = entries. into_iter ( ) . next ( ) else {
816
787
anyhow:: bail!( "No boot entries!" ) ;
@@ -939,9 +910,7 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
939
910
Ok ( ( ) )
940
911
}
941
912
942
- /// Implementation of the `bootc switch` CLI command.
943
- #[ context( "Switching" ) ]
944
- async fn switch ( opts : SwitchOpts ) -> Result < ( ) > {
913
+ fn imgref_for_switch ( opts : & SwitchOpts ) -> Result < ImageReference > {
945
914
let transport = ostree_container:: Transport :: try_from ( opts. transport . as_str ( ) ) ?;
946
915
let imgref = ostree_container:: ImageReference {
947
916
transport,
@@ -950,6 +919,56 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
950
919
let sigverify = sigpolicy_from_opt ( opts. enforce_container_sigpolicy ) ;
951
920
let target = ostree_container:: OstreeImageReference { sigverify, imgref } ;
952
921
let target = ImageReference :: from ( target) ;
922
+
923
+ return Ok ( target) ;
924
+ }
925
+
926
+ #[ context( "Composefs Switching" ) ]
927
+ async fn switch_composefs ( opts : SwitchOpts ) -> Result < ( ) > {
928
+ let target = imgref_for_switch ( & opts) ?;
929
+ // TODO: Handle in-place
930
+
931
+ let host = composefs_deployment_status ( )
932
+ . await
933
+ . context ( "Getting composefs deployment status" ) ?;
934
+
935
+ let new_spec = {
936
+ let mut new_spec = host. spec . clone ( ) ;
937
+ new_spec. image = Some ( target. clone ( ) ) ;
938
+ new_spec
939
+ } ;
940
+
941
+ if new_spec == host. spec {
942
+ println ! ( "Image specification is unchanged." ) ;
943
+ return Ok ( ( ) ) ;
944
+ }
945
+
946
+ let Some ( target_imgref) = new_spec. image else {
947
+ anyhow:: bail!( "Target image is undefined" )
948
+ } ;
949
+
950
+ let ( repo, entries, id) =
951
+ pull_composefs_repo ( & target_imgref. transport , & target_imgref. image ) . await ?;
952
+
953
+ let Some ( entry) = entries. into_iter ( ) . next ( ) else {
954
+ anyhow:: bail!( "No boot entries!" ) ;
955
+ } ;
956
+
957
+ match BootType :: from ( & entry) {
958
+ BootType :: Bls => setup_composefs_bls_boot ( BootSetupType :: Upgrade , repo, & id, entry) ,
959
+ BootType :: Uki => setup_composefs_uki_boot ( BootSetupType :: Upgrade , repo, & id, entry) ,
960
+ } ?;
961
+
962
+ write_composefs_state ( & Utf8PathBuf :: from ( "/sysroot" ) , id, & target_imgref, true ) ?;
963
+
964
+ Ok ( ( ) )
965
+ }
966
+
967
+ /// Implementation of the `bootc switch` CLI command.
968
+ #[ context( "Switching" ) ]
969
+ async fn switch ( opts : SwitchOpts ) -> Result < ( ) > {
970
+ let target = imgref_for_switch ( & opts) ?;
971
+
953
972
let prog: ProgressWriter = opts. progress . try_into ( ) ?;
954
973
955
974
// If we're doing an in-place mutation, we shortcut most of the rest of the work here
@@ -1170,7 +1189,13 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
1170
1189
upgrade ( opts) . await
1171
1190
}
1172
1191
}
1173
- Opt :: Switch ( opts) => switch ( opts) . await ,
1192
+ Opt :: Switch ( opts) => {
1193
+ if composefs_booted ( ) ? {
1194
+ switch_composefs ( opts) . await
1195
+ } else {
1196
+ switch ( opts) . await
1197
+ }
1198
+ }
1174
1199
Opt :: Rollback ( opts) => rollback ( opts) . await ,
1175
1200
Opt :: Edit ( opts) => edit ( opts) . await ,
1176
1201
Opt :: UsrOverlay => usroverlay ( ) . await ,
0 commit comments