@@ -15,6 +15,7 @@ mod osbuild;
1515pub ( crate ) mod osconfig;
1616
1717use std:: collections:: HashMap ;
18+ use std:: ffi:: OsStr ;
1819use std:: fs:: create_dir_all;
1920use std:: io:: Write ;
2021use std:: os:: fd:: { AsFd , AsRawFd } ;
@@ -43,6 +44,7 @@ use cap_std_ext::cmdext::CapStdExtCommandExt;
4344use cap_std_ext:: prelude:: CapStdExtDirExt ;
4445use clap:: ValueEnum ;
4546use composefs:: fs:: read_file;
47+ use composefs:: tree:: FileSystem ;
4648use fn_error_context:: context;
4749use ostree:: gio;
4850use ostree_ext:: composefs:: {
@@ -52,7 +54,8 @@ use ostree_ext::composefs::{
5254} ;
5355use ostree_ext:: composefs_boot:: bootloader:: UsrLibModulesVmlinuz ;
5456use ostree_ext:: composefs_boot:: {
55- bootloader:: BootEntry as ComposefsBootEntry , cmdline:: get_cmdline_composefs, uki, BootOps ,
57+ bootloader:: BootEntry as ComposefsBootEntry , cmdline:: get_cmdline_composefs,
58+ os_release:: OsReleaseInfo , uki, BootOps ,
5659} ;
5760use ostree_ext:: composefs_oci:: {
5861 image:: create_filesystem as create_composefs_filesystem, pull as composefs_oci_pull,
@@ -1575,9 +1578,9 @@ fn get_booted_bls() -> Result<BLSConfig> {
15751578
15761579pub ( crate ) enum BootSetupType < ' a > {
15771580 /// For initial setup, i.e. install to-disk
1578- Setup ( ( & ' a RootSetup , & ' a State ) ) ,
1581+ Setup ( ( & ' a RootSetup , & ' a State , & ' a FileSystem < Sha256HashValue > ) ) ,
15791582 /// For `bootc upgrade`
1580- Upgrade ,
1583+ Upgrade ( & ' a FileSystem < Sha256HashValue > ) ,
15811584}
15821585
15831586/// Compute SHA256Sum of VMlinuz + Initrd
@@ -1717,8 +1720,8 @@ pub(crate) fn setup_composefs_bls_boot(
17171720) -> Result < String > {
17181721 let id_hex = id. to_hex ( ) ;
17191722
1720- let ( esp_device, cmdline_refs) = match setup_type {
1721- BootSetupType :: Setup ( ( root_setup, state) ) => {
1723+ let ( esp_device, cmdline_refs, fs ) = match setup_type {
1724+ BootSetupType :: Setup ( ( root_setup, state, fs ) ) => {
17221725 // root_setup.kargs has [root=UUID=<UUID>, "rw"]
17231726 let mut cmdline_options = String :: from ( root_setup. kargs . join ( " " ) ) ;
17241727
@@ -1739,10 +1742,10 @@ pub(crate) fn setup_composefs_bls_boot(
17391742 . find ( |p| p. parttype . as_str ( ) == ESP_GUID )
17401743 . ok_or_else ( || anyhow:: anyhow!( "ESP partition not found" ) ) ?;
17411744
1742- ( esp_part. node . clone ( ) , cmdline_options)
1745+ ( esp_part. node . clone ( ) , cmdline_options, fs )
17431746 }
17441747
1745- BootSetupType :: Upgrade => {
1748+ BootSetupType :: Upgrade ( fs ) => {
17461749 let sysroot = Utf8PathBuf :: from ( "/sysroot" ) ;
17471750
17481751 let fsinfo = inspect_filesystem ( & sysroot) ?;
@@ -1760,6 +1763,7 @@ pub(crate) fn setup_composefs_bls_boot(
17601763 format!( "{COMPOSEFS_CMDLINE}={id_hex}" ) ,
17611764 ]
17621765 . join ( " " ) ,
1766+ fs,
17631767 )
17641768 }
17651769 } ;
@@ -1774,10 +1778,11 @@ pub(crate) fn setup_composefs_bls_boot(
17741778 . run_inherited_with_cmd_context ( )
17751779 . context ( "Mounting EFI" ) ?;
17761780
1777- let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ) ;
1781+ let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ( .. ) ) ;
17781782
17791783 let efi_dir = Utf8PathBuf :: from_path_buf ( mounted_efi. join ( EFI_LINUX ) )
17801784 . map_err ( |_| anyhow:: anyhow!( "EFI dir is not valid UTF-8" ) ) ?;
1785+
17811786 let ( bls_config, boot_digest) = match & entry {
17821787 ComposefsBootEntry :: Type1 ( ..) => unimplemented ! ( ) ,
17831788 ComposefsBootEntry :: Type2 ( ..) => unimplemented ! ( ) ,
@@ -1787,14 +1792,47 @@ pub(crate) fn setup_composefs_bls_boot(
17871792 let boot_digest = compute_boot_digest ( usr_lib_modules_vmlinuz, & repo)
17881793 . context ( "Computing boot digest" ) ?;
17891794
1795+ // Every update should have its own /usr/lib/os-release
1796+ let ( dir, fname) = fs
1797+ . root
1798+ . split ( OsStr :: new ( "/usr/lib/os-release" ) )
1799+ . context ( "Getting /usr/lib/os-release" ) ?;
1800+
1801+ let os_release = dir
1802+ . get_file_opt ( fname)
1803+ . context ( "Getting /usr/lib/os-release" ) ?;
1804+
1805+ let version = os_release. and_then ( |os_rel_file| {
1806+ let file_contents = match read_file ( os_rel_file, & repo) {
1807+ Ok ( c) => c,
1808+ Err ( e) => {
1809+ tracing:: warn!( "Could not read /usr/lib/os-release: {e:?}" ) ;
1810+ return None ;
1811+ }
1812+ } ;
1813+
1814+ let file_contents = match std:: str:: from_utf8 ( & file_contents) {
1815+ Ok ( c) => c,
1816+ Err ( ..) => {
1817+ tracing:: warn!( "/usr/lib/os-release did not have valid UTF-8" ) ;
1818+ return None ;
1819+ }
1820+ } ;
1821+
1822+ OsReleaseInfo :: parse ( file_contents) . get_version ( )
1823+ } ) ;
1824+
1825+ let default_sort_key = "1" ;
1826+
17901827 let mut bls_config = BLSConfig :: default ( ) ;
1791- bls_config. title = Some ( id_hex. clone ( ) ) ;
1792- bls_config. sort_key = Some ( "1" . into ( ) ) ;
1793- bls_config. machine_id = None ;
1794- bls_config. linux = format ! ( "/{EFI_LINUX}/{id_hex}/vmlinuz" ) ;
1795- bls_config. initrd = vec ! [ format!( "/{EFI_LINUX}/{id_hex}/initrd" ) ] ;
1796- bls_config. options = Some ( cmdline_refs) ;
1797- bls_config. extra = HashMap :: new ( ) ;
1828+
1829+ bls_config
1830+ . with_title ( id_hex. clone ( ) )
1831+ . with_sort_key ( default_sort_key. into ( ) )
1832+ . with_version ( version. unwrap_or ( default_sort_key. into ( ) ) )
1833+ . with_linux ( format ! ( "/{EFI_LINUX}/{id_hex}/vmlinuz" ) )
1834+ . with_initrd ( vec ! [ format!( "/{EFI_LINUX}/{id_hex}/initrd" ) ] )
1835+ . with_options ( cmdline_refs) ;
17981836
17991837 if let Some ( symlink_to) = find_vmlinuz_initrd_duplicates ( & boot_digest) ? {
18001838 bls_config. linux = format ! ( "/{EFI_LINUX}/{symlink_to}/vmlinuz" ) ;
@@ -1901,7 +1939,7 @@ pub(crate) fn setup_composefs_uki_boot(
19011939 entry : ComposefsBootEntry < Sha256HashValue > ,
19021940) -> Result < ( ) > {
19031941 let ( root_path, esp_device, is_insecure_from_opts) = match setup_type {
1904- BootSetupType :: Setup ( ( root_setup, state) ) => {
1942+ BootSetupType :: Setup ( ( root_setup, state, .. ) ) => {
19051943 if let Some ( v) = & state. config_opts . karg {
19061944 if v. len ( ) > 0 {
19071945 tracing:: warn!( "kargs passed for UKI will be ignored" ) ;
@@ -1922,7 +1960,7 @@ pub(crate) fn setup_composefs_uki_boot(
19221960 )
19231961 }
19241962
1925- BootSetupType :: Upgrade => {
1963+ BootSetupType :: Upgrade ( .. ) => {
19261964 let sysroot = Utf8PathBuf :: from ( "/sysroot" ) ;
19271965
19281966 let fsinfo = inspect_filesystem ( & sysroot) ?;
@@ -2014,7 +2052,7 @@ pub(crate) fn setup_composefs_uki_boot(
20142052 let boot_dir = root_path. join ( "boot" ) ;
20152053 create_dir_all ( & boot_dir) . context ( "Failed to create boot dir" ) ?;
20162054
2017- let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ) ;
2055+ let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ( .. ) ) ;
20182056
20192057 let efi_uuid_source = get_efi_uuid_source ( ) ;
20202058
@@ -2102,6 +2140,7 @@ pub(crate) async fn pull_composefs_repo(
21022140 ComposefsRepository < Sha256HashValue > ,
21032141 Vec < ComposefsBootEntry < Sha256HashValue > > ,
21042142 Sha256HashValue ,
2143+ FileSystem < Sha256HashValue > ,
21052144) > {
21062145 let rootfs_dir = cap_std:: fs:: Dir :: open_ambient_dir ( "/sysroot" , cap_std:: ambient_authority ( ) ) ?;
21072146
@@ -2125,7 +2164,7 @@ pub(crate) async fn pull_composefs_repo(
21252164 let entries = fs. transform_for_boot ( & repo) ?;
21262165 let id = fs. commit_image ( & repo, None ) ?;
21272166
2128- Ok ( ( repo, entries, id) )
2167+ Ok ( ( repo, entries, id, fs ) )
21292168}
21302169
21312170#[ context( "Setting up composefs boot" ) ]
@@ -2164,7 +2203,7 @@ fn setup_composefs_boot(root_setup: &RootSetup, state: &State, image_id: &str) -
21642203 match boot_type {
21652204 BootType :: Bls => {
21662205 let digest = setup_composefs_bls_boot (
2167- BootSetupType :: Setup ( ( & root_setup, & state) ) ,
2206+ BootSetupType :: Setup ( ( & root_setup, & state, & fs ) ) ,
21682207 repo,
21692208 & id,
21702209 entry,
@@ -2173,7 +2212,7 @@ fn setup_composefs_boot(root_setup: &RootSetup, state: &State, image_id: &str) -
21732212 boot_digest = Some ( digest) ;
21742213 }
21752214 BootType :: Uki => setup_composefs_uki_boot (
2176- BootSetupType :: Setup ( ( & root_setup, & state) ) ,
2215+ BootSetupType :: Setup ( ( & root_setup, & state, & fs ) ) ,
21772216 repo,
21782217 & id,
21792218 entry,
@@ -2309,7 +2348,7 @@ async fn install_to_filesystem_impl(
23092348 // Load a fd for the mounted target physical root
23102349 let ( id, verity) = initialize_composefs_repository ( state, rootfs) . await ?;
23112350
2312- tracing:: warn !(
2351+ tracing:: info !(
23132352 "id = {id}, verity = {verity}" ,
23142353 id = hex:: encode( id) ,
23152354 verity = verity. to_hex( )
0 commit comments