@@ -6,7 +6,7 @@ use fn_error_context::context;
66use serde:: { Deserialize , Serialize } ;
77
88use crate :: {
9- bootc_composefs:: boot:: BootType ,
9+ bootc_composefs:: { boot:: BootType , repo :: get_imgref } ,
1010 composefs_consts:: { COMPOSEFS_CMDLINE , ORIGIN_KEY_BOOT_DIGEST , TYPE1_ENT_PATH , USER_CFG } ,
1111 install:: EFI_LOADER_INFO ,
1212 parsers:: {
@@ -21,7 +21,7 @@ use crate::{
2121use std:: str:: FromStr ;
2222
2323use bootc_utils:: try_deserialize_timestamp;
24- use cap_std_ext:: cap_std:: fs:: Dir ;
24+ use cap_std_ext:: { cap_std:: fs:: Dir , dirext :: CapStdExtDirExt } ;
2525use ostree_container:: OstreeImageReference ;
2626use ostree_ext:: container:: { self as ostree_container} ;
2727use ostree_ext:: containers_image_proxy;
@@ -183,17 +183,46 @@ pub(crate) fn get_bootloader() -> Result<Bootloader> {
183183
184184/// Reads the .imginfo file for the provided deployment
185185#[ context( "Reading imginfo" ) ]
186- pub ( crate ) fn get_imginfo ( storage : & Storage , deployment_id : & str ) -> Result < ImgConfigManifest > {
187- let path = std:: path:: PathBuf :: from ( STATE_DIR_RELATIVE )
188- . join ( deployment_id)
189- . join ( format ! ( "{deployment_id}.imginfo" ) ) ;
186+ pub ( crate ) async fn get_imginfo (
187+ storage : & Storage ,
188+ deployment_id : & str ,
189+ imgref : & ImageReference ,
190+ ) -> Result < ImgConfigManifest > {
191+ let imginfo_fname = format ! ( "{deployment_id}.imginfo" ) ;
192+
193+ let depl_state_path = std:: path:: PathBuf :: from ( STATE_DIR_RELATIVE ) . join ( deployment_id) ;
194+ let path = depl_state_path. join ( imginfo_fname) ;
190195
191- let img_conf = storage
196+ let mut img_conf = storage
192197 . physical_root
193- . read_to_string ( & path)
198+ . open_optional ( & path)
194199 . context ( "Failed to open file" ) ?;
195200
196- let img_conf = serde_json:: from_str :: < ImgConfigManifest > ( & img_conf)
201+ let Some ( img_conf) = & mut img_conf else {
202+ let container_details =
203+ get_container_manifest_and_config ( & get_imgref ( & imgref. transport , & imgref. image ) )
204+ . await ?;
205+
206+ let state_dir = storage. physical_root . open_dir ( depl_state_path) ?;
207+
208+ state_dir
209+ . atomic_write (
210+ format ! ( "{}.imginfo" , deployment_id) ,
211+ serde_json:: to_vec ( & container_details) ?,
212+ )
213+ . context ( "Failed to write to .imginfo file" ) ?;
214+
215+ let state_dir = state_dir. reopen_as_ownedfd ( ) ?;
216+
217+ rustix:: fs:: fsync ( state_dir) . context ( "fsync" ) ?;
218+
219+ return Ok ( container_details) ;
220+ } ;
221+
222+ let mut buffer = String :: new ( ) ;
223+ img_conf. read_to_string ( & mut buffer) ?;
224+
225+ let img_conf = serde_json:: from_str :: < ImgConfigManifest > ( & buffer)
197226 . context ( "Failed to parse file as JSON" ) ?;
198227
199228 Ok ( img_conf)
@@ -210,7 +239,7 @@ async fn boot_entry_from_composefs_deployment(
210239 let ostree_img_ref = OstreeImageReference :: from_str ( & img_name_from_config) ?;
211240 let img_ref = ImageReference :: from ( ostree_img_ref) ;
212241
213- let img_conf = get_imginfo ( storage, & verity) ?;
242+ let img_conf = get_imginfo ( storage, & verity, & img_ref ) . await ?;
214243
215244 let image_digest = img_conf. manifest . config ( ) . digest ( ) . to_string ( ) ;
216245 let architecture = img_conf. config . architecture ( ) . to_string ( ) ;
0 commit comments