From 2e6af14e94237167a692496265ab124921810460 Mon Sep 17 00:00:00 2001 From: Christian Kastner Date: Mon, 11 Jan 2021 13:04:24 +0100 Subject: feat: Add QEMU amd64 (BIOS, UEFI) support This is analogous to the arm64 support via QEMU, with additonal support for BIOS. --- amd64-uefi.vmdb | 63 +++++++++++++++++++++++++++++++ amd64.vmdb | 56 ++++++++++++++++++++++++++++ check-all | 11 ++++++ smoke-amd64.sh | 8 ++++ smoke-amd64.vmdb | 72 +++++++++++++++++++++++++++++++++++ smoke-amd64.yarn | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++ smoke-uefi-amd64.vmdb | 76 +++++++++++++++++++++++++++++++++++++ 7 files changed, 387 insertions(+) create mode 100644 amd64-uefi.vmdb create mode 100644 amd64.vmdb create mode 100755 smoke-amd64.sh create mode 100644 smoke-amd64.vmdb create mode 100644 smoke-amd64.yarn create mode 100644 smoke-uefi-amd64.vmdb diff --git a/amd64-uefi.vmdb b/amd64-uefi.vmdb new file mode 100644 index 0000000..872de16 --- /dev/null +++ b/amd64-uefi.vmdb @@ -0,0 +1,63 @@ +# This is a sample VMDB2 input file that specifies a simple system for +# an amd64 machine that boots with UEFI. + +steps: + - mkimg: "{{ output }}" + size: 4G + + - mklabel: gpt + device: "{{ output }}" + + - mkpart: primary + device: "{{ output }}" + start: 0% + end: 1G + tag: efi + + - mkpart: primary + device: "{{ output }}" + start: 1G + end: 100% + tag: / + + - kpartx: "{{ output }}" + + - mkfs: vfat + partition: efi + + - mkfs: ext4 + partition: / + + - mount: / + + # Using the virtual-filesystems plugin here upsets qemu-debootstrap, + # which ends up unable to create /dev/fd within the chroot, causing + # the qemu-debootstrap phase to fail. Until we get to the bottom + # that, don't enable the plugin. + #- virtual-filesystems: / + + - unpack-rootfs: / + + - qemu-debootstrap: buster + arch: amd64 + mirror: http://deb.debian.org/debian + target: / + unless: rootfs_unpacked + + - apt: install + packages: + - linux-image-amd64 + fs-tag: / + unless: rootfs_unpacked + + - cache-rootfs: / + unless: rootfs_unpacked + + - chroot: / + shell: | + sed -i '/^root:[^:]*:/s//root::/' /etc/passwd + echo amd64-uefi-vmdb2 > /etc/hostname + + - grub: uefi + tag: / + efi: efi diff --git a/amd64.vmdb b/amd64.vmdb new file mode 100644 index 0000000..e8efe72 --- /dev/null +++ b/amd64.vmdb @@ -0,0 +1,56 @@ +# This is a sample VMDB2 input file to specify a simple +# system that boots on a 32-bit PC with BIOS. + +steps: + - mkimg: "{{ output }}" + size: 4G + + - mklabel: msdos + device: "{{ output }}" + + - mkpart: primary + device: "{{ output }}" + start: 0% + end: 50% + tag: / + + - kpartx: "{{ output }}" + + - mkfs: ext4 + partition: / + + - mount: / + + - unpack-rootfs: / + + - qemu-debootstrap: buster + arch: amd64 + mirror: http://deb.debian.org/debian + target: / + unless: rootfs_unpacked + + - apt: install + packages: + - linux-image-amd64 + tag: / + unless: rootfs_unpacked + + - cache-rootfs: / + unless: rootfs_unpacked + + - chroot: / + shell: | + echo amd64 > /etc/hostname + apt -y install python3 parted + + - fstab: / + + - chroot: / + shell: | + sed -i 's,^root:[^:]*:,root::,' /etc/passwd + + - resize-rootfs: / + + - grub: bios + tag: / + quiet: false diff --git a/check-all b/check-all index b4ff3a6..34307c5 100755 --- a/check-all +++ b/check-all @@ -45,6 +45,17 @@ then done fi +if [ -e /usr/share/OVMF/OVMF_VARS_4M.fd ] +then + bash -x ./smoke-amd64.sh "$amd64_tarball" +fi +tryit "$tarballdir/amd64.img" "amd64.vmdb" "$amd64_tarball" + +if [ -e /usr/share/OVMF/OVMF_VARS_4M.fd ] +then + tryit "$tarballdir/amd64-uefi.img" "amd64-uefi.vmdb" "$amd64_tarball" +fi + if [ -e /usr/share/OVMF/OVMF32_VARS_4M.fd ] then bash -x ./smoke-i386.sh "$i386_tarball" diff --git a/smoke-amd64.sh b/smoke-amd64.sh new file mode 100755 index 0000000..39691e9 --- /dev/null +++ b/smoke-amd64.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -eu + +tarball="$1" +shift + +yarn smoke-amd64.yarn --env ROOTFS_TARBALL="$tarball" "$@" diff --git a/smoke-amd64.vmdb b/smoke-amd64.vmdb new file mode 100644 index 0000000..ba337ac --- /dev/null +++ b/smoke-amd64.vmdb @@ -0,0 +1,72 @@ +steps: + - mkimg: "{{ output }}" + size: 4G + + - mklabel: msdos + device: "{{ output }}" + + - mkpart: primary + device: "{{ output }}" + start: 1M + end: 10M + tag: unused + + - mkpart: primary + device: "{{ output }}" + start: 10M + end: 100% + tag: rootfs + + - kpartx: "{{ output }}" + + - mkfs: ext4 + partition: rootfs + label: smoke + + - mount: rootfs + + - create-dir: /smoke-dir + perm: 0777 + uid: 1000 + gid: 1000 + + - create-file: /smoke-create-file.txt + contents: No smoke here. + perm: 0777 + uid: 1000 + gid: 1000 + + - copy-file: /smoke-copy-file.txt + src: smoke-copy-file.txt + perm: 0777 + uid: 1000 + gid: 1000 + + - unpack-rootfs: rootfs + + - qemu-debootstrap: buster + arch: amd64 + mirror: http://deb.debian.org/debian + keyring: /usr/share/keyrings/debian-archive-keyring.gpg + target: rootfs + unless: rootfs_unpacked + + - apt: install + packages: + - linux-image-amd64 + tag: rootfs + unless: rootfs_unpacked + + - cache-rootfs: rootfs + unless: rootfs_unpacked + + - chroot: rootfs + shell: | + sed -i '/^root:[^:]*:/s//root::/' /etc/passwd + echo amd64-vmdb2 > /etc/hostname + + - fstab: rootfs + + - grub: bios + tag: rootfs + console: serial diff --git a/smoke-amd64.yarn b/smoke-amd64.yarn new file mode 100644 index 0000000..155ee07 --- /dev/null +++ b/smoke-amd64.yarn @@ -0,0 +1,101 @@ +# Smoke test vmdb2-built images + +This yarn file builds a basic image, and runs it under Qemu. The image +is configured to have a serial console enabled, and the scenario below +will log in as root (no password), and command the virtual machine to +power off. If this works, the image is at least minimally functional, +so the "smoke test" passes. + +More elaborate testing can be added, but smoke testing is enough for +now. + +To run this yarn file, you need to run it as root (since it needs to +build an image as root), and you need to run on a system where +qemu-system-x86_64 is installed. Additionally, you need to add the +following option to yarn: + EXAMPLE + --env ROOTFS_TARBALL=/path/to/rootfs/tarball + +This means vmdb2 will use the given tarball when creating an image, +and if the tarball doesn't exist yet, it will create it. This makes +testing multiple time much faster. + + SCENARIO smoke test amd64 image + WHEN user runs vmdb smoke-amd64.vmdb --output smoke-amd64.img + THEN user can BIOS boot smoke-amd64.img and power it off from root shell + + WHEN user runs vmdb smoke-uefi-amd64.vmdb --output smoke-uefi-amd64.img + THEN user can UEFI boot smoke-uefi-amd64.img and power it off from root shell + + IMPLEMENTS WHEN user runs vmdb (\S+) --output (\S+) + "$SRCDIR/vmdb2" "$SRCDIR/$MATCH_1" \ + --output "$DATADIR/$MATCH_2" \ + --log "$DATADIR/vmdb.log" \ + --verbose \ + --rootfs-tarball "$ROOTFS_TARBALL" + + IMPLEMENTS THEN user can BIOS boot (\S+) and power it off from root shell + cd "$DATADIR" + img="$MATCH_1" + cat << EOF > run.sh + qemu-system-x86_64 -drive file="$img",format=raw -m 1024 -nographic + EOF + chmod a+rx run.sh + cat << EOF > expect.txt + set timeout 300 + proc abort {} { + puts "ERROR ERROR\n" + exit 1 + } + spawn ./run.sh + expect "login: " + send "root\n" + expect "# " + send "poweroff\r" + set timeout 5 + expect { + "reboot: Power down" {puts poweroffing\n} + eof abort + timeout abort + } + expect eof + wait + EOF + expect -d expect.txt > expect.out + + IMPLEMENTS THEN user can UEFI boot (\S+) and power it off from root shell + cd "$DATADIR" + img="$MATCH_1" + cat << EOF > run.sh + cp /usr/share/OVMF/OVMF_VARS_4M.fd . + qemu-system-x86_64 \ + -machine q35 \ + -cpu max \ + -m 1024 \ + -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE_4M.fd,readonly=on \ + -drive if=pflash,format=raw,unit=1,file=OVMF_VARS_4M.fd \ + -drive format=raw,file="$img" \ + -nographic + EOF + chmod a+rx run.sh + cat << EOF > expect.txt + set timeout 600 + proc abort {} { + puts "ERROR ERROR\n" + exit 1 + } + spawn ./run.sh + expect "login: " + send "root\n" + expect "# " + send "poweroff\r" + set timeout 5 + expect { + "reboot: Power down" {puts poweroffing\n} + eof abort + timeout abort + } + expect eof + wait + EOF + expect -d expect.txt > expect.out diff --git a/smoke-uefi-amd64.vmdb b/smoke-uefi-amd64.vmdb new file mode 100644 index 0000000..3044801 --- /dev/null +++ b/smoke-uefi-amd64.vmdb @@ -0,0 +1,76 @@ +steps: + - mkimg: "{{ output }}" + size: 4G + + - mklabel: gpt + device: "{{ output }}" + + - mkpart: primary + device: "{{ output }}" + start: 0% + end: 1G + tag: efifs + + - mkpart: primary + device: "{{ output }}" + start: 1G + end: 100% + tag: rootfs + + - kpartx: "{{ output }}" + + - mkfs: vfat + partition: efifs + + - mkfs: ext4 + partition: rootfs + label: smoke + + - mount: rootfs + + - create-dir: /smoke-dir + perm: 0777 + uid: 1000 + gid: 1000 + + - create-file: /smoke-create-file.txt + contents: No smoke here. + perm: 0777 + uid: 1000 + gid: 1000 + + - copy-file: /smoke-copy-file.txt + src: smoke-copy-file.txt + perm: 0777 + uid: 1000 + gid: 1000 + + - unpack-rootfs: rootfs + + - qemu-debootstrap: buster + arch: amd64 + mirror: http://deb.debian.org/debian + keyring: /usr/share/keyrings/debian-archive-keyring.gpg + target: rootfs + unless: rootfs_unpacked + + - apt: install + packages: + - linux-image-amd64 + tag: rootfs + unless: rootfs_unpacked + + - cache-rootfs: rootfs + unless: rootfs_unpacked + + - chroot: rootfs + shell: | + sed -i '/^root:[^:]*:/s//root::/' /etc/passwd + echo amd64-vmdb2 > /etc/hostname + + - fstab: rootfs + + - grub: uefi + tag: rootfs + efi: efifs + console: serial -- cgit v1.2.1