@@ -13,12 +13,16 @@ use ostree_ext::container as ostree_container;
1313use ostree_ext:: container_utils:: ostree_booted;
1414use ostree_ext:: keyfileext:: KeyFileExt ;
1515use ostree_ext:: oci_spec;
16+ use ostree_ext:: oci_spec:: image:: Digest ;
17+ use ostree_ext:: oci_spec:: image:: ImageConfiguration ;
1618use ostree_ext:: ostree;
19+ use ostree_ext:: sysroot:: SysrootLock ;
1720
1821use crate :: cli:: OutputFormat ;
22+ use crate :: spec:: ImageStatus ;
1923use crate :: spec:: { BootEntry , BootOrder , Host , HostSpec , HostStatus , HostType } ;
2024use crate :: spec:: { ImageReference , ImageSignature } ;
21- use crate :: store:: { CachedImageStatus , ContainerImageStore , Storage } ;
25+ use crate :: store:: { CachedImageStatus , Storage } ;
2226
2327impl From < ostree_container:: SignatureSource > for ImageSignature {
2428 fn from ( sig : ostree_container:: SignatureSource ) -> Self {
@@ -109,41 +113,81 @@ pub(crate) fn labels_of_config(
109113 config. config ( ) . as_ref ( ) . and_then ( |c| c. labels ( ) . as_ref ( ) )
110114}
111115
116+ /// Convert between a subset of ostree-ext metadata and the exposed spec API.
117+ fn create_imagestatus (
118+ image : ImageReference ,
119+ manifest_digest : & Digest ,
120+ config : & ImageConfiguration ,
121+ ) -> ImageStatus {
122+ let labels = labels_of_config ( 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+ . or_else ( || config. created ( ) . as_deref ( ) )
129+ . and_then ( bootc_utils:: try_deserialize_timestamp) ;
130+
131+ let version = ostree_container:: version_for_config ( config) . map ( ToOwned :: to_owned) ;
132+ let architecture = config. architecture ( ) . to_string ( ) ;
133+ ImageStatus {
134+ image,
135+ version,
136+ timestamp,
137+ image_digest : manifest_digest. to_string ( ) ,
138+ architecture,
139+ }
140+ }
141+
142+ fn imagestatus (
143+ sysroot : & SysrootLock ,
144+ deployment : & ostree:: Deployment ,
145+ image : ostree_container:: OstreeImageReference ,
146+ ) -> Result < CachedImageStatus > {
147+ let repo = & sysroot. repo ( ) ;
148+ let imgstate = ostree_container:: store:: query_image_commit ( repo, & deployment. csum ( ) ) ?;
149+ let image = ImageReference :: from ( image) ;
150+ let cached = imgstate
151+ . cached_update
152+ . map ( |cached| create_imagestatus ( image. clone ( ) , & cached. manifest_digest , & cached. config ) ) ;
153+ let imagestatus = create_imagestatus ( image, & imgstate. manifest_digest , & imgstate. configuration ) ;
154+
155+ Ok ( CachedImageStatus {
156+ image : Some ( imagestatus) ,
157+ cached_update : cached,
158+ } )
159+ }
160+
112161/// Given an OSTree deployment, parse out metadata into our spec.
113162#[ context( "Reading deployment metadata" ) ]
114163fn boot_entry_from_deployment (
115164 sysroot : & Storage ,
116165 deployment : & ostree:: Deployment ,
117166) -> Result < BootEntry > {
118167 let (
119- store,
120168 CachedImageStatus {
121169 image,
122170 cached_update,
123171 } ,
124172 incompatible,
125173 ) = if let Some ( origin) = deployment. origin ( ) . as_ref ( ) {
126174 let incompatible = crate :: utils:: origin_has_rpmostree_stuff ( origin) ;
127- let ( store , cached_imagestatus) = if incompatible {
175+ let cached_imagestatus = if incompatible {
128176 // If there are local changes, we can't represent it as a bootc compatible image.
129- ( None , CachedImageStatus :: default ( ) )
177+ CachedImageStatus :: default ( )
130178 } else if let Some ( image) = get_image_origin ( origin) ? {
131- let store = deployment. store ( ) ?;
132- let store = store. as_ref ( ) . unwrap_or ( & sysroot. store ) ;
133- let spec = Some ( store. spec ( ) ) ;
134- let status = store. imagestatus ( sysroot, deployment, image) ?;
135-
136- ( spec, status)
179+ imagestatus ( sysroot, deployment, image) ?
137180 } else {
138181 // The deployment isn't using a container image
139- ( None , CachedImageStatus :: default ( ) )
182+ CachedImageStatus :: default ( )
140183 } ;
141- ( store , cached_imagestatus, incompatible)
184+ ( cached_imagestatus, incompatible)
142185 } else {
143186 // The deployment has no origin at all (this generally shouldn't happen)
144- ( None , CachedImageStatus :: default ( ) , false )
187+ ( CachedImageStatus :: default ( ) , false )
145188 } ;
146189
190+ let store = Some ( crate :: spec:: Store :: OstreeContainer ) ;
147191 let r = BootEntry {
148192 image,
149193 cached_update,
0 commit comments