@@ -10,6 +10,7 @@ use ostree_container::OstreeImageReference;
1010use ostree_ext:: container as ostree_container;
1111use ostree_ext:: keyfileext:: KeyFileExt ;
1212use ostree_ext:: oci_spec;
13+ use ostree_ext:: oci_spec:: image:: ImageConfiguration ;
1314use ostree_ext:: ostree;
1415use 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" ) ]
116143fn 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