Skip to content

Commit e9c7113

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 7e5c8f5 commit e9c7113

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;
@@ -121,6 +122,7 @@ impl Component for Bios {
121122
meta,
122123
filetree: None,
123124
adopted_from: None,
125+
firmware: BTreeMap::new(),
124126
})
125127
}
126128

@@ -235,6 +237,7 @@ impl Component for Bios {
235237
meta: update.clone(),
236238
filetree: None,
237239
adopted_from: Some(meta.version),
240+
firmware: BTreeMap::new(),
238241
}))
239242
}
240243

@@ -257,6 +260,7 @@ impl Component for Bios {
257260
meta: updatemeta,
258261
filetree: None,
259262
adopted_from,
263+
firmware: BTreeMap::new(),
260264
})
261265
}
262266

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;
@@ -328,6 +329,7 @@ impl Component for Efi {
328329
meta: updatemeta.clone(),
329330
filetree: Some(updatef),
330331
adopted_from: Some(meta.version),
332+
firmware: BTreeMap::new(),
331333
}))
332334
}
333335

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

@@ -424,6 +481,7 @@ impl Component for Efi {
424481
meta: updatemeta,
425482
filetree: Some(updatef),
426483
adopted_from,
484+
firmware: BTreeMap::new(),
427485
})
428486
}
429487

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)