Bug#1033291: autopkgtest-virt-qemu: support booting images created using debvm-create

2023-06-25 Thread Helmut Grohne
Control: tags -1 - patch

Hi Simon,

On Sun, Jun 25, 2023 at 12:00:21PM +0100, Simon McVittie wrote:
> Control: forwarded -1 
> https://salsa.debian.org/ci-team/autopkgtest/-/merge_requests/236

Thanks for the extensive review both here and on the MR. Please allow me
to ignore all the pycodestyle and similar things until we have a
solution that meets functional requirements.

> The inability to reboot into an updated initrd or kernel is quite
> significant for autopkgtest, and I'd be very tempted to call it a
> blocker: I think many of the tests that specifically want a VM, and
> are not satisfied with a lxc/podman container, are going to want that
> *because* they are doing kernel/initrd things. On the merge request
> (thanks for opening that!) I suggested a way to fix that limitation by
> running `qemu-system-whatever -no-reboot` in a loop, so that the kernel
> and initrd can be re-extracted after each shutdown (where reboot(8)
> in the VM is turned into a shutdown as a result of -no-reboot).

I think this together with the insight from your other mail that you
want to reduce divergence of test environments is really helpful
guidance. I was aware of the option of a -no-reboot loop (and that's
even mentioned in the debvm-run manual page), but that comes with the
complication of figuring out when to shut down (as you explained in
detail already). I need deeper understanding of the context to reply in
a useful way here.

Let me also give a different view on this. You argued that the main
reason to use the qemu backend is the ability to reboot. I do not agree
with this. From my point of view, the main motivation is the better
isolation (than lxc) and therefore lower risk of damage to my system. I
also note that there is a particular test restriction "needs-reboot" and
the new vmlinux boot mode could declare that it does not support this
restriction. Do you thin that this would be an ok-ish alternative to
properly implementing reboot?

> You say "cloud image" here, but official Debian cloud images are
> partitioned disks, and debvm uses a raw ext* filesystem filling the
> entire disk (no partition table). Did you mean "cloud kernel"?

Yes.

> I'm already not very happy with -virt-qemu's use of screen-scraping
> serial gettys, because screen-scraping an interactive shell isn't a
> reliable thing to do, and the root shell on tty1/hvc1 means we end up
> running the tests in a rather unrealistic environment that doesn't match
> anyone's real Debian system: in practice real Debian systems are much
> more likely to be server + ssh, or graphical console + display manager,
> or graphical or serial console + getty, and they're certainly not what
> we end up using with -virt-qemu (which is usually serial console +
> passwordless root shell + su into user shell).

Ok, that's news to me, but good to know. In a sense, debvm is in a
similar spot here. Its main purpose is providing reproducing some kind
of environment (e.g. for reproducing a bug). The realistic part is of
lower importance though. So for debvm, I chose three main ways to
interact with it:
 * qemu -nographic and a serial console is the default
 * Running qemu with a graphical interface (interactively) and this can
   use a regular tty login or a display manager
 * ssh

> The way I'm hoping to resolve that is to introduce a -virt-ssh setup
> script that shares code (the autopkgtest_qemu module) with -virt-qemu,
> at which point we can use some sort of early-boot mechanism (perhaps
> cloud-init, or the serial console, or debugfs, or a virtual CD-ROM
> containing a script) to inject an authorized ssh key into the image and
> (if necessary) install sshd, and then access it via ssh like an ordinary
> server from then on. That'll make the test environment more realistic.

I'm not sure how this is going to work for autopkgtest-virt-qemu. For
debvm, ease of interactive use was a primary goal (as you basically can
everything you can do with debvm directly with mmdebstrap + qemu).
Therefore, I opted for adding the authorized_keys setup to the image
construction and you can simply pass a key to debvm-create and it'll
also install the ssh server then. This is a different approach than the
one you describe here where the key is added retroactively. I think I
can support the mechanisms you describe here in a debvm-create step at
ease.

