diff --git a/crates/integration-tests/src/tests/run_ephemeral_ssh.rs b/crates/integration-tests/src/tests/run_ephemeral_ssh.rs index c257bbc..7470bbe 100644 --- a/crates/integration-tests/src/tests/run_ephemeral_ssh.rs +++ b/crates/integration-tests/src/tests/run_ephemeral_ssh.rs @@ -70,6 +70,22 @@ fn build_broken_image() -> anyhow::Result { Ok(image_name) } +/// Test the `ephemeral test-basic` subcommand +/// +/// Verifies that `bcvk ephemeral test-basic` boots a VM and confirms +/// systemd reached a healthy "running" state via `systemctl is-system-running`. +fn test_ephemeral_test_basic() -> TestResult { + let sh = shell()?; + let bck = get_bck_command()?; + let image = get_test_image(); + let label = INTEGRATION_TEST_LABEL; + + cmd!(sh, "{bck} ephemeral test-basic --label {label} {image}").run()?; + + Ok(()) +} +integration_test!(test_ephemeral_test_basic); + /// Test running a non-interactive command via SSH fn test_run_ephemeral_ssh_command() -> TestResult { let sh = shell()?; diff --git a/crates/kit/src/ephemeral.rs b/crates/kit/src/ephemeral.rs index 652a335..79b9794 100644 --- a/crates/kit/src/ephemeral.rs +++ b/crates/kit/src/ephemeral.rs @@ -62,6 +62,13 @@ pub struct ContainerListEntry { pub command: Vec, } +/// Options for the test-basic subcommand +#[derive(clap::Parser, Debug)] +pub struct TestBasicOpts { + #[command(flatten)] + pub run_opts: run_ephemeral::RunEphemeralOpts, +} + /// Ephemeral VM operations #[derive(Debug, Subcommand)] pub enum EphemeralCommands { @@ -73,6 +80,10 @@ pub enum EphemeralCommands { #[clap(name = "run-ssh")] RunSsh(run_ephemeral_ssh::RunEphemeralSshOpts), + /// Boot an ephemeral VM and verify systemd is healthy + #[clap(name = "test-basic")] + TestBasic(TestBasicOpts), + /// Connect to running VMs via SSH #[clap(name = "ssh")] Ssh(SshOpts), @@ -100,6 +111,17 @@ impl EphemeralCommands { match self { EphemeralCommands::Run(opts) => run_ephemeral::run(opts), EphemeralCommands::RunSsh(opts) => run_ephemeral_ssh::run_ephemeral_ssh(opts), + EphemeralCommands::TestBasic(opts) => { + let ssh_opts = run_ephemeral_ssh::RunEphemeralSshOpts { + run_opts: opts.run_opts, + ssh_args: vec![ + "systemctl".to_string(), + "is-system-running".to_string(), + "--wait".to_string(), + ], + }; + run_ephemeral_ssh::run_ephemeral_ssh(ssh_opts) + } EphemeralCommands::Ssh(opts) => { // Create progress bar if stderr is a terminal let progress_bar = crate::boot_progress::create_boot_progress_bar(); diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 7b5b317..c69ec36 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -14,6 +14,7 @@ - [ephemeral run](./man/bcvk-ephemeral-run.md) - [ephemeral ssh](./man/bcvk-ephemeral-ssh.md) - [ephemeral run-ssh](./man/bcvk-ephemeral-run-ssh.md) + - [ephemeral test-basic](./man/bcvk-ephemeral-test-basic.md) - [to-disk](./man/bcvk-to-disk.md) - [images](./man/bcvk-images.md) - [images list](./man/bcvk-images-list.md) diff --git a/docs/src/man/bcvk-ephemeral-test-basic.md b/docs/src/man/bcvk-ephemeral-test-basic.md new file mode 100644 index 0000000..2af4446 --- /dev/null +++ b/docs/src/man/bcvk-ephemeral-test-basic.md @@ -0,0 +1,52 @@ +# NAME + +bcvk-ephemeral-test-basic - Boot an ephemeral VM and verify systemd is healthy + +# SYNOPSIS + +**bcvk ephemeral test-basic** \[*OPTIONS*\] *IMAGE* + +# DESCRIPTION + +Boot an ephemeral VM from **IMAGE** and verify that systemd reached a healthy +state by running **systemctl is-system-running --wait** via SSH. + +This is a quick smoke test for bootc container images. The **--wait** flag +ensures systemd has finished booting before reporting status. The command +exits 0 if systemd reports "running" (all units healthy), or non-zero if +the system is degraded or failed. + +Internally this is equivalent to: + + bcvk ephemeral run-ssh IMAGE -- systemctl is-system-running --wait + +The VM is automatically cleaned up after the check completes. + +# OPTIONS + + +Accepts the same options as **bcvk-ephemeral-run**(8). + + +# EXAMPLES + +Smoke test a Fedora bootc image: + + bcvk ephemeral test-basic quay.io/fedora/fedora-bootc:42 + +Test a locally built image: + + podman build -t localhost/mybootc . + bcvk ephemeral test-basic localhost/mybootc + +Test with custom resources: + + bcvk ephemeral test-basic --memory 4096 --vcpus 2 localhost/mybootc + +# SEE ALSO + +**bcvk-ephemeral**(8), **bcvk-ephemeral-run-ssh**(8) + +# VERSION + + diff --git a/docs/src/man/bcvk-ephemeral.md b/docs/src/man/bcvk-ephemeral.md index d1d27a4..2f9a2f5 100644 --- a/docs/src/man/bcvk-ephemeral.md +++ b/docs/src/man/bcvk-ephemeral.md @@ -54,6 +54,10 @@ bcvk-ephemeral-ps(8) : List running ephemeral VMs +bcvk-ephemeral-test-basic(8) + +: Boot an ephemeral VM and verify systemd is healthy + bcvk-ephemeral-rm-all(8) : Remove all ephemeral VM containers @@ -123,7 +127,7 @@ Or use instance types: # SEE ALSO **bcvk**(8), **bcvk-ephemeral-run**(8), **bcvk-ephemeral-run-ssh**(8), -**bcvk-ephemeral-ssh**(8), **bcvk-libvirt**(8) +**bcvk-ephemeral-test-basic**(8), **bcvk-ephemeral-ssh**(8), **bcvk-libvirt**(8) # VERSION