Skip to content

Commit b4a0145

Browse files
committed
spec: Add cached update metadata
In ostreedev/ostree-rs-ext#537 we added a facility to cache metadata (manifest+config) for container image updates with an eye for use in rpm-ostree. The `bootc update --check` code here in bootc was also updated to use it; but we didn't really expose it back in the status. This closes the gap, just bridging the cached update metadata into status. We want to do this as opposed to having `bootc update --check` grow its own API for example. Closes: #247 Signed-off-by: Colin Walters <[email protected]>
1 parent d2a2326 commit b4a0145

File tree

2 files changed

+47
-23
lines changed

2 files changed

+47
-23
lines changed

lib/src/spec.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ pub struct BootEntryOstree {
8888
pub struct BootEntry {
8989
/// The image reference
9090
pub image: Option<ImageStatus>,
91+
/// The last fetched cached update metadata
92+
pub cached_update: Option<ImageStatus>,
9193
/// Whether this boot entry is not compatible (has origin changes bootc does not understand)
9294
pub incompatible: bool,
9395
/// Whether this entry will be subject to garbage collection

lib/src/status.rs

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use ostree_container::OstreeImageReference;
1010
use ostree_ext::container as ostree_container;
1111
use ostree_ext::keyfileext::KeyFileExt;
1212
use ostree_ext::oci_spec;
13+
use ostree_ext::oci_spec::image::ImageConfiguration;
1314
use ostree_ext::ostree;
1415
use ostree_ext::sysroot::SysrootLock;
1516

@@ -112,48 +113,69 @@ pub(crate) fn labels_of_config(
112113
config.config().as_ref().and_then(|c| c.labels().as_ref())
113114
}
114115

116+
/// Convert between a subset of ostree-ext metadata and the exposed spec API.
117+
pub(crate) fn create_imagestatus(
118+
image: ImageReference,
119+
manifest_digest: &str,
120+
config: Option<&ImageConfiguration>,
121+
) -> ImageStatus {
122+
let labels = config.and_then(labels_of_config);
123+
let timestamp = labels
124+
.and_then(|l| {
125+
l.get(oci_spec::image::ANNOTATION_CREATED)
126+
.map(|s| s.as_str())
127+
})
128+
.and_then(try_deserialize_timestamp);
129+
130+
let version = config
131+
.and_then(ostree_container::version_for_config)
132+
.map(ToOwned::to_owned);
133+
ImageStatus {
134+
image,
135+
version,
136+
timestamp,
137+
image_digest: manifest_digest.to_owned(),
138+
}
139+
}
140+
141+
/// Given an OSTree deployment, parse out metadata into our spec.
115142
#[context("Reading deployment metadata")]
116143
fn boot_entry_from_deployment(
117144
sysroot: &SysrootLock,
118145
deployment: &ostree::Deployment,
119146
) -> Result<BootEntry> {
120147
let repo = &sysroot.repo();
121-
let (image, incompatible) = if let Some(origin) = deployment.origin().as_ref() {
148+
let (image, cached_update, incompatible) = if let Some(origin) = deployment.origin().as_ref() {
122149
let incompatible = crate::utils::origin_has_rpmostree_stuff(origin);
123-
let image = if incompatible {
150+
let (image, cached) = if incompatible {
124151
// If there are local changes, we can't represent it as a bootc compatible image.
125-
None
152+
(None, None)
126153
} else if let Some(image) = get_image_origin(origin)? {
127154
let image = ImageReference::from(image);
128155
let csum = deployment.csum();
129156
let imgstate = ostree_container::store::query_image_commit(repo, &csum)?;
130-
let config = imgstate.configuration.as_ref();
131-
let labels = config.and_then(labels_of_config);
132-
let timestamp = labels
133-
.and_then(|l| {
134-
l.get(oci_spec::image::ANNOTATION_CREATED)
135-
.map(|s| s.as_str())
136-
})
137-
.and_then(try_deserialize_timestamp);
138-
139-
let version = config
140-
.and_then(ostree_container::version_for_config)
141-
.map(ToOwned::to_owned);
142-
Some(ImageStatus {
157+
let cached = imgstate.cached_update.map(|cached| {
158+
create_imagestatus(image.clone(), &cached.manifest_digest, Some(&cached.config))
159+
});
160+
let imagestatus = create_imagestatus(
143161
image,
144-
version,
145-
timestamp,
146-
image_digest: imgstate.manifest_digest,
147-
})
162+
&imgstate.manifest_digest,
163+
imgstate.configuration.as_ref(),
164+
);
165+
// We found a container-image based deployment
166+
(Some(imagestatus), cached)
148167
} else {
149-
None
168+
// The deployment isn't using a container image
169+
(None, None)
150170
};
151-
(image, incompatible)
171+
(image, cached, incompatible)
152172
} else {
153-
(None, false)
173+
// The deployment has no origin at all (this generally shouldn't happen)
174+
(None, None, false)
154175
};
155176
let r = BootEntry {
156177
image,
178+
cached_update,
157179
incompatible,
158180
pinned: deployment.is_pinned(),
159181
ostree: Some(crate::spec::BootEntryOstree {

0 commit comments

Comments
 (0)