Hi Francesco,

On Fri, 08 Nov 2019 23:59:48 +0100 "Francesco Poli (wintermute)" 
<invernom...@paranoici.org> wrote:
> Hello and thanks for maintaining autopkgtest!
> 
> I wanted to give the QEMU/KVM testbed a try. Hence I tried to create
> a VM image by using autopkgtest-build-qemu. Its man page states:
> 
> [...]
> |      Note that you need to call this as root.
> [...]
> 
> And indeed the command
> 
>   $ autopkgtest-build-qemu unstable ~/var/cache/autopkgtest/sid.img
> 
> fails, when issued by a regular user, as it cannot even find parted
> in the search PATH.
> 
> I guess this is because of vmdb2, which requires superuser privileges.
> But why?
> Is there any hope to improve vmdb2 or to use another tool, in order
> to create a KVM testbed without requiring superuser privileges?

since you reported #944485 against mmdebstrap you already know that the answer
is "Yes" but I just stumbled across this bug and wanted to share one possible
solution with the readers here as well.

How to do it is described in the mmdebstrap man page under "Use as replacement
for autopkgtest-build-qemu and vmdb2" and the TLDR is:

    $ mmdebstrap --variant=important --include=linux-image-amd64 \
        --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=/usr/share/autopkgtest/setup-commands/setup-testbed \
        unstable debian-unstable.tar
    $ cat << END > extlinux.conf
    > default linux
    > timeout 0
    >
    > label linux
    > kernel /vmlinuz
    > append initrd=/initrd.img root=/dev/vda1 console=ttyS0
    END
    $ guestfish -N debian-unstable.img=disk:8G -- \
        part-disk /dev/sda mbr : \
        part-set-bootable /dev/sda 1 true : \
        mkfs ext2 /dev/sda1 : mount /dev/sda1 / : \
        tar-in debian-unstable.tar / xattrs:true : \
        extlinux / : copy-in extlinux.conf / : \
        sync : umount / : shutdown
    $ qemu-img convert -O qcow2 debian-unstable.img debian-unstable.qcow2

Unfortunately, extlinux is only available on amd64 and i386. To support more
architectures we have to boot using grub. Because this becomes a bit more
complicated I put the whole thing into a script:

https://salsa.debian.org/debian/mmdebstrap/-/blob/master/mmdebstrap-autopkgtest-build-qemu

This now works on amd64, arm64, armhf, i386 and ppc64el. But it only works for
building *native* qemu images because guestfish cannot handle foreign
architecture emulation. I see five options that allow avoiding guestfish for
building foreign architecture bootable images without being root.

Option 1 is to run guestfish inside another qemu instance. This is extremely
slow though. Since it's also easiest to set-up I won't go further into this
option here.

Option 2 is to do the partition setup and bootloader installation as an
initramfs hook script:

main script: http://paste.debian.net/1235312/
initramfs-hook: http://paste.debian.net/1235313/
initramfs-script: http://paste.debian.net/1235314/

Option 3 is to use debian-installer and use pre-seeding to make the whole
process unattended. I managed to get this working for amd64, i386, arm64 and
ppc64el. Here is how to do it for ppc64el:

    $ qemu-img create -f qcow2 disk.qcow 4G
    $ curl 
https://deb.debian.org/debian/dists/bullseye/main/installer-ppc64el/current/images/netboot/debian-installer/ppc64el/initrd.gz
 > initrd.gz
    $ curl 
https://deb.debian.org/debian/dists/bullseye/main/installer-ppc64el/current/images/netboot/debian-installer/ppc64el/vmlinux
 > linux
    $ qemu-system-ppc64le -no-reboot -machine pseries,graphics=off -serial 
stdio -display none -monitor none -m 1G -initrd initrd.gz -kernel linux -append 
'console=hvc0 auto-install/enable=true debconf/priority=critical 
preseed/url=http://www.debian.org/releases/stable/example-preseed.txt 
netcfg/get_hostname=hostname netcfg/get_domain=domain 
passwd/root-password=r00tme passwd/root-password-again=r00tme 
passwd/user-fullname=user passwd/username=user passwd/user-password=insecure 
passwd/user-password-again=insecure pkgsel/run_tasksel=false 
popularity-contest:popularity-contest/participate=false 
grub-installer/bootdev=/dev/sda1' -hda disk.qcow

Option 4 is to use u-boot-qemu like this (in case of riscv64):

    $ mmdebstrap --arch=riscv64 --variant=apt \
        --include=linux-image-riscv64,u-boot-menu,systemd-sysv
        --customize-hook='printf "U_BOOT_PARAMETERS=\"rw noquiet 
root=/dev/vda1\"\nU_BOOT_FDT_DIR=\"noexist\"\n" > "$1"/etc/default/u-boot' \
        --customize-hook='chroot "$1" u-boot-update' \
        unstable chroot.tar \
        "deb http://deb.debian.org/debian-ports/ sid main" \
        "deb http://deb.debian.org/debian-ports/ unreleased main"
    $ genext2fs --block-size 1024 --size-in-blocks 2097152 --bytes-per-inode 
16384 --tarball chroot.tar root.img
    $ dd if=root.img of=disk.img seek=1 bs=4194304
    $ dd if=/dev/zero bs=512 count=1 >> disk.img
    $ /sbin/parted -s disk.img "mklabel msdos"
    $ printf debi | dd of=disk.img seek=440 bs=1 conv=notrunc
    $ /sbin/parted -s disk.img "mkpart primary ext4 4MiB 2052MiB"

Option 5 is the same as above but will work for architectures without
u-boot-qemu support. Without a bootloader, the kernel and initrd can be passed
to qemu manually via -kernel and -initrd arguments.

While the last two options seem to be fragile, they have the advantage of
producing bit-by-bit reproducible output. The last option is also the only
option that works for all our architectures including mips*.

So now we have seven different option of creating a (native or foreign)
bootable Debian image without being root. Locally I have scripts for all of
these and I'm tempted to put any of these into a script so that it gets easier
to create images for autopkgtest-virt-qemu without superuser privileges.

On the other hand, I'm really not keen on adding yet another tool to this long
list:

https://wiki.debian.org/SystemBuildTools#General_tools

Thanks!

cheers, josch

Attachment: signature.asc
Description: signature

Reply via email to