@@ -3,6 +3,7 @@ use std::{io::Read, sync::OnceLock};
33use anyhow:: { Context , Result } ;
44use bootc_kernel_cmdline:: utf8:: Cmdline ;
55use fn_error_context:: context;
6+ use serde:: { Deserialize , Serialize } ;
67
78use crate :: {
89 bootc_composefs:: boot:: BootType ,
@@ -22,10 +23,10 @@ use std::str::FromStr;
2223use bootc_utils:: try_deserialize_timestamp;
2324use cap_std_ext:: cap_std:: fs:: Dir ;
2425use ostree_container:: OstreeImageReference ;
25- use ostree_ext:: container:: deploy:: ORIGIN_CONTAINER ;
2626use ostree_ext:: container:: { self as ostree_container} ;
2727use ostree_ext:: containers_image_proxy;
2828use ostree_ext:: oci_spec;
29+ use ostree_ext:: { container:: deploy:: ORIGIN_CONTAINER , oci_spec:: image:: ImageConfiguration } ;
2930
3031use ostree_ext:: oci_spec:: image:: ImageManifest ;
3132use tokio:: io:: AsyncReadExt ;
@@ -36,6 +37,13 @@ use crate::composefs_consts::{
3637} ;
3738use crate :: spec:: Bootloader ;
3839
40+ /// Used for storing the container image info alongside of .origin file
41+ #[ derive( Debug , Serialize , Deserialize ) ]
42+ pub ( crate ) struct ImgConfigManifest {
43+ pub ( crate ) config : ImageConfiguration ,
44+ pub ( crate ) manifest : ImageManifest ,
45+ }
46+
3947/// A parsed composefs command line
4048#[ derive( Clone ) ]
4149pub ( crate ) struct ComposefsCmdline {
@@ -134,7 +142,7 @@ pub(crate) fn get_sorted_type1_boot_entries(
134142#[ context( "Getting container info" ) ]
135143pub ( crate ) async fn get_container_manifest_and_config (
136144 imgref : & String ,
137- ) -> Result < ( ImageManifest , oci_spec :: image :: ImageConfiguration ) > {
145+ ) -> Result < ImgConfigManifest > {
138146 let config = containers_image_proxy:: ImageProxyConfig :: default ( ) ;
139147 let proxy = containers_image_proxy:: ImageProxy :: new_with_config ( config) . await ?;
140148
@@ -150,7 +158,7 @@ pub(crate) async fn get_container_manifest_and_config(
150158
151159 let config: oci_spec:: image:: ImageConfiguration = serde_json:: from_slice ( & buf) ?;
152160
153- Ok ( ( manifest, config) )
161+ Ok ( ImgConfigManifest { manifest, config } )
154162}
155163
156164#[ context( "Getting bootloader" ) ]
@@ -175,47 +183,45 @@ pub(crate) fn get_bootloader() -> Result<Bootloader> {
175183
176184#[ context( "Getting composefs deployment metadata" ) ]
177185async fn boot_entry_from_composefs_deployment (
186+ storage : & Storage ,
178187 origin : tini:: Ini ,
179188 verity : String ,
180189) -> Result < BootEntry > {
181190 let image = match origin. get :: < String > ( "origin" , ORIGIN_CONTAINER ) {
182191 Some ( img_name_from_config) => {
183192 let ostree_img_ref = OstreeImageReference :: from_str ( & img_name_from_config) ?;
184- let imgref = ostree_img_ref. imgref . to_string ( ) ;
185193 let img_ref = ImageReference :: from ( ostree_img_ref) ;
186194
187- // The image might've been removed, so don't error if we can't get the image manifest
188- let ( image_digest, version, architecture, created_at) =
189- match get_container_manifest_and_config ( & imgref) . await {
190- Ok ( ( manifest, config) ) => {
191- let digest = manifest. config ( ) . digest ( ) . to_string ( ) ;
192- let arch = config. architecture ( ) . to_string ( ) ;
193- let created = config. created ( ) . clone ( ) ;
194- let version = manifest
195- . annotations ( )
196- . as_ref ( )
197- . and_then ( |a| a. get ( oci_spec:: image:: ANNOTATION_VERSION ) . cloned ( ) ) ;
198-
199- ( digest, version, arch, created)
200- }
195+ let path = std:: path:: PathBuf :: from ( STATE_DIR_RELATIVE )
196+ . join ( & verity)
197+ . join ( format ! ( "{verity}.imginfo" ) ) ;
201198
202- Err ( e) => {
203- tracing:: debug!( "Failed to open image {img_ref}, because {e:?}" ) ;
204- ( "" . into ( ) , None , "" . into ( ) , None )
205- }
206- } ;
199+ let img_conf = storage
200+ . physical_root
201+ . read_to_string ( & path)
202+ . context ( "Failed to open imginfo file" ) ?;
203+
204+ let img_conf: ImgConfigManifest =
205+ serde_json:: from_str ( & img_conf) . context ( "Failed to parse imginfo file as JSON" ) ?;
207206
207+ let image_digest = img_conf. manifest . config ( ) . digest ( ) . to_string ( ) ;
208+ let architecture = img_conf. config . architecture ( ) . to_string ( ) ;
209+ let version = img_conf
210+ . manifest
211+ . annotations ( )
212+ . as_ref ( )
213+ . and_then ( |a| a. get ( oci_spec:: image:: ANNOTATION_VERSION ) . cloned ( ) ) ;
214+
215+ let created_at = img_conf. config . created ( ) . clone ( ) ;
208216 let timestamp = created_at. and_then ( |x| try_deserialize_timestamp ( & x) ) ;
209217
210- let image_status = ImageStatus {
218+ Some ( ImageStatus {
211219 image : img_ref,
212220 version,
213221 timestamp,
214222 image_digest,
215223 architecture,
216- } ;
217-
218- Some ( image_status)
224+ } )
219225 }
220226
221227 // Wasn't booted using a container image. Do nothing
@@ -313,7 +319,7 @@ pub(crate) async fn composefs_deployment_status_from(
313319 . with_context ( || format ! ( "Failed to parse file {depl_file_name}.origin as ini" ) ) ?;
314320
315321 let boot_entry =
316- boot_entry_from_composefs_deployment ( ini, depl_file_name. to_string ( ) ) . await ?;
322+ boot_entry_from_composefs_deployment ( storage , ini, depl_file_name. to_string ( ) ) . await ?;
317323
318324 // SAFETY: boot_entry.composefs will always be present
319325 let boot_type_from_origin = boot_entry. composefs . as_ref ( ) . unwrap ( ) . boot_type ;
0 commit comments