@@ -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 ;
@@ -29,8 +28,8 @@ use serde::{Deserialize, Serialize};
29
28
30
29
use crate :: deploy:: RequiredHostSpec ;
31
30
use crate :: install:: {
32
- open_composefs_repo , setup_composefs_bls_boot, setup_composefs_uki_boot, write_composefs_state,
33
- BootType , BootSetupType ,
31
+ pull_composefs_repo , setup_composefs_bls_boot, setup_composefs_uki_boot, write_composefs_state,
32
+ BootSetupType , BootType ,
34
33
} ;
35
34
use crate :: lints;
36
35
use crate :: progress_jsonl:: { ProgressWriter , RawProgressFd } ;
@@ -39,11 +38,6 @@ use crate::spec::ImageReference;
39
38
use crate :: status:: composefs_deployment_status;
40
39
use crate :: utils:: sigpolicy_from_opt;
41
40
42
- use ostree_ext:: composefs_boot:: BootOps ;
43
- use ostree_ext:: composefs_oci:: {
44
- image:: create_filesystem as create_composefs_filesystem, pull as composefs_oci_pull,
45
- } ;
46
-
47
41
/// Shared progress options
48
42
#[ derive( Debug , Parser , PartialEq , Eq ) ]
49
43
pub ( crate ) struct ProgressOptions {
@@ -783,44 +777,21 @@ async fn upgrade_composefs(_opts: UpgradeOpts) -> Result<()> {
783
777
. as_ref ( )
784
778
. ok_or_else ( || anyhow:: anyhow!( "No image source specified" ) ) ?;
785
779
786
- let booted_image = host
787
- . status
788
- . booted
789
- . ok_or ( anyhow:: anyhow!( "Could not find booted image" ) ) ?
790
- . image
791
- . ok_or ( anyhow:: anyhow!( "Could not find booted image" ) ) ?;
792
-
793
- tracing:: debug!( "booted_image: {booted_image:#?}" ) ;
794
- tracing:: debug!( "imgref: {imgref:#?}" ) ;
795
-
796
- let digest = booted_image
797
- . digest ( )
798
- . context ( "Getting digest for booted image" ) ?;
780
+ // let booted_image = host
781
+ // .status
782
+ // .booted
783
+ // .ok_or(anyhow::anyhow!("Could not find booted image"))?
784
+ // .image
785
+ // .ok_or(anyhow::anyhow!("Could not find booted image"))?;
799
786
800
- let rootfs_dir = cap_std:: fs:: Dir :: open_ambient_dir ( "/sysroot" , cap_std:: ambient_authority ( ) ) ?;
787
+ // tracing::debug!("booted_image: {booted_image:#?}");
788
+ // tracing::debug!("imgref: {imgref:#?}");
801
789
802
- let repo = open_composefs_repo ( & rootfs_dir) . context ( "Opening compoesfs repo" ) ?;
790
+ // let digest = booted_image
791
+ // .digest()
792
+ // .context("Getting digest for booted image")?;
803
793
804
- let ( id, verity) = composefs_oci_pull (
805
- & Arc :: new ( repo) ,
806
- & format ! ( "{}:{}" , imgref. transport, imgref. image) ,
807
- None ,
808
- )
809
- . await
810
- . context ( "Pulling composefs repo" ) ?;
811
-
812
- tracing:: debug!(
813
- "id = {id}, verity = {verity}" ,
814
- id = hex:: encode( id) ,
815
- verity = verity. to_hex( )
816
- ) ;
817
-
818
- let repo = open_composefs_repo ( & rootfs_dir) ?;
819
- let mut fs = create_composefs_filesystem ( & repo, digest. digest ( ) , None )
820
- . context ( "Failed to create composefs filesystem" ) ?;
821
-
822
- let entries = fs. transform_for_boot ( & repo) ?;
823
- let id = fs. commit_image ( & repo, None ) ?;
794
+ let ( repo, entries, id) = pull_composefs_repo ( & imgref. transport , & imgref. image ) . await ?;
824
795
825
796
let Some ( entry) = entries. into_iter ( ) . next ( ) else {
826
797
anyhow:: bail!( "No boot entries!" ) ;
@@ -949,9 +920,7 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
949
920
Ok ( ( ) )
950
921
}
951
922
952
- /// Implementation of the `bootc switch` CLI command.
953
- #[ context( "Switching" ) ]
954
- async fn switch ( opts : SwitchOpts ) -> Result < ( ) > {
923
+ fn imgref_for_switch ( opts : & SwitchOpts ) -> Result < ImageReference > {
955
924
let transport = ostree_container:: Transport :: try_from ( opts. transport . as_str ( ) ) ?;
956
925
let imgref = ostree_container:: ImageReference {
957
926
transport,
@@ -960,6 +929,56 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
960
929
let sigverify = sigpolicy_from_opt ( opts. enforce_container_sigpolicy ) ;
961
930
let target = ostree_container:: OstreeImageReference { sigverify, imgref } ;
962
931
let target = ImageReference :: from ( target) ;
932
+
933
+ return Ok ( target) ;
934
+ }
935
+
936
+ #[ context( "Composefs Switching" ) ]
937
+ async fn switch_composefs ( opts : SwitchOpts ) -> Result < ( ) > {
938
+ let target = imgref_for_switch ( & opts) ?;
939
+ // TODO: Handle in-place
940
+
941
+ let host = composefs_deployment_status ( )
942
+ . await
943
+ . context ( "Getting composefs deployment status" ) ?;
944
+
945
+ let new_spec = {
946
+ let mut new_spec = host. spec . clone ( ) ;
947
+ new_spec. image = Some ( target. clone ( ) ) ;
948
+ new_spec
949
+ } ;
950
+
951
+ if new_spec == host. spec {
952
+ println ! ( "Image specification is unchanged." ) ;
953
+ return Ok ( ( ) ) ;
954
+ }
955
+
956
+ let Some ( target_imgref) = new_spec. image else {
957
+ anyhow:: bail!( "Target image is undefined" )
958
+ } ;
959
+
960
+ let ( repo, entries, id) =
961
+ pull_composefs_repo ( & target_imgref. transport , & target_imgref. image ) . await ?;
962
+
963
+ let Some ( entry) = entries. into_iter ( ) . next ( ) else {
964
+ anyhow:: bail!( "No boot entries!" ) ;
965
+ } ;
966
+
967
+ match BootType :: from ( & entry) {
968
+ BootType :: Bls => setup_composefs_bls_boot ( BootSetupType :: Upgrade , repo, & id, entry) ,
969
+ BootType :: Uki => setup_composefs_uki_boot ( BootSetupType :: Upgrade , repo, & id, entry) ,
970
+ } ?;
971
+
972
+ write_composefs_state ( & Utf8PathBuf :: from ( "/sysroot" ) , id, & target_imgref, true ) ?;
973
+
974
+ Ok ( ( ) )
975
+ }
976
+
977
+ /// Implementation of the `bootc switch` CLI command.
978
+ #[ context( "Switching" ) ]
979
+ async fn switch ( opts : SwitchOpts ) -> Result < ( ) > {
980
+ let target = imgref_for_switch ( & opts) ?;
981
+
963
982
let prog: ProgressWriter = opts. progress . try_into ( ) ?;
964
983
965
984
// If we're doing an in-place mutation, we shortcut most of the rest of the work here
@@ -1182,7 +1201,13 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
1182
1201
upgrade ( opts) . await
1183
1202
}
1184
1203
}
1185
- Opt :: Switch ( opts) => switch ( opts) . await ,
1204
+ Opt :: Switch ( opts) => {
1205
+ if composefs_booted ( ) ? {
1206
+ switch_composefs ( opts) . await
1207
+ } else {
1208
+ switch ( opts) . await
1209
+ }
1210
+ }
1186
1211
Opt :: Rollback ( opts) => rollback ( opts) . await ,
1187
1212
Opt :: Edit ( opts) => edit ( opts) . await ,
1188
1213
Opt :: UsrOverlay => usroverlay ( ) . await ,
0 commit comments