diff --git a/src/bootupd.rs b/src/bootupd.rs index b7828691..36ea0c4b 100644 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -212,6 +212,20 @@ pub(crate) fn get_components() -> Components { get_components_impl(false) } +/// Return available components +#[context("Get available components")] +pub(crate) fn get_available_components(sysroot: &openat::Dir) -> Result { + let mut avail = BTreeMap::new(); + + for (name, component) in get_components_impl(false) { + if crate::component::get_component_update(sysroot, component.as_ref())?.is_some() { + avail.insert(name, component); + } + } + + Ok(avail) +} + pub(crate) fn generate_update_metadata(sysroot_path: &str) -> Result<()> { // create bootupd update dir which will save component metadata files for both components let updates_dir = Path::new(sysroot_path).join(crate::model::BOOTUPD_UPDATES_DIR); diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 1c30b24e..56e91466 100644 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -1,5 +1,5 @@ use crate::bootupd; -use anyhow::Result; +use anyhow::{Context, Result}; use clap::Parser; use log::LevelFilter; @@ -214,20 +214,23 @@ fn ensure_running_in_systemd() -> Result<()> { /// If running in container, just print the available payloads fn run_status_in_container(json_format: bool) -> Result<()> { - let all_components = crate::bootupd::get_components(); - if all_components.is_empty() { - return Ok(()); - } - let avail: Vec<_> = all_components.keys().cloned().collect(); + let sysroot = openat::Dir::open("/").context("opening sysroot directory /")?; + + let avail: Vec<_> = crate::bootupd::get_available_components(&sysroot)? + .into_keys() + .collect(); + if json_format { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); - let output: serde_json::Value = serde_json::json!({ + let output = serde_json::json!({ "components": avail }); serde_json::to_writer(&mut stdout, &output)?; } else { - println!("Available components: {}", avail.join(" ")); + if !avail.is_empty() { + println!("Available components: {}", avail.join(" ")); + } } Ok(()) } diff --git a/tests/tests/bootupctl-status-in-bootc.sh b/tests/tests/bootupctl-status-in-bootc.sh index 180163d0..a9488ca5 100755 --- a/tests/tests/bootupctl-status-in-bootc.sh +++ b/tests/tests/bootupctl-status-in-bootc.sh @@ -7,22 +7,41 @@ if [ ! -d "/sysroot/ostree/repo/" ]; then exit 100 fi +components_text_x86_64='Available components: BIOS EFI' +components_json_x86_64='{"components":["BIOS","EFI"]}' + +components_text_aarch64='Available components: EFI' +components_json_aarch64='{"components":["EFI"]}' + +none_components_json='{"components":[]}' + # check if running in container if [ "$container" ] || [ -f /run/.containerenv ] || [ -f /.dockerenv ]; then arch="$(uname --machine)" - if [[ "${arch}" == "x86_64" ]]; then - components_text='Available components: BIOS EFI' - components_json='{"components":["BIOS","EFI"]}' - else - # Assume aarch64 for now - components_text='Available components: EFI' - components_json='{"components":["EFI"]}' + output_text=$(bootupctl status | tr -d '\r') + output_json=$(bootupctl status --json) + + if [ "${arch}" == "x86_64" ]; then + [ "${components_text_x86_64}" == "${output_text}" ] + [ "${components_json_x86_64}" == "${output_json}" ] + # test if BIOS.json is missing + mv /usr/lib/bootupd/updates/BIOS.json{,-bak} + output_text=$(bootupctl status | tr -d '\r') + output_json=$(bootupctl status --json) fi - output=$(bootupctl status | tr -d '\r') - [ "${components_text}" == "${output}" ] - output=$(bootupctl status --json) - [ "${components_json}" == "${output}" ] + if [ "${arch}" == "x86_64" ] || [ "${arch}" == "aarch64" ]; then + [ "${components_text_aarch64}" == "${output_text}" ] + [ "${components_json_aarch64}" == "${output_json}" ] + fi + + # test if no components + mv /usr/lib/bootupd/updates/EFI.json{,-bak} + output_text=$(bootupctl status | tr -d '\r') + output_json=$(bootupctl status --json) + [ -z "${output_text}" ] + [ "${none_components_json}" == "${output_json}" ] + else echo "Skip running as not in container" fi