Skip to content

Commit d8e22ee

Browse files
committed
extends payload and stage for metadata update
moves content of input_dir /usr/lib/efi/firmware/<name>/<version>/EFI/boot/efi/
1 parent 9bac770 commit d8e22ee

File tree

1 file changed

+82
-32
lines changed

1 file changed

+82
-32
lines changed

src/efi.rs

Lines changed: 82 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::os::unix::io::AsRawFd;
99
use std::path::{Path, PathBuf};
1010
use std::process::Command;
1111

12-
use anyhow::{bail, Context, Result};
12+
use anyhow::{anyhow, bail, Context, Result};
1313
use cap_std::fs::Dir;
1414
use cap_std_ext::cap_std;
1515
use fn_error_context::context;
@@ -416,39 +416,89 @@ impl Component for Efi {
416416
}
417417

418418
fn extend_payload(&self, sysroot_path: &str, src_input: &str) -> Result<Option<bool>> {
419-
let ostreebootdir = Path::new(sysroot_path).join(ostreeutil::BOOT_PREFIX);
420-
let dest_efidir = component_updatedir(sysroot_path, self);
419+
let dest_efidir_base = Path::new(sysroot_path).join("usr/lib/efi").join("firmware");
420+
421+
// Fetch version and release from the source input using query_files
422+
let src_input_path = Path::new(src_input);
423+
let meta_from_src = packagesystem::query_files(sysroot_path, [src_input_path])
424+
.context(format!("Querying RPM metadata for {:?}", src_input_path))?;
425+
426+
let version_string_part = meta_from_src.version.splitn(2, ',').next()
427+
.ok_or_else(|| anyhow!(
428+
"RPM query returned an empty or malformed version string (no package name found in '{}').",
429+
meta_from_src.version
430+
))?;
431+
432+
let parts: Vec<&str> = version_string_part.split('-').collect();
433+
434+
let (pkg_name, version_release_str) = if parts.len() >= 3 {
435+
// Successfully extracted package name, version, and release
436+
let actual_pkg_name = parts[0];
437+
let version_part = parts[parts.len() - 2]; // version, e.g., "1.0"
438+
let release_part = parts[parts.len() - 1]
439+
.split('.')
440+
.next()
441+
.unwrap_or(parts[parts.len() - 1]); // release, e.g., "1" from "1.el8.noarch"
442+
(
443+
actual_pkg_name.to_string(),
444+
format!("{}-{}", version_part, release_part),
445+
)
446+
} else {
447+
return Err(anyhow!(
448+
"Unexpected RPM version string format: '{}'. Expected at least <pkg_name>-<version>-<release>.",
449+
version_string_part
450+
));
451+
};
421452

422-
// move files to staged updates
423-
if ostreebootdir.exists() {
424-
let cruft = ["loader", "grub2"];
425-
for p in cruft.iter() {
426-
let p = ostreebootdir.join(p);
427-
if p.exists() {
428-
std::fs::remove_dir_all(&p)?;
429-
}
430-
}
431-
// mv src data to /usr/lib_bootupd/updates/EFI
432-
let efisrc = ostreebootdir.join(src_input);
433-
if !efisrc.exists() {
434-
bail!("Failed to find {:?}", &efisrc);
435-
}
436-
Command::new("mv").args([&efisrc, &dest_efidir]).run()?;
453+
let final_dest_efi_path = dest_efidir_base
454+
.join(&pkg_name) // add the package name as a directory
455+
.join(&version_release_str)
456+
.join("EFI/boot/efi");
457+
458+
// Ensure the destination directory exists
459+
std::fs::create_dir_all(&final_dest_efi_path).with_context(|| {
460+
format!(
461+
"Failed to create destination directory {:?}",
462+
&final_dest_efi_path
463+
)
464+
})?;
465+
466+
let src_metadata = std::fs::metadata(src_input_path)
467+
.with_context(|| format!("Failed to get metadata for {:?}", src_input_path))?;
468+
469+
if src_metadata.is_dir() {
470+
log::debug!(
471+
"Copying contents of directory {:?} to {:?}",
472+
src_input,
473+
&final_dest_efi_path
474+
);
475+
Command::new("cp")
476+
.args([
477+
"-rp",
478+
&format!("{}/.", src_input),
479+
final_dest_efi_path.to_str().unwrap(),
480+
])
481+
.run()
482+
.with_context(|| {
483+
format!(
484+
"Failed to copy contents of {:?} to {:?}",
485+
src_input, &final_dest_efi_path
486+
)
487+
})?;
488+
} else if src_metadata.is_file() {
489+
log::debug!("Copying file {:?} to {:?}", src_input, &final_dest_efi_path);
490+
Command::new("cp")
491+
.args(["-p", src_input, final_dest_efi_path.to_str().unwrap()])
492+
.run()
493+
.with_context(|| {
494+
format!(
495+
"Failed to copy file {:?} to {:?}",
496+
src_input, &final_dest_efi_path
497+
)
498+
})?;
499+
} else {
500+
anyhow::bail!("Unsupported src_input type: {:?}", src_input);
437501
}
438-
439-
// canocinal path information parsed
440-
let efidir = openat::Dir::open(&dest_efidir)
441-
.with_context(|| format!("Opening {}", dest_efidir.display()))?;
442-
let files = crate::util::filenames(&efidir)?.into_iter().map(|mut f| {
443-
f.insert_str(0, src_input);
444-
f
445-
});
446-
447-
// writes EFI.JSON with the timestamp and version
448-
let meta =
449-
packagesystem::query_files(sysroot_path, files).context("Querying RPM metadata")?;
450-
write_update_metadata(sysroot_path, self, &meta)?;
451-
452502
Ok(Some(true))
453503
}
454504

0 commit comments

Comments
 (0)