1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
summary: Verify that updating all of base, gadget and kernel only needs one reboot
details: |
Check that when all of base, gadget and kernel are refreshed together, only one reboot
is needed. Verify that all the refreshed snaps can be reverted to the initial version.
# TODO make the test work with ubuntu-core-20
systems: [ubuntu-core-18-*]
environment:
BLOB_DIR: $(pwd)/fake-store-blobdir
prepare: |
if [ "$TRUST_TEST_KEYS" = "false" ]; then
echo "This test needs test keys to be trusted"
exit
fi
readlink "/snap/pc-kernel/current" > pc-kernel.rev
readlink "/snap/core18/current" > core.rev
readlink "/snap/pc/current" > pc.rev
restore: |
if [ "$TRUST_TEST_KEYS" = "false" ]; then
echo "This test needs test keys to be trusted"
exit
fi
"$TESTSTOOLS"/store-state teardown-fake-store "$BLOB_DIR"
execute: |
if [ "$TRUST_TEST_KEYS" = "false" ]; then
echo "This test needs test keys to be trusted"
exit
fi
core_snap=core20
if os.query is-core18; then
core_snap=core18
fi
if [ "$SPREAD_REBOOT" = 0 ]; then
snap ack "$TESTSLIB/assertions/testrootorg-store.account-key"
"$TESTSTOOLS"/store-state setup-fake-store "$BLOB_DIR"
"$TESTSTOOLS"/store-state init-fake-refreshes "$BLOB_DIR" pc-kernel
"$TESTSTOOLS"/store-state init-fake-refreshes "$BLOB_DIR" "$core_snap"
"$TESTSTOOLS"/store-state init-fake-refreshes "$BLOB_DIR" pc
snap refresh --no-wait core18 pc pc-kernel > refresh-change-id
test -n "$(cat refresh-change-id)"
change_id="$(cat refresh-change-id)"
# wait for the link task to be done for base
retry -n 50 --wait 1 sh -c 'journalctl -b -u snapd | MATCH "Waiting for system reboot"'
# all three link snaps should be done now, snapd has shutdown, so we cannot
# use 'snap change' and we need to inspect the state directly (even if
# snapd was up, it would not respond to API requests as it would be busy
# retrying auto-connect)
snap debug state --change "$change_id" /var/lib/snapd/state.json > tasks.state
# both link snaps are done
MATCH ' Wait\s+.*Make snap "pc-kernel" .* available' < tasks.state
MATCH " Done\s+.*Make snap \"$core_snap\" .* available" < tasks.state
MATCH ' Done\s+.*Make snap "pc" .* available' < tasks.state
# auto-connect of the base is in doing and waiting for reboot
MATCH " Do\s+.*Automatically connect eligible plugs and slots of snap \"$core_snap\"" < tasks.state
# auto-connect of the gadget is queued
MATCH ' Do\s+.*Automatically connect eligible plugs and slots of snap "pc"' < tasks.state
# auto-connect of the kernel is queued
MATCH ' Do\s+.*Automatically connect eligible plugs and slots of snap "pc-kernel"' < tasks.state
if os.query is-core18; then
snap debug boot-vars > boot-vars.dump
MATCH 'snap_mode=try' < boot-vars.dump
MATCH 'snap_try_core=core18_.*.snap' < boot-vars.dump
MATCH 'snap_try_kernel=pc-kernel_.*.snap' < boot-vars.dump
elif os.query is-core20; then
stat /boot/grub/kernel.efi | MATCH 'pc_kernel.*.snap/kernel.efi'
stat -L /boot/grub/kernel.efi
stat /boot/grub/try-kernel.efi | MATCH 'pc_kernel.*.snap/kernel.efi'
stat -L /boot/grub/try-kernel.efi
else
echo "unsupported Ubuntu Core system"
exit 1
fi
REBOOT
elif [ "$SPREAD_REBOOT" = 1 ]; then
change_id="$(cat refresh-change-id)"
# XXX: is this sufficiently robust?
snap watch "$change_id" || true
snap changes | MATCH "$change_id\s+(Done|Error)"
# we expect re-refresh to fail since the tests uses a fake store
snap change "$change_id" > tasks.done
MATCH '^Error .* Monitoring .* to determine whether extra refresh steps are required' < tasks.done
# no other errors
grep -v 'Monitoring .* to determine whether extra refresh steps are required' < tasks.done | NOMATCH '^Error'
# nothing was undone
grep -v 'Monitoring .* to determine whether extra refresh steps are required' < tasks.done | NOMATCH '^Undone'
# we did not even try to hijack shutdown (/bin/systemctl) because that
# could race with snapd (if that wanted to call it), so just check that
# the system is in a stable state once we have already determined that
# the change is complete
# XXX systemctl exits with non-0 when in degraded state
# Note: on bionic, is-system-running does not support --wait
retry -n 30 sh -c '(systemctl is-system-running || true) | MATCH "(running|degraded)"'
# fake refreshes generate revision numbers that are n+1
expecting_kernel="$(($(cat pc-kernel.rev) + 1))"
expecting_core="$(($(cat core.rev) + 1))"
expecting_gadget="$(($(cat pc.rev) + 1))"
# verify that current points to new revisions
test "$(readlink /snap/pc-kernel/current)" = "$expecting_kernel"
test "$(readlink /snap/pc/current)" = "$expecting_gadget"
test "$(readlink /snap/$core_snap/current)" = "$expecting_core"
# now we need to revert both snaps for restore to behave properly, start
# with the kernel
snap revert pc-kernel --revision "$(cat pc-kernel.rev)"
REBOOT
elif [ "$SPREAD_REBOOT" = 2 ]; then
snap watch --last=revert\?
# now the gadget
snap revert pc --revision "$(cat pc.rev)"
REBOOT
elif [ "$SPREAD_REBOOT" = 3 ]; then
snap watch --last=revert\?
# now the base
snap revert "$core_snap" --revision "$(cat core.rev)"
REBOOT
elif [ "$SPREAD_REBOOT" = 4 ]; then
snap watch --last=revert\?
# we're done, verify current symlinks to the right revisions
test "$(readlink /snap/pc-kernel/current)" = "$(cat pc-kernel.rev)"
test "$(readlink /snap/pc/current)" = "$(cat pc.rev)"
test "$(readlink /snap/$core_snap/current)" = "$(cat core.rev)"
else
echo "unexpected reboot"
exit 1
fi
|