Skip to content

Commit 6817ba7

Browse files
install/composefs: Put UKI in the ESP
Instead of putting the UKI in `/boot` in the root partition, this commit moves it to the ESP. Update grub user.cfg and pass the disk UUID to `--fs-uuid` Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent f75689c commit 6817ba7

File tree

1 file changed

+64
-10
lines changed

1 file changed

+64
-10
lines changed

crates/lib/src/install.rs

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::fs::create_dir_all;
1818
use std::io::Write;
1919
use std::os::fd::{AsFd, AsRawFd};
2020
use std::os::unix::process::CommandExt;
21-
use std::path::Path;
21+
use std::path::{Path, PathBuf};
2222
use std::process::Command;
2323
use std::str::FromStr;
2424
use std::sync::Arc;
@@ -108,6 +108,10 @@ const DEFAULT_REPO_CONFIG: &[(&str, &str)] = &[
108108
/// Kernel argument used to specify we want the rootfs mounted read-write by default
109109
const RW_KARG: &str = "rw";
110110

111+
/// The ESP partition label on Fedora CoreOS derivatives
112+
const COREOS_ESP_PART_LABEL: &str = "EFI-SYSTEM";
113+
const ANACONDA_ESP_PART_LABEL: &str = "EFI\\x20System\\x20Partition";
114+
111115
#[derive(clap::Args, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
112116
pub(crate) struct InstallTargetOpts {
113117
// TODO: A size specifier which allocates free space for the root in *addition* to the base container image size
@@ -1533,6 +1537,44 @@ fn setup_composefs_bls_boot(
15331537
Ok(())
15341538
}
15351539

1540+
fn get_esp_device() -> Option<PathBuf> {
1541+
let esp_devices = [COREOS_ESP_PART_LABEL, ANACONDA_ESP_PART_LABEL]
1542+
.into_iter()
1543+
.map(|p| Path::new("/dev/disk/by-partlabel/").join(p));
1544+
let mut esp_device = None;
1545+
for path in esp_devices {
1546+
if path.exists() {
1547+
esp_device = Some(path);
1548+
break;
1549+
}
1550+
}
1551+
return esp_device;
1552+
}
1553+
1554+
/// esp_device - /dev/disk/by-partlabel/<ESP_DEVICE>
1555+
fn get_esp_uuid(esp_device: &PathBuf) -> Result<String> {
1556+
// not using blkid here as the output might change from under us
1557+
let resolved = std::fs::canonicalize(esp_device)
1558+
.with_context(|| format!("Failed to resolve link {esp_device:?}"))?;
1559+
1560+
let mut uuid = String::new();
1561+
1562+
for dir_entry in std::fs::read_dir("/dev/disk/by-uuid")? {
1563+
let file = dir_entry?;
1564+
1565+
let uuid_resolve = std::fs::canonicalize(file.path())
1566+
.with_context(|| format!("Failed to resolve link {file:?}"))?;
1567+
1568+
if resolved == uuid_resolve {
1569+
// SAFETY: UUID has to be [A-Fa-f0-9\-]
1570+
uuid = file.file_name().to_string_lossy().into_owned();
1571+
break;
1572+
}
1573+
}
1574+
1575+
Ok(uuid)
1576+
}
1577+
15361578
#[context("Setting up UKI boot")]
15371579
fn setup_composefs_uki_boot(
15381580
root_setup: &RootSetup,
@@ -1541,35 +1583,47 @@ fn setup_composefs_uki_boot(
15411583
id: &Sha256HashValue,
15421584
entry: BootEntry<Sha256HashValue>,
15431585
) -> Result<()> {
1544-
let rootfs_uuid = match &root_setup.rootfs_uuid {
1545-
Some(u) => u,
1546-
None => anyhow::bail!("Expected rootfs to have a UUID by now"),
1586+
// Write the UKI to <ESP>/EFI/Linux
1587+
let Some(esp_device) = get_esp_device() else {
1588+
anyhow::bail!("ESP device not found");
15471589
};
15481590

1549-
let boot_dir = root_setup.physical_root_path.join("boot");
1550-
create_dir_all(&boot_dir).context("Failed to create boot dir")?;
1591+
let mounted_esp: PathBuf = root_setup.physical_root_path.join("../esp").into();
1592+
create_dir_all(&mounted_esp).context("Failed to create dir {mounted_esp:?}")?;
1593+
1594+
Task::new("Mounting ESP", "mount")
1595+
.args([&esp_device, &mounted_esp.clone()])
1596+
.run()?;
15511597

15521598
composefs_write_boot_simple(
15531599
&repo,
15541600
entry,
15551601
&id,
1556-
boot_dir.as_std_path(),
1602+
&mounted_esp,
15571603
None,
15581604
Some(&format!("{}", id.to_hex())),
15591605
&[],
15601606
)?;
15611607

1608+
Task::new("Unmounting ESP", "umount")
1609+
.arg(mounted_esp)
1610+
.run()?;
1611+
1612+
let boot_dir = root_setup.physical_root_path.join("boot");
1613+
create_dir_all(&boot_dir).context("Failed to create boot dir")?;
1614+
15621615
// Add the user grug cfg
15631616
let grub_user_config = format!(
15641617
r#"
15651618
menuentry "Fedora Bootc UKI" {{
15661619
insmod fat
15671620
insmod chain
1568-
search --no-floppy --set=root --fs-uuid {rootfs_uuid}
1569-
chainloader /boot/EFI/Linux/{uki_id}.efi
1621+
search --no-floppy --set=root --fs-uuid {esp_uuid}
1622+
chainloader /EFI/Linux/{uki_id}.efi
15701623
}}
15711624
"#,
1572-
uki_id = id.to_hex()
1625+
uki_id = id.to_hex(),
1626+
esp_uuid = get_esp_uuid(&esp_device)?
15731627
);
15741628

15751629
std::fs::write(boot_dir.join("grub2/user.cfg"), grub_user_config)

0 commit comments

Comments
 (0)