@@ -6,7 +6,6 @@ use std::ffi::{CString, OsStr, OsString};
66use std:: io:: Seek ;
77use std:: os:: unix:: process:: CommandExt ;
88use std:: process:: Command ;
9- use std:: sync:: Arc ;
109
1110use anyhow:: { ensure, Context , Result } ;
1211use camino:: Utf8PathBuf ;
@@ -29,8 +28,8 @@ use serde::{Deserialize, Serialize};
2928
3029use crate :: deploy:: RequiredHostSpec ;
3130use 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 ,
3433} ;
3534use crate :: lints;
3635use crate :: progress_jsonl:: { ProgressWriter , RawProgressFd } ;
@@ -39,11 +38,6 @@ use crate::spec::ImageReference;
3938use crate :: status:: composefs_deployment_status;
4039use crate :: utils:: sigpolicy_from_opt;
4140
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-
4741/// Shared progress options
4842#[ derive( Debug , Parser , PartialEq , Eq ) ]
4943pub ( crate ) struct ProgressOptions {
@@ -783,44 +777,21 @@ async fn upgrade_composefs(_opts: UpgradeOpts) -> Result<()> {
783777 . as_ref ( )
784778 . ok_or_else ( || anyhow:: anyhow!( "No image source specified" ) ) ?;
785779
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"))?;
799786
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:#?}");
801789
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")?;
803793
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 ?;
824795
825796 let Some ( entry) = entries. into_iter ( ) . next ( ) else {
826797 anyhow:: bail!( "No boot entries!" ) ;
@@ -949,9 +920,7 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
949920 Ok ( ( ) )
950921}
951922
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 > {
955924 let transport = ostree_container:: Transport :: try_from ( opts. transport . as_str ( ) ) ?;
956925 let imgref = ostree_container:: ImageReference {
957926 transport,
@@ -960,6 +929,56 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
960929 let sigverify = sigpolicy_from_opt ( opts. enforce_container_sigpolicy ) ;
961930 let target = ostree_container:: OstreeImageReference { sigverify, imgref } ;
962931 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+
963982 let prog: ProgressWriter = opts. progress . try_into ( ) ?;
964983
965984 // 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<()> {
11821201 upgrade ( opts) . await
11831202 }
11841203 }
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+ }
11861211 Opt :: Rollback ( opts) => rollback ( opts) . await ,
11871212 Opt :: Edit ( opts) => edit ( opts) . await ,
11881213 Opt :: UsrOverlay => usroverlay ( ) . await ,
0 commit comments