switch from guestfish to debvm

This commit is contained in:
Johannes Schauer Marin Rodrigues 2023-06-19 12:59:34 +02:00
parent e523741610
commit 956dcb42e1
Signed by untrusted user: josch
GPG key ID: F2CBA5C78FBD83E1
4 changed files with 40 additions and 414 deletions

View file

@ -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

View file

@ -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 <<EOF
upload -<<END /etc/default/mini-httpd
START=1
DAEMON_OPTS="-h 127.0.0.1 -p 80 -u nobody -dd /mnt/cache -i /var/run/mini-httpd.pid -T UTF-8"
END
EOF
fi
# delete possibly leftover symlink
if [ -e ./shared/cache.tmp ]; then
rm ./shared/cache.tmp

View file

@ -1,255 +0,0 @@
#!/bin/sh
#
# © 2022 Johannes Schauer Marin Rodrigues <josch@mister-muffin.de>
#
# 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

View file

@ -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"