mirror of
https://github.com/token2/snapd.git
synced 2026-03-13 11:15:47 -07:00
* tests: test refresh mixing essential and apps in hybrid systems Check that on a hybrid system, refreshes of both essential snaps and apps and non-model bases don't make the apps wait for a reboot. In particular check that the refresh of the kernel, gadget and model base wait for a reboot. Check that apps that depend on the model base also wait for it to be refreshed and that apps that don't can completely refresh before the reboot. Signed-off-by: Miguel Pires <miguel.pires@canonical.com> * tests: use correct model for system in muinstaller-real Signed-off-by: Miguel Pires <miguel.pires@canonical.com> --------- Signed-off-by: Miguel Pires <miguel.pires@canonical.com>
216 lines
9.2 KiB
YAML
216 lines
9.2 KiB
YAML
summary: Check app refreshes don't wait for a reboot in hybrid systems
|
|
|
|
details: |
|
|
Check that (on hybrid systems) refreshes of both essential (e.g., kernel,
|
|
gadget) and non-essential snaps don't make apps and non-model bases wait for
|
|
a reboot like the essential snaps. Check that if an app depends on the model
|
|
base, it does wait for its refresh (and a reboot) because the base must be
|
|
refreshed before the kernel and gadget since those depend on it.
|
|
|
|
systems: [ubuntu-22.04-64, ubuntu-24.04-64]
|
|
|
|
environment:
|
|
NESTED_ENABLE_TPM: false
|
|
NESTED_ENABLE_SECURE_BOOT: false
|
|
NESTED_BUILD_SNAPD_FROM_CURRENT: true
|
|
NESTED_ENABLE_OVMF: true
|
|
NESTED_REPACK_KERNEL_SNAP: true
|
|
# store related setup
|
|
STORE_ADDR: localhost:11028
|
|
STORE_DIR: $(pwd)/fake-store-blobdir
|
|
|
|
prepare: |
|
|
if [ "$TRUST_TEST_KEYS" = "false" ]; then
|
|
echo "This test needs test keys to be trusted"
|
|
exit
|
|
fi
|
|
echo "Install used snaps"
|
|
snap install test-snapd-curl --devmode --edge
|
|
snap install jq --devmode --edge
|
|
if [ -d /var/lib/snapd/seed ]; then
|
|
mv /var/lib/snapd/seed /var/lib/snapd/seed.orig
|
|
fi
|
|
"$TESTSTOOLS"/store-state setup-fake-store "$STORE_DIR"
|
|
|
|
|
|
restore: |
|
|
if [ "$TRUST_TEST_KEYS" = "false" ]; then
|
|
echo "This test needs test keys to be trusted"
|
|
exit
|
|
fi
|
|
rm -rf /var/lib/snapd/seed
|
|
if [ -d /var/lib/snapd/seed.orig ]; then
|
|
mv /var/lib/snapd/seed.orig /var/lib/snapd/seed
|
|
fi
|
|
"$TESTSTOOLS"/store-state teardown-fake-store "$STORE_DIR"
|
|
rm -rf ./classic-root
|
|
|
|
debug: |
|
|
if remote.exec true; then
|
|
remote.exec snap changes
|
|
CHG_ID=$(remote.exec snap changes | grep "Install.*from files" | awk '{print $1}')
|
|
remote.exec snap change "$CHG_ID"
|
|
fi
|
|
|
|
execute: |
|
|
if [ "$TRUST_TEST_KEYS" = "false" ]; then
|
|
echo "This test needs test keys to be trusted"
|
|
exit
|
|
fi
|
|
|
|
echo Expose the needed assertions through the fakestore
|
|
cp "$TESTSLIB"/assertions/developer1.account "$STORE_DIR/asserts"
|
|
cp "$TESTSLIB"/assertions/developer1.account-key "$STORE_DIR/asserts"
|
|
cp "$TESTSLIB"/assertions/testrootorg-store.account-key "$STORE_DIR/asserts"
|
|
export SNAPPY_FORCE_SAS_URL=http://$STORE_ADDR
|
|
|
|
# shellcheck source=tests/lib/prepare.sh
|
|
. "$TESTSLIB/prepare.sh"
|
|
#shellcheck source=tests/lib/nested.sh
|
|
. "$TESTSLIB"/nested.sh
|
|
version="$(nested_get_version)"
|
|
|
|
snap download --basename=pc-kernel --channel="$version/stable" pc-kernel
|
|
uc20_build_initramfs_kernel_snap "$PWD/pc-kernel.snap" "$NESTED_ASSETS_DIR"
|
|
mv "${NESTED_ASSETS_DIR}"/pc-kernel_*.snap pc-kernel.snap
|
|
|
|
# Prepare gadget with the right gadget.yaml
|
|
snap download --basename=pc --channel="$version/stable" pc
|
|
unsquashfs -d pc pc.snap
|
|
sed -i 's/name: ubuntu-seed/name: EFI System partition/' pc/meta/gadget.yaml
|
|
sed -i 's/role: system-seed/role: system-seed-null/' pc/meta/gadget.yaml
|
|
snap pack --filename=pc-new.snap pc
|
|
|
|
version="$(nested_get_version)"
|
|
gendeveloper1 sign-model < "$TESTSLIB"/assertions/developer1-"$version"-classic-dangerous.json > my.model
|
|
|
|
# prepare a classic seed
|
|
snap prepare-image --classic \
|
|
--channel=edge \
|
|
--snap ./pc-kernel.snap \
|
|
--snap ./pc-new.snap \
|
|
my.model \
|
|
./classic-seed
|
|
|
|
# make the seed label more predictable for muinstaller auto-mode
|
|
LABEL=classic
|
|
mv ./classic-seed/system-seed/systems/* ./classic-seed/system-seed/systems/"$LABEL"
|
|
cp -a ./classic-seed/system-seed/ /var/lib/snapd/seed
|
|
|
|
# do some light checking that the system is valid
|
|
test-snapd-curl.curl -s --unix-socket /run/snapd.socket http://localhost/v2/systems | jq '.result.systems[0].label' | MATCH "$LABEL"
|
|
test-snapd-curl.curl -s --unix-socket /run/snapd.socket http://localhost/v2/systems/"$LABEL" > system
|
|
jq '.result.model.distribution' system | MATCH "ubuntu"
|
|
# build muinstaller and put in place
|
|
go build -o muinstaller "$TESTSLIB"/muinstaller/main.go
|
|
|
|
# create fake disk for the installer to work on
|
|
truncate --size=5G fake-disk.img
|
|
loop_device=$(losetup --show -f ./fake-disk.img)
|
|
# and "install" the current seed to the fake disk
|
|
./muinstaller "$LABEL" "$loop_device" "$TESTSLIB"/muinstaller/mk-classic-rootfs.sh
|
|
# validate that the fake installer created the expected partitions
|
|
sfdisk -d "$loop_device" > fdisk_output
|
|
MATCH "${loop_device}p1 .* name=\"BIOS Boot\"" < fdisk_output
|
|
# TODO: the real MVP hybrid device will not contain a ubuntu-seed
|
|
# partition (needs a different gadget)
|
|
MATCH "${loop_device}p2 .* name=\"EFI System partition\"" < fdisk_output
|
|
MATCH "${loop_device}p3 .* name=\"ubuntu-boot\"" < fdisk_output
|
|
MATCH "${loop_device}p4 .* name=\"ubuntu-save\"" < fdisk_output
|
|
MATCH "${loop_device}p5 .* name=\"ubuntu-data\"" < fdisk_output
|
|
|
|
# image partitions are not mounted anymore
|
|
for d in ubuntu-seed ubuntu-boot ubuntu-data ubuntu-save; do
|
|
test -d /run/mnt/"$d"
|
|
not mountpoint /run/mnt/"$d"
|
|
done
|
|
|
|
# mount image to inspect data
|
|
mount -o ro "${loop_device}"p3 /run/mnt/ubuntu-boot
|
|
mount -o ro "${loop_device}"p5 /run/mnt/ubuntu-data
|
|
|
|
# seed is populated
|
|
test -d /run/mnt/ubuntu-data/var/lib/snapd/seed/systems/"$LABEL"
|
|
# rootfs is there
|
|
test -x /run/mnt/ubuntu-data/usr/lib/systemd/systemd
|
|
# ensure not "ubuntu-data/system-data" is generated, this is a dir only
|
|
# used on core and should not be there on classic
|
|
not test -d /run/mnt/ubuntu-data/system-data
|
|
# TODO: ensure we don't have this
|
|
#not test -d /run/mnt/ubuntu-data/_writable_defaults
|
|
# and the boot assets are in the right place
|
|
test -e /run/mnt/ubuntu-boot/EFI/ubuntu/kernel.efi
|
|
test -e /run/mnt/ubuntu-boot/EFI/ubuntu/grubenv
|
|
test -e /run/mnt/ubuntu-boot/EFI/boot/grubx64.efi
|
|
# and we have a modenv in the image
|
|
MATCH "mode=run" < /run/mnt/ubuntu-data/var/lib/snapd/modeenv
|
|
MATCH "classic=true" < /run/mnt/ubuntu-data/var/lib/snapd/modeenv
|
|
umount /run/mnt/ubuntu-{boot,data}
|
|
|
|
# HACK: better to change nested_start_vm() to take an image name
|
|
# Note that use "core" here as the boot is so close to core that classic
|
|
# does not work
|
|
IMAGE_NAME="$(nested_get_image_name core)"
|
|
mv fake-disk.img "$NESTED_IMAGES_DIR/$IMAGE_NAME"
|
|
|
|
# boot into the created image
|
|
# Note that use "core" here as the boot is so close to core that classic
|
|
# does not work
|
|
touch "$NESTED_IMAGES_DIR/$IMAGE_NAME.configured"
|
|
tests.nested create-vm core
|
|
|
|
remote.exec "cat /etc/os-release" | MATCH 'NAME="Ubuntu"'
|
|
remote.exec "snap changes" | MATCH "Done.* Initialize system state"
|
|
|
|
echo "Install the required apps and check for expected snaps"
|
|
remote.exec "sudo snap install test-snapd-tools-core22 test-snapd-sh"
|
|
|
|
for snap in snapd core22 pc pc-kernel test-snapd-tools-core22 test-snapd-sh; do
|
|
remote.exec "snap list" | MATCH "$snap"
|
|
done
|
|
|
|
echo "Downloads and pack snaps (snapd, gadget, kernel and apps) to update"
|
|
snap download --basename=pc --channel="$version/edge" pc
|
|
rm -r pc
|
|
unsquashfs -d pc pc.snap
|
|
sed -i 's/name: ubuntu-seed/name: EFI System partition/' pc/meta/gadget.yaml
|
|
sed -i 's/role: system-seed/role: system-seed-null/' pc/meta/gadget.yaml
|
|
snap pack --filename=pc-edge.snap pc
|
|
remote.push pc-edge.snap
|
|
|
|
remote.exec "snap download --basename=snapd-edge --channel=latest/edge snapd"
|
|
remote.exec "snap download --basename=core22-edge --channel=latest/edge core22"
|
|
remote.exec "snap download --basename=pc-kernel-edge --channel=\"$version/edge\" pc-kernel"
|
|
remote.exec "snap download --basename=test-snapd-sh-edge --channel=latest/edge test-snapd-sh"
|
|
remote.exec "snap download --basename=test-snapd-tools-core22-edge --channel=latest/edge test-snapd-tools-core22"
|
|
|
|
echo "Update all snaps at once"
|
|
remote.exec "sudo snap install --dangerous ./snapd-edge.snap ./pc-kernel-edge.snap ./pc-edge.snap ./core22-edge.snap ./test-snapd-sh-edge.snap ./test-snapd-tools-core22-edge.snap"
|
|
CHG_ID=$(remote.exec snap changes | grep "Install.*from files" | awk '{print $1}')
|
|
|
|
echo "Check that the essential snaps' refresh is pending on a reboot"
|
|
remote.retry -n 20 "snap change $CHG_ID | MATCH \"Task set to wait until a system restart\""
|
|
remote.exec "snap change $CHG_ID" | MATCH "Wait.*Make snap \"pc-kernel\".*available"
|
|
for snap in pc core22; do
|
|
remote.exec "snap change $CHG_ID" | MATCH "Done.*Make snap \"$snap\".* available to the system"
|
|
remote.exec "snap change $CHG_ID" | MATCH "Do.*Automatically connect eligible plugs.*snap \"$snap\""
|
|
done
|
|
|
|
echo "Check that the app that depends on the model base is also pending"
|
|
remote.exec "snap change $CHG_ID" | MATCH "Do.*Ensure prerequisites for \"test-snapd-tools-core22\" are available"
|
|
|
|
echo "But snapd and the other app's refresh has finished"
|
|
remote.retry --wait 3 -n 10 "snap change $CHG_ID | MATCH \"Done.*Run health check.*snapd\""
|
|
remote.retry --wait 3 -n 10 "snap change $CHG_ID | MATCH \"Done.*Run health check.*test-snapd-sh\""
|
|
|
|
BOOT_ID=$(tests.nested boot-id)
|
|
remote.exec sudo reboot || true
|
|
remote.wait-for reboot --wait 10 -n 90 "$BOOT_ID"
|
|
|
|
echo "After a reboot, the kernel and gadget snaps' refresh is done"
|
|
remote.retry --wait 5 -n 20 "snap changes | MATCH \"$CHG_ID.*Done.*Install\""
|
|
remote.exec "snap change $CHG_ID" | MATCH "Done.*Run health check.*pc"
|
|
remote.exec "snap change $CHG_ID" | MATCH "Done.*Run health check.*pc-kernel"
|
|
remote.exec "snap change $CHG_ID" | MATCH "Done.*Run health check.*core22"
|
|
remote.exec "snap change $CHG_ID" | MATCH "Done.*Run health check.*test-snapd-tools-core22"
|