@@ -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 ;
@@ -28,8 +27,8 @@ use serde::{Deserialize, Serialize};
2827
2928use crate :: deploy:: RequiredHostSpec ;
3029use 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 ,
3332} ;
3433use crate :: lints;
3534use crate :: progress_jsonl:: { ProgressWriter , RawProgressFd } ;
@@ -38,11 +37,6 @@ use crate::spec::ImageReference;
3837use crate :: status:: composefs_deployment_status;
3938use crate :: utils:: sigpolicy_from_opt;
4039
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-
4640/// Shared progress options
4741#[ derive( Debug , Parser , PartialEq , Eq ) ]
4842pub ( crate ) struct ProgressOptions {
@@ -773,44 +767,21 @@ async fn upgrade_composefs(_opts: UpgradeOpts) -> Result<()> {
773767 . as_ref ( )
774768 . ok_or_else ( || anyhow:: anyhow!( "No image source specified" ) ) ?;
775769
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"))?;
789776
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:#?}");
791779
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")?;
793783
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 ?;
814785
815786 let Some ( entry) = entries. into_iter ( ) . next ( ) else {
816787 anyhow:: bail!( "No boot entries!" ) ;
@@ -939,9 +910,7 @@ async fn upgrade(opts: UpgradeOpts) -> Result<()> {
939910 Ok ( ( ) )
940911}
941912
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 > {
945914 let transport = ostree_container:: Transport :: try_from ( opts. transport . as_str ( ) ) ?;
946915 let imgref = ostree_container:: ImageReference {
947916 transport,
@@ -950,6 +919,56 @@ async fn switch(opts: SwitchOpts) -> Result<()> {
950919 let sigverify = sigpolicy_from_opt ( opts. enforce_container_sigpolicy ) ;
951920 let target = ostree_container:: OstreeImageReference { sigverify, imgref } ;
952921 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+
953972 let prog: ProgressWriter = opts. progress . try_into ( ) ?;
954973
955974 // 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<()> {
11701189 upgrade ( opts) . await
11711190 }
11721191 }
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+ }
11741199 Opt :: Rollback ( opts) => rollback ( opts) . await ,
11751200 Opt :: Edit ( opts) => edit ( opts) . await ,
11761201 Opt :: UsrOverlay => usroverlay ( ) . await ,
0 commit comments