From 965faf9f1cce072a56568e6f23757df1ae238bba Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 20 Sep 2023 17:16:49 -0400 Subject: [PATCH] install: Add support for selecting components So one can use e.g. `--component=EFI` to only install UEFI. --- src/bootupd.rs | 34 +++++++++++++++++++++++++++++----- src/cli/bootupd.rs | 18 ++++++++++++++---- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/bootupd.rs b/src/bootupd.rs index 0266a736..e4e2fd19 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -26,21 +26,45 @@ pub(crate) enum ClientRequest { Status, } -pub(crate) fn install(source_root: &str, dest_root: &str, device: &str) -> Result<()> { +pub(crate) fn install( + source_root: &str, + dest_root: &str, + device: Option<&str>, + target_components: Option<&[String]>, +) -> Result<()> { + // TODO: Change this to an Option<&str>; though this probably balloons into having + // DeviceComponent and FileBasedComponent + let device = device.unwrap_or(""); let source_root = openat::Dir::open(source_root)?; SavedState::ensure_not_present(dest_root) .context("failed to install, invalid re-install attempted")?; - let components = get_components(); - if components.is_empty() { + let all_components = get_components(); + if all_components.is_empty() { println!("No components available for this platform."); return Ok(()); } + let target_components = if let Some(target_components) = target_components { + target_components + .iter() + .map(|name| { + all_components + .get(name.as_str()) + .ok_or_else(|| anyhow!("Unknown component: {name}")) + }) + .collect::>>()? + } else { + all_components.values().collect() + }; + + if target_components.is_empty() { + anyhow::bail!("No components specified"); + } let mut state = SavedState::default(); - for component in components.values() { + for component in target_components { // skip for BIOS if device is empty - if component.name() == "BIOS" && device.trim().is_empty() { + if component.name() == "BIOS" && device.is_empty() { println!( "Skip installing component {} without target device", component.name() diff --git a/src/cli/bootupd.rs b/src/cli/bootupd.rs index 2a643779..a15563ae 100644 --- a/src/cli/bootupd.rs +++ b/src/cli/bootupd.rs @@ -47,9 +47,14 @@ pub struct InstallOpts { /// Target root #[clap(value_parser)] dest_root: String, + /// Target device, used by bios bootloader installation - #[clap(long, value_parser, default_value_t = String::from(""))] - device: String, + #[clap(long)] + device: Option, + + #[clap(long = "component")] + /// Only install these components + components: Option>, } #[derive(Debug, Parser)] @@ -77,8 +82,13 @@ impl DCommand { /// Runner for `install` verb. pub(crate) fn run_install(opts: InstallOpts) -> Result<()> { - bootupd::install(&opts.src_root, &opts.dest_root, &opts.device) - .context("boot data installation failed")?; + bootupd::install( + &opts.src_root, + &opts.dest_root, + opts.device.as_deref(), + opts.components.as_deref(), + ) + .context("boot data installation failed")?; Ok(()) } }