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
|
summary: Install a gadget that uses volume-assignments
details: |
Tests volume-assignments syntax, and that we get the volumes installed to the expected
disks. The gadget will assign two different volumes to two different disks. The disks
are hardcoded at their PCI location, which hopefully does not change easily. We must
use a path in /dev/disk/.. as those are the only supported device assignments currently
for volumes. The test also tests gadget update.
systems: [ubuntu-2*]
environment:
NESTED_CUSTOM_MODEL: $TESTSLIB/assertions/valid-for-testing-pc-{VERSION}.model
NESTED_ENABLE_SECURE_BOOT: false
NESTED_BUILD_SNAPD_FROM_CURRENT: true
NESTED_IMAGE_ID: volassign
prepare: |
VERSION=$(tests.nested show version)
snap download --basename=pc --channel="$VERSION/edge" pc
unsquashfs -d pc-gadget pc.snap
# append volume-assignments
cat <<EOF >> pc-gadget/meta/gadget.yaml
backup:
schema: mbr
structure:
- name: system-backup
type: DA,21686148-6449-6E6F-744E-656564454649
size: 32M
content:
- image: content.img
volume-assignments:
- assignment-name: do-not-match-device
assignment:
pc:
device: /dev/disk/by-id/nvme0003
- assignment-name: test-device
assignment:
# FIXME: we should really not use those kind of paths, they are
# difficult to predict
pc:
device: /dev/disk/by-path/pci-0000:00:05.0
backup:
device: /dev/disk/by-path/pci-0000:00:06.0
EOF
# build the test image
truncate -s 31M pc-gadget/content.img
mkfs.ext4 pc-gadget/content.img
mkdir -p /mnt/pc-cnt
mount -oloop pc-gadget/content.img /mnt/pc-cnt
echo "test file that we want to read later" > /mnt/pc-cnt/test.txt
sync
umount /mnt/pc-cnt
# enable debug
cat <<EOF >> pc-gadget/cmdline.extra
snapd.debug=1
EOF
# Make sure that we get a different snap than the store one
touch pc-gadget/empty
snap pack --filename=pc_x1.snap pc-gadget/ "$(tests.nested get extra-snaps-path)"
tests.nested build-image core
execute: |
# shellcheck source=tests/lib/nested.sh
. "$TESTSLIB/nested.sh"
# create new disk for the gadget volume-assignments that we attach
# to the VM
BACKUP_VOLUME="$NESTED_IMAGES_DIR/$(nested_get_image_name_base core)-backup.img"
# setup extra disk options for tests.nested
params=(
"-drive" "file=${BACKUP_VOLUME},if=none,snapshot=off,format=raw,id=disk2"
"-device" "virtio-blk-pci,drive=disk2,addr=6"
)
NESTED_PARAM_EXTRA="${params[*]}"
tests.nested create-vm core --extra-param "$NESTED_PARAM_EXTRA"
# Build a new gadget that has content that needs to be updated
sed -i 's/This program cannot be run in DOS mode/This program cannot be run in XXX mode/' \
pc-gadget/grubx64.efi
gojq --yaml-input --yaml-output \
'(.volumes.pc.structure[] | select(.name == "ubuntu-boot") | .update.edition) |= . + 1' \
< pc-gadget/meta/gadget.yaml > gadget.yaml.tmp
mv gadget.yaml.tmp pc-gadget/meta/gadget.yaml
snap pack --filename=pc.snap pc-gadget
remote.push pc.snap
remote.exec "sudo snap wait system seed.loaded"
# verify device path exists
# even though at this point if it didn't exist the system would have
# failed to install
remote.exec "ls /dev/disk/by-path | grep 'pci-0000:00:05.0'"
remote.exec "ls /dev/disk/by-path | grep 'pci-0000:00:06.0'"
# verify contents are looking good
remote.exec "sudo mkdir -p /run/mnt/test"
remote.exec "sudo mount -t ext4 /dev/vdb1 /run/mnt/test"
remote.exec "ls /run/mnt/test" | MATCH "test.txt"
remote.exec "cat /run/mnt/test/test.txt" | MATCH "test file that we want to read later"
remote.exec "sudo umount /run/mnt/test"
boot_id=$(tests.nested boot-id)
# Install new gadget
CHG_ID="$(remote.exec "sudo snap install --no-wait --dangerous pc.snap")"
# It should reboot now
remote.wait-for reboot "$boot_id"
remote.exec sudo snap watch "$CHG_ID"
# Check that asset has been updated
remote.exec sudo grep -i -a '"This program cannot be run in XXX mode"' \
/run/mnt/ubuntu-boot/EFI/boot/grubx64.efi
# test a gadget update with no matching assignment
gojq --yaml-input --yaml-output \
'del(."volume-assignments"[] | select(."assignment-name" == "test-device"))' \
< pc-gadget/meta/gadget.yaml > gadget.yaml.tmp
gojq --yaml-input --yaml-output \
'(.volumes.pc.structure[] | select(.name == "ubuntu-boot") | .update.edition) |= . + 1' \
< gadget.yaml.tmp > gadget.yaml.tmp1
mv gadget.yaml.tmp1 pc-gadget/meta/gadget.yaml
snap pack --filename=pc-bad.snap pc-gadget
remote.push pc-bad.snap
# Install new gadget with no correct device assignment
remote.exec "sudo snap install --dangerous pc-bad.snap" 2>&1 | MATCH "no matching volume-assignment for current device"
|