@@ -10,6 +10,7 @@ use ostree_container::OstreeImageReference;
10
10
use ostree_ext:: container as ostree_container;
11
11
use ostree_ext:: keyfileext:: KeyFileExt ;
12
12
use ostree_ext:: oci_spec;
13
+ use ostree_ext:: oci_spec:: image:: ImageConfiguration ;
13
14
use ostree_ext:: ostree;
14
15
use ostree_ext:: sysroot:: SysrootLock ;
15
16
@@ -112,48 +113,69 @@ pub(crate) fn labels_of_config(
112
113
config. config ( ) . as_ref ( ) . and_then ( |c| c. labels ( ) . as_ref ( ) )
113
114
}
114
115
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.
115
142
#[ context( "Reading deployment metadata" ) ]
116
143
fn boot_entry_from_deployment (
117
144
sysroot : & SysrootLock ,
118
145
deployment : & ostree:: Deployment ,
119
146
) -> Result < BootEntry > {
120
147
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 ( ) {
122
149
let incompatible = crate :: utils:: origin_has_rpmostree_stuff ( origin) ;
123
- let image = if incompatible {
150
+ let ( image, cached ) = if incompatible {
124
151
// If there are local changes, we can't represent it as a bootc compatible image.
125
- None
152
+ ( None , None )
126
153
} else if let Some ( image) = get_image_origin ( origin) ? {
127
154
let image = ImageReference :: from ( image) ;
128
155
let csum = deployment. csum ( ) ;
129
156
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 (
143
161
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)
148
167
} else {
149
- None
168
+ // The deployment isn't using a container image
169
+ ( None , None )
150
170
} ;
151
- ( image, incompatible)
171
+ ( image, cached , incompatible)
152
172
} else {
153
- ( None , false )
173
+ // The deployment has no origin at all (this generally shouldn't happen)
174
+ ( None , None , false )
154
175
} ;
155
176
let r = BootEntry {
156
177
image,
178
+ cached_update,
157
179
incompatible,
158
180
pinned : deployment. is_pinned ( ) ,
159
181
ostree : Some ( crate :: spec:: BootEntryOstree {
0 commit comments