From fa9aad708b30e3c08dd43b8ce809caf23133077d Mon Sep 17 00:00:00 2001 From: Benjamin Leggett Date: Fri, 17 Apr 2026 19:29:53 -0400 Subject: [PATCH 1/2] Add `collect` subcommand that only runs postinstall debug collection --- src/collect_cmd.rs | 41 +++++++++++++++++++++++++++++++++++++++++ src/main.rs | 19 +++++++++++++++++-- 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/collect_cmd.rs diff --git a/src/collect_cmd.rs b/src/collect_cmd.rs new file mode 100644 index 0000000..57e0703 --- /dev/null +++ b/src/collect_cmd.rs @@ -0,0 +1,41 @@ +use crate::{create_base_path, create_gzip_from, write_group_report}; +use edera_check::recorders::postinstall::system::SystemRecorder as postrecorder; + +use anyhow::{Result, anyhow}; +use console::style; +use edera_check::helpers::{CheckGroup, host_executor::HostNamespaceExecutor}; +use std::{env, path::PathBuf}; + +pub async fn do_collect(report_dir: Option) -> Result<()> { + let host_executor = HostNamespaceExecutor::new(); + + let groups: Vec> = vec![Box::new(postrecorder::new(host_executor.clone()))]; + + let hostname = host_executor + .spawn_in_host_ns(async { std::fs::read_to_string("/proc/sys/kernel/hostname").unwrap() }) + .await?; + + let base_dir = if let Some(dir) = report_dir { + PathBuf::from(dir) + } else { + env::temp_dir() + }; + + let base_path = create_base_path(base_dir, hostname.trim(), "collect") + .map_err(|e| anyhow!("failed to create bundle base path: {e}"))?; + + for group in groups { + println!( + "{} {} [{}] - {}", + style("Running Group").cyan(), + style(group.name()).cyan().bold(), + style(group.category()).white().bold(), + group.description() + ); + let result = group.run().await; + result.log_individual_checks(); + write_group_report(group, &result, &base_path)?; + } + + create_gzip_from(base_path, host_executor).await +} diff --git a/src/main.rs b/src/main.rs index 1e3702b..fc2fc80 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +mod collect_cmd; mod postinstall_cmd; mod preinstall_cmd; @@ -82,12 +83,25 @@ struct PostinstallArgs { report_dir: Option, } +#[derive(Args)] +struct CollectArgs { + /// Directory path to write report to. Will be created if it doesn't exist. Defaults to `/tmp` + #[arg(short = 'd', long)] + report_dir: Option, +} + #[derive(Subcommand)] enum Commands { - /// Run before installing Edera to validate hardware/host installation readiness. + #[command( + about = "Run before installing Edera to validate hardware/host installation readiness.\nAlso collects a system information snapshot." + )] Preinstall(PreinstallArgs), - /// Run after installing Edera to validate workload readiness. + #[command( + about = "Run after installing Edera to validate workload readiness.\nAlso collects a system information snapshot." + )] Postinstall(PostinstallArgs), + #[command(about = "Run after installing Edera to collect a system information snapshot.")] + Collect(CollectArgs), } #[tokio::main(flavor = "multi_thread", worker_threads = 10)] @@ -120,6 +134,7 @@ async fn main() -> Result<()> { ) .await } + Commands::Collect(args) => collect_cmd::do_collect(args.report_dir).await, } } From 1da61533adab52a1fbc22e5732df3624147ada80 Mon Sep 17 00:00:00 2001 From: Benjamin Leggett Date: Thu, 23 Apr 2026 15:05:22 -0400 Subject: [PATCH 2/2] README bump --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 38578f3..986a6d7 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,16 @@ Run this on a system that has been booted into an Edera installation to validate --- +### Generate system report + +```bash +sudo edera-check collect +``` + +Run this on a system that has been booted into an Edera installation to collect a system report, including logs and other useful troubleshooting information. + +--- + ## Example Output ```text