@@ -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 } ;
@@ -41,7 +42,8 @@ use cap_std_ext::cap_tempfile::TempDir;
4142use cap_std_ext:: cmdext:: CapStdExtCommandExt ;
4243use cap_std_ext:: prelude:: CapStdExtDirExt ;
4344use clap:: ValueEnum ;
44- use composefs_boot:: bootloader:: read_file;
45+ use composefs:: fs:: read_file;
46+ use composefs:: tree:: FileSystem ;
4547use fn_error_context:: context;
4648use ostree:: gio;
4749use ostree_ext:: composefs:: {
@@ -51,7 +53,8 @@ use ostree_ext::composefs::{
5153} ;
5254use ostree_ext:: composefs_boot:: bootloader:: UsrLibModulesVmlinuz ;
5355use ostree_ext:: composefs_boot:: {
54- bootloader:: BootEntry as ComposefsBootEntry , cmdline:: get_cmdline_composefs, uki, BootOps ,
56+ bootloader:: BootEntry as ComposefsBootEntry , cmdline:: get_cmdline_composefs,
57+ os_release:: OsReleaseInfo , uki, BootOps ,
5558} ;
5659use ostree_ext:: composefs_oci:: {
5760 image:: create_filesystem as create_composefs_filesystem, pull as composefs_oci_pull,
@@ -1551,9 +1554,9 @@ fn get_booted_bls() -> Result<BLSConfig> {
15511554
15521555pub ( crate ) enum BootSetupType < ' a > {
15531556 /// For initial setup, i.e. install to-disk
1554- Setup ( ( & ' a RootSetup , & ' a State ) ) ,
1557+ Setup ( ( & ' a RootSetup , & ' a State , & ' a FileSystem < Sha256HashValue > ) ) ,
15551558 /// For `bootc upgrade`
1556- Upgrade ,
1559+ Upgrade ( & ' a FileSystem < Sha256HashValue > ) ,
15571560}
15581561
15591562/// Compute SHA256Sum of VMlinuz + Initrd
@@ -1693,8 +1696,8 @@ pub(crate) fn setup_composefs_bls_boot(
16931696) -> Result < String > {
16941697 let id_hex = id. to_hex ( ) ;
16951698
1696- let ( esp_device, cmdline_refs) = match setup_type {
1697- BootSetupType :: Setup ( ( root_setup, state) ) => {
1699+ let ( esp_device, cmdline_refs, fs ) = match setup_type {
1700+ BootSetupType :: Setup ( ( root_setup, state, fs ) ) => {
16981701 // root_setup.kargs has [root=UUID=<UUID>, "rw"]
16991702 let mut cmdline_options = String :: from ( root_setup. kargs . join ( " " ) ) ;
17001703
@@ -1715,10 +1718,10 @@ pub(crate) fn setup_composefs_bls_boot(
17151718 . find ( |p| p. parttype . as_str ( ) == ESP_GUID )
17161719 . ok_or_else ( || anyhow:: anyhow!( "ESP partition not found" ) ) ?;
17171720
1718- ( esp_part. node . clone ( ) , cmdline_options)
1721+ ( esp_part. node . clone ( ) , cmdline_options, fs )
17191722 }
17201723
1721- BootSetupType :: Upgrade => {
1724+ BootSetupType :: Upgrade ( fs ) => {
17221725 let sysroot = Utf8PathBuf :: from ( "/sysroot" ) ;
17231726
17241727 let fsinfo = inspect_filesystem ( & sysroot) ?;
@@ -1736,6 +1739,7 @@ pub(crate) fn setup_composefs_bls_boot(
17361739 format!( "{COMPOSEFS_CMDLINE}={id_hex}" ) ,
17371740 ]
17381741 . join ( " " ) ,
1742+ fs,
17391743 )
17401744 }
17411745 } ;
@@ -1750,10 +1754,11 @@ pub(crate) fn setup_composefs_bls_boot(
17501754 . run_inherited_with_cmd_context ( )
17511755 . context ( "Mounting EFI" ) ?;
17521756
1753- let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ) ;
1757+ let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ( .. ) ) ;
17541758
17551759 let efi_dir = Utf8PathBuf :: from_path_buf ( mounted_efi. join ( EFI_LINUX ) )
17561760 . map_err ( |_| anyhow:: anyhow!( "EFI dir is not valid UTF-8" ) ) ?;
1761+
17571762 let ( bls_config, boot_digest) = match & entry {
17581763 ComposefsBootEntry :: Type1 ( ..) => unimplemented ! ( ) ,
17591764 ComposefsBootEntry :: Type2 ( ..) => unimplemented ! ( ) ,
@@ -1763,14 +1768,45 @@ pub(crate) fn setup_composefs_bls_boot(
17631768 let boot_digest = compute_boot_digest ( usr_lib_modules_vmlinuz, & repo)
17641769 . context ( "Computing boot digest" ) ?;
17651770
1771+ // Every update should have its own /usr/lib/os-release
1772+ let ( dir, fname) = fs
1773+ . root
1774+ . split ( OsStr :: new ( "/usr/lib/os-release" ) )
1775+ . context ( "Getting /usr/lib/os-release" ) ?;
1776+
1777+ let os_release = dir. get_file_opt ( fname) . context ( "Getting /usr/lib/os-release" ) ?;
1778+
1779+ let version = os_release. and_then ( |os_rel_file| {
1780+ let file_contents = match read_file ( os_rel_file, & repo) {
1781+ Ok ( c) => c,
1782+ Err ( e) => {
1783+ tracing:: warn!( "Could not read /usr/lib/os-release: {e:?}" ) ;
1784+ return None ;
1785+ }
1786+ } ;
1787+
1788+ let file_contents = match std:: str:: from_utf8 ( & file_contents) {
1789+ Ok ( c) => c,
1790+ Err ( ..) => {
1791+ tracing:: warn!( "/usr/lib/os-release did not have valid UTF-8" ) ;
1792+ return None ;
1793+ }
1794+ } ;
1795+
1796+ OsReleaseInfo :: parse ( file_contents) . get_version ( )
1797+ } ) ;
1798+
1799+ let default_sort_key = "1" ;
1800+
17661801 let mut bls_config = BLSConfig :: default ( ) ;
1767- bls_config. title = Some ( id_hex. clone ( ) ) ;
1768- bls_config. sort_key = Some ( "1" . into ( ) ) ;
1769- bls_config. machine_id = None ;
1770- bls_config. linux = format ! ( "/{EFI_LINUX}/{id_hex}/vmlinuz" ) ;
1771- bls_config. initrd = vec ! [ format!( "/{EFI_LINUX}/{id_hex}/initrd" ) ] ;
1772- bls_config. options = Some ( cmdline_refs) ;
1773- bls_config. extra = HashMap :: new ( ) ;
1802+
1803+ bls_config
1804+ . with_title ( id_hex. clone ( ) )
1805+ . with_sort_key ( default_sort_key. into ( ) )
1806+ . with_version ( version. unwrap_or ( default_sort_key. into ( ) ) )
1807+ . with_linux ( format ! ( "/{EFI_LINUX}/{id_hex}/vmlinuz" ) )
1808+ . with_initrd ( vec ! [ format!( "/{EFI_LINUX}/{id_hex}/initrd" ) ] )
1809+ . with_options ( cmdline_refs) ;
17741810
17751811 if let Some ( symlink_to) = find_vmlinuz_initrd_duplicates ( & boot_digest) ? {
17761812 bls_config. linux = format ! ( "/{EFI_LINUX}/{symlink_to}/vmlinuz" ) ;
@@ -1877,7 +1913,7 @@ pub(crate) fn setup_composefs_uki_boot(
18771913 entry : ComposefsBootEntry < Sha256HashValue > ,
18781914) -> Result < ( ) > {
18791915 let ( root_path, esp_device, is_insecure_from_opts) = match setup_type {
1880- BootSetupType :: Setup ( ( root_setup, state) ) => {
1916+ BootSetupType :: Setup ( ( root_setup, state, .. ) ) => {
18811917 if let Some ( v) = & state. config_opts . karg {
18821918 if v. len ( ) > 0 {
18831919 tracing:: warn!( "kargs passed for UKI will be ignored" ) ;
@@ -1898,7 +1934,7 @@ pub(crate) fn setup_composefs_uki_boot(
18981934 )
18991935 }
19001936
1901- BootSetupType :: Upgrade => {
1937+ BootSetupType :: Upgrade ( .. ) => {
19021938 let sysroot = Utf8PathBuf :: from ( "/sysroot" ) ;
19031939
19041940 let fsinfo = inspect_filesystem ( & sysroot) ?;
@@ -1990,7 +2026,7 @@ pub(crate) fn setup_composefs_uki_boot(
19902026 let boot_dir = root_path. join ( "boot" ) ;
19912027 create_dir_all ( & boot_dir) . context ( "Failed to create boot dir" ) ?;
19922028
1993- let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ) ;
2029+ let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ( .. ) ) ;
19942030
19952031 let efi_uuid_source = get_efi_uuid_source ( ) ;
19962032
@@ -2078,6 +2114,7 @@ pub(crate) async fn pull_composefs_repo(
20782114 ComposefsRepository < Sha256HashValue > ,
20792115 Vec < ComposefsBootEntry < Sha256HashValue > > ,
20802116 Sha256HashValue ,
2117+ FileSystem < Sha256HashValue > ,
20812118) > {
20822119 let rootfs_dir = cap_std:: fs:: Dir :: open_ambient_dir ( "/sysroot" , cap_std:: ambient_authority ( ) ) ?;
20832120
@@ -2101,7 +2138,7 @@ pub(crate) async fn pull_composefs_repo(
21012138 let entries = fs. transform_for_boot ( & repo) ?;
21022139 let id = fs. commit_image ( & repo, None ) ?;
21032140
2104- Ok ( ( repo, entries, id) )
2141+ Ok ( ( repo, entries, id, fs ) )
21052142}
21062143
21072144#[ context( "Setting up composefs boot" ) ]
@@ -2140,7 +2177,7 @@ fn setup_composefs_boot(root_setup: &RootSetup, state: &State, image_id: &str) -
21402177 match boot_type {
21412178 BootType :: Bls => {
21422179 let digest = setup_composefs_bls_boot (
2143- BootSetupType :: Setup ( ( & root_setup, & state) ) ,
2180+ BootSetupType :: Setup ( ( & root_setup, & state, & fs ) ) ,
21442181 repo,
21452182 & id,
21462183 entry,
@@ -2149,7 +2186,7 @@ fn setup_composefs_boot(root_setup: &RootSetup, state: &State, image_id: &str) -
21492186 boot_digest = Some ( digest) ;
21502187 }
21512188 BootType :: Uki => setup_composefs_uki_boot (
2152- BootSetupType :: Setup ( ( & root_setup, & state) ) ,
2189+ BootSetupType :: Setup ( ( & root_setup, & state, & fs ) ) ,
21532190 repo,
21542191 & id,
21552192 entry,
@@ -2285,7 +2322,7 @@ async fn install_to_filesystem_impl(
22852322 // Load a fd for the mounted target physical root
22862323 let ( id, verity) = initialize_composefs_repository ( state, rootfs) . await ?;
22872324
2288- tracing:: warn !(
2325+ tracing:: info !(
22892326 "id = {id}, verity = {verity}" ,
22902327 id = hex:: encode( id) ,
22912328 verity = verity. to_hex( )
0 commit comments