Skip to content

Commit 8f47aa1

Browse files
committed
feat(efi::install)install from extend-payload-path
Added additional flow in efi::install to read from the path created by extend_payload_to_esp command and install to /boot/efi
1 parent 0e09130 commit 8f47aa1

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

src/bios.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use camino::Utf8PathBuf;
33
use openat_ext::OpenatDirExt;
44
#[cfg(target_arch = "powerpc64")]
55
use std::borrow::Cow;
6+
use std::collections::BTreeMap;
67
use std::io::prelude::*;
78
use std::path::Path;
89
use std::process::Command;
@@ -122,6 +123,7 @@ impl Component for Bios {
122123
meta,
123124
filetree: None,
124125
adopted_from: None,
126+
firmware: BTreeMap::new(),
125127
})
126128
}
127129

@@ -236,6 +238,7 @@ impl Component for Bios {
236238
meta: update.clone(),
237239
filetree: None,
238240
adopted_from: Some(meta.version),
241+
firmware: BTreeMap::new(),
239242
}))
240243
}
241244

@@ -258,6 +261,7 @@ impl Component for Bios {
258261
meta: updatemeta,
259262
filetree: None,
260263
adopted_from,
264+
firmware: BTreeMap::new(),
261265
})
262266
}
263267

src/efi.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
use std::cell::RefCell;
8+
use std::collections::BTreeMap;
89
use std::os::unix::io::AsRawFd;
910
use std::path::{Path, PathBuf};
1011
use std::process::Command;
@@ -332,6 +333,7 @@ impl Component for Efi {
332333
meta: updatemeta.clone(),
333334
filetree: Some(updatef),
334335
adopted_from: Some(meta.version),
336+
firmware: BTreeMap::new(),
335337
}))
336338
}
337339

@@ -376,15 +378,70 @@ impl Component for Efi {
376378
.arg(destpath)
377379
.current_dir(format!("/proc/self/fd/{}", src_root.as_raw_fd()))
378380
.run()?;
381+
382+
let mut found_firmware = BTreeMap::new();
383+
// Scan and install supplemental firmware
384+
let firmware_base_dir_path = Path::new("usr/lib/efi/firmware");
385+
if src_root.exists(firmware_base_dir_path)? {
386+
let firmware_base_dir = src_root.sub_dir(firmware_base_dir_path)?;
387+
for pkg_entry in firmware_base_dir.list_dir(".")?.flatten() {
388+
if firmware_base_dir.get_file_type(&pkg_entry)? != openat::SimpleType::Dir {
389+
continue;
390+
}
391+
let pkg_name = pkg_entry.file_name().to_string_lossy().to_string();
392+
let pkg_dir = firmware_base_dir.sub_dir(pkg_entry.file_name())?;
393+
394+
let mut versions: Vec<_> = pkg_dir.list_dir(".")?.filter_map(Result::ok).collect();
395+
versions.sort_by_key(|e| e.file_name().to_owned());
396+
397+
if let Some(ver_entry) = versions.pop() {
398+
let ver_dir = pkg_dir.sub_dir(ver_entry.file_name())?;
399+
let meta_path = Path::new("EFI.json");
400+
401+
if ver_dir.exists(meta_path)? {
402+
log::debug!(
403+
"Found supplemental firmware: {}/{}",
404+
pkg_name,
405+
ver_entry.file_name().to_string_lossy()
406+
);
407+
let firmware_meta: ContentMetadata =
408+
serde_json::from_reader(ver_dir.open_file(meta_path)?)?;
409+
let payload_src_dir = ver_dir.sub_dir("EFI")?;
410+
let firmware_filetree =
411+
crate::filetree::FileTree::new_from_dir(&payload_src_dir)?;
412+
// copy all by applying a diff with a empty filetree
413+
let empty_filetree = filetree::FileTree {
414+
children: Default::default(),
415+
};
416+
let diff = empty_filetree.diff(&firmware_filetree)?;
417+
filetree::apply_diff(&payload_src_dir, destd, &diff, None)
418+
.context("applying supplemental firmware")?;
419+
420+
found_firmware.insert(
421+
pkg_name.clone(),
422+
Box::new(InstalledContent {
423+
meta: firmware_meta,
424+
filetree: Some(firmware_filetree),
425+
adopted_from: None,
426+
firmware: BTreeMap::new(),
427+
}),
428+
);
429+
}
430+
}
431+
}
432+
}
433+
379434
if update_firmware {
380-
if let Some(vendordir) = self.get_efi_vendor(&src_root)? {
435+
if let Some(vendordir) = self.get_efi_vendor(src_root)? {
381436
self.update_firmware(device, destd, &vendordir)?
382437
}
383438
}
439+
384440
Ok(InstalledContent {
385441
meta,
386442
filetree: Some(ft),
387443
adopted_from: None,
444+
firmware: found_firmware,
388445
})
389446
}
390447

@@ -428,6 +485,7 @@ impl Component for Efi {
428485
meta: updatemeta,
429486
filetree: Some(updatef),
430487
adopted_from,
488+
firmware: BTreeMap::new(),
431489
})
432490
}
433491

src/model_legacy.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ pub(crate) struct InstalledContent01 {
3030
pub(crate) meta: ContentMetadata01,
3131
/// File tree
3232
pub(crate) filetree: Option<crate::filetree::FileTree>,
33+
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
34+
pub(crate) firmware: BTreeMap<String, Box<InstalledContent01>>,
3335
}
3436

3537
/// Will be serialized into /boot/bootupd-state.json
@@ -59,6 +61,11 @@ impl InstalledContent01 {
5961
meta: self.meta.upconvert(),
6062
filetree: self.filetree,
6163
adopted_from: None,
64+
firmware: self
65+
.firmware
66+
.into_iter()
67+
.map(|(k, v)| (k, Box::new(v.upconvert())))
68+
.collect(),
6269
}
6370
}
6471
}

0 commit comments

Comments
 (0)