diff --git a/coverage.sh b/coverage.sh index dc01ade..4b675e8 100755 --- a/coverage.sh +++ b/coverage.sh @@ -45,10 +45,11 @@ rm -f shared/cover_db.img if [ "$HAVE_QEMU" = "yes" ]; then # prepare image for cover_db - guestfish -N shared/cover_db.img=disk:64M -- mkfs vfat /dev/sda + fallocate -l 64M shared/cover_db.img + /usr/sbin/mkfs.vfat shared/cover_db.img - if [ ! -e "./shared/cache/debian-$DEFAULT_DIST.qcow" ]; then - echo "./shared/cache/debian-$DEFAULT_DIST.qcow does not exist" >&2 + if [ ! -e "./shared/cache/debian-$DEFAULT_DIST.ext4" ]; then + echo "./shared/cache/debian-$DEFAULT_DIST.ext4 does not exist" >&2 exit 1 fi fi diff --git a/make_mirror.sh b/make_mirror.sh index 5185000..6b7b865 100755 --- a/make_mirror.sh +++ b/make_mirror.sh @@ -65,7 +65,7 @@ deletecache() { ;; esac done - for f in "$dir/debian-"*.qcow; do + for f in "$dir/debian-"*.ext4; do if [ -e "$f" ]; then rm --one-file-system "$f" fi @@ -401,10 +401,7 @@ cleanuptmpdir() { if [ ! -e "$tmpdir" ]; then return fi - for f in "$tmpdir/worker.sh" \ - "$tmpdir/mini-httpd" "$tmpdir/hosts" \ - "$tmpdir/debian-chroot.tar" \ - "$tmpdir/mmdebstrap.service"; do + for f in "$tmpdir/worker.sh" "$tmpdir/mmdebstrap.service"; do if [ ! -e "$f" ]; then echo "does not exist: $f" >&2 continue @@ -418,17 +415,6 @@ SOURCE_DATE_EPOCH="$(date --date="$(grep-dctrl -s Date -n '' "$newmirrordir/dist export SOURCE_DATE_EPOCH if [ "$HAVE_QEMU" = "yes" ]; then - case "$HOSTARCH" in - amd64|i386|arm64) - # okay - ;; - *) - echo "qemu support is only available on amd64, i386 and arm64" >&2 - echo "because grub is only available on those arches" >&2 - exit 1 - ;; - esac - # we use the caching proxy again when building the qemu image # - we can re-use the packages that were already downloaded earlier # - we make sure that the qemu image uses the same Release file even @@ -448,49 +434,26 @@ if [ "$HAVE_QEMU" = "yes" ]; then exit 1 fi - # We must not use any --dpkgopt here because any dpkg options still - # leak into the chroot with chrootless mode. - # We do not use our own package cache here because - # - it doesn't (and shouldn't) contain the extra packages - # - it doesn't matter if the base system is from a different mirror timestamp - # procps is needed for /sbin/sysctl tmpdir="$(mktemp -d)" trap 'kill "$PROXYPID" || :;cleanuptmpdir; cleanup_newcachedir' EXIT INT TERM - pkgs=perl-doc,systemd-sysv,perl,arch-test,fakechroot,fakeroot,mount,uidmap,qemu-user-static,binfmt-support,qemu-user,dpkg-dev,mini-httpd,libdevel-cover-perl,libtemplate-perl,debootstrap,procps,apt-cudf,aspcud,python3,libcap2-bin,gpg,debootstrap,distro-info-data,iproute2,ubuntu-keyring,apt-utils,grub-efi,disorderfs,squashfs-tools-ng,genext2fs + pkgs=perl-doc,systemd-sysv,perl,arch-test,fakechroot,fakeroot,mount,uidmap,qemu-user-static,qemu-user,dpkg-dev,mini-httpd,libdevel-cover-perl,libtemplate-perl,debootstrap,procps,apt-cudf,aspcud,python3,libcap2-bin,gpg,debootstrap,distro-info-data,iproute2,ubuntu-keyring,apt-utils,disorderfs,squashfs-tools-ng,genext2fs,linux-image-generic if [ ! -e ./mmdebstrap ]; then pkgs="$pkgs,mmdebstrap" fi - case "$HOSTARCH" in - amd64|arm64) - pkgs="$pkgs,linux-image-$HOSTARCH" - ;; - i386) - pkgs="$pkgs,linux-image-686" - ;; - ppc64el) - pkgs="$pkgs,linux-image-powerpc64le" - ;; - *) - echo "no kernel image for $HOSTARCH" >&2 - exit 1 - ;; - esac - if [ "$HOSTARCH" = amd64 ] && [ "$RUN_MA_SAME_TESTS" = "yes" ]; then - arches=amd64,arm64 - pkgs="$pkgs,libfakechroot:arm64,libfakeroot:arm64" - elif [ "$HOSTARCH" = arm64 ] && [ "$RUN_MA_SAME_TESTS" = "yes" ]; then - arches=arm64,amd64 - pkgs="$pkgs,libfakechroot:amd64,libfakeroot:amd64" - else - arches=$HOSTARCH + arches=$HOSTARCH + if [ "$RUN_MA_SAME_TESTS" = "yes" ]; then + case "$HOSTARCH" in + amd64) + arches=amd64,arm64 + pkgs="$pkgs,libfakechroot:arm64,libfakeroot:arm64" + ;; + arm64) + arches=arm64,amd64 + pkgs="$pkgs,libfakechroot:amd64,libfakeroot:amd64" + ;; + esac fi - $CMD --variant=apt --architectures="$arches" --include="$pkgs" \ - --setup-hook='echo "Acquire::http::Proxy \"http://127.0.0.1:8080/\";" > "$1/etc/apt/apt.conf.d/00proxy"' \ - --customize-hook='rm "$1/etc/apt/apt.conf.d/00proxy"' \ - "$DEFAULT_DIST" - "$mirror" > "$tmpdir/debian-chroot.tar" - - kill $PROXYPID cat << END > "$tmpdir/mmdebstrap.service" [Unit] @@ -550,85 +513,32 @@ umount /mnt systemctl poweroff END chmod +x "$tmpdir/worker.sh" - # initially we serve from the new cache so that debootstrap can grab - # the new package repository and not the old - cat << END > "$tmpdir/mini-httpd" -START=1 -DAEMON_OPTS="-h 127.0.0.1 -p 80 -u nobody -dd /mnt/$newcache -i /var/run/mini-httpd.pid -T UTF-8" -END - cat << 'END' > "$tmpdir/hosts" -127.0.0.1 localhost -END - #libguestfs-test-tool - #export LIBGUESTFS_DEBUG=1 LIBGUESTFS_TRACE=1 - # - # In case the rootfs was prepared in fakechroot mode, ldconfig has to - # run to populate /etc/ld.so.cache or otherwise fakechroot tests will - # fail to run. - # - # The disk size is sufficient in most cases. Sometimes, gcc will do - # an upload with unstripped executables to make tracking down ICEs much - # easier (see #872672, #894014). During times with unstripped gcc, the - # buildd variant will not be 400MB but 1.3GB large and needs a 10G - # disk. if [ -z ${DISK_SIZE+x} ]; then DISK_SIZE=10G fi - case "$HOSTARCH" in - amd64) GRUB_TARGET=x86_64-efi;; - i386) GRUB_TARGET=i386-efi;; - arm64) GRUB_TARGET=arm64-efi;; - esac - case "$HOSTARCH" in - arm64) SERIAL="loglevel=3 console=tty0 console=ttyAMA0,115200n8" ;; - *) SERIAL="loglevel=3 console=tty0 console=ttyS0,115200n8" ;; - esac - guestfish -- \ - disk-create "$newcachedir/debian-$DEFAULT_DIST.qcow" qcow2 "$DISK_SIZE" : \ - add-drive "$newcachedir/debian-$DEFAULT_DIST.qcow" format:qcow2 : \ - launch : \ - part-init /dev/sda gpt : \ - part-add /dev/sda primary 8192 262144 : \ - part-add /dev/sda primary 262145 -34 : \ - part-set-gpt-type /dev/sda 1 C12A7328-F81F-11D2-BA4B-00A0C93EC93B : \ - mkfs ext2 /dev/sda2 : \ - mount /dev/sda2 / : \ - tar-in "$tmpdir/debian-chroot.tar" / xattrs:true : \ - mkdir-p /boot/efi : \ - mkfs vfat /dev/sda1 : \ - mount /dev/sda1 /boot/efi : \ - command /sbin/ldconfig : \ - mkdir-p /etc/systemd/system/multi-user.target.wants : \ - ln-s ../mmdebstrap.service /etc/systemd/system/multi-user.target.wants/mmdebstrap.service : \ - copy-in "$tmpdir/mmdebstrap.service" /etc/systemd/system/ : \ - copy-in "$tmpdir/worker.sh" / : \ - copy-in "$tmpdir/mini-httpd" /etc/default : \ - copy-in "$tmpdir/hosts" /etc/ : \ - touch /mmdebstrap-testenv : \ - command "sh -c 'echo UUID=\$(blkid -c /dev/null -o value -s UUID /dev/sda2) / ext4 errors=remount-ro 0 1 > /etc/fstab'" : \ - command "sh -c 'echo UUID=\$(blkid -c /dev/null -o value -s UUID /dev/sda1) /boot/efi vfat errors=remount-ro 0 2 >> /etc/fstab'" : \ - command "sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT=/GRUB_CMDLINE_LINUX_DEFAULT=\"biosdevname=0 net.ifnames=0 consoleblank=0 rw $SERIAL\"/' /etc/default/grub" : \ - command "update-initramfs -u" : \ - command "grub-mkconfig -o /boot/grub/grub.cfg" : \ - command "grub-install /dev/sda --target=$GRUB_TARGET --no-nvram --force-extra-removable --no-floppy --modules=part_gpt --grub-mkdevicemap=/boot/grub/device.map" : \ - sync : \ - umount /boot/efi : \ - umount / : \ - shutdown + # set PATH to pick up the correct mmdebstrap variant + env PATH="$(dirname "$(realpath --canonicalize-existing "$CMD")"):$PATH" \ + debvm-create --skip=usrmerge --size="$DISK_SIZE" \ + --release="$DEFAULT_DIST" --skip=usrmerge \ + --output="$newcachedir/debian-$DEFAULT_DIST.ext4" -- \ + --architectures="$arches" --include="$pkgs" \ + --setup-hook='echo "Acquire::http::Proxy \"http://127.0.0.1:8080/\";" > "$1/etc/apt/apt.conf.d/00proxy"' \ + --hook-dir=/usr/share/mmdebstrap/hooks/maybe-merged-usr \ + --customize-hook='rm "$1/etc/apt/apt.conf.d/00proxy"' \ + --customize-hook='mkdir -p "$1/etc/systemd/system/multi-user.target.wants"' \ + --customize-hook='ln -s ../mmdebstrap.service "$1/etc/systemd/system/multi-user.target.wants/mmdebstrap.service"' \ + --customize-hook='touch "$1/mmdebstrap-testenv"' \ + --customize-hook='copy-in "'"$tmpdir"'/mmdebstrap.service" /etc/systemd/system/' \ + --customize-hook='copy-in "'"$tmpdir"'/worker.sh" /' \ + --customize-hook='printf 127.0.0.1 localhost > "$1/etc/hosts"' \ + --customize-hook='printf "START=1\nDAEMON_OPTS=\"-h 127.0.0.1 -p 80 -u nobody -dd /mnt/cache -i /var/run/mini-httpd.pid -T UTF-8\"\n" > "$1/etc/default/mini-httpd"' \ + "$mirror" + + kill $PROXYPID cleanuptmpdir trap "cleanup_newcachedir" EXIT INT TERM fi -if [ "$HAVE_QEMU" = "yes" ]; then - # now replace the minihttpd config with one that serves the new repository - guestfish -a "$newcachedir/debian-$DEFAULT_DIST.qcow" -i < -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# The software is provided "as is", without warranty of any kind, express or -# implied, including but not limited to the warranties of merchantability, -# fitness for a particular purpose and noninfringement. In no event shall the -# authors or copyright holders be liable for any claim, damages or other -# liability, whether in an action of contract, tort or otherwise, arising -# from, out of or in connection with the software or the use or other dealings -# in the software. - -set -eu - -# This script creates debian-$RELEASE.qcow2 in the current directory which can -# then be used by the autopkgtest qemu backend. -# -# Thanks to Francesco Poli for providing ideas and testing this. -# -# Thanks to Lars Wirzenius of vmdb2 where the grub and efi magic comes from. -# -# Only the native architecture is supported because guestfish doesn't support -# foreign architectures. - -usage() { - echo "Usage: $0 [--size=SIZE] [--boot=BOOT] RELEASE IMAGE" >&2 - echo >&2 - echo "RELEASE is a Debian release like unstable" >&2 - echo "IMAGE will be stored in qcow2 format" >&2 - echo "SIZE is 25G by default" >&2 - echo "BOOT is either auto (the default), bios, efi or ieee1275" >&2 -} - -nativearch="$(dpkg --print-architecture)" - -SIZE="25G" # default from autopkgtest-build-qemu -BOOT="auto" -if [ "$#" -lt 2 ]; then - echo "Error: Insufficient number of arguments" >&2 - usage - exit 1 -elif [ "$#" -eq 2 ]; then - RELEASE=$1 - IMAGE=$2 -else - # parse options - OPTS=$(getopt -n "$0" -o h --long size:,boot:,architecture:,help -- "$@") - if [ "$?" -ne 0 ]; then - echo "Error: Cannot parse arguments" >&2 - usage - exit 1 - fi - eval set -- "$OPTS" - while true; do - case "$1" in - --size) SIZE="$2"; shift 2; continue;; - --boot) BOOT="$2"; shift 2; continue;; - --help) usage; exit 1;; - --architecture) - echo "Error: cannot (yet) create foreign architecture images" >&2 - exit 1 - ;; - --) shift; break;; - *) - echo "Error: unknown option $1" >&2 - usage - exit 1 - ;; - esac - done - RELEASE=$1 - IMAGE=$2 -fi - -# By default with --boot=auto (the default), bios boot is chosen for -# amd64 and i386. Compare /usr/share/autopkgtest/lib/autopkgtest_qemu.py -# But in practice, amd64 and i386 also support efi boot. But then -# autopkgtest-virt-qemu has to be run with --boot=efi -case "$BOOT" in - auto) - case "$nativearch" in - amd64|i386) BOOT=bios;; - armhf|arm64) BOOT=efi;; - ppc64el) BOOT=ieee1275;; - esac - ;; - bios) - case "$nativearch" in amd64|i386);; - *) - echo "bios booting only possible on amd64 and i386" >&2 - exit 1 - ;; - esac - ;; - efi) - case "$nativearch" in amd64|i386|armhf|arm64);; - *) - echo "efi booting only possible on amd64, i386, armhf and arm64" >&2 - exit 1 - ;; - esac - ;; - ieee1275) - if [ "$nativearch" != "ppc64el" ]; then - echo "ieee1275 booting only possible on ppc64el" >&2 - exit 1 - fi - ;; - *) - echo "invalid value for --boot" >&2;; -esac - -case "$nativearch" in - amd64) - [ $BOOT = bios ] || [ $BOOT = efi ] - if [ $BOOT = bios ]; then - include="linux-image-amd64 grub-pc" - grub_target="i386-pc" - elif [ $BOOT = efi ]; then - include="linux-image-amd64 grub-efi" - grub_target="x86_64-efi" - fi - ;; - arm64) - [ $BOOT = efi ] - include="linux-image-arm64 grub-efi" - grub_target="arm64-efi" - ;; - armhf) - [ $BOOT = efi ] - include="linux-image-armmp-lpae grub-efi" - grub_target="arm-efi" - ;; - i386) - [ $BOOT = bios ] || [ $BOOT = efi ] - if [ $BOOT = bios ]; then - include="linux-image-686-pae grub-pc" - grub_target="i386-pc" - elif [ $BOOT = efi ]; then - include="linux-image-686-pae grub-efi" - grub_target="i386-efi" - fi - ;; - ppc64el) - [ $BOOT = ieee1275 ] - include="linux-image-powerpc64le grub-ieee1275" - grub_target="powerpc-ieee1275" - ;; - *) - echo "architecture $nativearch not yet supported" >&2 - exit 1 - ;; -esac - -case "$nativearch" in - arm64|armhf) serial="loglevel=3 console=tty0 console=ttyAMA0,115200n8" ;; - ppc64el) serial="loglevel=3 console=tty0 console=hvc0,115200n8" ;; - *) serial="loglevel=3 console=tty0 console=ttyS0,115200n8" ;; -esac - -if ! command -v guestfish >/dev/null; then - echo "Error: requires guestfish being installed" >&2 - exit 1 -fi - -if [ ! -e /usr/share/autopkgtest/setup-commands/setup-testbed ]; then - echo "Error: requires autopkgtest being installed" >&2 - exit 1 -fi - -run_mmdebstrap() { - mmdebstrap --variant=important --include="$include" \ - --customize-hook='chroot "$1" passwd --delete root' \ - --customize-hook='chroot "$1" useradd --home-dir /home/user --create-home user' \ - --customize-hook='chroot "$1" passwd --delete user' \ - --customize-hook='echo host > "$1/etc/hostname"' \ - --customize-hook='echo "127.0.0.1 localhost host" > "$1/etc/hosts"' \ - --customize-hook='env AUTOPKGTEST_BUILD_QEMU=1 /usr/share/autopkgtest/setup-commands/setup-testbed "$1"' \ - "$RELEASE" - -} - -guestfish_bios() { - guestfish -- \ - disk-create "$IMAGE" qcow2 "$SIZE" : \ - add-drive "$IMAGE" format:qcow2 : \ - launch : \ - part-disk /dev/sda mbr : \ - part-set-bootable /dev/sda 1 true : \ - mkfs ext4 /dev/sda1 : mount /dev/sda1 / : \ - tar-in - / xattrs:true : \ - command "sh -c 'echo UUID=\$(blkid -c /dev/null -o value -s UUID /dev/sda1) / ext4 errors=remount-ro 0 1 > /etc/fstab'" : \ - command "update-initramfs -u" : \ - command "grub-mkconfig -o /boot/grub/grub.cfg" : \ - command "grub-install /dev/sda --target=$grub_target --no-nvram --force-extra-removable --no-floppy --modules=part_gpt --grub-mkdevicemap=/boot/grub/device.map" : \ - sync : umount / : shutdown -} - -guestfish_efi() { - guestfish -- \ - disk-create "$IMAGE" qcow2 "$SIZE" : \ - add-drive "$IMAGE" format:qcow2 : \ - launch : \ - part-init /dev/sda gpt : \ - part-add /dev/sda primary 8192 262144 : \ - part-add /dev/sda primary 262145 -34 : \ - part-set-gpt-type /dev/sda 1 C12A7328-F81F-11D2-BA4B-00A0C93EC93B : \ - mkfs ext4 /dev/sda2 : mount /dev/sda2 / : \ - tar-in - / xattrs:true : \ - mkdir-p /boot/efi : \ - mkfs vfat /dev/sda1 : mount /dev/sda1 /boot/efi : \ - command "sh -c 'echo UUID=\$(blkid -c /dev/null -o value -s UUID /dev/sda2) / ext4 errors=remount-ro 0 1 > /etc/fstab'" : \ - command "sh -c 'echo UUID=\$(blkid -c /dev/null -o value -s UUID /dev/sda1) /boot/efi vfat errors=remount-ro 0 2 >> /etc/fstab'" : \ - command "sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT=/GRUB_CMDLINE_LINUX_DEFAULT=\"biosdevname=0 net.ifnames=0 consoleblank=0 rw $serial\"/' /etc/default/grub" : \ - command "update-initramfs -u" : \ - command "grub-mkconfig -o /boot/grub/grub.cfg" : \ - command "grub-install /dev/sda --target=$grub_target --no-nvram --force-extra-removable --no-floppy --modules=part_gpt --grub-mkdevicemap=/boot/grub/device.map" : \ - sync : umount /boot/efi : umount / : shutdown -} - -guestfish_ieee1275() { - guestfish -- \ - disk-create "$IMAGE" qcow2 "$SIZE" : \ - add-drive "$IMAGE" format:qcow2 : \ - launch : \ - part-init /dev/sda gpt : \ - part-add /dev/sda primary 8192 20480 : \ - part-add /dev/sda primary 20481 -34 : \ - part-set-gpt-type /dev/sda 1 9E1A2D38-C612-4316-AA26-8B49521E5A8B : \ - mkfs ext4 /dev/sda2 : mount /dev/sda2 / : \ - tar-in - / xattrs:true : \ - command "sh -c 'echo UUID=\$(blkid -c /dev/null -o value -s UUID /dev/sda2) / ext4 errors=remount-ro 0 1 > /etc/fstab'" : \ - command "sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT=/GRUB_CMDLINE_LINUX_DEFAULT=\"biosdevname=0 net.ifnames=0 consoleblank=0 rw $serial\"/' /etc/default/grub" : \ - command "update-initramfs -u" : \ - command "grub-mkconfig -o /boot/grub/grub.cfg" : \ - command "grub-install /dev/sda --target=$grub_target --no-nvram --force-extra-removable --no-floppy --modules=part_gpt --grub-mkdevicemap=/boot/grub/device.map" : \ - sync : umount / : shutdown -} - -case "$BOOT" in - bios) run_mmdebstrap | guestfish_bios;; - efi) run_mmdebstrap | guestfish_efi;; - ieee1275) run_mmdebstrap | guestfish_ieee1275;; -esac - -echo "Success! The image is stored as $IMAGE" >&2 diff --git a/run_qemu.sh b/run_qemu.sh index 7099242..91a11b3 100755 --- a/run_qemu.sh +++ b/run_qemu.sh @@ -8,7 +8,6 @@ tmpdir="$(mktemp -d)" cleanup() { rv=$? - rm -f "$tmpdir/debian-$DEFAULT_DIST-overlay.qcow" rm -f "$tmpdir/log" [ -e "$tmpdir" ] && rmdir "$tmpdir" if [ -n "${TAIL_PID:-}" ]; then @@ -26,26 +25,6 @@ cleanup() { trap cleanup INT TERM EXIT -ARCH=$(dpkg --print-architecture) -case $ARCH in - i386) - MACHINE="accel=kvm:tcg" - CODE="/usr/share/OVMF/OVMF32_CODE_4M.secboot.fd" - QEMUARCH="i386" - ;; - amd64) - MACHINE="accel=kvm:tcg" - CODE="/usr/share/OVMF/OVMF_CODE.fd" - QEMUARCH="x86_64" - ;; - arm64) - MACHINE="type=virt,gic-version=host,accel=kvm" - CODE="/usr/share/AAVMF/AAVMF_CODE.fd" - QEMUARCH="aarch64" - ;; - *) echo "qemu kvm not supported on $ARCH" >&2;; -esac - echo 1 > shared/exitstatus.txt if [ -e shared/output.txt ]; then rm shared/output.txt @@ -54,27 +33,18 @@ touch shared/output.txt tail -f shared/output.txt & TAIL_PID=$! -# the path to debian-$DEFAULT_DIST.qcow must be absolute or otherwise qemu will -# look for the path relative to debian-$DEFAULT_DIST-overlay.qcow -qemu-img create -f qcow2 -b "$(realpath "$cachedir")/debian-$DEFAULT_DIST.qcow" -F qcow2 "$tmpdir/debian-$DEFAULT_DIST-overlay.qcow" # to connect to serial use: # minicom -D 'unix#/tmp/ttyS0' # # or this (quit with ctrl+q): # socat stdin,raw,echo=0,escape=0x11 unix-connect:/tmp/ttyS0 ret=0 -timeout --foreground 40m qemu-system-"$QEMUARCH" \ - -cpu host \ - -no-user-config \ - -M "$MACHINE" -m 4G -nographic \ - -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-pci,rng=rng0 \ +timeout --foreground 40m debvm-run --image="$(realpath "$cachedir")/debian-$DEFAULT_DIST.ext4" -- \ + -m 4G -snapshot \ -monitor unix:/tmp/monitor,server,nowait \ -serial unix:/tmp/ttyS0,server,nowait \ -serial unix:/tmp/ttyS1,server,nowait \ - -net nic,model=virtio -net user \ - -drive if=pflash,format=raw,unit=0,read-only=on,file="$CODE" \ -virtfs local,id=mmdebstrap,path="$(pwd)/shared",security_model=none,mount_tag=mmdebstrap \ - -drive file="$tmpdir/debian-$DEFAULT_DIST-overlay.qcow",cache=unsafe,index=0,if=virtio \ >"$tmpdir/log" 2>&1 || ret=$? if [ "$ret" -ne 0 ]; then cat "$tmpdir/log"