Skip to content

Commit 9847935

Browse files
Minor fixes and refactoring
Use UTF8Path in BLSConfig Use `ok_or_else` so error objects are lazily evaluated Add tests for `get_imgref` Update UKI path for systemd-boot to `EFI/Linux/bootc` Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent 561f71f commit 9847935

File tree

5 files changed

+75
-36
lines changed

5 files changed

+75
-36
lines changed

crates/lib/src/bootc_composefs/boot.rs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
use std::ffi::OsStr;
12
use std::fs::create_dir_all;
23
use std::io::Write;
34
use std::path::Path;
4-
use std::{ffi::OsStr, path::PathBuf};
55

66
use anyhow::{anyhow, Context, Result};
77
use bootc_blockdev::find_parent_devices;
@@ -64,7 +64,7 @@ const SYSTEMD_LOADER_CONF_PATH: &str = "loader/loader.conf";
6464
/// directory specified by the BLS spec. We do this because we want systemd-boot to only look at
6565
/// our config files and not show the actual UKIs in the bootloader menu
6666
/// This is relative to the ESP
67-
const SYSTEMD_UKI_DIR: &str = "EFI/Linux/uki";
67+
const SYSTEMD_UKI_DIR: &str = "EFI/Linux/bootc";
6868

6969
pub(crate) enum BootSetupType<'a> {
7070
/// For initial setup, i.e. install to-disk
@@ -460,8 +460,10 @@ pub(crate) fn setup_composefs_bls_boot(
460460
.with_sort_key(default_sort_key.into())
461461
.with_version(version)
462462
.with_cfg(BLSConfigType::NonEFI {
463-
linux: format!("/{}/{id_hex}/vmlinuz", entry_paths.abs_entries_path),
464-
initrd: vec![format!("/{}/{id_hex}/initrd", entry_paths.abs_entries_path)],
463+
linux: format!("/{}/{id_hex}/vmlinuz", entry_paths.abs_entries_path).into(),
464+
initrd: vec![
465+
format!("/{}/{id_hex}/initrd", entry_paths.abs_entries_path).into()
466+
],
465467
options: Some(cmdline_refs),
466468
});
467469

@@ -474,12 +476,14 @@ pub(crate) fn setup_composefs_bls_boot(
474476
..
475477
} => {
476478
*linux =
477-
format!("/{}/{symlink_to}/vmlinuz", entry_paths.abs_entries_path);
479+
format!("/{}/{symlink_to}/vmlinuz", entry_paths.abs_entries_path)
480+
.into();
478481

479482
*initrd = vec![format!(
480483
"/{}/{symlink_to}/initrd",
481484
entry_paths.abs_entries_path
482-
)];
485+
)
486+
.into()];
483487
}
484488

