From 6021a01c09c670954ba0241b699ee964e6ad07f3 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Fri, 12 Jun 2026 11:11:53 -0400 Subject: [PATCH 1/2] switch: fix --apply not rebooting when already staged When 'bootc switch --apply' is called targeting an image that is already staged, the spec comparison short-circuits with 'Image specification is unchanged' and returns early without rebooting. This is the same class of bug that was fixed for 'bootc upgrade --apply' in commit 0067a47c. Fix both the ostree and composefs switch paths. Full AI use (reproduced bug, patched bootc, verified bugfix). I verified the verification and the patch. Signed-off-by: Jonathan Lebon --- crates/lib/src/bootc_composefs/switch.rs | 3 +++ crates/lib/src/cli.rs | 3 +++ tmt/tests/booted/test-image-upgrade-reboot.nu | 12 ++++++++---- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/lib/src/bootc_composefs/switch.rs b/crates/lib/src/bootc_composefs/switch.rs index f6b3855be..3f8b5af8d 100644 --- a/crates/lib/src/bootc_composefs/switch.rs +++ b/crates/lib/src/bootc_composefs/switch.rs @@ -31,6 +31,9 @@ pub(crate) async fn switch_composefs( if new_spec == host.spec { println!("Image specification is unchanged."); + if opts.apply && host.status.staged.is_some() { + crate::reboot::reboot()?; + } return Ok(()); } diff --git a/crates/lib/src/cli.rs b/crates/lib/src/cli.rs index 9a7c307ff..fc58e29ea 100644 --- a/crates/lib/src/cli.rs +++ b/crates/lib/src/cli.rs @@ -1398,6 +1398,9 @@ async fn switch_ostree( if new_spec == host.spec { println!("Image specification is unchanged."); + if opts.apply && host.status.staged.is_some() { + crate::reboot::reboot()?; + } return Ok(()); } diff --git a/tmt/tests/booted/test-image-upgrade-reboot.nu b/tmt/tests/booted/test-image-upgrade-reboot.nu index f28cff1da..b00213481 100644 --- a/tmt/tests/booted/test-image-upgrade-reboot.nu +++ b/tmt/tests/booted/test-image-upgrade-reboot.nu @@ -8,7 +8,8 @@ # This test does: # bootc image copy-to-storage # podman build -# bootc switch --apply +# bootc switch (stage only) +# bootc switch --apply (spec unchanged, must still reboot) # Verify we boot into the new image # # For composefs builds, it additionally verifies that composefs is @@ -65,10 +66,13 @@ def initial_build [] { $st.status.booted.composefs.verity | save /var/original-verity } - # Now, switch into the new image - print $"Applying ($imgsrc)" + # Now, switch into the new image. First stage it, then run switch --apply for + # the same target. This exercises the case where --apply must still reboot for + # staged deployments. + print $"Staging ($imgsrc)" bootc switch --transport containers-storage ($imgsrc) - tmt-reboot + print "Re-running with --apply (spec unchanged, should still reboot)" + tmt-reboot -c $"bootc switch --apply --transport containers-storage ($imgsrc)" } # Check we have the updated image From 0ad7910ff1d1a4f0755583e021a097d7fa79788d Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Fri, 12 Jun 2026 12:47:39 -0400 Subject: [PATCH 2/2] tmt/README.md: redirect to CONTRIBUTING.md The tmt README instructions to `tmt run` directly just won't work without the bcvk wrappers. My agent got tripped up on this. That README overall looks pretty stock. Just keep it short and redirect to CONTRIBUTING.md. While we're there, also mention tmt and libvirt, which would've helped my agent. Very mild AI assistance. Signed-off-by: Jonathan Lebon --- CONTRIBUTING.md | 4 +++- tmt/README.md | 13 ++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a189e5162..f9df3c5b9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,9 @@ accepted! - A development environment (toolbox or a host) with a Rust and C compiler, etc. While this isn't specific to bootc, you will find the experience of working on Rust is greatly aided with use of e.g. [rust-analyzer](https://github.com/rust-lang/rust-analyzer/). -- Install [bcvk](https://github.com/bootc-dev/bcvk). +- Install [bcvk](https://github.com/bootc-dev/bcvk). For running TMT + integration tests, also install `tmt` and `libvirt` + (e.g. `dnf install bcvk tmt libvirt`). ## Ensure you're familiar with a bootc system diff --git a/tmt/README.md b/tmt/README.md index 15ace2433..6744b1726 100644 --- a/tmt/README.md +++ b/tmt/README.md @@ -1,11 +1,6 @@ -# Run integration test locally +# TMT integration tests -In the bootc CI, integration tests are executed via Packit on the Testing Farm. In addition, the integration tests can also be run locally on a developer's machine, which is especially valuable for debugging purposes. +In the bootc CI, integration tests are executed via Packit on the Testing Farm. -To run integration tests locally, you need to [install tmt](https://tmt.readthedocs.io/en/stable/guide.html#the-first-steps) and `provision-virtual` plugin in this case. Be ready with `dnf install -y tmt+provision-virtual`. Then, use `tmt run -vvvvv plans -n integration` command to run the all integration tests. - -To run integration tests on different distros, just change `image: fedora-rawhide` in https://github.com/bootc-dev/bootc/blob/9d15eedea0d54a4dbc15d267dbdb055817336254/tmt/plans/integration.fmf#L6. - -The available images value can be found from https://tmt.readthedocs.io/en/stable/plugins/provision.html#images. - -Enjoy integration test local running! +See [CONTRIBUTING.md](../CONTRIBUTING.md#running-tmt-integration-tests) for +instructions on running them locally.