-
Notifications
You must be signed in to change notification settings - Fork 193
Expand file tree
/
Copy pathswitch.rs
More file actions
109 lines (93 loc) · 2.93 KB
/
switch.rs
File metadata and controls
109 lines (93 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use anyhow::{Context, Result};
use fn_error_context::context;
use crate::{
bootc_composefs::{
state::update_target_imgref_in_origin,
status::get_composefs_status,
update::{DoUpgradeOpts, UpdateAction, do_upgrade, is_image_pulled, validate_update},
},
cli::{SwitchOpts, imgref_for_switch},
store::{BootedComposefs, Storage},
};
#[context("Composefs Switching")]
pub(crate) async fn switch_composefs(
opts: SwitchOpts,
storage: &Storage,
booted_cfs: &BootedComposefs,
) -> Result<()> {
let target = imgref_for_switch(&opts)?;
// TODO: Handle in-place
let host = get_composefs_status(storage, booted_cfs)
.await
.context("Getting composefs deployment status")?;
let new_spec = {
let mut new_spec = host.spec.clone();
new_spec.image = Some(target.clone());
new_spec
};
if new_spec == host.spec {
println!("Image specification is unchanged.");
return Ok(());
}
let Some(target_imgref) = new_spec.image else {
anyhow::bail!("Target image is undefined")
};
const COMPOSEFS_SWITCH_JOURNAL_ID: &str = "7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1";
tracing::info!(
message_id = COMPOSEFS_SWITCH_JOURNAL_ID,
bootc.operation = "switch",
bootc.target_image = target_imgref.to_string(),
bootc.apply_mode = opts.apply,
"Starting composefs switch operation",
);
let repo = &*booted_cfs.repo;
let (image, img_config) = is_image_pulled(repo, &target_imgref).await?;
let do_upgrade_opts = DoUpgradeOpts {
soft_reboot: opts.soft_reboot,
apply: opts.apply,
download_only: false,
};
if let Some(cfg_verity) = image {
let action = validate_update(
storage,
booted_cfs,
&host,
img_config.manifest.config().digest(),
&cfg_verity,
true,
)?;
match action {
UpdateAction::Skip => {
println!("No changes in image: {target_imgref:#}");
return Ok(());
}
UpdateAction::Proceed => {
return do_upgrade(
storage,
booted_cfs,
&host,
&target_imgref,
&img_config,
&do_upgrade_opts,
)
.await;
}
UpdateAction::UpdateOrigin => {
// The staged image will never be the current image's verity digest
println!("Image already in composefs repository");
println!("Updating target image reference");
return update_target_imgref_in_origin(storage, booted_cfs, &target_imgref);
}
}
}
do_upgrade(
storage,
booted_cfs,
&host,
&target_imgref,
&img_config,
&do_upgrade_opts,
)
.await?;
Ok(())
}