Skip to content

Commit edcf721

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 eac8e4d commit edcf721

File tree

1 file changed

+64
-10
lines changed

1 file changed

+64
-10
lines changed

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;
@@ -107,6 +107,10 @@ const DEFAULT_REPO_CONFIG: &[(&str, &str)] = &[
107107
/// Kernel argument used to specify we want the rootfs mounted read-write by default
108108
const RW_KARG: &str = "rw";
109109

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

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

1558-
let boot_dir = root_setup.physical_root_path.join("boot");
1559-
create_dir_all(&boot_dir).context("Failed to create boot dir")?;
1600+
let mounted_esp: PathBuf = root_setup.physical_root_path.join("../esp").into();
1601+
create_dir_all(&mounted_esp).context("Failed to create dir {mounted_esp:?}")?;
1602+
1603+
Task::new("Mounting ESP", "mount")
1604+
.args([&esp_device, &mounted_esp.clone()])
1605+
.run()?;
15601606

15611607
composefs_write_boot_simple(
15621608
&repo,
15631609
entry,
15641610
&id,
1565-
boot_dir.as_std_path(),
1611+
&mounted_esp,
15661612
None,
15671613
Some(&format!("{}", id.to_hex())),
15681614
&[],
15691615
)?;
15701616

1617+
Task::new("Unmounting ESP", "umount")
1618+
.arg(mounted_esp)
1619+
.run()?;
1620+
1621+
let boot_dir = root_setup.physical_root_path.join("boot");
1622+
create_dir_all(&boot_dir).context("Failed to create boot dir")?;
1623+
15711624
// Add the user grug cfg
15721625
let grub_user_config = format!(
15731626
r#"
15741627
menuentry "Fedora Bootc UKI" {{
15751628
insmod fat
15761629
insmod chain
1577-
search --no-floppy --set=root --fs-uuid {rootfs_uuid}
1578-
chainloader /boot/EFI/Linux/{uki_id}.efi
1630+
search --no-floppy --set=root --fs-uuid {esp_uuid}
1631+
chainloader /EFI/Linux/{uki_id}.efi
15791632
}}
15801633
"#,
1581-
uki_id = id.to_hex()
1634+
uki_id = id.to_hex(),
1635+
esp_uuid = get_esp_uuid(&esp_device)?
15821636
);
15831637

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

0 commit comments

Comments
 (0)