So how do we proceed here? Quite evidently, our goals diverge here.
While my goals are ease of unprivileged use, safe containment and broad
architecture support, your goals are reduction of divergence of test
beds and realistically reproducing regular environments if I capture
things correctly.

In any case, thanks for the extensive high quality feedback.

Helmut



Bug#1033291: autopkgtest-virt-qemu: support booting images created using debvm-create

2023-06-25 Thread Simon McVittie
Control: forwarded -1 
https://salsa.debian.org/ci-team/autopkgtest/-/merge_requests/236

On Tue, 21 Mar 2023 at 19:58:19 +0100, Helmut Grohne wrote:
>  * You cannot test bootloaders with this (obviously).
>  * You cannot test stuff that requires rebooting into an updated initrd
>or Linux kernel.
>  * You cannot use a non-ext filesystem.

The lack of bootloaders is a bit annoying, but not necessarily fatal:
we'll often already have a different bootloader per architecture.

The inability to reboot into an updated initrd or kernel is quite
significant for autopkgtest, and I'd be very tempted to call it a
blocker: I think many of the tests that specifically want a VM, and
are not satisfied with a lxc/podman container, are going to want that
*because* they are doing kernel/initrd things. On the merge request
(thanks for opening that!) I suggested a way to fix that limitation by
running `qemu-system-whatever -no-reboot` in a loop, so that the kernel
and initrd can be re-extracted after each shutdown (where reboot(8)
in the VM is turned into a shutdown as a result of -no-reboot).

