-
Notifications
You must be signed in to change notification settings - Fork 182
Add an "upgrade from previous" test #2060
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,8 @@ | |
| base_img := "localhost/bootc" | ||
| # Synthetic upgrade image for testing | ||
| upgrade_img := base_img + "-upgrade" | ||
| # Base image with tmt dependencies added, used as the boot source for upgrade tests | ||
| upgrade_source_img := base_img + "-upgrade-source" | ||
|
|
||
| # Build variant: ostree (default) or composefs | ||
| variant := env("BOOTC_variant", "ostree") | ||
|
|
@@ -141,6 +143,29 @@ test-composefs bootloader filesystem boot_type seal_state *ARGS: | |
| {{ARGS}} \ | ||
| $(if [ "{{boot_type}}" = "uki" ]; then echo "readonly"; else echo "integration"; fi) | ||
|
|
||
| # Run upgrade test: boot VM from published base image (with tmt deps added), | ||
| # upgrade to locally-built image, reboot, then run readonly tests to verify. | ||
| # The --upgrade-image flag triggers --bind-storage-ro in bcvk, making the | ||
| # locally-built image available inside the VM via containers-storage transport. | ||
| [group('core')] | ||
| test-upgrade *ARGS: build _build-upgrade-source-image | ||
| #!/bin/bash | ||
| set -xeuo pipefail | ||
| composefs_args=() | ||
| if [[ "{{variant}}" = composefs ]]; then | ||
| composefs_args=(--composefs-backend \ | ||
| --bootloader={{bootloader}} \ | ||
| --filesystem={{filesystem}} \ | ||
| --seal-state={{seal_state}} \ | ||
| --boot-type={{boot_type}} \ | ||
| --karg=enforcing=0) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need this after #2035 right?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is building the from image which at this time still has an older bootc. But yes once the update propagates we can update the baseline. That said, what I do really want to do here is have another variant of this which starts from a pinned old OS version (think e.g. rhel 9.4) - of course we can't even do a composefs based install of that to start (and bcvk might not even work) but we can prove it out. |
||
| fi | ||
| cargo xtask run-tmt --env=BOOTC_variant={{variant}} \ | ||
| --env=BOOTC_test_upgrade_image={{base_img}} \ | ||
| --upgrade-image={{base_img}} \ | ||
| "${composefs_args[@]}" \ | ||
| {{upgrade_source_img}} {{ARGS}} readonly | ||
|
|
||
| # Run cargo fmt and clippy checks in container | ||
| [group('core')] | ||
| validate: | ||
|
|
@@ -339,6 +364,10 @@ _keygen: | |
| _build-upgrade-image: | ||
| cat tmt/tests/Dockerfile.upgrade | podman build -t {{upgrade_img}} --from={{base_img}} - | ||
|
|
||
| # Build the upgrade source image: base image + tmt dependencies (rsync, nu, cloud-init) | ||
| _build-upgrade-source-image: | ||
| podman build --build-arg=base={{base}} --build-arg=variant={{variant}} -t {{upgrade_source_img}} -f tmt/tests/Dockerfile.upgrade-source . | ||
|
|
||
| # Copy an image from user podman storage to root's podman storage | ||
| # This allows building as regular user then running privileged tests | ||
| [group('testing')] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Build an image suitable for upgrade testing: takes the published base image | ||
| # and adds the minimal dependencies needed by tmt (rsync, nu, etc.) | ||
| # so we can boot it in a VM, then upgrade into the locally-built image. | ||
| # | ||
| # Note: we do NOT pass `cloudinit` to provision-derived.sh because bcvk | ||
| # handles SSH key injection itself; cloud-init interferes with that. | ||
| ARG base | ||
| FROM ${base} | ||
| COPY hack/provision-derived.sh hack/packages.txt contrib/packaging/configure-rootfs /run/provision/ | ||
| ARG variant=ostree | ||
| RUN --mount=type=tmpfs,target=/tmp <<EORUN | ||
| set -xeuo pipefail | ||
| cd /run/provision | ||
| # Install nu and tmt dependencies using the same script as the main build, | ||
| # but with SKIP_CONFIGS=1 since we don't need LBIs or test kargs in the | ||
| # upgrade source image (those come from the image we upgrade into). | ||
| SKIP_CONFIGS=1 ./provision-derived.sh | ||
| # Ensure a root filesystem type is configured so `bootc install to-disk` | ||
| # works for base images that don't ship a default (e.g. Fedora). | ||
| # For the ostree variant, configure-rootfs will default to xfs. | ||
| ./configure-rootfs "${variant}" | ||
| # For composefs, rebuild the initramfs to include the bootc dracut module. | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm going to fix this separately too |
||
| # The module's check() returns 255 so it's never auto-included, but it's | ||
| # required for composefs root setup during boot. | ||
| if [[ "${variant}" == composefs* ]]; then | ||
| mkdir -p /etc/dracut.conf.d | ||
| echo 'add_dracutmodules+=" bootc "' > /etc/dracut.conf.d/50-bootc-composefs.conf | ||
| kver=$(cd /usr/lib/modules && echo *) | ||
| dracut --force --kver "$kver" "/usr/lib/modules/$kver/initramfs.img" | ||
| fi | ||
| rm -rf /run/provision | ||
| EORUN | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| use std assert | ||
| use tap.nu | ||
|
|
||
| tap begin "verify SELinux is enforcing" | ||
|
|
||
| # Composefs upgrade source images boot with enforcing=0 because the | ||
| # base image's SELinux policy doesn't yet cover composefs file contexts. | ||
| # Skip this check in that case. | ||
| let upgrade_image = $env.BOOTC_test_upgrade_image? | default "" | ||
| let is_composefs = (tap is_composefs) | ||
| if $upgrade_image != "" and $is_composefs { | ||
| print "# skip: composefs upgrade boots with enforcing=0 (base image SELinux policy gap)" | ||
| tap ok | ||
| exit 0 | ||
| } | ||
|
|
||
| let enforce = (open /sys/fs/selinux/enforce | str trim) | ||
| assert equal $enforce "1" "SELinux should be in enforcing mode" | ||
| print "SELinux is enforcing" | ||
|
|
||
| tap ok |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| use std assert | ||
| use tap.nu | ||
|
|
||
| tap begin "verify bootc upgrade --check succeeds after upgrade" | ||
|
|
||
| # After an upgrade (bootc switch), verify that the running system can | ||
| # still query for further upgrades. This catches regressions where | ||
| # on-disk state created by an older bootc is incompatible with the | ||
| # new bootc's upgrade machinery (e.g. #2074). | ||
| # Only meaningful when we actually performed an upgrade. | ||
| let upgrade_image = $env.BOOTC_test_upgrade_image? | default "" | ||
| if $upgrade_image == "" { | ||
| print "# skip: not an upgrade test (BOOTC_test_upgrade_image not set)" | ||
| tap ok | ||
| exit 0 | ||
| } | ||
|
|
||
| # Read the pre-upgrade bootc version saved during first boot. | ||
| let old_version_str = (open /var/bootc-pre-upgrade-version | str trim) | ||
| let old_ver = ($old_version_str | split row "." | each { into int }) | ||
| print $"Pre-upgrade bootc version: ($old_version_str)" | ||
|
|
||
| let is_composefs = (tap is_composefs) | ||
|
|
||
| print "Running bootc upgrade --check to verify upgrade machinery works..." | ||
| let result = do -i { bootc upgrade --check } | complete | ||
| if $result.exit_code == 0 { | ||
| print "bootc upgrade --check succeeded" | ||
| } else { | ||
| print $"bootc upgrade --check failed: ($result.stderr)" | ||
| # Known failure: composefs upgrades from bootc <= 1.13 have | ||
| # incompatible on-disk state (see #2074). | ||
| let old_bootc_le_1_13 = ($old_ver.0 < 1) or (($old_ver.0 == 1) and ($old_ver.1 <= 13)) | ||
|
Comment on lines
+31
to
+33
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK cool, this successfully reproduces the problem from #2074 |
||
| if $is_composefs and $old_bootc_le_1_13 { | ||
| print $"# known failure: composefs upgrade --check from bootc ($old_version_str) \(see #2074\)" | ||
| } else { | ||
| error make { msg: $"bootc upgrade --check failed unexpectedly: ($result.stderr)" } | ||
| } | ||
| } | ||
|
|
||
| tap ok | ||
Uh oh!
There was an error while loading. Please reload this page.