Richard W.M. Jones
2022-Jun-08 16:49 UTC
[Libguestfs] [PATCH virt-v2v 2/3] test-data/phony-guests: Allow virt-v2v to work against phony Fedora
We didn't use the phony Fedora guest before with virt-v2v (only the
phony Windows image). This commit makes miscellaneous changes so that
it can be used for testing:
- Add dummy rpm and dracut commands.
- Add dummy kernel, initramfs and modules directory.
- Add dummy grub configuration pointing to the kernel.
---
.gitignore | 1 +
test-data/phony-guests/Makefile.am | 19 +++++--
test-data/phony-guests/fedora.c | 67 +++++++++++++++++++++++
test-data/phony-guests/make-fedora-img.pl | 26 ++++++++-
4 files changed, 108 insertions(+), 5 deletions(-)
diff --git a/.gitignore b/.gitignore
index ac7d6a3ce0..04ab847dcd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -117,6 +117,7 @@ Makefile.in
/test-data/phony-guests/fedora-luks.img
/test-data/phony-guests/fedora-md1.img
/test-data/phony-guests/fedora-md2.img
+/test-data/phony-guests/fedora-static-bin
/test-data/phony-guests/fedora.db
/test-data/phony-guests/guests.xml
/test-data/phony-guests/guests-all-good.xml
diff --git a/test-data/phony-guests/Makefile.am
b/test-data/phony-guests/Makefile.am
index 60313548af..c45ddc1123 100644
--- a/test-data/phony-guests/Makefile.am
+++ b/test-data/phony-guests/Makefile.am
@@ -76,7 +76,8 @@ blank-%.img:
# Make a (dummy) Fedora image.
fedora.img: make-fedora-img.pl \
fedora-journal.tar.xz \
- fedora.db
+ fedora.db \
+ fedora-static-bin
SRCDIR=$(srcdir) LAYOUT=partitions $(top_builddir)/run --test ./$<
# Make a (dummy) Fedora image using md devices
@@ -84,7 +85,8 @@ fedora-md1.img fedora-md2.img: stamp-fedora-md.img
stamp-fedora-md.img: make-fedora-img.pl \
fedora-journal.tar.xz \
- fedora.db
+ fedora.db \
+ fedora-static-bin
rm -f $@
SRCDIR=$(srcdir) LAYOUT=partitions-md $(top_builddir)/run --test ./$<
touch $@
@@ -93,13 +95,15 @@ stamp-fedora-md.img: make-fedora-img.pl \
# for root and home.
fedora-btrfs.img: make-fedora-img.pl \
fedora-journal.tar.xz \
- fedora.db
+ fedora.db \
+ fedora-static-bin
SRCDIR=$(srcdir) LAYOUT=btrfs $(top_builddir)/run --test ./$<
# Make a (dummy) Fedora image with LVM encrypted with LUKS.
fedora-luks.img: make-fedora-img.pl \
fedora-journal.tar.xz \
- fedora.db
+ fedora.db \
+ fedora-static-bin
SRCDIR=$(srcdir) LAYOUT=lvm-luks $(top_builddir)/run --test ./$<
# Make a (dummy) Debian image.
@@ -137,6 +141,13 @@ fedora.db: fedora-db.sql.xz
xzcat $< | $(SQLITE3) $@-t
mv $@-t $@
+# This is included in the phony Fedora image to act as a phony "rpm"
+# and "dracut" command. For the use of -all-static here, see
+# libguestfs/tests/Makefile.am
+check_PROGRAMS = fedora-static-bin
+fedora_static_bin_SOURCES = fedora.c
+fedora_static_bin_LDFLAGS = -all-static
+
windows-software: windows-software.reg
rm -f $@ $@-t
cp $(srcdir)/minimal-hive $@-t
diff --git a/test-data/phony-guests/fedora.c b/test-data/phony-guests/fedora.c
new file mode 100644
index 0000000000..36eaa233fc
--- /dev/null
+++ b/test-data/phony-guests/fedora.c
@@ -0,0 +1,67 @@
+/* libguestfs test images
+ * Copyright (C) 2009-2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA.
+ */
+
+/* This is "just enough" of a binary to look like RPM and dracut, as
+ * far as virt-v2v is concerned.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+/* NB: This is also defined in make-fedora-img.pl */
+#define KVER "5.19.0-0.rc1.14.fc37.x86_64"
+
+static const char *
+basename (const char *str)
+{
+ const char *ret = strrchr (str, '/');
+ return ret == NULL ? str : ret + 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (argc == 3 &&
+ strcmp (basename (argv[0]), "rpm") == 0 &&
+ strcmp (argv[1], "-ql") == 0 &&
+ strncmp (argv[2], "kernel-", 7) == 0) {
+ /* XXX These files and directories actually exist. It would be
+ * better to list files in /boot and /lib/modules matching a
+ * pattern rather than hard-coding the list here, which duplicates
+ * information in make-fedora-img.pl.
+ */
+ printf ("/boot/vmlinuz-" KVER "\n");
+ printf ("/lib/modules/" KVER "\n");
+ printf ("/lib/modules/" KVER "/kernel\n");
+ printf ("/lib/modules/" KVER "/kernel/drivers\n");
+ printf ("/lib/modules/" KVER
"/kernel/drivers/block\n");
+ printf ("/lib/modules/" KVER
"/kernel/drivers/block/virtio_blk.ko\n");
+ }
+ else if (argc >= 1 &&
+ strcmp (basename (argv[0]), "dracut") == 0) {
+ // do nothing, pretend to rebuild the initramfs
+ }
+ else {
+ fprintf (stderr, "phony Fedora: unknown command\n");
+ exit (1);
+ }
+
+ exit (0);
+}
diff --git a/test-data/phony-guests/make-fedora-img.pl
b/test-data/phony-guests/make-fedora-img.pl
index f340f4d744..ad30960fa3 100755
--- a/test-data/phony-guests/make-fedora-img.pl
+++ b/test-data/phony-guests/make-fedora-img.pl
@@ -240,6 +240,7 @@ $g->mount ($bootdev, '/boot');
$g->mkdir ('/bin');
$g->mkdir ('/etc');
$g->mkdir ('/etc/sysconfig');
+$g->mkdir ('/sbin');
$g->mkdir ('/usr');
$g->mkdir ('/usr/share');
$g->mkdir ('/usr/share/zoneinfo');
@@ -276,8 +277,17 @@ $g->upload
($ENV{SRCDIR}.'/../binaries/bin-x86_64-dynamic', '/bin/ls');
$g->tar_in ($ENV{SRCDIR}.'/fedora-journal.tar.xz',
'/var/log/journal', compress => "xz");
+# NB: This is also defined in fedora.c
+my $kver = "5.19.0-0.rc1.14.fc37.x86_64";
$g->mkdir ('/boot/grub');
-$g->touch ('/boot/grub/grub.conf');
+$g->write ('/boot/grub/grub.conf', <<EOF);
+title Fedora
+ root (hd0,0)
+ kernel /vmlinuz-$kver
+ initrd /initramfs-$kver.img
+EOF
+
+$g->touch ('/etc/modprobe.conf');
# Test files.
$g->write ('/etc/test1', 'abcdefg');
@@ -300,6 +310,20 @@ $g->ln_s ('/bin/test1', '/bin/test5');
$g->mkfifo (0777, '/bin/test6');
$g->mknod (0777, 10, 10, '/bin/test7');
+# Virt-v2v needs an RPM command, or at least something which acts
+# similarly, and also a dracut command.
+$g->upload ('fedora-static-bin', '/bin/rpm');
+$g->chmod (0777, '/bin/rpm');
+$g->upload ('fedora-static-bin', '/sbin/dracut');
+$g->chmod (0777, '/sbin/dracut');
+
+# Virt-v2v also needs a kernel, initrd and modules path.
+$g->touch ("/boot/vmlinuz-$kver");
+$g->touch ("/boot/initramfs-$kver.img");
+$g->mkdir_p ("/lib/modules/$kver/kernel/drivers/block");
+$g->upload ($ENV{SRCDIR}.'/../binaries/bin-x86_64-dynamic',
+ "/lib/modules/$kver/kernel/drivers/block/virtio_blk.ko");
+
# Cleanup
$g->shutdown ();
$g->close ();
--
2.35.1
Richard W.M. Jones
2022-Jun-09 08:08 UTC
[Libguestfs] [PATCH virt-v2v 2/3] test-data/phony-guests: Allow virt-v2v to work against phony Fedora
On Wed, Jun 08, 2022 at 05:49:01PM +0100, Richard W.M. Jones wrote:> +# Virt-v2v also needs a kernel, initrd and modules path. > +$g->touch ("/boot/vmlinuz-$kver"); > +$g->touch ("/boot/initramfs-$kver.img"); > +$g->mkdir_p ("/lib/modules/$kver/kernel/drivers/block"); > +$g->upload ($ENV{SRCDIR}.'/../binaries/bin-x86_64-dynamic', > + "/lib/modules/$kver/kernel/drivers/block/virtio_blk.ko");Surprisingly this works even on !x86-64. I just tested it on aarch64. Here: https://github.com/libguestfs/virt-v2v/blob/0d1b2ec1b733db1ca0bebf2e4a9e8d5fd7db7f93/convert/linux_kernels.ml#L192 we use guestfs_file_architecture on a kernel module to determine the architecture of the kernel. Because we uploaded an x86-64 binary this means we detect the kernel as being x86_64: installed kernel packages in this guest: * kernel 5.19.0-0.rc1.14.fc37.x86_64 (x86_64) <------- ki_arch /boot/vmlinuz-5.19.0-0.rc1.14.fc37.x86_64 /boot/initramfs-5.19.0-0.rc1.14.fc37.x86_64.img no config /lib/modules/5.19.0-0.rc1.14.fc37.x86_64 1 modules found virtio: blk=true net=false rng=false balloon=false pvpanic=false vsock=false xen=false debug=false Then we run dracut, which would fail on a real guest if the host is aarch64, but succeeds here because the phony dracut binary is aarch64: libguestfs: trace: v2v: command "/sbin/dracut --verbose --add-drivers virtio_blk /boot/initramfs-5.19.0-0.rc1.14.fc37.x86_64.img 5.19.0-0.rc1.14.fc37.x86_64" Later: gcaps_block_bus = virtio-blk gcaps_net_bus = e1000 gcaps_virtio_rng = false gcaps_virtio_balloon = false gcaps_isa_pvpanic = false gcaps_virtio_socket = false gcaps_machine = i440fx gcaps_arch = x86_64 <--------- gcaps_acpi = true gcaps_virtio_1_0 = false gcaps_default_cpu = true Anyway this is kind of a bug in virt-v2v (because it should reject conversion of a !hostarch guest), and also in this test, but this is a fairly obscure corner case so I guess I'll leave it for now. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org
Laszlo Ersek
2022-Jun-09 08:13 UTC
[Libguestfs] [PATCH virt-v2v 2/3] test-data/phony-guests: Allow virt-v2v to work against phony Fedora
On 06/08/22 18:49, Richard W.M. Jones wrote:> We didn't use the phony Fedora guest before with virt-v2v (only the > phony Windows image). This commit makes miscellaneous changes so that > it can be used for testing: > > - Add dummy rpm and dracut commands. > > - Add dummy kernel, initramfs and modules directory. > > - Add dummy grub configuration pointing to the kernel. > --- > .gitignore | 1 + > test-data/phony-guests/Makefile.am | 19 +++++-- > test-data/phony-guests/fedora.c | 67 +++++++++++++++++++++++ > test-data/phony-guests/make-fedora-img.pl | 26 ++++++++- > 4 files changed, 108 insertions(+), 5 deletions(-) > > diff --git a/.gitignore b/.gitignore > index ac7d6a3ce0..04ab847dcd 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -117,6 +117,7 @@ Makefile.in > /test-data/phony-guests/fedora-luks.img > /test-data/phony-guests/fedora-md1.img > /test-data/phony-guests/fedora-md2.img > +/test-data/phony-guests/fedora-static-bin > /test-data/phony-guests/fedora.db > /test-data/phony-guests/guests.xml > /test-data/phony-guests/guests-all-good.xml > diff --git a/test-data/phony-guests/Makefile.am b/test-data/phony-guests/Makefile.am > index 60313548af..c45ddc1123 100644 > --- a/test-data/phony-guests/Makefile.am > +++ b/test-data/phony-guests/Makefile.am > @@ -76,7 +76,8 @@ blank-%.img: > # Make a (dummy) Fedora image. > fedora.img: make-fedora-img.pl \ > fedora-journal.tar.xz \ > - fedora.db > + fedora.db \ > + fedora-static-bin > SRCDIR=$(srcdir) LAYOUT=partitions $(top_builddir)/run --test ./$< > > # Make a (dummy) Fedora image using md devices > @@ -84,7 +85,8 @@ fedora-md1.img fedora-md2.img: stamp-fedora-md.img > > stamp-fedora-md.img: make-fedora-img.pl \ > fedora-journal.tar.xz \ > - fedora.db > + fedora.db \ > + fedora-static-bin > rm -f $@ > SRCDIR=$(srcdir) LAYOUT=partitions-md $(top_builddir)/run --test ./$< > touch $@ > @@ -93,13 +95,15 @@ stamp-fedora-md.img: make-fedora-img.pl \ > # for root and home. > fedora-btrfs.img: make-fedora-img.pl \ > fedora-journal.tar.xz \ > - fedora.db > + fedora.db \ > + fedora-static-bin > SRCDIR=$(srcdir) LAYOUT=btrfs $(top_builddir)/run --test ./$< > > # Make a (dummy) Fedora image with LVM encrypted with LUKS. > fedora-luks.img: make-fedora-img.pl \ > fedora-journal.tar.xz \ > - fedora.db > + fedora.db \ > + fedora-static-bin > SRCDIR=$(srcdir) LAYOUT=lvm-luks $(top_builddir)/run --test ./$< > > # Make a (dummy) Debian image. > @@ -137,6 +141,13 @@ fedora.db: fedora-db.sql.xz > xzcat $< | $(SQLITE3) $@-t > mv $@-t $@ > > +# This is included in the phony Fedora image to act as a phony "rpm" > +# and "dracut" command. For the use of -all-static here, see > +# libguestfs/tests/Makefile.am > +check_PROGRAMS = fedora-static-bin > +fedora_static_bin_SOURCES = fedora.c > +fedora_static_bin_LDFLAGS = -all-static > + > windows-software: windows-software.reg > rm -f $@ $@-t > cp $(srcdir)/minimal-hive $@-t > diff --git a/test-data/phony-guests/fedora.c b/test-data/phony-guests/fedora.c > new file mode 100644 > index 0000000000..36eaa233fc > --- /dev/null > +++ b/test-data/phony-guests/fedora.c > @@ -0,0 +1,67 @@ > +/* libguestfs test images > + * Copyright (C) 2009-2020 Red Hat Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + */ > + > +/* This is "just enough" of a binary to look like RPM and dracut, as > + * far as virt-v2v is concerned. > + */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <assert.h> > + > +/* NB: This is also defined in make-fedora-img.pl */ > +#define KVER "5.19.0-0.rc1.14.fc37.x86_64" > + > +static const char * > +basename (const char *str) > +{ > + const char *ret = strrchr (str, '/'); > + return ret == NULL ? str : ret + 1; > +} > + > +int > +main (int argc, char *argv[]) > +{ > + if (argc == 3 && > + strcmp (basename (argv[0]), "rpm") == 0 && > + strcmp (argv[1], "-ql") == 0 && > + strncmp (argv[2], "kernel-", 7) == 0) { > + /* XXX These files and directories actually exist. It would be > + * better to list files in /boot and /lib/modules matching a > + * pattern rather than hard-coding the list here, which duplicates > + * information in make-fedora-img.pl. > + */ > + printf ("/boot/vmlinuz-" KVER "\n"); > + printf ("/lib/modules/" KVER "\n"); > + printf ("/lib/modules/" KVER "/kernel\n"); > + printf ("/lib/modules/" KVER "/kernel/drivers\n"); > + printf ("/lib/modules/" KVER "/kernel/drivers/block\n"); > + printf ("/lib/modules/" KVER "/kernel/drivers/block/virtio_blk.ko\n"); > + } > + else if (argc >= 1 && > + strcmp (basename (argv[0]), "dracut") == 0) { > + // do nothing, pretend to rebuild the initramfs > + } > + else { > + fprintf (stderr, "phony Fedora: unknown command\n"); > + exit (1); > + } > + > + exit (0); > +} > diff --git a/test-data/phony-guests/make-fedora-img.pl b/test-data/phony-guests/make-fedora-img.pl > index f340f4d744..ad30960fa3 100755 > --- a/test-data/phony-guests/make-fedora-img.pl > +++ b/test-data/phony-guests/make-fedora-img.pl > @@ -240,6 +240,7 @@ $g->mount ($bootdev, '/boot'); > $g->mkdir ('/bin'); > $g->mkdir ('/etc'); > $g->mkdir ('/etc/sysconfig'); > +$g->mkdir ('/sbin'); > $g->mkdir ('/usr'); > $g->mkdir ('/usr/share'); > $g->mkdir ('/usr/share/zoneinfo'); > @@ -276,8 +277,17 @@ $g->upload ($ENV{SRCDIR}.'/../binaries/bin-x86_64-dynamic', '/bin/ls'); > > $g->tar_in ($ENV{SRCDIR}.'/fedora-journal.tar.xz', '/var/log/journal', compress => "xz"); > > +# NB: This is also defined in fedora.c > +my $kver = "5.19.0-0.rc1.14.fc37.x86_64"; > $g->mkdir ('/boot/grub'); > -$g->touch ('/boot/grub/grub.conf'); > +$g->write ('/boot/grub/grub.conf', <<EOF); > +title Fedora > + root (hd0,0) > + kernel /vmlinuz-$kver > + initrd /initramfs-$kver.img > +EOF > + > +$g->touch ('/etc/modprobe.conf'); > > # Test files. > $g->write ('/etc/test1', 'abcdefg'); > @@ -300,6 +310,20 @@ $g->ln_s ('/bin/test1', '/bin/test5'); > $g->mkfifo (0777, '/bin/test6'); > $g->mknod (0777, 10, 10, '/bin/test7'); > > +# Virt-v2v needs an RPM command, or at least something which acts > +# similarly, and also a dracut command. > +$g->upload ('fedora-static-bin', '/bin/rpm'); > +$g->chmod (0777, '/bin/rpm'); > +$g->upload ('fedora-static-bin', '/sbin/dracut'); > +$g->chmod (0777, '/sbin/dracut'); > + > +# Virt-v2v also needs a kernel, initrd and modules path. > +$g->touch ("/boot/vmlinuz-$kver"); > +$g->touch ("/boot/initramfs-$kver.img"); > +$g->mkdir_p ("/lib/modules/$kver/kernel/drivers/block"); > +$g->upload ($ENV{SRCDIR}.'/../binaries/bin-x86_64-dynamic', > + "/lib/modules/$kver/kernel/drivers/block/virtio_blk.ko"); > + > # Cleanup > $g->shutdown (); > $g->close (); >Looks OK to me, I just suggest using a different function name rather than "basename". While the C code is certainly OK, conceptually we already have two standard basename() functions, a POSIX compatible one from <libgen.h>, and a glibc (_GNU_SOURCE) override. (While looking for sources on this, I stumbled upon <https://nanxiao.me/en/beware-of-using-gnu-ibc-basename-function/>, so apparently the glibc override does exactly what your version does. So I think we should either rename the internal basename() to something else, or just use (= statically link) the _GNU_SOURCE variant from glibc). With that: Acked-by: Laszlo Ersek <lersek at redhat.com> Thanks Laszlo