> We include python3 here, because autopkgtest-virt-qemu says so. We also
> include a generic kernel image, because debvm prefers a cloud image,
> which lacks support for the 9p filesystem used by autopkgtest-virt-qemu
> (see #1027174). Then we must enable the additional serial gettys.

You say "cloud image" here, but official Debian cloud images are
partitioned disks, and debvm uses a raw ext* filesystem filling the
entire disk (no partition table). Did you mean "cloud kernel"?

I'm already not very happy with -virt-qemu's use of screen-scraping
serial gettys, because screen-scraping an interactive shell isn't a
reliable thing to do, and the root shell on tty1/hvc1 means we end up
running the tests in a rather unrealistic environment that doesn't match
anyone's real Debian system: in practice real Debian systems are much
more likely to be server + ssh, or graphical console + display manager,
or graphical or serial console + getty, and they're certainly not what
we end up using with -virt-qemu (which is usually serial console +
passwordless root shell + su into user shell).

The way I'm hoping to resolve that is to introduce a -virt-ssh setup
script that shares code (the autopkgtest_qemu module) with -virt-qemu,
at which point we can use some sort of early-boot mechanism (perhaps
cloud-init, or the serial console, or debugfs, or a virtual CD-ROM
containing a script) to inject an authorized ssh key into the image and
(if necessary) install sshd, and then access it via ssh like an ordinary
server from then on. That'll make the test environment more realistic.

I believe the only reason we need python3(-minimal) in the image is for
the eofcat tool that is used to capture commands' stdout/stderr, which
means we can discard that when using -virt-ssh.

smcv



Bug#1033291: autopkgtest-virt-qemu: support booting images created using debvm-create

2023-04-20 Thread Jochen Sprickerhof

Hi Helmut,

thanks for implementing this!

* Helmut Grohne  [2023-03-21 19:58]:

We include python3 here, because autopkgtest-virt-qemu says so. We also
include a generic kernel image, because debvm prefers a cloud image,
which lacks support for the 9p filesystem used by autopkgtest-virt-qemu
(see #1027174). Then we must enable the additional serial gettys. While
systemd has a getty generator, this generator cannot enable the consoles
that autopkgtest-virt-qemu needs. autopkgtest-virt-qemu really wants
boot messages one ttyS0 (or hvc0), so this is what we must pass as
console= boot parameter.

[..]

@@ -435,6 +488,18 @@
argv.append(
'if=pflash,format=raw,unit=1,file=%s/efivars.fd' % workdir
)
+elif boot == 'vmlinux':
+ext2_extract_boot_components(
+self.images[0].file, workdir + "/kernel", workdir + "/initrd"
+)
+label = subprocess.check_output(
+["/sbin/e2label", self.images[0].file], encoding="utf-8"
+).strip()
+argv.extend([
+"-kernel", workdir + "/kernel",
+"-initrd", workdir + "/initrd",
+"-append", "root=LABEL=%s rw console=ttyS0" % label,
+])
else:
adtlog.debug(
'Assuming nothing special needs to be done to set up '


Adding console=ttyS0 unconditionally seems to break arm64:

autopkgtest-virt-qemu --show-boot --qemu-architecture aarch64 
autopkgtest_arm64.ext4

In debvm-run we add it for amd64|i386 only:

https://sources.debian.org/src/debvm/0.2.10/bin/debvm-run/#L356

Attached is a patch to do the same here.

Cheers Jochen
diff --git a/lib/autopkgtest_qemu.py b/lib/autopkgtest_qemu.py
index cdb34ec..201313b 100644
--- a/lib/autopkgtest_qemu.py
+++ b/lib/autopkgtest_qemu.py
@@ -495,10 +495,13 @@ class Qemu:
 label = subprocess.check_output(
 ["/sbin/e2label", self.images[0].file], encoding="utf-8"
 ).strip()
+console = ""
+if self.qemu_architecture in ('i386', 'x86_64'):
+console = " console=ttyS0"
 argv.extend([
 "-kernel", workdir + "/kernel",
 "-initrd", workdir + "/initrd",
-"-append", "root=LABEL=%s rw console=ttyS0" % label,
+"-append", "root=LABEL=%s rw%s" % (label, console),
 ])
 else:
 adtlog.debug(


signature.asc
Description: PGP signature


Bug#1033291: autopkgtest-virt-qemu: support booting images created using debvm-create

2023-03-21 Thread Paul Gevers

Hi Helmut,

On 21-03-2023 19:58, Helmut Grohne wrote:

you may have heared about this shiny new thing called debvm. At least
Paul knows it as he helped me get its autopkgtests pass. Thank you. 


You're welcome. But for the rest of your bug, I'm too busy with Release 
Team work to think about it. If Antonio (or Simon) doesn't handle it, 
please ping this bug after the bookworm release. I'm trying hard to have 
a short freeze.


Paul


OpenPGP_signature
Description: OpenPGP digital signature


Bug#1033291: autopkgtest-virt-qemu: support booting images created using debvm-create

2023-03-21 Thread Helmut Grohne
Package: autopkgtest
Version: 5.28
Severity: wishlist
Control: affects -1 + debvm
X-Debbugs-Cc: jo...@debian.org, jspri...@debian.org

Hi Antonio and Paul,

you may have heared about this shiny new thing called debvm. At least
Paul knows it as he helped me get its autopkgtests pass. Thank you. This
is a tool for creating and running ephemeral virtual machines. And
autopkgtest-virt-qemu is a tool for running virtual machine images.
Sounds like these two should somehow fit together. This is exactly what
this bug is about.

debvm has a quite special idea how a virtual machine image looks like:
 * A virtual machine image is a (sparse) raw image.
 * It contains an ext2 (or later) filesystem.
 * The filesystem has a non-empty filesystem label.
 * The filesystem contains Linux kernel and initrd, but not a
   bootloader.

This makes some things very easy:
 * Since qemu becomes the actual bootloader, this removes a lot of
   architecture-specific issues and one can boot all architectures
   in a uniform way.
 * A raw image can easily be resized later
 * Generating such an image can be done entirely without root and this
   implies that running autopkgtests in qemu can be done entirely
   without root privileges.

There also are downsides:
 * You cannot test bootloaders with this (obviously).
 * You cannot test stuff that requires rebooting into an updated initrd
   or Linux kernel.
 * You cannot use a non-ext filesystem.

So this is not what everyone wants, but probably what some people want.

It also isn't like every image created by debvm-create just works. You
do need some options:

debvm-create -o autopkgtest.ext4 -z 10G -- \
--include python3,linux-image-generic \
--customize-hook='systemctl --root="$1" enable serial-getty@ttyS1 
serial-getty@hvc1' \
--customize-hook='sed "s/^deb /deb-src /" "$1/etc/apt/sources.list" > 
"$1/etc/apt/sources.list.d/src.list"' \
--customize-hook='APT_CONFIG=$MMDEBSTRAP_APT_CONFIG apt-get update'

We include python3 here, because autopkgtest-virt-qemu says so. We also
include a generic kernel image, because debvm prefers a cloud image,
which lacks support for the 9p filesystem used by autopkgtest-virt-qemu
(see #1027174). Then we must enable the additional serial gettys. While
systemd has a getty generator, this generator cannot enable the consoles
that autopkgtest-virt-qemu needs. autopkgtest-virt-qemu really wants
boot messages one ttyS0 (or hvc0), so this is what we must pass as
console= boot parameter. At the same time it wants a root shell on hvc1,
which is not considered by the generator even when passing
systemd.getty_auto, so we have to enable these at image construction
time. By default debvm will perform a root autologin on serial gettys,
so as soon as we enable them, they'll do the right thing for
autopkgtest-virt-qemu. And finally, we need to add deb-src lines as
debvm doesn't add them by default.

Once we have this image, we need to teach autopkgtest this strange boot
protocol of debvm and this is what this particular bug report is about.
I'm attaching a patch to autopkgtest that adds the --boot=vmlinux value
to implement this boot protocol as well as adding support for
--boot=auto. And with this patch, you can say

autopkgtest hello -- qemu autopkgtest.ext4

and have things just work.

What do you think? Do you like the feature idea? Do you like the patch?
This is a first iteration and probably not the last, but it definitely
should be good to start the conversation.

Helmut
diff -Nru autopkgtest-5.28/debian/changelog 
autopkgtest-5.28+nmu1/debian/changelog
--- autopkgtest-5.28/debian/changelog   2023-01-30 19:29:59.0 +0100
+++ autopkgtest-5.28+nmu1/debian/changelog  2023-03-21 13:52:17.0 
+0100
@@ -1,3 +1,10 @@
+autopkgtest (5.28+nmu1) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * virt-qemu: Support images created by debvm-create. (Closes: #-1)
+
+ -- Helmut Grohne   Tue, 21 Mar 2023 13:52:17 +0100
+
 autopkgtest (5.28) unstable; urgency=medium
 
   [ Jochen Sprickerhof ]
diff -Nru autopkgtest-5.28/lib/autopkgtest_qemu.py 
autopkgtest-5.28+nmu1/lib/autopkgtest_qemu.py
--- autopkgtest-5.28/lib/autopkgtest_qemu.py2023-01-30 19:29:59.0 
+0100
+++ autopkgtest-5.28+nmu1/lib/autopkgtest_qemu.py   2023-03-21 
13:52:17.0 +0100
@@ -36,6 +36,7 @@
 
 import errno
 import fcntl
+import itertools
 import json
 import os
 import re
@@ -46,6 +47,7 @@
 import tempfile
 import time
 from typing import (
+BinaryIO,
 List,
 Optional,
 Sequence,
@@ -124,6 +126,52 @@
 return []
 
 
+def call_debugfs(
+image: str, command: str, stdout: Optional[BinaryIO] = None
+) -> subprocess.CompletedProcess:
+result = subprocess.run(
+["/sbin/debugfs", "-R", command, image],
+stdout=stdout or subprocess.PIPE,
+stderr=subprocess.PIPE,
+)
+if result.returncode:
+raise ValueError(
+"command %r exited %d and stderr %r"