485489
_ => unreachable!(),
@@ -549,7 +553,7 @@ pub(crate) fn setup_composefs_bls_boot(
549553
fn write_pe_to_esp(
550554
repo: &ComposefsRepository<Sha256HashValue>,
551555
file: &RegularFile<Sha256HashValue>,
552-
file_path: &PathBuf,
556+
file_path: &Utf8Path,
553557
pe_type: PEType,
554558
uki_id: &String,
555559
is_insecure_from_opts: bool,
@@ -600,7 +604,7 @@ fn write_pe_to_esp(
600604

601605
let final_pe_path = match file_path.parent() {
602606
Some(parent) => {
603-
let renamed_path = match parent.as_str()?.ends_with(EFI_ADDON_DIR_EXT) {
607+
let renamed_path = match parent.as_str().ends_with(EFI_ADDON_DIR_EXT) {
604608
true => {
605609
let dir_name = format!("{}{}", uki_id, EFI_ADDON_DIR_EXT);
606610

@@ -626,13 +630,12 @@ fn write_pe_to_esp(
626630
.with_context(|| format!("Opening {final_pe_path:?}"))?;
627631

628632
let pe_name = match pe_type {
629-
PEType::Uki => format!("{}{}", uki_id, EFI_EXT),
633+
PEType::Uki => &format!("{}{}", uki_id, EFI_EXT),
630634
PEType::UkiAddon => file_path
631635
.components()
632636
.last()
633-
.unwrap()
634-
.to_string_lossy()
635-
.to_string(),
637+
.ok_or_else(|| anyhow::anyhow!("Failed to get UKI Addon file name"))?
638+
.as_str(),
636639
};
637640

638641
pe_dir
@@ -750,7 +753,7 @@ fn write_systemd_uki_config(
750753
bls_conf
751754
.with_title(boot_label)
752755
.with_cfg(BLSConfigType::EFI {
753-
efi: format!("/{SYSTEMD_UKI_DIR}/{}{}", id.to_hex(), EFI_EXT),
756+
efi: format!("/{SYSTEMD_UKI_DIR}/{}{}", id.to_hex(), EFI_EXT).into(),
754757
})
755758
.with_sort_key(default_sort_key.into())
756759
// TODO (Johan-Liebert1): Get version from UKI like we get boot label
@@ -880,26 +883,27 @@ pub(crate) fn setup_composefs_uki_boot(
880883
.file_path
881884
.components()
882885
.last()
883-
.ok_or(anyhow::anyhow!("Could not get UKI addon name"))?;
886+
.ok_or_else(|| anyhow::anyhow!("Could not get UKI addon name"))?;
884887

885888
let addon_name = addon_name.as_str()?;
886889

887890
let addon_name =
888-
addon_name
889-
.strip_suffix(EFI_ADDON_FILE_EXT)
890-
.ok_or(anyhow::anyhow!(
891-
"UKI addon doesn't end with {EFI_ADDON_DIR_EXT}"
892-
))?;
891+
addon_name.strip_suffix(EFI_ADDON_FILE_EXT).ok_or_else(|| {
892+
anyhow::anyhow!("UKI addon doesn't end with {EFI_ADDON_DIR_EXT}")
893+
})?;
893894

894895
if !addons.iter().any(|passed_addon| passed_addon == addon_name) {
895896
continue;
896897
}
897898
}
898899

900+
let utf8_file_path = Utf8Path::from_path(&entry.file_path)
901+
.ok_or_else(|| anyhow::anyhow!("Path is not valid UTf8"))?;
902+
899903
let ret = write_pe_to_esp(
900904
&repo,
901905
&entry.file,
902-
&entry.file_path,
906+
utf8_file_path,
903907
entry.pe_type,
904908
&id.to_hex(),
905909
is_insecure_from_opts,

crates/lib/src/bootc_composefs/repo.rs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,15 @@ pub(crate) async fn initialize_composefs_repository(
6060
/// Ex
6161
/// docker://quay.io/some-image
6262
/// containers-storage:some-image
63-
pub(crate) fn get_imgref(transport: &String, image: &String) -> String {
63+
pub(crate) fn get_imgref(transport: &str, image: &str) -> String {
6464
let img = image.strip_prefix(":").unwrap_or(&image);
6565
let transport = transport.strip_suffix(":").unwrap_or(&transport);
6666

67-
let final_imgref = if transport == "registry" {
67+
if transport == "registry" {
6868
format!("docker://{img}")
6969
} else {
7070
format!("{transport}:{img}")
71-
};
72-
73-
final_imgref
71+
}
7472
}
7573

7674
/// Pulls the `image` from `transport` into a composefs repository at /sysroot
@@ -108,3 +106,39 @@ pub(crate) async fn pull_composefs_repo(
108106

109107
Ok((repo, entries, id, fs))
110108
}
109+
110+
#[cfg(test)]
111+
mod tests {
112+
use super::*;
113+
114+
const IMAGE_NAME: &str = "quay.io/example/image:latest";
115+
116+
#[test]
117+
fn test_get_imgref_registry_transport() {
118+
assert_eq!(
119+
get_imgref("registry:", IMAGE_NAME),
120+
format!("docker://{IMAGE_NAME}")
121+
);
122+
}
123+
124+
#[test]
125+
fn test_get_imgref_containers_storage() {
126+
assert_eq!(
127+
get_imgref("containers-storage", IMAGE_NAME),
128+
format!("containers-storage:{IMAGE_NAME}")
129+
);
130+
131+
assert_eq!(
132+
get_imgref("containers-storage:", IMAGE_NAME),
133+
format!("containers-storage:{IMAGE_NAME}")
134+
);
135+
}
136+
137+
#[test]
138+
fn test_get_imgref_edge_cases() {
139+
assert_eq!(
140+
get_imgref("registry", IMAGE_NAME),
141+
format!("docker://{IMAGE_NAME}")
142+
);
143+
}
144+
}

crates/lib/src/bootc_composefs/state.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ pub(crate) fn get_booted_bls(boot_dir: &Dir) -> Result<BLSConfig> {
4545
for entry in sorted_entries {
4646
match &entry.cfg_type {
4747
BLSConfigType::EFI { efi } => {
48-
let composfs_param_value = booted.value().ok_or(anyhow::anyhow!(
49-
"Failed to get composefs kernel cmdline value"
50-
))?;
48+
let composefs_param_value = booted.value().ok_or_else(|| {
49+
anyhow::anyhow!("Failed to get composefs kernel cmdline value")
50+
})?;
5151

52-
if efi.contains(composfs_param_value) {
52+
if efi.as_str().contains(composefs_param_value) {
5353
return Ok(entry);
5454
}
5555
}

crates/lib/src/bootc_composefs/status.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ pub(crate) async fn composefs_deployment_status() -> Result<Host> {
400400

401401
match &bls_config.cfg_type {
402402
// For UKI boot
403-
BLSConfigType::EFI { efi } => efi.contains(composefs_digest.as_ref()),
403+
BLSConfigType::EFI { efi } => efi.as_str().contains(composefs_digest.as_ref()),
404404

405405
// For boot entry Type1
406406
BLSConfigType::NonEFI { options, .. } => !options

crates/lib/src/parsers/bls_config.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![allow(dead_code)]
66

77
use anyhow::{anyhow, Result};
8+
use camino::Utf8PathBuf;
89
use core::fmt;
910
use std::collections::HashMap;
1011
use std::fmt::Display;
@@ -14,13 +15,13 @@ use uapi_version::Version;
1415
pub enum BLSConfigType {
1516
EFI {
1617
/// The path to the EFI binary, usually a UKI
17-
efi: String,
18+
efi: Utf8PathBuf,
1819
},
1920
NonEFI {
2021
/// The path to the linux kernel to boot.
21-
linux: String,
22+
linux: Utf8PathBuf,
2223
/// The paths to the initrd images.
23-
initrd: Vec<String>,
24+
initrd: Vec<Utf8PathBuf>,
2425
/// Kernel command line options.
2526
options: Option<String>,
2627
},
@@ -189,12 +190,12 @@ pub(crate) fn parse_bls_config(input: &str) -> Result<BLSConfig> {
189190
match key {
190191
"title" => title = Some(value),
191192
"version" => version = Some(value),
192-
"linux" => linux = Some(value),
193-
"initrd" => initrd.push(value),
193+
"linux" => linux = Some(Utf8PathBuf::from(value)),
194+
"initrd" => initrd.push(Utf8PathBuf::from(value)),
194195
"options" => options = Some(value),
195196
"machine-id" => machine_id = Some(value),
196197
"sort-key" => sort_key = Some(value),
197-
"efi" => efi = Some(value),
198+
"efi" => efi = Some(Utf8PathBuf::from(value)),
198199
_ => {
199200
extra.insert(key.to_string(), value);
200201
}

0 commit comments

Comments
 (0)