Skip to content

Commit d25c78d

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 26352a5 commit d25c78d

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;
@@ -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
@@ -1540,6 +1544,44 @@ fn setup_composefs_bls_boot(
15401544
Ok(())
15411545
}
15421546

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

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

15591605
composefs_write_boot_simple(
15601606
&repo,
15611607
entry,
15621608
&id,
1563-
boot_dir.as_std_path(),
1609+
&mounted_esp,
15641610
None,
15651611
Some(&format!("{}", id.to_hex())),
15661612
&[],
15671613
)?;
15681614

1615+
Task::new("Unmounting ESP", "umount")
1616+
.arg(mounted_esp)
1617+
.run()?;
1618+
1619+
let boot_dir = root_setup.physical_root_path.join("boot");
1620+
create_dir_all(&boot_dir).context("Failed to create boot dir")?;
1621+
15691622
// Add the user grug cfg
15701623
let grub_user_config = format!(
15711624
r#"
15721625
menuentry "Fedora Bootc UKI" {{
15731626
insmod fat
15741627
insmod chain
1575-
search --no-floppy --set=root --fs-uuid {rootfs_uuid}
1576-
chainloader /boot/EFI/Linux/{uki_id}.efi
1628+
search --no-floppy --set=root --fs-uuid {esp_uuid}
1629+
chainloader /EFI/Linux/{uki_id}.efi
15771630
}}
15781631
"#,
1579-
uki_id = id.to_hex()
1632+
uki_id = id.to_hex(),
1633+
esp_uuid = get_esp_uuid(&esp_device)?
15801634
);
15811635

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

0 commit comments

Comments
 (0)