From e0301cd45a047765a54ff1c4cd680506bdcea850 Mon Sep 17 00:00:00 2001 From: ckyrouac Date: Thu, 5 Jun 2025 14:54:04 -0400 Subject: [PATCH] reinstall: Only pull the image if it's not already present This enables using a local image with system-reinstall-bootc. A couple drive by cleanups to the integration tests are included. Signed-off-by: ckyrouac --- .github/workflows/ci.yml | 4 +-- system-reinstall-bootc/src/main.rs | 5 +--- system-reinstall-bootc/src/podman.rs | 25 +++++++++++++++++- tests-integration/src/system_reinstall.rs | 31 ++++++++++++++++++++--- 4 files changed, 55 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 07b8d0bab..d04bb84e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -115,8 +115,8 @@ jobs: sudo mkdir -p /run/sshd sudo install -m 0755 target/release/system-reinstall-bootc /usr/bin/system-reinstall-bootc - sudo podman pull quay.io/fedora/fedora-bootc:42 - sudo bootc-integration-tests system-reinstall quay.io/fedora/fedora-bootc:42 --test-threads=1 + # These tests may mutate the system live so we can't run in parallel + sudo bootc-integration-tests system-reinstall localhost/bootc --test-threads=1 # And the fsverity case sudo podman run --privileged --pid=host localhost/bootc-fsverity bootc install to-existing-root --stateroot=other \ diff --git a/system-reinstall-bootc/src/main.rs b/system-reinstall-bootc/src/main.rs index c166f2dc6..7e45e4ccb 100644 --- a/system-reinstall-bootc/src/main.rs +++ b/system-reinstall-bootc/src/main.rs @@ -25,10 +25,7 @@ fn run() -> Result<()> { podman::ensure_podman_installed()?; //pull image early so it can be inspected, e.g. to check for cloud-init - let mut pull_image_command = podman::pull_image_command(&config.bootc_image); - pull_image_command - .run_with_cmd_context() - .context(format!("pulling image {}", &config.bootc_image))?; + podman::pull_if_not_present(&config.bootc_image)?; println!(); diff --git a/system-reinstall-bootc/src/podman.rs b/system-reinstall-bootc/src/podman.rs index e86973380..cc87fc500 100644 --- a/system-reinstall-bootc/src/podman.rs +++ b/system-reinstall-bootc/src/podman.rs @@ -96,12 +96,35 @@ pub(crate) fn reinstall_command(image: &str, ssh_key_file: &str) -> Result Command { +fn pull_image_command(image: &str) -> Command { let mut command = Command::new("podman"); command.args(["pull", image]); command } +fn image_exists_command(image: &str) -> Command { + let mut command = Command::new("podman"); + command.args(["image", "exists", image]); + command +} + +pub(crate) fn pull_if_not_present(image: &str) -> Result<()> { + let result = image_exists_command(image).status()?; + + if result.success() { + println!("Image {} is already present locally, skipping pull.", image); + return Ok(()); + } else { + println!("Image {} is not present locally, pulling it now.", image); + println!(); + pull_image_command(image) + .run_with_cmd_context() + .context(format!("pulling image {}", image))?; + } + + Ok(()) +} + /// Path to the podman installation script. Can be influenced by the build /// SYSTEM_REINSTALL_BOOTC_INSTALL_PODMAN_PATH parameter to override. Defaults /// to /usr/lib/system-reinstall-bootc/install-podman diff --git a/tests-integration/src/system_reinstall.rs b/tests-integration/src/system_reinstall.rs index 25f36f012..d7227d773 100644 --- a/tests-integration/src/system_reinstall.rs +++ b/tests-integration/src/system_reinstall.rs @@ -10,7 +10,7 @@ use std::{ use crate::install; -const TIMEOUT: u64 = 120000; +const TIMEOUT: u64 = 60000; fn get_deployment_dir() -> Result { let base_path = Path::new("/ostree/deploy/default/deploy"); @@ -62,11 +62,14 @@ pub(crate) fn run(image: &str, testargs: libtest_mimic::Arguments) -> Result<()> )?; // Basic flow stdout verification + p.exp_string( + format!("Image {image} is already present locally, skipping pull.").as_str(), + )?; p.exp_regex("Found only one user ([^:]+) with ([\\d]+) SSH authorized keys.")?; p.exp_string("Would you like to import its SSH authorized keys")?; p.exp_string("into the root user on the new bootc system?")?; p.exp_string("Then you can login as root@ using those keys. [Y/n]")?; - p.send_line("a")?; + p.send_line("y")?; p.exp_string("Going to run command:")?; @@ -133,13 +136,35 @@ pub(crate) fn run(image: &str, testargs: libtest_mimic::Arguments) -> Result<()> )?; p.exp_regex("Found only one user ([^:]+) with ([\\d]+) SSH authorized keys.")?; - p.send_line("a")?; + p.exp_string("[Y/n]")?; + p.send_line("y")?; p.exp_string("NOTICE: This will replace the installed operating system and reboot. Are you sure you want to continue? [y/N]")?; p.send_line("y")?; p.exp_string("Insufficient free space")?; p.exp_eof()?; Ok(()) }), + Trial::test("image pull check", move || { + let sh = &xshell::Shell::new()?; + install::reset_root(sh, image)?; + + // Run system-reinstall-bootc + let mut p: PtySession = rexpect::spawn( + "/usr/bin/system-reinstall-bootc quay.io/centos-bootc/centos-bootc:stream10", + Some(600000), // Increase timeout for pulling the image + )?; + + p.exp_string("Image quay.io/centos-bootc/centos-bootc:stream10 is not present locally, pulling it now.")?; + p.exp_regex("Found only one user ([^:]+) with ([\\d]+) SSH authorized keys.")?; + p.exp_string("[Y/n]")?; + p.send_line("y")?; + p.exp_string("NOTICE: This will replace the installed operating system and reboot. Are you sure you want to continue? [y/N]")?; + p.send_line("y")?; + p.exp_string("Operation complete, rebooting in 10 seconds. Press Ctrl-C to cancel reboot, or press enter to continue immediately.")?; + p.send_control('c')?; + p.exp_eof()?; + Ok(()) + }), ]; libtest_mimic::run(&testargs, tests.into()).exit()