Skip to content

Commit 634cf2f

Browse files
committed
feat(extend_payload_to_esp):add payload to esp
bootup extend_payload_to_esp <path> will move the dir to esp This features gives user ability to able move any dir to esp through bootupd update and and appends metadata to efi. This will help in mounting uboot binaries to esp as required by rpi4. example usage: `bootupctl backend extend_payload_to_esp /usr/lib/mydata` will move the content of the dir to `usr/lib/bootupd/updates/EFI` and appends metadata to `/usr/lib/bootupd/updates/EFI.json`
1 parent f7b48bd commit 634cf2f

File tree

5 files changed

+74
-0
lines changed

5 files changed

+74
-0
lines changed

src/bios.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,7 @@ impl Component for Bios {
224224
fn get_efi_vendor(&self, _: &openat::Dir) -> Result<Option<String>> {
225225
Ok(None)
226226
}
227+
fn extend_payload(&self, _: &str, _: &str) -> Result<Option<bool>> {
228+
Ok(None)
229+
}
227230
}

src/cli/bootupctl.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ pub enum CtlBackend {
7373
Generate(super::bootupd::GenerateOpts),
7474
#[clap(name = "install", hide = true)]
7575
Install(super::bootupd::InstallOpts),
76+
#[clap(name = "extend-payload-to-esp", hide = true)]
77+
ExtendPayload(super::bootupd::ExtendPayloadOpts),
7678
}
7779

7880
#[derive(Debug, Parser)]
@@ -102,6 +104,9 @@ impl CtlCommand {
102104
CtlVerb::Backend(CtlBackend::Install(opts)) => {
103105
super::bootupd::DCommand::run_install(opts)
104106
}
107+
CtlVerb::Backend(CtlBackend::ExtendPayload(opts)) => {
108+
super::bootupd::DCommand::run_extend_payload(opts)
109+
}
105110
CtlVerb::MigrateStaticGrubConfig => Self::run_migrate_static_grub_config(),
106111
}
107112
}

src/cli/bootupd.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ pub enum DVerb {
3535
GenerateUpdateMetadata(GenerateOpts),
3636
#[clap(name = "install", about = "Install components")]
3737
Install(InstallOpts),
38+
#[clap(
39+
name = "extend-payload-to-esp",
40+
about = "Extend bootloader payload with additional files"
41+
)]
42+
ExtendPayload(ExtendPayloadOpts),
3843
}
3944

4045
#[derive(Debug, Parser)]
@@ -82,12 +87,20 @@ pub struct GenerateOpts {
8287
sysroot: Option<String>,
8388
}
8489

90+
#[derive(Debug, Parser)]
91+
pub struct ExtendPayloadOpts {
92+
/// Source directory containing files to add
93+
#[clap(value_parser)]
94+
src_root: String,
95+
}
96+
8597
impl DCommand {
8698
/// Run CLI application.
8799
pub fn run(self) -> Result<()> {
88100
match self.cmd {
89101
DVerb::Install(opts) => Self::run_install(opts),
90102
DVerb::GenerateUpdateMetadata(opts) => Self::run_generate_meta(opts),
103+
DVerb::ExtendPayload(opts) => Self::run_extend_payload(opts),
91104
}
92105
}
93106

@@ -122,4 +135,17 @@ impl DCommand {
122135
.context("boot data installation failed")?;
123136
Ok(())
124137
}
138+
139+
pub(crate) fn run_extend_payload(opts: ExtendPayloadOpts) -> Result<()> {
140+
let components = crate::bootupd::get_components();
141+
let sysroot = "/";
142+
for component in components.values() {
143+
if let Some(updated) = component.extend_payload(sysroot, &opts.src_root)? {
144+
if updated {
145+
println!("Extended payload for {} successfully", component.name());
146+
}
147+
}
148+
}
149+
Ok(())
150+
}
125151
}

src/component.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ pub(crate) trait Component {
7575

7676
/// Locating efi vendor dir
7777
fn get_efi_vendor(&self, sysroot: &openat::Dir) -> Result<Option<String>>;
78+
79+
/// Extending payload from input dir
80+
fn extend_payload(&self, sysroot: &str, src_root: &str) -> Result<Option<bool>>;
7881
}
7982

8083
/// Given a component name, create an implementation.

src/efi.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,43 @@ impl Component for Efi {
415415
Ok(meta)
416416
}
417417

418+
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);
421+
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()?;
437+
}
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+
452+
Ok(Some(true))
453+
}
454+
418455
fn query_update(&self, sysroot: &openat::Dir) -> Result<Option<ContentMetadata>> {
419456
get_component_update(sysroot, self)
420457
}

0 commit comments

Comments
 (0)