bootc_lib/bootc_composefs/
switch.rs1use anyhow::{Context, Result};
2use fn_error_context::context;
3
4use crate::{
5 bootc_composefs::{
6 state::update_target_imgref_in_origin,
7 status::get_composefs_status,
8 update::{do_upgrade, is_image_pulled, validate_update, DoUpgradeOpts, UpdateAction},
9 },
10 cli::{imgref_for_switch, SwitchOpts},
11 store::{BootedComposefs, Storage},
12};
13
14#[context("Composefs Switching")]
15pub(crate) async fn switch_composefs(
16 opts: SwitchOpts,
17 storage: &Storage,
18 booted_cfs: &BootedComposefs,
19) -> Result<()> {
20 let target = imgref_for_switch(&opts)?;
21 let host = get_composefs_status(storage, booted_cfs)
24 .await
25 .context("Getting composefs deployment status")?;
26
27 let new_spec = {
28 let mut new_spec = host.spec.clone();
29 new_spec.image = Some(target.clone());
30 new_spec
31 };
32
33 if new_spec == host.spec {
34 println!("Image specification is unchanged.");
35 return Ok(());
36 }
37
38 let Some(target_imgref) = new_spec.image else {
39 anyhow::bail!("Target image is undefined")
40 };
41
42 let repo = &*booted_cfs.repo;
43 let (image, img_config) = is_image_pulled(repo, &target_imgref).await?;
44
45 let do_upgrade_opts = DoUpgradeOpts {
46 soft_reboot: opts.soft_reboot,
47 apply: opts.apply,
48 };
49
50 if let Some(cfg_verity) = image {
51 let action = validate_update(
52 storage,
53 booted_cfs,
54 &host,
55 img_config.manifest.config().digest().digest(),
56 &cfg_verity,
57 true,
58 )?;
59
60 match action {
61 UpdateAction::Skip => {
62 println!("No changes in image: {target_imgref:#}");
63 return Ok(());
64 }
65
66 UpdateAction::Proceed => {
67 return do_upgrade(
68 storage,
69 booted_cfs,
70 &host,
71 &target_imgref,
72 &img_config,
73 &do_upgrade_opts,
74 )
75 .await;
76 }
77
78 UpdateAction::UpdateOrigin => {
79 println!("Image already in composefs repository");
81 println!("Updating target image reference");
82 return update_target_imgref_in_origin(storage, booted_cfs, &target_imgref);
83 }
84 }
85 }
86
87 do_upgrade(
88 storage,
89 booted_cfs,
90 &host,
91 &target_imgref,
92 &img_config,
93 &do_upgrade_opts,
94 )
95 .await?;
96
97 Ok(())
98}