Cloud images, qemu, cloud-init and snapd spread tests April 16, 2019
Posted by jdstrand in canonical, ubuntu, ubuntu-server, uncategorized.Tags: snapd
trackback
It is useful for testing to want to work with official cloud images as local VMs. Eg, when I work on snapd, I like to have different images available to work with its spread tests.
The autopkgtest package makes working with Ubuntu images quite easy:
$ sudo apt-get install qemu-kvm autopkgtest
$ autopkgtest-buildvm-ubuntu-cloud -r bionic # -a i386
Downloading https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img...
# and to integrate into spread
$ mkdir -p ~/.spread/qemu
$ mv ./autopkgtest-bionic-amd64.img ~/.spread/qemu/ubuntu-18.04-64.img
# now can run any test from 'spread -list' starting with
# 'qemu:ubuntu-18.04-64:'
This post isn’t really about autopkgtest, snapd or spread specifically though….
I found myself wanting an official Debian unstable cloud image so I could use it in spread while testing snapd. I learned it is easy enough to create the images yourself but then I found that Debian started providing raw and qcow2 cloud images for use in OpenStack and so I started exploring how to use them and generalize how to use arbitrary cloud images.
General procedure
The basic steps are:
- obtain a cloud image
- make copy of the cloud image for safekeeping
- resize the copy
- create a seed.img with cloud-init to set the username/password
- boot with networking and the seed file
- login, update, etc
- cleanly shutdown
- use normally (ie, without seed file)
In this case, I grabbed the ‘debian-testing-openstack-amd64.qcow2’ image from http://cdimage.debian.org/cdimage/openstack/testing/ and verified it. Since this is based on Debian ‘testing’ (current stable images are also available), when I copied it I named it accordingly. Eg, I knew for spread it needed to be ‘debian-sid-64.img’ so I did:
$ cp ./debian-testing-openstack-amd64.qcow2 ./debian-sid-64.img
Or if downloaded a raw image, convert it to qcow2 instead of the cp like so:
$ qemu-img convert -f raw ./.img -O qcow2 ./.img
Then I resized it; I picked 20G since I recalled that is what autopkgtest uses:
$ qemu-img resize debian-sid-64.img 20G
These are already setup for cloud-init, so I created a cloud-init data file (note, the ‘#cloud-config’ comment at the top is important):
$ cat ./debian-data
#cloud-config
password: debian
chpasswd: { expire: false }
ssh_pwauth: true
and a cloud-init meta-data file:
$ cat ./debian-meta-data
instance-id: i-debian-sid-64
local-hostname: debian-sid-64
and fed that into cloud-localds to create a seed file:
$ cloud-localds -v ./debian-seed.img ./debian-data ./debian-meta-data
Then start the image with:
$ kvm -M pc -m 1024 -smp 1 -monitor pty -nographic -hda ./debian-sid-64.img -drive "file=./debian-seed.img,if=virtio,format=raw" -net nic -net user,hostfwd=tcp:127.0.0.1:59355-:22
(I’m using the invocation that is reminiscent of how spread invokes it; feel free to use a virtio invocation as described by Scott Moser if that better suits your environment.)
Here, the “59355” can be any unused high port. The idea is after the image boots, you can login with ssh using:
$ ssh -p 59355 debian@127.0.0.1
Once logged in, perform any updates, etc that you want in place when tests are run, then disable cloud-init for the next boot and cleanly shutdown with:
$ sudo touch /etc/cloud/cloud-init.disabled
$ sudo shutdown -h now
The above is the generalized procedure which can hopefully be adapted for other distros that provide cloud images, etc.
For integrating into spread, just copy the image to ‘~/.spread/qemu’, naming it how spread expects. spread will use ‘-snapshot’ with the VM as part of its tests, so if you want to update the images later since they might be out of date, omit the seed file (and optionally ‘-net nic -net user,hostfwd=tcp:127.0.0.1:59355-:22’ if you don’t need port forwarding), and use:
$ kvm -M pc -m 1024 -smp 1 -monitor pty -nographic -hda ./debian-sid-64.img
UPDATE 2019-04-23: the above is confirmed to work with Fedora 28, 29, 31 and 32 (though, if using the resulting image to test snapd, be sure to configure the password as ‘fedora’ and then be sure to ‘yum update ; yum install kernel-modules nc strace’ in the image).
UPDATE 2019-04-22: the above is confirmed to work with CentOS 7 and CentOS 8 (though, if using the resulting image to test snapd, be sure to configure the password as ‘centos’ and then be sure to ‘yum update ; yum install epel-release ; yum install golang nc strace’ in the image).
UPDATE 2020-02-16: https://wiki.debian.org/ContinuousIntegration/autopkgtest documents how to create autopkgtest images for Debian as ‘$ autopkgtest-build-qemu unstable autopkgtest-unstable.img’. This is confirmed to work on an Ubuntu 20.04 host but broken on an Ubuntu 18.04 host (seems to be https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=922501).
UPDATE 2020-06-27: the above is confirmed to work with Amazon Linux 2. The user is ‘ec2-user’. Booting without the seed image has password auth disabled, and the boot is slow due to nfs being enabled and it requires gssproxy to start before it and gssproxy.service doesn’t start due to lack of randomness. To workaround, can login and do (need to investigate and fix correctly via cloud-init (or just remove nfs-utils)):
$ sudo -i sh -c 'echo PasswordAuthentication yes >> /etc/ssh/sshd_config'
$ sudo mkdir /etc/systemd/system/gssproxy.service.d
$ sudo sh -c 'sed "s/Before=.*/Before=/" /usr/lib/systemd/system/gssproxy.service > /etc/systemd/system/gssproxy.service.d/local.conf'
$ sudo systemctl daemon-reload
UPDATE 2020-07-21: the above is confirmed to work with OpenSUSE 15.2 and the Tumbleweed JeOS appliance image. Spread doesn’t yet have this setup for qemu, but the user is ‘opensuse’. Configure the password as ‘opensuse’ then be sure to ‘zypper update ; zypper install apparmor-abstractions apparmor-profiles apparmor-utils rpmbuild squashfs’ (with Tumbleweed JeOS, also install ‘kernel-default’ for squashfs kernel support).
Extra steps for Debian cloud images without default e1000 networking
Unfortunately, for the Debian cloud images, there were additional steps because spread doesn’t use virtio, but instead the default the e1000 driver, and the Debian cloud kernel doesn’t include this:
$ grep E1000 /boot/config-4.19.0-4-cloud-amd64
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
So… when the machine booted, there was no networking. To adjust for this, I blew away the image, copied from the safely kept downloaded image, resized then started it with:
$ kvm -M pc -m 1024 -smp 1 -monitor pty -nographic -hda $HOME/.spread/qemu/debian-sid-64.img -drive "file=$HOME/.spread/qemu/debian-seed.img,if=virtio,format=raw" -device virtio-net-pci,netdev=eth0 -netdev type=user,id=eth0
This allowed the VM to start with networking, at which point I adjusted /etc/apt/sources.list to refer to ‘sid’ instead of ‘buster’ then ran apt-get update then apt-get dist-upgrade to upgrade to sid. I then installed the Debian distro kernel with:
$ sudo apt-get install linux-image-amd64
Then uninstalled the currently running kernel with:
$ sudo apt-get remove --purge linux-image-cloud-amd64 linux-image-4.19.0-4-cloud-amd64
(I used ‘dpkg -l | grep linux-image’ to see the cloud kernels I wanted to remove). Removing the package that provides the currently running kernel is a dangerous operation for most systems, so there is a scary message to abort the operation. In our case, it isn’t so scary (we can just try again ;) and this is exactly what we want to do.
Next I cleanly shutdown the VM with:
$ sudo shutdown -h now
and try to start it again like with the ‘general procedures’, above (I’m keeping the seed file here because I want cloud-init to be re-run with the e1000 driver):
$ kvm -M pc -m 1024 -smp 1 -monitor pty -nographic -hda ./debian-sid-64.img -drive "file=./debian-seed.img,if=virtio,format=raw" -net nic -net user,hostfwd=tcp:127.0.0.1:59355-:22
Now I try to login via ssh:
$ ssh -p 59355 debian@127.0.0.1
...
debian@127.0.0.1's password:
...
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Apr 16 16:13:15 2019
debian@debian:~$ sudo touch /etc/cloud/cloud-init.disabled
debian@debian:~$ sudo shutdown -h now
Connection to 127.0.0.1 closed.
While this VM is no longer the official cloud image, it is still using the Debian distro kernel and Debian archive, which is good enough for my purposes and at this point I’m ready to use this VM in my testing (eg, for me, copy ‘debian-sid-64.img’ to ‘~/.spread/qemu’).
Comments»
No comments yet — be the first.