Compare commits
4 Commits
changed/a8
...
c8-stream-
Author | SHA1 | Date | |
---|---|---|---|
|
540294472a | ||
|
f8538d2090 | ||
|
55b111a4aa | ||
|
e951e074b3 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +1,2 @@
|
||||
SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-5
|
||||
SOURCES/libguestfs-1.40.2.tar.gz
|
||||
SOURCES/libguestfs-1.44.0.tar.gz
|
||||
SOURCES/libguestfs.keyring
|
||||
SOURCES/rhsrvany.exe
|
||||
|
@ -1,4 +1,2 @@
|
||||
130adbc011dc0af736465b813c2b22a600c128c1 SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-5
|
||||
45755f0f73b503790974484053ff482f32665b13 SOURCES/libguestfs-1.40.2.tar.gz
|
||||
99d241dc4a5ba0dc6111954ed7a872e0b0bb6944 SOURCES/libguestfs-1.44.0.tar.gz
|
||||
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring
|
||||
2bd96e478fc004cd323b5bd754c856641877dac6 SOURCES/rhsrvany.exe
|
||||
|
@ -1,15 +1,18 @@
|
||||
From a7fefab912d97962fb77f0f57799b7b70634376c Mon Sep 17 00:00:00 2001
|
||||
From 5b6d2b05fe0c4035b9791a751e3133d26c7baa2d Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 21 Dec 2012 15:50:11 +0000
|
||||
Subject: [PATCH] RHEL 8: Remove libguestfs live (RHBZ#798980).
|
||||
|
||||
This isn't supported in RHEL 8.
|
||||
|
||||
Disable daemon tests that require the 'unix' backend.
|
||||
---
|
||||
lib/launch-unix.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
lib/launch-unix.c | 7 +++++++
|
||||
tests/daemon/Makefile.am | 4 +---
|
||||
2 files changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/launch-unix.c b/lib/launch-unix.c
|
||||
index 4794a7b13..993b83601 100644
|
||||
index 0d344f9df..74dd1bb4a 100644
|
||||
--- a/lib/launch-unix.c
|
||||
+++ b/lib/launch-unix.c
|
||||
@@ -37,6 +37,12 @@
|
||||
@ -33,6 +36,21 @@ index 4794a7b13..993b83601 100644
|
||||
}
|
||||
|
||||
static int
|
||||
diff --git a/tests/daemon/Makefile.am b/tests/daemon/Makefile.am
|
||||
index 921e6d1df..8b2887247 100644
|
||||
--- a/tests/daemon/Makefile.am
|
||||
+++ b/tests/daemon/Makefile.am
|
||||
@@ -23,9 +23,7 @@ include $(top_srcdir)/subdir-rules.mk
|
||||
|
||||
check_DATA = captive-daemon.pm
|
||||
|
||||
-TESTS = \
|
||||
- test-daemon-start.pl \
|
||||
- test-btrfs.pl
|
||||
+TESTS =
|
||||
|
||||
TESTS_ENVIRONMENT = $(top_builddir)/run --test
|
||||
|
||||
--
|
||||
2.18.4
|
||||
2.31.1
|
||||
|
@ -1,56 +0,0 @@
|
||||
From a5e8afb4ed8576a1b3398add2ede49a1f90ad01a Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 30 Jul 2020 13:57:45 +0100
|
||||
Subject: [PATCH] daemon, lib: Replace deprecated security_context_t with char
|
||||
*.
|
||||
|
||||
This gives deprecation warnings. It always was simply a char *, and
|
||||
the recommendation upstream is to replace uses with char *:
|
||||
|
||||
https://github.com/SELinuxProject/selinux/commit/9eb9c9327563014ad6a807814e7975424642d5b9
|
||||
(cherry picked from commit eb78e990ac5277a4282293f8787af871a1420b61)
|
||||
---
|
||||
daemon/selinux.c | 3 +--
|
||||
lib/launch-libvirt.c | 5 ++---
|
||||
2 files changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/daemon/selinux.c b/daemon/selinux.c
|
||||
index 1c1446d30..f4d839c19 100644
|
||||
--- a/daemon/selinux.c
|
||||
+++ b/daemon/selinux.c
|
||||
@@ -63,8 +63,7 @@ char *
|
||||
do_getcon (void)
|
||||
{
|
||||
#if defined(HAVE_GETCON)
|
||||
- security_context_t context;
|
||||
- char *r;
|
||||
+ char *context, *r;
|
||||
|
||||
if (getcon (&context) == -1) {
|
||||
reply_with_perror ("getcon");
|
||||
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
|
||||
index bc5978cc4..4a47bbb29 100644
|
||||
--- a/lib/launch-libvirt.c
|
||||
+++ b/lib/launch-libvirt.c
|
||||
@@ -288,8 +288,7 @@ create_cow_overlay_libvirt (guestfs_h *g, void *datav, struct drive *drv)
|
||||
if (data->selinux_imagelabel) {
|
||||
debug (g, "setting SELinux label on %s to %s",
|
||||
overlay, data->selinux_imagelabel);
|
||||
- if (setfilecon (overlay,
|
||||
- (security_context_t) data->selinux_imagelabel) == -1)
|
||||
+ if (setfilecon (overlay, data->selinux_imagelabel) == -1)
|
||||
selinux_warning (g, __func__, "setfilecon", overlay);
|
||||
}
|
||||
#endif
|
||||
@@ -840,7 +839,7 @@ is_custom_hv (guestfs_h *g)
|
||||
static void
|
||||
set_socket_create_context (guestfs_h *g)
|
||||
{
|
||||
- security_context_t scon; /* this is actually a 'char *' */
|
||||
+ char *scon;
|
||||
context_t con;
|
||||
|
||||
if (getcon (&scon) == -1) {
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,22 +1,22 @@
|
||||
From 683153015b95a7b6d4979d48736c80e366986c72 Mon Sep 17 00:00:00 2001
|
||||
From 91b2a6e50211c58ea31a36351ec63c358f708bf9 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 18 Jul 2013 18:31:53 +0100
|
||||
Subject: [PATCH] RHEL 8: Remove 9p APIs from RHEL (RHBZ#921710).
|
||||
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
daemon/9p.c | 224 --------------------------------------
|
||||
daemon/9p.c | 182 --------------------------------------
|
||||
daemon/Makefile.am | 1 -
|
||||
docs/C_SOURCE_FILES | 1 -
|
||||
generator/actions_core.ml | 21 ----
|
||||
generator/actions_core.ml | 21 -----
|
||||
generator/proc_nr.ml | 2 -
|
||||
gobject/Makefile.inc | 2 -
|
||||
po/POTFILES | 2 -
|
||||
8 files changed, 1 insertion(+), 254 deletions(-)
|
||||
8 files changed, 1 insertion(+), 212 deletions(-)
|
||||
delete mode 100644 daemon/9p.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 0067d7b7b..e9351eadc 100644
|
||||
index 3df1b6a7a..36e44dfd5 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -78,7 +78,7 @@ SUBDIRS += tests/xfs
|
||||
@ -30,10 +30,10 @@ index 0067d7b7b..e9351eadc 100644
|
||||
SUBDIRS += tests/disk-labels
|
||||
diff --git a/daemon/9p.c b/daemon/9p.c
|
||||
deleted file mode 100644
|
||||
index 55644249d..000000000
|
||||
index 743a96abd..000000000
|
||||
--- a/daemon/9p.c
|
||||
+++ /dev/null
|
||||
@@ -1,224 +0,0 @@
|
||||
@@ -1,182 +0,0 @@
|
||||
-/* libguestfs - the guestfsd daemon
|
||||
- * Copyright (C) 2011 Red Hat Inc.
|
||||
- *
|
||||
@ -65,21 +65,32 @@ index 55644249d..000000000
|
||||
-#include <dirent.h>
|
||||
-#include <fcntl.h>
|
||||
-
|
||||
-#include "ignore-value.h"
|
||||
-
|
||||
-#include "daemon.h"
|
||||
-#include "actions.h"
|
||||
-
|
||||
-#define BUS_PATH "/sys/bus/virtio/drivers/9pnet_virtio"
|
||||
-
|
||||
-static char *read_whole_file (const char *filename);
|
||||
-static void
|
||||
-modprobe_9pnet_virtio (void)
|
||||
-{
|
||||
- /* Required with Linux 5.6 and maybe earlier kernels. For unclear
|
||||
- * reasons the module is not an automatic dependency of the 9p
|
||||
- * module so doesn't get loaded automatically.
|
||||
- */
|
||||
- ignore_value (command (NULL, NULL, "modprobe", "9pnet_virtio", NULL));
|
||||
-}
|
||||
-
|
||||
-/* https://bugzilla.redhat.com/show_bug.cgi?id=714981#c1 */
|
||||
-char **
|
||||
-do_list_9p (void)
|
||||
-{
|
||||
- CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (r);
|
||||
-
|
||||
- DIR *dir;
|
||||
-
|
||||
- modprobe_9pnet_virtio ();
|
||||
-
|
||||
- dir = opendir (BUS_PATH);
|
||||
- if (!dir) {
|
||||
- perror ("opendir: " BUS_PATH);
|
||||
@ -118,7 +129,7 @@ index 55644249d..000000000
|
||||
- * the mount tag length to be unlimited (or up to 65536 bytes).
|
||||
- * See: linux/include/linux/virtio_9p.h
|
||||
- */
|
||||
- CLEANUP_FREE char *mount_tag = read_whole_file (mount_tag_path);
|
||||
- CLEANUP_FREE char *mount_tag = read_whole_file (mount_tag_path, NULL);
|
||||
- if (mount_tag == 0)
|
||||
- continue;
|
||||
-
|
||||
@ -153,60 +164,6 @@ index 55644249d..000000000
|
||||
- return take_stringsbuf (&r);
|
||||
-}
|
||||
-
|
||||
-/* Read whole file into dynamically allocated array. If there is an
|
||||
- * error, DON'T call reply_with_perror, just return NULL. Returns a
|
||||
- * \0-terminated string.
|
||||
- */
|
||||
-static char *
|
||||
-read_whole_file (const char *filename)
|
||||
-{
|
||||
- char *r = NULL;
|
||||
- size_t alloc = 0, size = 0;
|
||||
- int fd;
|
||||
-
|
||||
- fd = open (filename, O_RDONLY|O_CLOEXEC);
|
||||
- if (fd == -1) {
|
||||
- perror (filename);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- while (1) {
|
||||
- alloc += 256;
|
||||
- char *r2 = realloc (r, alloc);
|
||||
- if (r2 == NULL) {
|
||||
- perror ("realloc");
|
||||
- free (r);
|
||||
- close (fd);
|
||||
- return NULL;
|
||||
- }
|
||||
- r = r2;
|
||||
-
|
||||
- /* The '- 1' in the size calculation ensures there is space below
|
||||
- * to add \0 to the end of the input.
|
||||
- */
|
||||
- ssize_t n = read (fd, r + size, alloc - size - 1);
|
||||
- if (n == -1) {
|
||||
- fprintf (stderr, "read: %s: %m\n", filename);
|
||||
- free (r);
|
||||
- close (fd);
|
||||
- return NULL;
|
||||
- }
|
||||
- if (n == 0)
|
||||
- break;
|
||||
- size += n;
|
||||
- }
|
||||
-
|
||||
- if (close (fd) == -1) {
|
||||
- fprintf (stderr, "close: %s: %m\n", filename);
|
||||
- free (r);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- r[size] = '\0';
|
||||
-
|
||||
- return r;
|
||||
-}
|
||||
-
|
||||
-/* Takes optional arguments, consult optargs_bitmask. */
|
||||
-int
|
||||
-do_mount_9p (const char *mount_tag, const char *mountpoint, const char *options)
|
||||
@ -249,6 +206,7 @@ index 55644249d..000000000
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- modprobe_9pnet_virtio ();
|
||||
- r = command (NULL, &err,
|
||||
- "mount", "-o", opts, "-t", "9p", mount_tag, mp, NULL);
|
||||
- if (r == -1) {
|
||||
@ -259,10 +217,10 @@ index 55644249d..000000000
|
||||
- return 0;
|
||||
-}
|
||||
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
||||
index 5d1c222db..a9b40be25 100644
|
||||
index 038be592c..df9dcc4ee 100644
|
||||
--- a/daemon/Makefile.am
|
||||
+++ b/daemon/Makefile.am
|
||||
@@ -76,7 +76,6 @@ guestfsd_SOURCES = \
|
||||
@@ -82,7 +82,6 @@ guestfsd_SOURCES = \
|
||||
../common/protocol/guestfs_protocol.h \
|
||||
../common/utils/cleanups.h \
|
||||
../common/utils/guestfs-utils.h \
|
||||
@ -271,22 +229,22 @@ index 5d1c222db..a9b40be25 100644
|
||||
actions.h \
|
||||
available.c \
|
||||
diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
|
||||
index 7f1c60b30..f45e7124d 100644
|
||||
index cd5bd2924..831b7e25a 100644
|
||||
--- a/docs/C_SOURCE_FILES
|
||||
+++ b/docs/C_SOURCE_FILES
|
||||
@@ -71,7 +71,6 @@ common/windows/windows.h
|
||||
@@ -63,7 +63,6 @@ common/windows/windows.c
|
||||
common/windows/windows.h
|
||||
customize/crypt-c.c
|
||||
customize/dummy.c
|
||||
customize/perl_edit-c.c
|
||||
-daemon/9p.c
|
||||
daemon/acl.c
|
||||
daemon/actions.h
|
||||
daemon/augeas.c
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index deda483a9..f466600df 100644
|
||||
index 806565b19..37476c93e 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -6167,27 +6167,6 @@ This returns true iff the device exists and contains all zero bytes.
|
||||
@@ -6157,27 +6157,6 @@ This returns true iff the device exists and contains all zero bytes.
|
||||
|
||||
Note that for large devices this can take a long time to run." };
|
||||
|
||||
@ -315,7 +273,7 @@ index deda483a9..f466600df 100644
|
||||
name = "list_dm_devices"; added = (1, 11, 15);
|
||||
style = RStringList (RDevice, "devices"), [], [];
|
||||
diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
|
||||
index 11a557076..1ef5ba0b7 100644
|
||||
index 30e42864f..57976be36 100644
|
||||
--- a/generator/proc_nr.ml
|
||||
+++ b/generator/proc_nr.ml
|
||||
@@ -295,8 +295,6 @@ let proc_nr = [
|
||||
@ -328,10 +286,10 @@ index 11a557076..1ef5ba0b7 100644
|
||||
288, "ntfsresize";
|
||||
289, "btrfs_filesystem_resize";
|
||||
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
|
||||
index 067f861a9..7afe83c59 100644
|
||||
index 650f8ddac..c4e735967 100644
|
||||
--- a/gobject/Makefile.inc
|
||||
+++ b/gobject/Makefile.inc
|
||||
@@ -93,7 +93,6 @@ guestfs_gobject_headers= \
|
||||
@@ -94,7 +94,6 @@ guestfs_gobject_headers= \
|
||||
include/guestfs-gobject/optargs-mksquashfs.h \
|
||||
include/guestfs-gobject/optargs-mkswap.h \
|
||||
include/guestfs-gobject/optargs-mktemp.h \
|
||||
@ -339,7 +297,7 @@ index 067f861a9..7afe83c59 100644
|
||||
include/guestfs-gobject/optargs-mount_local.h \
|
||||
include/guestfs-gobject/optargs-ntfsclone_out.h \
|
||||
include/guestfs-gobject/optargs-ntfsfix.h \
|
||||
@@ -186,7 +185,6 @@ guestfs_gobject_sources= \
|
||||
@@ -188,7 +187,6 @@ guestfs_gobject_sources= \
|
||||
src/optargs-mksquashfs.c \
|
||||
src/optargs-mkswap.c \
|
||||
src/optargs-mktemp.c \
|
||||
@ -348,18 +306,18 @@ index 067f861a9..7afe83c59 100644
|
||||
src/optargs-ntfsclone_out.c \
|
||||
src/optargs-ntfsfix.c \
|
||||
diff --git a/po/POTFILES b/po/POTFILES
|
||||
index 79f4b8c56..b99333d0d 100644
|
||||
index 69ea7134a..0782e8ceb 100644
|
||||
--- a/po/POTFILES
|
||||
+++ b/po/POTFILES
|
||||
@@ -58,7 +58,6 @@ customize/crypt-c.c
|
||||
customize/dummy.c
|
||||
@@ -47,7 +47,6 @@ common/visit/visit.c
|
||||
common/windows/windows.c
|
||||
customize/crypt-c.c
|
||||
customize/perl_edit-c.c
|
||||
customize/test-password.pl
|
||||
-daemon/9p.c
|
||||
daemon/acl.c
|
||||
daemon/augeas.c
|
||||
daemon/available.c
|
||||
@@ -291,7 +290,6 @@ gobject/src/optargs-mkfs_btrfs.c
|
||||
@@ -277,7 +276,6 @@ gobject/src/optargs-mkfs_btrfs.c
|
||||
gobject/src/optargs-mksquashfs.c
|
||||
gobject/src/optargs-mkswap.c
|
||||
gobject/src/optargs-mktemp.c
|
||||
@ -368,5 +326,5 @@ index 79f4b8c56..b99333d0d 100644
|
||||
gobject/src/optargs-ntfsclone_out.c
|
||||
gobject/src/optargs-ntfsfix.c
|
||||
--
|
||||
2.18.4
|
||||
2.31.1
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 524b0c748a3a2d47b4c76e3aa546b9d4af144e6c Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Sat, 7 Dec 2019 11:08:54 +0000
|
||||
Subject: [PATCH] caml_named_value returns const value pointer in OCaml 4.09+
|
||||
|
||||
(cherry picked from ocaml-augeas
|
||||
commit 1cf5aef99b26a46529ca797547c0b49627fffe78)
|
||||
---
|
||||
common/mlaugeas/augeas-c.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/common/mlaugeas/augeas-c.c b/common/mlaugeas/augeas-c.c
|
||||
index 3e0ba67ba..3b1dc2551 100644
|
||||
--- a/common/mlaugeas/augeas-c.c
|
||||
+++ b/common/mlaugeas/augeas-c.c
|
||||
@@ -77,7 +77,7 @@ static const int error_map_len = sizeof error_map / sizeof error_map[0];
|
||||
static void
|
||||
raise_error (augeas_t t, const char *msg)
|
||||
{
|
||||
- value *exn = caml_named_value ("Augeas.Error");
|
||||
+ const value *exn = caml_named_value ("Augeas.Error");
|
||||
value args[4];
|
||||
const int code = aug_error (t);
|
||||
const char *aug_err_minor;
|
||||
@@ -113,7 +113,7 @@ raise_error (augeas_t t, const char *msg)
|
||||
static void
|
||||
raise_init_error (const char *msg)
|
||||
{
|
||||
- value *exn = caml_named_value ("Augeas.Error");
|
||||
+ const value *exn = caml_named_value ("Augeas.Error");
|
||||
value args[4];
|
||||
|
||||
args[0] = caml_alloc (1, 0);
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 336961659225584add638442cc0cf933803e008e Mon Sep 17 00:00:00 2001
|
||||
From 4dd2f3f56a39411a255ad0a8f38081d46620dbd8 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 29 Jul 2013 14:47:56 +0100
|
||||
Subject: [PATCH] RHEL 8: Disable unsupported remote drive protocols
|
||||
@ -62,7 +62,7 @@ index f558964bf..8f264ed17 100644
|
||||
|
||||
Run L<virt-alignment-scan(1)> on guests or disk images:
|
||||
diff --git a/fish/guestfish.pod b/fish/guestfish.pod
|
||||
index f1fdf094d..bacb60e0b 100644
|
||||
index 9f086f110..bb4167b06 100644
|
||||
--- a/fish/guestfish.pod
|
||||
+++ b/fish/guestfish.pod
|
||||
@@ -131,9 +131,9 @@ To list what is available do:
|
||||
@ -77,7 +77,7 @@ index f1fdf094d..bacb60e0b 100644
|
||||
|
||||
=head2 Remote control
|
||||
|
||||
@@ -1145,12 +1145,12 @@ L<guestfs(3)/REMOTE STORAGE>>.
|
||||
@@ -1134,12 +1134,12 @@ L<guestfs(3)/REMOTE STORAGE>>.
|
||||
On the command line, you can use the I<-a> option to add network
|
||||
block devices using a URI-style format, for example:
|
||||
|
||||
@ -92,7 +92,7 @@ index f1fdf094d..bacb60e0b 100644
|
||||
|
||||
The possible I<-a URI> formats are described below.
|
||||
|
||||
@@ -1160,40 +1160,6 @@ The possible I<-a URI> formats are described below.
|
||||
@@ -1149,40 +1149,6 @@ The possible I<-a URI> formats are described below.
|
||||
|
||||
Add the local disk image (or device) called F<disk.img>.
|
||||
|
||||
@ -133,7 +133,7 @@ index f1fdf094d..bacb60e0b 100644
|
||||
=head2 B<-a nbd://example.com[:port]>
|
||||
|
||||
=head2 B<-a nbd://example.com[:port]/exportname>
|
||||
@@ -1228,35 +1194,13 @@ The equivalent API command would be:
|
||||
@@ -1217,35 +1183,13 @@ The equivalent API command would be:
|
||||
|
||||
><fs> add pool/disk protocol:rbd server:tcp:example.com:port
|
||||
|
||||
@ -171,7 +171,7 @@ index f1fdf094d..bacb60e0b 100644
|
||||
In this case, the password is C<pass@word>.
|
||||
|
||||
diff --git a/fish/test-add-uri.sh b/fish/test-add-uri.sh
|
||||
index 756df997b..8f84fd31b 100755
|
||||
index 21d424984..ddabeb639 100755
|
||||
--- a/fish/test-add-uri.sh
|
||||
+++ b/fish/test-add-uri.sh
|
||||
@@ -40,14 +40,6 @@ function fail ()
|
||||
@ -220,7 +220,7 @@ index 756df997b..8f84fd31b 100755
|
||||
rm test-add-uri.out
|
||||
rm test-add-uri.img
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index f466600df..3893d0e8d 100644
|
||||
index 37476c93e..9f0402510 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -297,29 +297,6 @@ F<filename> is interpreted as a local file or device.
|
||||
@ -305,10 +305,10 @@ index f466600df..3893d0e8d 100644
|
||||
example if using the libvirt backend and if the libvirt backend is configured to
|
||||
start the qemu appliance as a special user such as C<qemu.qemu>. If in doubt,
|
||||
diff --git a/lib/drives.c b/lib/drives.c
|
||||
index 82ef30093..3d712c6e4 100644
|
||||
index 46af66db4..c81ded5d7 100644
|
||||
--- a/lib/drives.c
|
||||
+++ b/lib/drives.c
|
||||
@@ -165,6 +165,7 @@ create_drive_non_file (guestfs_h *g,
|
||||
@@ -168,6 +168,7 @@ create_drive_non_file (guestfs_h *g,
|
||||
return drv;
|
||||
}
|
||||
|
||||
@ -316,7 +316,7 @@ index 82ef30093..3d712c6e4 100644
|
||||
static struct drive *
|
||||
create_drive_curl (guestfs_h *g,
|
||||
const struct drive_create_data *data)
|
||||
@@ -223,6 +224,7 @@ create_drive_gluster (guestfs_h *g,
|
||||
@@ -226,6 +227,7 @@ create_drive_gluster (guestfs_h *g,
|
||||
|
||||
return create_drive_non_file (g, data);
|
||||
}
|
||||
@ -324,7 +324,7 @@ index 82ef30093..3d712c6e4 100644
|
||||
|
||||
static int
|
||||
nbd_port (void)
|
||||
@@ -291,6 +293,7 @@ create_drive_rbd (guestfs_h *g,
|
||||
@@ -294,6 +296,7 @@ create_drive_rbd (guestfs_h *g,
|
||||
return create_drive_non_file (g, data);
|
||||
}
|
||||
|
||||
@ -332,7 +332,7 @@ index 82ef30093..3d712c6e4 100644
|
||||
static struct drive *
|
||||
create_drive_sheepdog (guestfs_h *g,
|
||||
const struct drive_create_data *data)
|
||||
@@ -391,6 +394,7 @@ create_drive_iscsi (guestfs_h *g,
|
||||
@@ -394,6 +397,7 @@ create_drive_iscsi (guestfs_h *g,
|
||||
|
||||
return create_drive_non_file (g, data);
|
||||
}
|
||||
@ -340,7 +340,7 @@ index 82ef30093..3d712c6e4 100644
|
||||
|
||||
/**
|
||||
* Create the special F</dev/null> drive.
|
||||
@@ -826,6 +830,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
@@ -856,6 +860,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
drv = create_drive_file (g, &data);
|
||||
}
|
||||
}
|
||||
@ -348,7 +348,7 @@ index 82ef30093..3d712c6e4 100644
|
||||
else if (STREQ (protocol, "ftp")) {
|
||||
data.protocol = drive_protocol_ftp;
|
||||
drv = create_drive_curl (g, &data);
|
||||
@@ -850,6 +855,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
@@ -880,6 +885,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
data.protocol = drive_protocol_iscsi;
|
||||
drv = create_drive_iscsi (g, &data);
|
||||
}
|
||||
@ -356,7 +356,7 @@ index 82ef30093..3d712c6e4 100644
|
||||
else if (STREQ (protocol, "nbd")) {
|
||||
data.protocol = drive_protocol_nbd;
|
||||
drv = create_drive_nbd (g, &data);
|
||||
@@ -858,6 +864,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
@@ -888,6 +894,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
data.protocol = drive_protocol_rbd;
|
||||
drv = create_drive_rbd (g, &data);
|
||||
}
|
||||
@ -364,7 +364,7 @@ index 82ef30093..3d712c6e4 100644
|
||||
else if (STREQ (protocol, "sheepdog")) {
|
||||
data.protocol = drive_protocol_sheepdog;
|
||||
drv = create_drive_sheepdog (g, &data);
|
||||
@@ -870,6 +877,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
@@ -900,6 +907,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
data.protocol = drive_protocol_tftp;
|
||||
drv = create_drive_curl (g, &data);
|
||||
}
|
||||
@ -373,10 +373,10 @@ index 82ef30093..3d712c6e4 100644
|
||||
error (g, _("unknown protocol ‘%s’"), protocol);
|
||||
drv = NULL; /*FALLTHROUGH*/
|
||||
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
|
||||
index af944ddb7..58559a6b4 100644
|
||||
index bce9eb79f..2bb13b875 100644
|
||||
--- a/lib/guestfs.pod
|
||||
+++ b/lib/guestfs.pod
|
||||
@@ -714,70 +714,6 @@ servers. The server string is documented in
|
||||
@@ -715,70 +715,6 @@ servers. The server string is documented in
|
||||
L</guestfs_add_drive_opts>. The C<username> and C<secret> parameters are
|
||||
also optional, and if not given, then no authentication will be used.
|
||||
|
||||
@ -447,7 +447,7 @@ index af944ddb7..58559a6b4 100644
|
||||
=head3 NETWORK BLOCK DEVICE
|
||||
|
||||
Libguestfs can access Network Block Device (NBD) disks remotely.
|
||||
@@ -840,42 +776,6 @@ L<https://bugs.launchpad.net/qemu/+bug/1155677>
|
||||
@@ -841,42 +777,6 @@ L<https://bugs.launchpad.net/qemu/+bug/1155677>
|
||||
|
||||
=back
|
||||
|
||||
@ -491,7 +491,7 @@ index af944ddb7..58559a6b4 100644
|
||||
|
||||
Libguestfs has APIs for inspecting an unknown disk image to find out
|
||||
diff --git a/tests/disks/test-qemu-drive-libvirt.sh b/tests/disks/test-qemu-drive-libvirt.sh
|
||||
index e49c69b43..9b1abc4ec 100755
|
||||
index 3c5aa592e..f73827bd6 100755
|
||||
--- a/tests/disks/test-qemu-drive-libvirt.sh
|
||||
+++ b/tests/disks/test-qemu-drive-libvirt.sh
|
||||
@@ -64,34 +64,6 @@ check_output
|
||||
@ -605,5 +605,5 @@ index 19dd60a2f..583e031bd 100755
|
||||
-grep -sq -- '-drive file=ssh://rich@example.com/disk.img,' "$DEBUG_QEMU_FILE" || fail
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
--
|
||||
2.18.4
|
||||
2.31.1
|
||||
|
@ -1,78 +0,0 @@
|
||||
From 3860ab78d9fe5c34785aabc2227ebc8687b1171b Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 5 Sep 2019 09:00:14 +0100
|
||||
Subject: [PATCH] ocaml: Change calls to caml_named_value() to cope with const
|
||||
value* return.
|
||||
|
||||
In OCaml >= 4.09 the return value pointer of caml_named_value is
|
||||
declared const.
|
||||
|
||||
Based on Pino Toscano's original patch to ocaml-augeas.
|
||||
|
||||
(cherry picked from commit 9788fa50601ad4f1eab56d0b763591268026e536)
|
||||
---
|
||||
common/mlpcre/pcre-c.c | 3 +--
|
||||
common/mltools/uri-c.c | 6 ++----
|
||||
common/mlvisit/visit-c.c | 4 +---
|
||||
3 files changed, 4 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/common/mlpcre/pcre-c.c b/common/mlpcre/pcre-c.c
|
||||
index 0762a8341..07f99b8d6 100644
|
||||
--- a/common/mlpcre/pcre-c.c
|
||||
+++ b/common/mlpcre/pcre-c.c
|
||||
@@ -73,12 +73,11 @@ init (void)
|
||||
static void
|
||||
raise_pcre_error (const char *msg, int errcode)
|
||||
{
|
||||
- value *exn = caml_named_value ("PCRE.Error");
|
||||
value args[2];
|
||||
|
||||
args[0] = caml_copy_string (msg);
|
||||
args[1] = Val_int (errcode);
|
||||
- caml_raise_with_args (*exn, 2, args);
|
||||
+ caml_raise_with_args (*caml_named_value ("PCRE.Error"), 2, args);
|
||||
}
|
||||
|
||||
/* Wrap and unwrap pcre regular expression handles, with a finalizer. */
|
||||
diff --git a/common/mltools/uri-c.c b/common/mltools/uri-c.c
|
||||
index 2a8837cd9..e03647c7b 100644
|
||||
--- a/common/mltools/uri-c.c
|
||||
+++ b/common/mltools/uri-c.c
|
||||
@@ -46,10 +46,8 @@ guestfs_int_mllib_parse_uri (value argv /* arg value, not an array! */)
|
||||
int r;
|
||||
|
||||
r = parse_uri (String_val (argv), &uri);
|
||||
- if (r == -1) {
|
||||
- value *exn = caml_named_value ("URI.Parse_failed");
|
||||
- caml_raise (*exn);
|
||||
- }
|
||||
+ if (r == -1)
|
||||
+ caml_raise (*caml_named_value ("URI.Parse_failed"));
|
||||
|
||||
/* Convert the struct into an OCaml tuple. */
|
||||
rv = caml_alloc_tuple (5);
|
||||
diff --git a/common/mlvisit/visit-c.c b/common/mlvisit/visit-c.c
|
||||
index 7137c4998..201f6d762 100644
|
||||
--- a/common/mlvisit/visit-c.c
|
||||
+++ b/common/mlvisit/visit-c.c
|
||||
@@ -53,7 +53,6 @@ value
|
||||
guestfs_int_mllib_visit (value gv, value dirv, value fv)
|
||||
{
|
||||
CAMLparam3 (gv, dirv, fv);
|
||||
- value *visit_failure_exn;
|
||||
guestfs_h *g = (guestfs_h *) (intptr_t) Int64_val (gv);
|
||||
struct visitor_function_wrapper_args args;
|
||||
/* The dir string could move around when we call the
|
||||
@@ -84,8 +83,7 @@ guestfs_int_mllib_visit (value gv, value dirv, value fv)
|
||||
* already printed the error to stderr (XXX - fix), so we raise a
|
||||
* generic exception.
|
||||
*/
|
||||
- visit_failure_exn = caml_named_value ("Visit.Failure");
|
||||
- caml_raise (*visit_failure_exn);
|
||||
+ caml_raise (*caml_named_value ("Visit.Failure"));
|
||||
}
|
||||
free (dir);
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,4 +1,4 @@
|
||||
From cbb6a42b9074ed78c74ddefee4ec7571132a4d24 Mon Sep 17 00:00:00 2001
|
||||
From 34f8c6a5eb0eabfba4ab1831b45e2baa73a4b501 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 19 Sep 2014 13:38:20 +0100
|
||||
Subject: [PATCH] RHEL 8: Remove User-Mode Linux (RHBZ#1144197).
|
||||
@ -9,7 +9,7 @@ This isn't supported in RHEL 8.
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/lib/launch-uml.c b/lib/launch-uml.c
|
||||
index da20c17d9..a5e0e8179 100644
|
||||
index 5aec50a57..8b9fcd770 100644
|
||||
--- a/lib/launch-uml.c
|
||||
+++ b/lib/launch-uml.c
|
||||
@@ -44,7 +44,9 @@ struct backend_uml_data {
|
||||
@ -30,7 +30,7 @@ index da20c17d9..a5e0e8179 100644
|
||||
/* Test for features which are not supported by the UML backend.
|
||||
* Possibly some of these should just be warnings, not errors.
|
||||
*/
|
||||
@@ -128,10 +131,17 @@ uml_supported (guestfs_h *g)
|
||||
@@ -133,10 +136,17 @@ uml_supported (guestfs_h *g)
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -48,7 +48,7 @@ index da20c17d9..a5e0e8179 100644
|
||||
struct backend_uml_data *data = datav;
|
||||
CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (cmdline);
|
||||
int console_sock = -1, daemon_sock = -1;
|
||||
@@ -491,8 +501,10 @@ launch_uml (guestfs_h *g, void *datav, const char *arg)
|
||||
@@ -496,8 +506,10 @@ launch_uml (guestfs_h *g, void *datav, const char *arg)
|
||||
}
|
||||
g->state = CONFIG;
|
||||
return -1;
|
||||
@ -59,7 +59,7 @@ index da20c17d9..a5e0e8179 100644
|
||||
/* This is called from the forked subprocess just before vmlinux runs,
|
||||
* so it can just print the message straight to stderr, where it will
|
||||
* be picked up and funnelled through the usual appliance event API.
|
||||
@@ -522,6 +534,7 @@ print_vmlinux_command_line (guestfs_h *g, char **argv)
|
||||
@@ -527,6 +539,7 @@ print_vmlinux_command_line (guestfs_h *g, char **argv)
|
||||
|
||||
fputc ('\n', stderr);
|
||||
}
|
||||
@ -68,5 +68,5 @@ index da20c17d9..a5e0e8179 100644
|
||||
static int
|
||||
shutdown_uml (guestfs_h *g, void *datav, int check_for_errors)
|
||||
--
|
||||
2.18.4
|
||||
2.31.1
|
||||
|
@ -1,121 +0,0 @@
|
||||
From 5c5cc8b7bc2588c04dd0d0472b466f978f8ac55c Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 6 Feb 2020 10:17:35 +0000
|
||||
Subject: [PATCH] ocaml: Use caml_alloc_initialized_string instead of memcpy.
|
||||
|
||||
See this commit in libguestfs-common:
|
||||
https://github.com/libguestfs/libguestfs-common/commit/398dc56a6cb5d6d01506338fa94ef580e668d5e9
|
||||
|
||||
(cherry picked from commit 9f3148c791a970b7d6adf249e949a1b7e0b4b0c1)
|
||||
---
|
||||
generator/OCaml.ml | 10 ++++------
|
||||
m4/guestfs-ocaml.m4 | 18 ++++++++++++++++++
|
||||
ocaml/guestfs-c.c | 3 +--
|
||||
ocaml/guestfs-c.h | 18 ++++++++++++++++++
|
||||
4 files changed, 41 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/generator/OCaml.ml b/generator/OCaml.ml
|
||||
index bd4f73b85..1b6970f6d 100644
|
||||
--- a/generator/OCaml.ml
|
||||
+++ b/generator/OCaml.ml
|
||||
@@ -504,12 +504,11 @@ copy_table (char * const * argv)
|
||||
| name, FString ->
|
||||
pr " v = caml_copy_string (%s->%s);\n" typ name
|
||||
| name, FBuffer ->
|
||||
- pr " v = caml_alloc_string (%s->%s_len);\n" typ name;
|
||||
- pr " memcpy (String_val (v), %s->%s, %s->%s_len);\n"
|
||||
+ pr " v = caml_alloc_initialized_string (%s->%s_len, %s->%s);\n"
|
||||
typ name typ name
|
||||
| name, FUUID ->
|
||||
- pr " v = caml_alloc_string (32);\n";
|
||||
- pr " memcpy (String_val (v), %s->%s, 32);\n" typ name
|
||||
+ pr " v = caml_alloc_initialized_string (32, %s->%s);\n"
|
||||
+ typ name
|
||||
| name, (FBytes|FInt64|FUInt64) ->
|
||||
pr " v = caml_copy_int64 (%s->%s);\n" typ name
|
||||
| name, (FInt32|FUInt32) ->
|
||||
@@ -757,8 +756,7 @@ copy_table (char * const * argv)
|
||||
pr " for (i = 0; r[i] != NULL; ++i) free (r[i]);\n";
|
||||
pr " free (r);\n";
|
||||
| RBufferOut _ ->
|
||||
- pr " rv = caml_alloc_string (size);\n";
|
||||
- pr " memcpy (String_val (rv), r, size);\n";
|
||||
+ pr " rv = caml_alloc_initialized_string (size, r);\n";
|
||||
pr " free (r);\n"
|
||||
);
|
||||
|
||||
diff --git a/m4/guestfs-ocaml.m4 b/m4/guestfs-ocaml.m4
|
||||
index 3c504ce7e..90658e8c5 100644
|
||||
--- a/m4/guestfs-ocaml.m4
|
||||
+++ b/m4/guestfs-ocaml.m4
|
||||
@@ -221,6 +221,24 @@ AS_IF([test "x$have_Hivex_OPEN_UNSAFE" = "xno"],[
|
||||
])
|
||||
AC_SUBST([HIVEX_OPEN_UNSAFE_FLAG])
|
||||
|
||||
+dnl Check if OCaml has caml_alloc_initialized_string (added 2017).
|
||||
+AS_IF([test "x$OCAMLC" != "xno" && test "x$OCAMLFIND" != "xno" && \
|
||||
+ test "x$enable_ocaml" = "xyes"],[
|
||||
+ AC_MSG_CHECKING([for caml_alloc_initialized_string])
|
||||
+ cat >conftest.c <<'EOF'
|
||||
+#include <caml/alloc.h>
|
||||
+int main () { char *p = (void *) caml_alloc_initialized_string; return 0; }
|
||||
+EOF
|
||||
+ AS_IF([$OCAMLC conftest.c >&AS_MESSAGE_LOG_FD 2>&1],[
|
||||
+ AC_MSG_RESULT([yes])
|
||||
+ AC_DEFINE([HAVE_CAML_ALLOC_INITIALIZED_STRING],[1],
|
||||
+ [caml_alloc_initialized_string found at compile time.])
|
||||
+ ],[
|
||||
+ AC_MSG_RESULT([no])
|
||||
+ ])
|
||||
+ rm -f conftest.c conftest.o
|
||||
+])
|
||||
+
|
||||
dnl Flags we want to pass to every OCaml compiler call.
|
||||
OCAML_WARN_ERROR="-warn-error CDEFLMPSUVYZX+52-3"
|
||||
AC_SUBST([OCAML_WARN_ERROR])
|
||||
diff --git a/ocaml/guestfs-c.c b/ocaml/guestfs-c.c
|
||||
index 3b5fb198f..18d7dd978 100644
|
||||
--- a/ocaml/guestfs-c.c
|
||||
+++ b/ocaml/guestfs-c.c
|
||||
@@ -360,8 +360,7 @@ event_callback_wrapper_locked (guestfs_h *g,
|
||||
|
||||
ehv = Val_int (event_handle);
|
||||
|
||||
- bufv = caml_alloc_string (buf_len);
|
||||
- memcpy (String_val (bufv), buf, buf_len);
|
||||
+ bufv = caml_alloc_initialized_string (buf_len, buf);
|
||||
|
||||
arrayv = caml_alloc (array_len, 0);
|
||||
for (i = 0; i < array_len; ++i) {
|
||||
diff --git a/ocaml/guestfs-c.h b/ocaml/guestfs-c.h
|
||||
index f05dbd8e7..93ad3e2bf 100644
|
||||
--- a/ocaml/guestfs-c.h
|
||||
+++ b/ocaml/guestfs-c.h
|
||||
@@ -19,6 +19,24 @@
|
||||
#ifndef GUESTFS_OCAML_C_H
|
||||
#define GUESTFS_OCAML_C_H
|
||||
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <caml/alloc.h>
|
||||
+#include <caml/mlvalues.h>
|
||||
+
|
||||
+/* Replacement if caml_alloc_initialized_string is missing, added
|
||||
+ * to OCaml runtime in 2017.
|
||||
+ */
|
||||
+#ifndef HAVE_CAML_ALLOC_INITIALIZED_STRING
|
||||
+static inline value
|
||||
+caml_alloc_initialized_string (mlsize_t len, const char *p)
|
||||
+{
|
||||
+ value sv = caml_alloc_string (len);
|
||||
+ memcpy ((char *) String_val (sv), p, len);
|
||||
+ return sv;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#define Guestfs_val(v) (*((guestfs_h **)Data_custom_val(v)))
|
||||
extern void guestfs_int_ocaml_raise_error (guestfs_h *g, const char *func)
|
||||
Noreturn;
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,69 @@
|
||||
From cb2ac63562447e2780bd7103ed060fd6013b9054 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 7 Jul 2015 09:28:03 -0400
|
||||
Subject: [PATCH] RHEL 8: Reject use of libguestfs-winsupport features except
|
||||
for virt-* tools (RHBZ#1240276).
|
||||
|
||||
Fix the tests: it doesn't let us use guestfish for arbitrary Windows
|
||||
edits.
|
||||
---
|
||||
generator/c.ml | 16 ++++++++++++++++
|
||||
test-data/phony-guests/make-windows-img.sh | 1 +
|
||||
tests/charsets/test-charset-fidelity.c | 2 ++
|
||||
3 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/generator/c.ml b/generator/c.ml
|
||||
index 86d3b26f8..a625361a9 100644
|
||||
--- a/generator/c.ml
|
||||
+++ b/generator/c.ml
|
||||
@@ -1846,6 +1846,22 @@ and generate_client_actions actions () =
|
||||
check_args_validity c_name style;
|
||||
trace_call name c_name style;
|
||||
|
||||
+ (* RHEL 8 *)
|
||||
+ if name = "mount" || name = "mount_ro" || name = "mount_options" ||
|
||||
+ name = "mount_vfs" then (
|
||||
+ pr " if (g->program && !STRPREFIX (g->program, \"virt-\")) {\n";
|
||||
+ pr " CLEANUP_FREE char *vfs_type = guestfs_vfs_type (g, mountable);\n";
|
||||
+ pr " if (vfs_type && STREQ (vfs_type, \"ntfs\")) {\n";
|
||||
+ pr " error (g, \"mount: unsupported filesystem type\");\n";
|
||||
+ pr " if (trace_flag)\n";
|
||||
+ pr " guestfs_int_trace (g, \"%%s = %%s (error)\",\n";
|
||||
+ pr " \"%s\", \"-1\");\n" name;
|
||||
+ pr " return %s;\n" (string_of_errcode errcode);
|
||||
+ pr " }\n";
|
||||
+ pr " }\n";
|
||||
+ pr "\n";
|
||||
+ );
|
||||
+
|
||||
(* Calculate the total size of all FileIn arguments to pass
|
||||
* as a progress bar hint.
|
||||
*)
|
||||
diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh
|
||||
index 30908a918..73cf5144e 100755
|
||||
--- a/test-data/phony-guests/make-windows-img.sh
|
||||
+++ b/test-data/phony-guests/make-windows-img.sh
|
||||
@@ -37,6 +37,7 @@ fi
|
||||
|
||||
# Create a disk image.
|
||||
guestfish <<EOF
|
||||
+set-program virt-testing
|
||||
sparse windows.img-t 512M
|
||||
run
|
||||
|
||||
diff --git a/tests/charsets/test-charset-fidelity.c b/tests/charsets/test-charset-fidelity.c
|
||||
index 39ccc2068..2b2e2d8a9 100644
|
||||
--- a/tests/charsets/test-charset-fidelity.c
|
||||
+++ b/tests/charsets/test-charset-fidelity.c
|
||||
@@ -94,6 +94,8 @@ main (int argc, char *argv[])
|
||||
if (g == NULL)
|
||||
error (EXIT_FAILURE, 0, "failed to create handle");
|
||||
|
||||
+ guestfs_set_program (g, "virt-testing");
|
||||
+
|
||||
if (guestfs_add_drive_scratch (g, 1024*1024*1024, -1) == -1)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,125 +0,0 @@
|
||||
From 3b4082b239ec0976b366293067e42f91d56cfcd5 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 6 Feb 2020 10:15:29 +0000
|
||||
Subject: [PATCH] ocaml: Use caml_alloc_initialized_string instead of memcpy.
|
||||
|
||||
Since about 2017 OCaml has had a function for creating an initialized
|
||||
string. This uses the function instead of caml_alloc_string + memcpy
|
||||
(which doesn't work for OCaml 4.10) and defines a replacement if the
|
||||
function is missing.
|
||||
|
||||
Note this requires configure.ac in libguestfs.git and virt-v2v.git to
|
||||
define HAVE_CAML_ALLOC_INITIALIZED_STRING.
|
||||
|
||||
(cherry picked from commit 398dc56a6cb5d6d01506338fa94ef580e668d5e9)
|
||||
---
|
||||
common/mlpcre/pcre-c.c | 16 ++++++++++++++--
|
||||
common/mlvisit/visit-c.c | 16 ++++++++++++++--
|
||||
common/mlxml/xml-c.c | 16 ++++++++++++++--
|
||||
3 files changed, 42 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/common/mlpcre/pcre-c.c b/common/mlpcre/pcre-c.c
|
||||
index 07f99b8d6..7dbba5857 100644
|
||||
--- a/common/mlpcre/pcre-c.c
|
||||
+++ b/common/mlpcre/pcre-c.c
|
||||
@@ -39,6 +39,19 @@
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
+/* Replacement if caml_alloc_initialized_string is missing, added
|
||||
+ * to OCaml runtime in 2017.
|
||||
+ */
|
||||
+#ifndef HAVE_CAML_ALLOC_INITIALIZED_STRING
|
||||
+static inline value
|
||||
+caml_alloc_initialized_string (mlsize_t len, const char *p)
|
||||
+{
|
||||
+ value sv = caml_alloc_string (len);
|
||||
+ memcpy ((char *) String_val (sv), p, len);
|
||||
+ return sv;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/* Data on the most recent match is stored in this thread-local
|
||||
* variable. It is freed either by the next call to PCRE.matches or
|
||||
* by (clean) thread exit.
|
||||
@@ -257,8 +270,7 @@ guestfs_int_pcre_sub (value nv)
|
||||
if (len < 0)
|
||||
raise_pcre_error ("pcre_get_substring", len);
|
||||
|
||||
- strv = caml_alloc_string (len);
|
||||
- memcpy (String_val (strv), str, len);
|
||||
+ strv = caml_alloc_initialized_string (len, str);
|
||||
CAMLreturn (strv);
|
||||
}
|
||||
|
||||
diff --git a/common/mlvisit/visit-c.c b/common/mlvisit/visit-c.c
|
||||
index 201f6d762..d5585ca94 100644
|
||||
--- a/common/mlvisit/visit-c.c
|
||||
+++ b/common/mlvisit/visit-c.c
|
||||
@@ -35,6 +35,19 @@
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
+/* Replacement if caml_alloc_initialized_string is missing, added
|
||||
+ * to OCaml runtime in 2017.
|
||||
+ */
|
||||
+#ifndef HAVE_CAML_ALLOC_INITIALIZED_STRING
|
||||
+static inline value
|
||||
+caml_alloc_initialized_string (mlsize_t len, const char *p)
|
||||
+{
|
||||
+ value sv = caml_alloc_string (len);
|
||||
+ memcpy ((char *) String_val (sv), p, len);
|
||||
+ return sv;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
struct visitor_function_wrapper_args {
|
||||
/* In both case we are pointing to local roots, hence why these are
|
||||
* value* not value.
|
||||
@@ -198,8 +211,7 @@ copy_xattr (const struct guestfs_xattr *xattr)
|
||||
rv = caml_alloc (2, 0);
|
||||
v = caml_copy_string (xattr->attrname);
|
||||
Store_field (rv, 0, v);
|
||||
- v = caml_alloc_string (xattr->attrval_len);
|
||||
- memcpy (String_val (v), xattr->attrval, xattr->attrval_len);
|
||||
+ v = caml_alloc_initialized_string (xattr->attrval_len, xattr->attrval);
|
||||
Store_field (rv, 1, v);
|
||||
CAMLreturn (rv);
|
||||
}
|
||||
diff --git a/common/mlxml/xml-c.c b/common/mlxml/xml-c.c
|
||||
index d3db7e227..a0fa0fc3d 100644
|
||||
--- a/common/mlxml/xml-c.c
|
||||
+++ b/common/mlxml/xml-c.c
|
||||
@@ -40,6 +40,19 @@
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
+/* Replacement if caml_alloc_initialized_string is missing, added
|
||||
+ * to OCaml runtime in 2017.
|
||||
+ */
|
||||
+#ifndef HAVE_CAML_ALLOC_INITIALIZED_STRING
|
||||
+static inline value
|
||||
+caml_alloc_initialized_string (mlsize_t len, const char *p)
|
||||
+{
|
||||
+ value sv = caml_alloc_string (len);
|
||||
+ memcpy ((char *) String_val (sv), p, len);
|
||||
+ return sv;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/* xmlDocPtr type */
|
||||
#define docptr_val(v) (*((xmlDocPtr *)Data_custom_val(v)))
|
||||
|
||||
@@ -183,8 +196,7 @@ mllib_xml_to_string (value docv, value formatv)
|
||||
doc = docptr_val (docv);
|
||||
xmlDocDumpFormatMemory (doc, &mem, &size, Bool_val (formatv));
|
||||
|
||||
- strv = caml_alloc_string (size);
|
||||
- memcpy (String_val (strv), mem, size);
|
||||
+ strv = caml_alloc_initialized_string (size, mem);
|
||||
free (mem);
|
||||
|
||||
CAMLreturn (strv);
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,37 @@
|
||||
From dbd1eaab6a478cf0c3ea093a56b3d04c29278615 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 12 Jan 2021 10:23:11 +0000
|
||||
Subject: [PATCH] build: Avoid warnings about unknown pragmas.
|
||||
|
||||
In commit 4bbbf03b8bc266ed2b63c461cd0945250bb134fe we started to
|
||||
ignore bogus GCC 11 warnings. Unfortunately earlier versions of GCC
|
||||
don't know about those pragmas so give warnings [hence errors in
|
||||
developer builds] like:
|
||||
|
||||
tsk.c:75:32: error: unknown option after '#pragma GCC diagnostic' kind [-Werror=pragmas]
|
||||
|
||||
Turn off these warnings.
|
||||
|
||||
Updates: commit 4bbbf03b8bc266ed2b63c461cd0945250bb134fe
|
||||
(cherry picked from commit 812f837c97f48ce0c26a0e02286fb9180c282923)
|
||||
---
|
||||
m4/guestfs-c.m4 | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/m4/guestfs-c.m4 b/m4/guestfs-c.m4
|
||||
index 25ffea0d9..bbb4db464 100644
|
||||
--- a/m4/guestfs-c.m4
|
||||
+++ b/m4/guestfs-c.m4
|
||||
@@ -108,6 +108,9 @@ gl_WARN_ADD([-Wformat-truncation=1])
|
||||
dnl GCC 9 at level 2 gives apparently bogus errors when %.*s is used.
|
||||
gl_WARN_ADD([-Wformat-overflow=1])
|
||||
|
||||
+dnl GCC < 11 gives warnings when disabling GCC 11 warnings.
|
||||
+gl_WARN_ADD([-Wno-pragmas])
|
||||
+
|
||||
AC_SUBST([WARN_CFLAGS])
|
||||
|
||||
NO_SNV_CFLAGS=
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 96462b30d5ca6e45601512609cedfc874739137d Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 5 Sep 2019 09:00:14 +0100
|
||||
Subject: [PATCH] ocaml: Change calls to caml_named_value() to cope with const
|
||||
value* return.
|
||||
|
||||
In OCaml >= 4.09 the return value pointer of caml_named_value is
|
||||
declared const.
|
||||
|
||||
Based on Pino Toscano's original patch to ocaml-augeas.
|
||||
|
||||
(cherry picked from commit 74ce7332dbb9bab2a69737257f0d07c93eb9bab4)
|
||||
---
|
||||
generator/daemon.ml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/generator/daemon.ml b/generator/daemon.ml
|
||||
index a4e136aaa..b67c4d20b 100644
|
||||
--- a/generator/daemon.ml
|
||||
+++ b/generator/daemon.ml
|
||||
@@ -746,7 +746,7 @@ let generate_daemon_caml_stubs () =
|
||||
let nr_args = List.length args_do_function in
|
||||
|
||||
pr "{\n";
|
||||
- pr " static value *cb = NULL;\n";
|
||||
+ pr " static const value *cb = NULL;\n";
|
||||
pr " CAMLparam0 ();\n";
|
||||
pr " CAMLlocal2 (v, retv);\n";
|
||||
pr " CAMLlocalN (args, %d);\n"
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,34 +0,0 @@
|
||||
From 93422725a0a8248d97b67cdbc20e065f5164e089 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 6 Feb 2020 10:27:48 +0000
|
||||
Subject: [PATCH] cat: Fix GCC 10 warning.
|
||||
|
||||
I believe this warning is bogus, but simply initializing the local
|
||||
variable is enough to avoid it.
|
||||
|
||||
log.c: In function 'do_log':
|
||||
log.c:390:7: error: 'comm_len' may be used uninitialized in this function [-Werror=maybe-uninitialized]
|
||||
390 | printf (" %.*s", (int) comm_len, comm);
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
(cherry picked from commit 4e199494c41d3240aa5c0708887b7a7513c6b6f2)
|
||||
---
|
||||
cat/log.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cat/log.c b/cat/log.c
|
||||
index 25107e25f..f8a5c85f2 100644
|
||||
--- a/cat/log.c
|
||||
+++ b/cat/log.c
|
||||
@@ -337,7 +337,7 @@ do_log_journal (void)
|
||||
while ((r = guestfs_journal_next (g)) > 0) {
|
||||
CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
|
||||
const char *priority_str, *identifier, *comm, *pid, *message;
|
||||
- size_t priority_len, identifier_len, comm_len, pid_len, message_len;
|
||||
+ size_t priority_len, identifier_len, comm_len = 0, pid_len, message_len;
|
||||
int priority = LOG_INFO;
|
||||
int64_t ts;
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,94 @@
|
||||
From 22416a2329ec531b9608c21b11ff3d53275fe7a0 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 22 Feb 2021 10:18:45 +0000
|
||||
Subject: [PATCH] daemon: lvm: Use lvcreate --yes to avoid interactive prompts.
|
||||
|
||||
See https://bugzilla.redhat.com/show_bug.cgi?id=1930996#c1
|
||||
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1930996
|
||||
(cherry picked from commit 21cd97732c4973db835b8b6540c8ad582ebd2bda)
|
||||
---
|
||||
daemon/lvm.c | 2 +-
|
||||
tests/regressions/Makefile.am | 2 ++
|
||||
tests/regressions/rhbz1930996.sh | 36 ++++++++++++++++++++++++++++++++
|
||||
3 files changed, 39 insertions(+), 1 deletion(-)
|
||||
create mode 100755 tests/regressions/rhbz1930996.sh
|
||||
|
||||
diff --git a/daemon/lvm.c b/daemon/lvm.c
|
||||
index 841dc4b6b..72c59c3a1 100644
|
||||
--- a/daemon/lvm.c
|
||||
+++ b/daemon/lvm.c
|
||||
@@ -219,7 +219,7 @@ do_lvcreate (const char *logvol, const char *volgroup, int mbytes)
|
||||
snprintf (size, sizeof size, "%d", mbytes);
|
||||
|
||||
r = command (NULL, &err,
|
||||
- "lvm", "lvcreate",
|
||||
+ "lvm", "lvcreate", "--yes",
|
||||
"-L", size, "-n", logvol, volgroup, NULL);
|
||||
if (r == -1) {
|
||||
reply_with_error ("%s", err);
|
||||
diff --git a/tests/regressions/Makefile.am b/tests/regressions/Makefile.am
|
||||
index ecb0d68a7..c1e0ee8a9 100644
|
||||
--- a/tests/regressions/Makefile.am
|
||||
+++ b/tests/regressions/Makefile.am
|
||||
@@ -49,6 +49,7 @@ EXTRA_DIST = \
|
||||
rhbz1370424.sh \
|
||||
rhbz1370424.xml \
|
||||
rhbz1477623.sh \
|
||||
+ rhbz1930996.sh \
|
||||
test-noexec-stack.pl
|
||||
|
||||
TESTS = \
|
||||
@@ -79,6 +80,7 @@ TESTS = \
|
||||
rhbz1285847.sh \
|
||||
rhbz1370424.sh \
|
||||
rhbz1477623.sh \
|
||||
+ rhbz1930996.sh \
|
||||
test-big-heap \
|
||||
test-noexec-stack.pl \
|
||||
$(SLOW_TESTS)
|
||||
diff --git a/tests/regressions/rhbz1930996.sh b/tests/regressions/rhbz1930996.sh
|
||||
new file mode 100755
|
||||
index 000000000..27089beaa
|
||||
--- /dev/null
|
||||
+++ b/tests/regressions/rhbz1930996.sh
|
||||
@@ -0,0 +1,36 @@
|
||||
+#!/bin/bash -
|
||||
+# libguestfs
|
||||
+# Copyright (C) 2017-2021 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.
|
||||
+
|
||||
+# Regression test for:
|
||||
+# https://bugzilla.redhat.com/show_bug.cgi?id=1930996#c1
|
||||
+#
|
||||
+# Actually a bug/change in LVM, previously we failed to create an LV
|
||||
+# if the underlying disk contained a filesystem signature.
|
||||
+
|
||||
+set -e
|
||||
+
|
||||
+$TEST_FUNCTIONS
|
||||
+skip_if_skipped
|
||||
+skip_unless_phony_guest fedora.img
|
||||
+
|
||||
+f=rhbz1930996.img
|
||||
+rm -f $f
|
||||
+
|
||||
+guestfish -N $f=lvfs vgremove VG : vgcreate VG /dev/sda1 : lvcreate LV2 VG 100
|
||||
+
|
||||
+rm $f
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,29 +0,0 @@
|
||||
From 17df30b82007073a40deb37ff7f840d56a1b5bf1 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 6 Feb 2020 10:33:39 +0000
|
||||
Subject: [PATCH] builder: Fix const correctness for OCaml 4.10.
|
||||
|
||||
String_val now returns a const char *.
|
||||
|
||||
(cherry picked from commit d6fcf519f2d860fe3167629f042f5ff6a4ccc40d)
|
||||
---
|
||||
builder/setlocale-c.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/builder/setlocale-c.c b/builder/setlocale-c.c
|
||||
index f2ad85352..6d877e7ac 100644
|
||||
--- a/builder/setlocale-c.c
|
||||
+++ b/builder/setlocale-c.c
|
||||
@@ -44,7 +44,8 @@ virt_builder_setlocale (value val_category, value val_name)
|
||||
{
|
||||
CAMLparam2 (val_category, val_name);
|
||||
CAMLlocal2 (rv, rv2);
|
||||
- char *ret, *locstring;
|
||||
+ const char *locstring;
|
||||
+ char *ret;
|
||||
int category;
|
||||
|
||||
category = lc_string_table[Int_val (val_category)];
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,113 @@
|
||||
From e1b339688e5f8f2a14fe0c7e9d02ad68004e4655 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 15 Apr 2021 09:18:22 +0100
|
||||
Subject: [PATCH] inspection: More reliable detection of Linux split /usr
|
||||
configurations
|
||||
|
||||
In RHEL 8+, /usr/etc no longer exists. Since we were looking for this
|
||||
directory in order to detect a separate /usr partition, those were no
|
||||
longer detected, so the merging of /usr data into the root was not
|
||||
being done. The result was incomplete inspection data and failure of
|
||||
virt-v2v.
|
||||
|
||||
All Linux systems since forever have had /usr/src but not /src, so
|
||||
detect this instead.
|
||||
|
||||
Furthermore the merging code didn't work, because we expected that the
|
||||
root filesystem had a distro assigned, but in this configuration we
|
||||
may need to look for that information in /usr/lib/os-release (not on
|
||||
the root filesystem). This change makes the merging work even if we
|
||||
have incomplete information about the root filesystem, so long as we
|
||||
have an /etc/fstab entry pointing to the /usr mountpoint.
|
||||
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1949683
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1930133
|
||||
Fixes: commit 394d11be49121884295e61964ed47f5a8488c252
|
||||
(cherry picked from commit 26427b9ecc64e7e5e53a1d577cef9dc080d08877)
|
||||
---
|
||||
daemon/inspect.ml | 33 +++++++++++++++------------------
|
||||
daemon/inspect_fs.ml | 6 +++---
|
||||
2 files changed, 18 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/daemon/inspect.ml b/daemon/inspect.ml
|
||||
index 945a476f6..fb75b4a6c 100644
|
||||
--- a/daemon/inspect.ml
|
||||
+++ b/daemon/inspect.ml
|
||||
@@ -182,11 +182,9 @@ and check_for_duplicated_bsd_root fses =
|
||||
and collect_linux_inspection_info fses =
|
||||
List.map (
|
||||
function
|
||||
- | { role = RoleRoot { distro = Some d } } as root ->
|
||||
- if d <> DISTRO_COREOS then
|
||||
- collect_linux_inspection_info_for fses root
|
||||
- else
|
||||
- root
|
||||
+ | { role = RoleRoot { distro = Some DISTRO_COREOS } } as root -> root
|
||||
+ | { role = RoleRoot _ } as root ->
|
||||
+ collect_linux_inspection_info_for fses root
|
||||
| fs -> fs
|
||||
) fses
|
||||
|
||||
@@ -196,29 +194,28 @@ and collect_linux_inspection_info fses =
|
||||
* or other ways to identify the OS).
|
||||
*)
|
||||
and collect_linux_inspection_info_for fses root =
|
||||
- let root_distro, root_fstab =
|
||||
+ let root_fstab =
|
||||
match root with
|
||||
- | { role = RoleRoot { distro = Some d; fstab = f } } -> d, f
|
||||
+ | { role = RoleRoot { fstab = f } } -> f
|
||||
| _ -> assert false in
|
||||
|
||||
try
|
||||
let usr =
|
||||
List.find (
|
||||
function
|
||||
- | { role = RoleUsr { distro = d } }
|
||||
- when d = Some root_distro || d = None -> true
|
||||
+ | { role = RoleUsr _; fs_location = usr_mp } ->
|
||||
+ (* This checks that this usr is found in the fstab of
|
||||
+ * the root filesystem.
|
||||
+ *)
|
||||
+ List.exists (
|
||||
+ fun (mountable, _) ->
|
||||
+ usr_mp.mountable = mountable
|
||||
+ ) root_fstab
|
||||
| _ -> false
|
||||
) fses in
|
||||
|
||||
- let usr_mountable = usr.fs_location.mountable in
|
||||
-
|
||||
- (* This checks that [usr] is found in the fstab of the root
|
||||
- * filesystem. If not, [Not_found] is thrown.
|
||||
- *)
|
||||
- ignore (
|
||||
- List.find (fun (mountable, _) -> usr_mountable = mountable) root_fstab
|
||||
- );
|
||||
-
|
||||
+ eprintf "collect_linux_inspection_info_for: merging:\n%sinto:\n%s"
|
||||
+ (string_of_fs usr) (string_of_fs root);
|
||||
merge usr root;
|
||||
root
|
||||
with
|
||||
diff --git a/daemon/inspect_fs.ml b/daemon/inspect_fs.ml
|
||||
index 6e00c7083..02b5a0470 100644
|
||||
--- a/daemon/inspect_fs.ml
|
||||
+++ b/daemon/inspect_fs.ml
|
||||
@@ -164,10 +164,10 @@ and check_filesystem mountable =
|
||||
()
|
||||
)
|
||||
(* Linux /usr? *)
|
||||
- else if Is.is_dir "/etc" &&
|
||||
- Is.is_dir "/bin" &&
|
||||
- Is.is_dir "/share" &&
|
||||
+ else if Is.is_dir "/bin" &&
|
||||
Is.is_dir "/local" &&
|
||||
+ Is.is_dir "/share" &&
|
||||
+ Is.is_dir "/src" &&
|
||||
not (Is.is_file "/etc/fstab") then (
|
||||
debug_matching "Linux /usr";
|
||||
role := `Usr;
|
||||
--
|
||||
2.31.1
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 791a16b049ea1ce2c450acd367fce774d9aab5b1 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 31 Aug 2021 08:27:15 +0100
|
||||
Subject: [PATCH] lib: Autodetect backing format for qemu-img create -b
|
||||
|
||||
qemu 6.1 has decided to change qemu-img create so that a backing
|
||||
format (-F) is required if a backing file (-b) is specified. Since we
|
||||
don't want to change the libguestfs API to force callers to specify
|
||||
this because that would be an API break, autodetect it.
|
||||
|
||||
This is similar to commit c8c181e8d9 ("launch: libvirt: Autodetect
|
||||
backing format for readonly drive overlays").
|
||||
|
||||
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1998820
|
||||
(cherry picked from commit 45de287447bb18d59749fbfc1ec5072413090109)
|
||||
---
|
||||
lib/create.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/lib/create.c b/lib/create.c
|
||||
index 44a7df25f..75a4d3a28 100644
|
||||
--- a/lib/create.c
|
||||
+++ b/lib/create.c
|
||||
@@ -255,6 +255,7 @@ disk_create_qcow2 (guestfs_h *g, const char *filename, int64_t size,
|
||||
const struct guestfs_disk_create_argv *optargs)
|
||||
{
|
||||
const char *backingformat = NULL;
|
||||
+ CLEANUP_FREE char *backingformat_free = NULL;
|
||||
const char *preallocation = NULL;
|
||||
const char *compat = NULL;
|
||||
int clustersize = -1;
|
||||
@@ -270,6 +271,14 @@ disk_create_qcow2 (guestfs_h *g, const char *filename, int64_t size,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
+ else if (backingfile) {
|
||||
+ /* Since qemu 6.1, qemu-img create has requires a backing format (-F)
|
||||
+ * parameter if backing file (-b) is used (RHBZ#1998820).
|
||||
+ */
|
||||
+ backingformat = backingformat_free = guestfs_disk_format (g, backingfile);
|
||||
+ if (!backingformat)
|
||||
+ return -1;
|
||||
+ }
|
||||
if (optargs->bitmask & GUESTFS_DISK_CREATE_PREALLOCATION_BITMASK) {
|
||||
if (STREQ (optargs->preallocation, "off") ||
|
||||
STREQ (optargs->preallocation, "sparse"))
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 8eb9f06b156c6362a17712cfed9c629dec297a2c Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 6 Feb 2020 10:22:42 +0000
|
||||
Subject: [PATCH] mlxml: Fix pointed target signedness.
|
||||
|
||||
xml-c.c: In function 'mllib_xml_to_string':
|
||||
xml-c.c:199:47: error: pointer targets in passing argument 2 of 'caml_alloc_initialized_string' differ in signedness [-Werror=pointer-sign]
|
||||
199 | strv = caml_alloc_initialized_string (size, mem);
|
||||
| ^~~
|
||||
| |
|
||||
| xmlChar * {aka unsigned char *}
|
||||
|
||||
(cherry picked from commit ea10827b4cfb3cfe5f782421c01d2902e5f73f90)
|
||||
---
|
||||
common/mlxml/xml-c.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/common/mlxml/xml-c.c b/common/mlxml/xml-c.c
|
||||
index a0fa0fc3d..715c3bb24 100644
|
||||
--- a/common/mlxml/xml-c.c
|
||||
+++ b/common/mlxml/xml-c.c
|
||||
@@ -196,7 +196,7 @@ mllib_xml_to_string (value docv, value formatv)
|
||||
doc = docptr_val (docv);
|
||||
xmlDocDumpFormatMemory (doc, &mem, &size, Bool_val (formatv));
|
||||
|
||||
- strv = caml_alloc_initialized_string (size, mem);
|
||||
+ strv = caml_alloc_initialized_string (size, (const char *) mem);
|
||||
free (mem);
|
||||
|
||||
CAMLreturn (strv);
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,126 +0,0 @@
|
||||
From 83c76b6c610df17e0b9bfd9cd11deb43ebc40411 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Tue, 19 Feb 2019 10:50:01 +0100
|
||||
Subject: [PATCH] common/mlpcre: add offset flag for PCRE.matches
|
||||
|
||||
This way it is possible to change where the matching start, instead of
|
||||
always assuming it is the beginning.
|
||||
|
||||
(cherry picked from commit 0ed2e5c14a302d15fd3b75ee2c1cb808a06cb746)
|
||||
---
|
||||
common/mlpcre/PCRE.ml | 2 +-
|
||||
common/mlpcre/PCRE.mli | 5 ++++-
|
||||
common/mlpcre/pcre-c.c | 16 +++++++++++++---
|
||||
common/mlpcre/pcre_tests.ml | 11 ++++++++---
|
||||
4 files changed, 26 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/common/mlpcre/PCRE.ml b/common/mlpcre/PCRE.ml
|
||||
index b054928f9..33074af1c 100644
|
||||
--- a/common/mlpcre/PCRE.ml
|
||||
+++ b/common/mlpcre/PCRE.ml
|
||||
@@ -23,7 +23,7 @@ exception Error of string * int
|
||||
type regexp
|
||||
|
||||
external compile : ?anchored:bool -> ?caseless:bool -> ?dotall:bool -> ?extended:bool -> ?multiline:bool -> string -> regexp = "guestfs_int_pcre_compile_byte" "guestfs_int_pcre_compile"
|
||||
-external matches : regexp -> string -> bool = "guestfs_int_pcre_matches"
|
||||
+external matches : ?offset:int -> regexp -> string -> bool = "guestfs_int_pcre_matches"
|
||||
external sub : int -> string = "guestfs_int_pcre_sub"
|
||||
external subi : int -> int * int = "guestfs_int_pcre_subi"
|
||||
|
||||
diff --git a/common/mlpcre/PCRE.mli b/common/mlpcre/PCRE.mli
|
||||
index eacb6fd90..e10d512fc 100644
|
||||
--- a/common/mlpcre/PCRE.mli
|
||||
+++ b/common/mlpcre/PCRE.mli
|
||||
@@ -62,7 +62,7 @@ val compile : ?anchored:bool -> ?caseless:bool -> ?dotall:bool -> ?extended:bool
|
||||
See pcreapi(3) for details of what they do.
|
||||
All flags default to false. *)
|
||||
|
||||
-val matches : regexp -> string -> bool
|
||||
+val matches : ?offset:int -> regexp -> string -> bool
|
||||
(** Test whether the regular expression matches the string. This
|
||||
returns true if the regexp matches or false otherwise.
|
||||
|
||||
@@ -71,6 +71,9 @@ val matches : regexp -> string -> bool
|
||||
or the thread/program exits. You can call {!sub} to return
|
||||
these substrings.
|
||||
|
||||
+ The [?offset] flag is used to change the start of the search,
|
||||
+ which by default is at the beginning of the string (position 0).
|
||||
+
|
||||
This can raise {!Error} if PCRE returns an error. *)
|
||||
|
||||
val sub : int -> string
|
||||
diff --git a/common/mlpcre/pcre-c.c b/common/mlpcre/pcre-c.c
|
||||
index 7dbba5857..ec3a6f00d 100644
|
||||
--- a/common/mlpcre/pcre-c.c
|
||||
+++ b/common/mlpcre/pcre-c.c
|
||||
@@ -133,6 +133,15 @@ is_Some_true (value v)
|
||||
Bool_val (Field (v, 0)) /* Some true */;
|
||||
}
|
||||
|
||||
+static int
|
||||
+Optint_val (value intv, int defval)
|
||||
+{
|
||||
+ if (intv == Val_int (0)) /* None */
|
||||
+ return defval;
|
||||
+ else /* Some int */
|
||||
+ return Int_val (Field (intv, 0));
|
||||
+}
|
||||
+
|
||||
value
|
||||
guestfs_int_pcre_compile (value anchoredv, value caselessv, value dotallv,
|
||||
value extendedv, value multilinev,
|
||||
@@ -177,9 +186,9 @@ guestfs_int_pcre_compile_byte (value *argv, int argn)
|
||||
}
|
||||
|
||||
value
|
||||
-guestfs_int_pcre_matches (value rev, value strv)
|
||||
+guestfs_int_pcre_matches (value offsetv, value rev, value strv)
|
||||
{
|
||||
- CAMLparam2 (rev, strv);
|
||||
+ CAMLparam3 (offsetv, rev, strv);
|
||||
pcre *re = Regexp_val (rev);
|
||||
struct last_match *m, *oldm;
|
||||
size_t len = caml_string_length (strv);
|
||||
@@ -217,7 +226,8 @@ guestfs_int_pcre_matches (value rev, value strv)
|
||||
caml_raise_out_of_memory ();
|
||||
}
|
||||
|
||||
- m->r = pcre_exec (re, NULL, m->subject, len, 0, 0, m->vec, veclen);
|
||||
+ m->r = pcre_exec (re, NULL, m->subject, len, Optint_val (offsetv, 0), 0,
|
||||
+ m->vec, veclen);
|
||||
if (m->r < 0 && m->r != PCRE_ERROR_NOMATCH) {
|
||||
int ret = m->r;
|
||||
free_last_match (m);
|
||||
diff --git a/common/mlpcre/pcre_tests.ml b/common/mlpcre/pcre_tests.ml
|
||||
index 346019c40..3e5981107 100644
|
||||
--- a/common/mlpcre/pcre_tests.ml
|
||||
+++ b/common/mlpcre/pcre_tests.ml
|
||||
@@ -30,9 +30,9 @@ let compile ?(anchored = false) ?(caseless = false)
|
||||
patt;
|
||||
PCRE.compile ~anchored ~caseless ~dotall ~extended ~multiline patt
|
||||
|
||||
-let matches re str =
|
||||
- eprintf "PCRE.matches %s ->%!" str;
|
||||
- let r = PCRE.matches re str in
|
||||
+let matches ?(offset = 0) re str =
|
||||
+ eprintf "PCRE.matches %s, %d ->%!" str offset;
|
||||
+ let r = PCRE.matches ~offset re str in
|
||||
eprintf " %b\n%!" r;
|
||||
r
|
||||
|
||||
@@ -103,6 +103,11 @@ let () =
|
||||
assert (subi 1 = (2, 3));
|
||||
assert (subi 2 = (3, 3));
|
||||
|
||||
+ assert (matches ~offset:5 re0 "aaabcabc" = true);
|
||||
+ assert (sub 0 = "ab");
|
||||
+
|
||||
+ assert (matches ~offset:5 re0 "aaabcbaac" = false);
|
||||
+
|
||||
assert (replace re0 "dd" "abcabcaabccca" = "ddcabcaabccca");
|
||||
assert (replace ~global:true re0 "dd" "abcabcaabccca" = "ddcddcddccca");
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,44 @@
|
||||
From 3435938f43ca3737ec1d73da4d8cad756b5c9508 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 26 Mar 2021 16:04:43 +0000
|
||||
Subject: [PATCH] daemon: chroot: Fix long-standing possible deadlock.
|
||||
|
||||
The child (chrooted) process wrote its answer on the pipe and then
|
||||
exited. Meanwhile the parent waiting for the child to exit before
|
||||
reading from the pipe. Thus if the output was larger than a Linux
|
||||
pipebuffer then the whole thing would deadlock.
|
||||
|
||||
(cherry picked from commit 94e64b28bee3b8dc7ed354a366d6a8f7ba5f245c)
|
||||
---
|
||||
daemon/chroot.ml | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/daemon/chroot.ml b/daemon/chroot.ml
|
||||
index 5e856c91f..7da8ae29e 100644
|
||||
--- a/daemon/chroot.ml
|
||||
+++ b/daemon/chroot.ml
|
||||
@@ -62,6 +62,10 @@ let f t func arg =
|
||||
(* Parent. *)
|
||||
close wfd;
|
||||
|
||||
+ let chan = in_channel_of_descr rfd in
|
||||
+ let ret = input_value chan in
|
||||
+ close_in chan;
|
||||
+
|
||||
let _, status = waitpid [] pid in
|
||||
(match status with
|
||||
| WEXITED 0 -> ()
|
||||
@@ -76,10 +80,6 @@ let f t func arg =
|
||||
failwithf "chroot ‘%s’ stopped by signal %d" t.name i
|
||||
);
|
||||
|
||||
- let chan = in_channel_of_descr rfd in
|
||||
- let ret = input_value chan in
|
||||
- close_in chan;
|
||||
-
|
||||
match ret with
|
||||
| Either ret -> ret
|
||||
| Or exn -> raise exn
|
||||
--
|
||||
2.31.1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,415 +0,0 @@
|
||||
From 8b7c559f6c619bab8a708358db15b2959623c833 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Tue, 19 Feb 2019 14:54:31 +0100
|
||||
Subject: [PATCH] v2v: add Var_expander
|
||||
|
||||
This helper module provides a facility to replace %{FOO}-like variables
|
||||
in text strings with user-provided content.
|
||||
|
||||
(cherry picked from commit a27748d7000f417c16045967497208d275a09ce8)
|
||||
---
|
||||
.gitignore | 1 +
|
||||
v2v/Makefile.am | 32 ++++++++++-
|
||||
v2v/dummy.c | 2 +
|
||||
v2v/var_expander.ml | 72 ++++++++++++++++++++++++
|
||||
v2v/var_expander.mli | 82 +++++++++++++++++++++++++++
|
||||
v2v/var_expander_tests.ml | 113 ++++++++++++++++++++++++++++++++++++++
|
||||
6 files changed, 300 insertions(+), 2 deletions(-)
|
||||
create mode 100644 v2v/dummy.c
|
||||
create mode 100644 v2v/var_expander.ml
|
||||
create mode 100644 v2v/var_expander.mli
|
||||
create mode 100644 v2v/var_expander_tests.ml
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 637bf7765..f2efcdde2 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -693,6 +693,7 @@ Makefile.in
|
||||
/v2v/uefi.ml
|
||||
/v2v/uefi.mli
|
||||
/v2v/v2v_unit_tests
|
||||
+/v2v/var_expander_tests
|
||||
/v2v/virt-v2v
|
||||
/v2v/virt-v2v.1
|
||||
/v2v/virt-v2v-copy-to-local
|
||||
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
|
||||
index 2312812fb..f196be81d 100644
|
||||
--- a/v2v/Makefile.am
|
||||
+++ b/v2v/Makefile.am
|
||||
@@ -98,6 +98,7 @@ SOURCES_MLI = \
|
||||
utils.mli \
|
||||
v2v.mli \
|
||||
vCenter.mli \
|
||||
+ var_expander.mli \
|
||||
windows.mli \
|
||||
windows_virtio.mli
|
||||
|
||||
@@ -106,6 +107,7 @@ SOURCES_ML = \
|
||||
types.ml \
|
||||
uefi.ml \
|
||||
utils.ml \
|
||||
+ var_expander.ml \
|
||||
python_script.ml \
|
||||
name_from_disk.ml \
|
||||
vCenter.ml \
|
||||
@@ -442,7 +444,7 @@ TESTS += \
|
||||
endif
|
||||
|
||||
if HAVE_OCAML_PKG_OUNIT
|
||||
-TESTS += v2v_unit_tests
|
||||
+TESTS += v2v_unit_tests var_expander_tests
|
||||
endif
|
||||
|
||||
if ENABLE_APPLIANCE
|
||||
@@ -651,7 +653,7 @@ EXTRA_DIST += \
|
||||
# Unit tests.
|
||||
check_PROGRAMS =
|
||||
if HAVE_OCAML_PKG_OUNIT
|
||||
-check_PROGRAMS += v2v_unit_tests
|
||||
+check_PROGRAMS += v2v_unit_tests var_expander_tests
|
||||
endif
|
||||
|
||||
v2v_unit_tests_BOBJECTS = \
|
||||
@@ -671,13 +673,28 @@ v2v_unit_tests_SOURCES = $(virt_v2v_SOURCES)
|
||||
v2v_unit_tests_CPPFLAGS = $(virt_v2v_CPPFLAGS)
|
||||
v2v_unit_tests_CFLAGS = $(virt_v2v_CFLAGS)
|
||||
|
||||
+var_expander_tests_BOBJECTS = \
|
||||
+ var_expander.cmo \
|
||||
+ var_expander_tests.cmo
|
||||
+var_expander_tests_XOBJECTS = $(var_expander_tests_BOBJECTS:.cmo=.cmx)
|
||||
+
|
||||
+var_expander_tests_SOURCES = dummy.c
|
||||
+var_expander_tests_CPPFLAGS = $(virt_v2v_CPPFLAGS)
|
||||
+var_expander_tests_CFLAGS = $(virt_v2v_CFLAGS)
|
||||
+
|
||||
if !HAVE_OCAMLOPT
|
||||
# Can't call this v2v_unit_tests_OBJECTS because automake gets confused.
|
||||
v2v_unit_tests_THEOBJECTS = $(v2v_unit_tests_BOBJECTS)
|
||||
v2v_unit_tests.cmo: OCAMLPACKAGES += -package oUnit
|
||||
+
|
||||
+var_expander_tests_THEOBJECTS = $(var_expander_tests_BOBJECTS)
|
||||
+var_expander_tests.cmo: OCAMLPACKAGES += -package oUnit
|
||||
else
|
||||
v2v_unit_tests_THEOBJECTS = $(v2v_unit_tests_XOBJECTS)
|
||||
v2v_unit_tests.cmx: OCAMLPACKAGES += -package oUnit
|
||||
+
|
||||
+var_expander_tests_THEOBJECTS = $(var_expander_tests_XOBJECTS)
|
||||
+var_expander_tests.cmx: OCAMLPACKAGES += -package oUnit
|
||||
endif
|
||||
|
||||
v2v_unit_tests_DEPENDENCIES = \
|
||||
@@ -696,6 +713,17 @@ v2v_unit_tests_LINK = \
|
||||
$(OCAMLLINKFLAGS) \
|
||||
$(v2v_unit_tests_THEOBJECTS) -o $@
|
||||
|
||||
+var_expander_tests_DEPENDENCIES = \
|
||||
+ $(var_expander_tests_THEOBJECTS) \
|
||||
+ ../common/mlpcre/mlpcre.$(MLARCHIVE) \
|
||||
+ $(top_srcdir)/ocaml-link.sh
|
||||
+var_expander_tests_LINK = \
|
||||
+ $(top_srcdir)/ocaml-link.sh -cclib '$(OCAMLCLIBS)' -- \
|
||||
+ $(OCAMLFIND) $(BEST) $(OCAMLFLAGS) \
|
||||
+ $(OCAMLPACKAGES) -package oUnit \
|
||||
+ $(OCAMLLINKFLAGS) \
|
||||
+ $(var_expander_tests_THEOBJECTS) -o $@
|
||||
+
|
||||
# Dependencies.
|
||||
.depend: \
|
||||
$(srcdir)/*.mli \
|
||||
diff --git a/v2v/dummy.c b/v2v/dummy.c
|
||||
new file mode 100644
|
||||
index 000000000..ebab6198c
|
||||
--- /dev/null
|
||||
+++ b/v2v/dummy.c
|
||||
@@ -0,0 +1,2 @@
|
||||
+/* Dummy source, to be used for OCaml-based tools with no C sources. */
|
||||
+enum { foo = 1 };
|
||||
diff --git a/v2v/var_expander.ml b/v2v/var_expander.ml
|
||||
new file mode 100644
|
||||
index 000000000..24b9bafe3
|
||||
--- /dev/null
|
||||
+++ b/v2v/var_expander.ml
|
||||
@@ -0,0 +1,72 @@
|
||||
+(* virt-v2v
|
||||
+ * Copyright (C) 2019 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.
|
||||
+ *)
|
||||
+
|
||||
+open Std_utils
|
||||
+
|
||||
+exception Invalid_variable of string
|
||||
+
|
||||
+let var_re = PCRE.compile "(^|[^%])%{([^}]+)}"
|
||||
+
|
||||
+let check_variable var =
|
||||
+ String.iter (
|
||||
+ function
|
||||
+ | '0'..'9'
|
||||
+ | 'a'..'z'
|
||||
+ | 'A'..'Z'
|
||||
+ | '_'
|
||||
+ | '-' -> ()
|
||||
+ | _ -> raise (Invalid_variable var)
|
||||
+ ) var
|
||||
+
|
||||
+let scan_variables str =
|
||||
+ let res = ref [] in
|
||||
+ let offset = ref 0 in
|
||||
+ while PCRE.matches ~offset:!offset var_re str; do
|
||||
+ let var = PCRE.sub 2 in
|
||||
+ check_variable var;
|
||||
+ let _, end_ = PCRE.subi 0 in
|
||||
+ List.push_back res var;
|
||||
+ offset := end_
|
||||
+ done;
|
||||
+ List.remove_duplicates !res
|
||||
+
|
||||
+let replace_fn str fn =
|
||||
+ let res = ref str in
|
||||
+ let offset = ref 0 in
|
||||
+ while PCRE.matches ~offset:!offset var_re !res; do
|
||||
+ let var = PCRE.sub 2 in
|
||||
+ check_variable var;
|
||||
+ let start_, end_ = PCRE.subi 0 in
|
||||
+ match fn var with
|
||||
+ | None ->
|
||||
+ offset := end_
|
||||
+ | Some text ->
|
||||
+ let prefix_len =
|
||||
+ let prefix_start, prefix_end = PCRE.subi 1 in
|
||||
+ prefix_end - prefix_start in
|
||||
+ res := (String.sub !res 0 (start_ + prefix_len)) ^ text ^ (String.sub !res end_ (String.length !res - end_));
|
||||
+ offset := start_ + prefix_len + String.length text
|
||||
+ done;
|
||||
+ !res
|
||||
+
|
||||
+let replace_list str lst =
|
||||
+ let fn var =
|
||||
+ try Some (List.assoc var lst)
|
||||
+ with Not_found -> None
|
||||
+ in
|
||||
+ replace_fn str fn
|
||||
diff --git a/v2v/var_expander.mli b/v2v/var_expander.mli
|
||||
new file mode 100644
|
||||
index 000000000..80aa33c2c
|
||||
--- /dev/null
|
||||
+++ b/v2v/var_expander.mli
|
||||
@@ -0,0 +1,82 @@
|
||||
+(* virt-v2v
|
||||
+ * Copyright (C) 2019 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.
|
||||
+ *)
|
||||
+
|
||||
+(** Simple variable expander.
|
||||
+
|
||||
+ This module provides the support to expand variables in strings,
|
||||
+ specified in the form of [%{name}].
|
||||
+
|
||||
+ For example:
|
||||
+
|
||||
+{v
|
||||
+let str = "variable-%{INDEX} in %{INDEX} replaced %{INDEX} times"
|
||||
+let index = ref 0
|
||||
+let fn = function
|
||||
+ | "INDEX" ->
|
||||
+ incr index;
|
||||
+ Some (string_of_int !index)
|
||||
+ | _ -> None
|
||||
+in
|
||||
+let str = Var_expander.replace_fn str fn
|
||||
+(* now str is "variable-1 in 2 replaced 3 times" *)
|
||||
+v}
|
||||
+
|
||||
+ The names of variables can contain only ASCII letters (uppercase,
|
||||
+ and lowercase), digits, underscores, and dashes.
|
||||
+
|
||||
+ The replacement is done in a single pass: this means that if a
|
||||
+ variable is replaced with the text of a variable, that new text
|
||||
+ is kept as is in the final output. In practice:
|
||||
+
|
||||
+{v
|
||||
+let str = "%{VAR}"
|
||||
+let str = Var_expander.replace_list str [("VAR", "%{VAR}")]
|
||||
+(* now str is "%{VAR}" *)
|
||||
+v}
|
||||
+*)
|
||||
+
|
||||
+exception Invalid_variable of string
|
||||
+(** Invalid variable name error.
|
||||
+
|
||||
+ In case a variable contains characters not allowed, then this
|
||||
+ exception with the actual unacceptable variable. *)
|
||||
+
|
||||
+val scan_variables : string -> string list
|
||||
+(** Scan the pattern string for all the variables available.
|
||||
+
|
||||
+ This can raise {!Invalid_variable} in case there are invalid
|
||||
+ variable names. *)
|
||||
+
|
||||
+val replace_fn : string -> (string -> string option) -> string
|
||||
+(** Replaces a string expanding all the variables.
|
||||
+
|
||||
+ The replacement function specify how a variable is replaced;
|
||||
+ if [None] is returned, then that variable is not replaced.
|
||||
+
|
||||
+ This can raise {!Invalid_variable} in case there are invalid
|
||||
+ variable names. *)
|
||||
+
|
||||
+val replace_list : string -> (string * string) list -> string
|
||||
+(** Replaces a string expanding all the variables.
|
||||
+
|
||||
+ The replacement list specify how a variable is replaced;
|
||||
+ if it is not specified in the list, then that variable is not
|
||||
+ replaced.
|
||||
+
|
||||
+ This can raise {!Invalid_variable} in case there are invalid
|
||||
+ variable names. *)
|
||||
diff --git a/v2v/var_expander_tests.ml b/v2v/var_expander_tests.ml
|
||||
new file mode 100644
|
||||
index 000000000..35b628369
|
||||
--- /dev/null
|
||||
+++ b/v2v/var_expander_tests.ml
|
||||
@@ -0,0 +1,113 @@
|
||||
+(* virt-v2v
|
||||
+ * Copyright (C) 2019 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.
|
||||
+ *)
|
||||
+
|
||||
+open Printf
|
||||
+open OUnit
|
||||
+
|
||||
+open Std_utils
|
||||
+
|
||||
+let assert_equal_string = assert_equal ~printer:identity
|
||||
+let assert_equal_stringlist = assert_equal ~printer:(fun x -> "(" ^ (String.escaped (String.concat "," x)) ^ ")")
|
||||
+
|
||||
+let replace_none_fn _ = None
|
||||
+let replace_empty_fn _ = Some ""
|
||||
+
|
||||
+let test_no_replacement () =
|
||||
+ assert_equal_string "" (Var_expander.replace_fn "" replace_none_fn);
|
||||
+ assert_equal_string "x" (Var_expander.replace_fn "x" replace_none_fn);
|
||||
+ assert_equal_string "%{}" (Var_expander.replace_fn "%{}" replace_none_fn);
|
||||
+ assert_equal_string "%{EMPTY}" (Var_expander.replace_fn "%{EMPTY}" replace_none_fn);
|
||||
+ assert_equal_string "%{EMPTY} %{no}" (Var_expander.replace_fn "%{EMPTY} %{no}" replace_none_fn);
|
||||
+ assert_equal_string "a %{EMPTY} b" (Var_expander.replace_fn "a %{EMPTY} b" replace_none_fn);
|
||||
+ ()
|
||||
+
|
||||
+let test_replacements () =
|
||||
+ assert_equal_string "" (Var_expander.replace_fn "%{EMPTY}" replace_empty_fn);
|
||||
+ assert_equal_string "x " (Var_expander.replace_fn "x %{EMPTY}" replace_empty_fn);
|
||||
+ assert_equal_string "xy" (Var_expander.replace_fn "x%{EMPTY}y" replace_empty_fn);
|
||||
+ assert_equal_string "x<->y" (Var_expander.replace_fn "x%{FOO}y" (function | "FOO" -> Some "<->" | _ -> None));
|
||||
+ assert_equal_string "a x b" (Var_expander.replace_fn "a %{FOO} b" (function | "FOO" -> Some "x" | _ -> None));
|
||||
+ assert_equal_string "%{FOO} x" (Var_expander.replace_fn "%{FOO} %{BAR}" (function | "BAR" -> Some "x" | _ -> None));
|
||||
+ assert_equal_string "%{FOO}" (Var_expander.replace_fn "%{BAR}" (function | "BAR" -> Some "%{FOO}" | _ -> None));
|
||||
+ assert_equal_string "%{FOO} x" (Var_expander.replace_fn "%{BAR} %{FOO}" (function | "BAR" -> Some "%{FOO}" | "FOO" -> Some "x" | _ -> None));
|
||||
+ begin
|
||||
+ let str = "%{INDEX}, %{INDEX}, %{INDEX}" in
|
||||
+ let index = ref 0 in
|
||||
+ let fn = function
|
||||
+ | "INDEX" ->
|
||||
+ incr index;
|
||||
+ Some (string_of_int !index)
|
||||
+ | _ -> None
|
||||
+ in
|
||||
+ assert_equal_string "1, 2, 3" (Var_expander.replace_fn str fn)
|
||||
+ end;
|
||||
+ ()
|
||||
+
|
||||
+let test_escape () =
|
||||
+ assert_equal_string "%%{FOO}" (Var_expander.replace_fn "%%{FOO}" replace_empty_fn);
|
||||
+ assert_equal_string "x %%{FOO} x" (Var_expander.replace_fn "%{FOO} %%{FOO} %{FOO}" (function | "FOO" -> Some "x" | _ -> None));
|
||||
+ ()
|
||||
+
|
||||
+let test_list () =
|
||||
+ assert_equal_string "x %{NONE}" (Var_expander.replace_list "%{FOO} %{NONE}" [("FOO", "x")]);
|
||||
+ ()
|
||||
+
|
||||
+let test_scan_variables () =
|
||||
+ let assert_invalid_variable var =
|
||||
+ let str = "%{" ^ var ^ "}" in
|
||||
+ assert_raises (Var_expander.Invalid_variable var)
|
||||
+ (fun () -> Var_expander.scan_variables str)
|
||||
+ in
|
||||
+ assert_equal_stringlist [] (Var_expander.scan_variables "");
|
||||
+ assert_equal_stringlist [] (Var_expander.scan_variables "foo");
|
||||
+ assert_equal_stringlist ["FOO"] (Var_expander.scan_variables "%{FOO}");
|
||||
+ assert_equal_stringlist ["FOO"; "BAR"] (Var_expander.scan_variables "%{FOO} %{BAR}");
|
||||
+ assert_equal_stringlist ["FOO"; "BAR"] (Var_expander.scan_variables "%{FOO} %{BAR} %{FOO}");
|
||||
+ assert_equal_stringlist ["FOO"; "BAR"] (Var_expander.scan_variables "%{FOO} %%{ESCAPED} %{BAR}");
|
||||
+ assert_invalid_variable "FOO/BAR";
|
||||
+ ()
|
||||
+
|
||||
+let test_errors () =
|
||||
+ let assert_invalid_variable var =
|
||||
+ let str = "%{" ^ var ^ "}" in
|
||||
+ assert_raises (Var_expander.Invalid_variable var)
|
||||
+ (fun () -> Var_expander.replace_fn str replace_none_fn)
|
||||
+ in
|
||||
+ assert_invalid_variable "FOO/BAR";
|
||||
+ assert_invalid_variable "FOO:BAR";
|
||||
+ assert_invalid_variable "FOO(BAR";
|
||||
+ assert_invalid_variable "FOO)BAR";
|
||||
+ assert_invalid_variable "FOO@BAR";
|
||||
+ ()
|
||||
+
|
||||
+(* Suites declaration. *)
|
||||
+let suite =
|
||||
+ TestList ([
|
||||
+ "basic" >::: [
|
||||
+ "no_replacement" >:: test_no_replacement;
|
||||
+ "replacements" >:: test_replacements;
|
||||
+ "escape" >:: test_escape;
|
||||
+ "list" >:: test_list;
|
||||
+ "scan_variables" >:: test_scan_variables;
|
||||
+ "errors" >:: test_errors;
|
||||
+ ];
|
||||
+ ])
|
||||
+
|
||||
+let () =
|
||||
+ ignore (run_test_tt_main suite);
|
||||
+ Printf.fprintf stderr "\n"
|
||||
--
|
||||
2.18.4
|
||||
|
36
SOURCES/0012-inspection-Return-RPM-epoch.patch
Normal file
36
SOURCES/0012-inspection-Return-RPM-epoch.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From 3ce392c9870a589cc50d2270fcf07b4d129c3dc3 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Sat, 27 Mar 2021 09:31:00 +0000
|
||||
Subject: [PATCH] inspection: Return RPM epoch.
|
||||
|
||||
Fixes: commit c9ee831affed55abe0f928134cbbd2ed83b2f510
|
||||
(cherry picked from commit fef73bce7eec0ce0753a2e150e4e088020d38643)
|
||||
---
|
||||
daemon/rpm-c.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemon/rpm-c.c b/daemon/rpm-c.c
|
||||
index 92a3abf58..be0e81e22 100644
|
||||
--- a/daemon/rpm-c.c
|
||||
+++ b/daemon/rpm-c.c
|
||||
@@ -108,13 +108,16 @@ guestfs_int_daemon_rpm_next_application (value unitv)
|
||||
|
||||
h = headerLink (h);
|
||||
app.app2_name = headerFormat (h, "%{NAME}", NULL);
|
||||
- // XXXapp.app2_epoch = headerFormat (h, "%{NAME}", NULL);
|
||||
app.app2_version = headerFormat (h, "%{VERSION}", NULL);
|
||||
app.app2_release = headerFormat (h, "%{RELEASE}", NULL);
|
||||
app.app2_arch = headerFormat (h, "%{ARCH}", NULL);
|
||||
app.app2_url = headerFormat (h, "%{URL}", NULL);
|
||||
app.app2_summary = headerFormat (h, "%{SUMMARY}", NULL);
|
||||
app.app2_description = headerFormat (h, "%{DESCRIPTION}", NULL);
|
||||
+
|
||||
+ /* epoch is special as the only int field. */
|
||||
+ app.app2_epoch = headerGetNumber (h, RPMTAG_EPOCH);
|
||||
+
|
||||
headerFree (h);
|
||||
|
||||
/* Convert this to an OCaml struct. Any NULL fields must be turned
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,785 +0,0 @@
|
||||
From 87df9bcb99bdb60d5cedf52e155361826e700816 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 25 Feb 2019 13:14:43 +0100
|
||||
Subject: [PATCH] v2v: add -o json output mode
|
||||
|
||||
Add a new output mode to virt-v2v: similar to -o local, the written
|
||||
metadata is a JSON file with the majority of the data that virt-v2v
|
||||
knowns about (or collects) during the conversion.
|
||||
|
||||
This is meant to be used only when no existing output mode is usable,
|
||||
and a guest needs to be converted to run on KVM anyway. The user of
|
||||
this mode is supposed to use all the data in the JSON, as they contain
|
||||
important details on how even run the guest (e.g. w.r.t. firmware,
|
||||
drivers of disks/NICs, etc).
|
||||
|
||||
(cherry picked from commit f190e08d85556dac293ef15bfeee38e54471570f)
|
||||
---
|
||||
v2v/Makefile.am | 4 +
|
||||
v2v/cmdline.ml | 29 +++
|
||||
v2v/create_json.ml | 348 ++++++++++++++++++++++++++++++++++
|
||||
v2v/create_json.mli | 29 +++
|
||||
v2v/output_json.ml | 116 ++++++++++++
|
||||
v2v/output_json.mli | 31 +++
|
||||
v2v/virt-v2v-output-local.pod | 55 ++++++
|
||||
v2v/virt-v2v.pod | 15 +-
|
||||
8 files changed, 625 insertions(+), 2 deletions(-)
|
||||
create mode 100644 v2v/create_json.ml
|
||||
create mode 100644 v2v/create_json.mli
|
||||
create mode 100644 v2v/output_json.ml
|
||||
create mode 100644 v2v/output_json.mli
|
||||
|
||||
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
|
||||
index f196be81d..53c137fc6 100644
|
||||
--- a/v2v/Makefile.am
|
||||
+++ b/v2v/Makefile.am
|
||||
@@ -52,6 +52,7 @@ SOURCES_MLI = \
|
||||
config.mli \
|
||||
convert_linux.mli \
|
||||
convert_windows.mli \
|
||||
+ create_json.mli \
|
||||
create_libvirt_xml.mli \
|
||||
create_ovf.mli \
|
||||
DOM.mli \
|
||||
@@ -75,6 +76,7 @@ SOURCES_MLI = \
|
||||
networks.mli \
|
||||
openstack_image_properties.mli \
|
||||
output_glance.mli \
|
||||
+ output_json.mli \
|
||||
output_libvirt.mli \
|
||||
output_local.mli \
|
||||
output_null.mli \
|
||||
@@ -117,6 +119,7 @@ SOURCES_ML = \
|
||||
parse_ovf_from_ova.ml \
|
||||
parse_ova.ml \
|
||||
create_ovf.ml \
|
||||
+ create_json.ml \
|
||||
linux.ml \
|
||||
windows.ml \
|
||||
windows_virtio.ml \
|
||||
@@ -141,6 +144,7 @@ SOURCES_ML = \
|
||||
convert_windows.ml \
|
||||
output_null.ml \
|
||||
output_glance.ml \
|
||||
+ output_json.ml \
|
||||
output_libvirt.ml \
|
||||
output_local.ml \
|
||||
output_qemu.ml \
|
||||
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
|
||||
index 46f6910d0..4d390f249 100644
|
||||
--- a/v2v/cmdline.ml
|
||||
+++ b/v2v/cmdline.ml
|
||||
@@ -138,6 +138,7 @@ let parse_cmdline () =
|
||||
| "glance" -> output_mode := `Glance
|
||||
| "libvirt" -> output_mode := `Libvirt
|
||||
| "disk" | "local" -> output_mode := `Local
|
||||
+ | "json" -> output_mode := `JSON
|
||||
| "null" -> output_mode := `Null
|
||||
| "openstack" | "osp" | "rhosp" -> output_mode := `Openstack
|
||||
| "ovirt" | "rhv" | "rhev" -> output_mode := `RHV
|
||||
@@ -413,6 +414,17 @@ read the man page virt-v2v(1).
|
||||
| `RHV -> no_options (); `RHV
|
||||
| `QEmu -> no_options (); `QEmu
|
||||
|
||||
+ | `JSON ->
|
||||
+ if is_query then (
|
||||
+ Output_json.print_output_options ();
|
||||
+ exit 0
|
||||
+ )
|
||||
+ else (
|
||||
+ let json_options =
|
||||
+ Output_json.parse_output_options output_options in
|
||||
+ `JSON json_options
|
||||
+ )
|
||||
+
|
||||
| `Openstack ->
|
||||
if is_query then (
|
||||
Output_openstack.print_output_options ();
|
||||
@@ -546,6 +558,23 @@ read the man page virt-v2v(1).
|
||||
Output_libvirt.output_libvirt output_conn output_storage,
|
||||
output_format, output_alloc
|
||||
|
||||
+ | `JSON json_options ->
|
||||
+ if output_password <> None then
|
||||
+ error_option_cannot_be_used_in_output_mode "json" "-op";
|
||||
+ if output_conn <> None then
|
||||
+ error_option_cannot_be_used_in_output_mode "json" "-oc";
|
||||
+ let os =
|
||||
+ match output_storage with
|
||||
+ | None ->
|
||||
+ error (f_"-o json: output directory was not specified, use '-os /dir'")
|
||||
+ | Some d when not (is_directory d) ->
|
||||
+ error (f_"-os %s: output directory does not exist or is not a directory") d
|
||||
+ | Some d -> d in
|
||||
+ if qemu_boot then
|
||||
+ error_option_cannot_be_used_in_output_mode "json" "--qemu-boot";
|
||||
+ Output_json.output_json os json_options,
|
||||
+ output_format, output_alloc
|
||||
+
|
||||
| `Local ->
|
||||
if output_password <> None then
|
||||
error_option_cannot_be_used_in_output_mode "local" "-op";
|
||||
diff --git a/v2v/create_json.ml b/v2v/create_json.ml
|
||||
new file mode 100644
|
||||
index 000000000..fdf7b12f5
|
||||
--- /dev/null
|
||||
+++ b/v2v/create_json.ml
|
||||
@@ -0,0 +1,348 @@
|
||||
+(* virt-v2v
|
||||
+ * Copyright (C) 2019 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.
|
||||
+ *)
|
||||
+
|
||||
+open Std_utils
|
||||
+open C_utils
|
||||
+open Tools_utils
|
||||
+
|
||||
+open Types
|
||||
+open Utils
|
||||
+
|
||||
+module G = Guestfs
|
||||
+
|
||||
+let json_list_of_string_list =
|
||||
+ List.map (fun x -> JSON.String x)
|
||||
+
|
||||
+let json_list_of_string_string_list =
|
||||
+ List.map (fun (x, y) -> x, JSON.String y)
|
||||
+
|
||||
+let push_optional_string lst name = function
|
||||
+ | None -> ()
|
||||
+ | Some v -> List.push_back lst (name, JSON.String v)
|
||||
+
|
||||
+let push_optional_int lst name = function
|
||||
+ | None -> ()
|
||||
+ | Some v -> List.push_back lst (name, JSON.Int (Int64.of_int v))
|
||||
+
|
||||
+let json_unknown_string = function
|
||||
+ | "unknown" -> JSON.Null
|
||||
+ | v -> JSON.String v
|
||||
+
|
||||
+let find_target_disk targets { s_disk_id = id } =
|
||||
+ try List.find (fun t -> t.target_overlay.ov_source.s_disk_id = id) targets
|
||||
+ with Not_found -> assert false
|
||||
+
|
||||
+let create_json_metadata source targets target_buses
|
||||
+ guestcaps inspect target_firmware =
|
||||
+ let doc = ref [
|
||||
+ "version", JSON.Int 1L;
|
||||
+ "name", JSON.String source.s_name;
|
||||
+ "memory", JSON.Int source.s_memory;
|
||||
+ "vcpu", JSON.Int (Int64.of_int source.s_vcpu);
|
||||
+ ] in
|
||||
+
|
||||
+ (match source.s_genid with
|
||||
+ | None -> ()
|
||||
+ | Some genid -> List.push_back doc ("genid", JSON.String genid)
|
||||
+ );
|
||||
+
|
||||
+ if source.s_cpu_vendor <> None || source.s_cpu_model <> None ||
|
||||
+ source.s_cpu_topology <> None then (
|
||||
+ let cpu = ref [] in
|
||||
+
|
||||
+ push_optional_string cpu "vendor" source.s_cpu_vendor;
|
||||
+ push_optional_string cpu "model" source.s_cpu_model;
|
||||
+ (match source.s_cpu_topology with
|
||||
+ | None -> ()
|
||||
+ | Some { s_cpu_sockets; s_cpu_cores; s_cpu_threads } ->
|
||||
+ let attrs = [
|
||||
+ "sockets", JSON.Int (Int64.of_int s_cpu_sockets);
|
||||
+ "cores", JSON.Int (Int64.of_int s_cpu_cores);
|
||||
+ "threads", JSON.Int (Int64.of_int s_cpu_threads);
|
||||
+ ] in
|
||||
+ List.push_back cpu ("topology", JSON.Dict attrs)
|
||||
+ );
|
||||
+
|
||||
+ List.push_back doc ("cpu", JSON.Dict !cpu);
|
||||
+ );
|
||||
+
|
||||
+ let firmware =
|
||||
+ let firmware_type =
|
||||
+ match target_firmware with
|
||||
+ | TargetBIOS -> "bios"
|
||||
+ | TargetUEFI -> "uefi" in
|
||||
+
|
||||
+ let fw = ref [
|
||||
+ "type", JSON.String firmware_type;
|
||||
+ ] in
|
||||
+
|
||||
+ (match target_firmware with
|
||||
+ | TargetBIOS -> ()
|
||||
+ | TargetUEFI ->
|
||||
+ let uefi_firmware = find_uefi_firmware guestcaps.gcaps_arch in
|
||||
+ let flags =
|
||||
+ List.map (
|
||||
+ function
|
||||
+ | Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED -> "secure_boot_required"
|
||||
+ ) uefi_firmware.Uefi.flags in
|
||||
+
|
||||
+ let uefi = ref [
|
||||
+ "code", JSON.String uefi_firmware.Uefi.code;
|
||||
+ "vars", JSON.String uefi_firmware.Uefi.vars;
|
||||
+ "flags", JSON.List (json_list_of_string_list flags);
|
||||
+ ] in
|
||||
+
|
||||
+ push_optional_string uefi "code-debug" uefi_firmware.Uefi.code_debug;
|
||||
+
|
||||
+ List.push_back fw ("uefi", JSON.Dict !uefi)
|
||||
+ );
|
||||
+
|
||||
+ !fw in
|
||||
+ List.push_back doc ("firmware", JSON.Dict firmware);
|
||||
+
|
||||
+ List.push_back doc ("features",
|
||||
+ JSON.List (json_list_of_string_list source.s_features));
|
||||
+
|
||||
+ let machine =
|
||||
+ match guestcaps.gcaps_machine with
|
||||
+ | I440FX -> "pc"
|
||||
+ | Q35 -> "q35"
|
||||
+ | Virt -> "virt" in
|
||||
+ List.push_back doc ("machine", JSON.String machine);
|
||||
+
|
||||
+ let disks, removables =
|
||||
+ let disks = ref []
|
||||
+ and removables = ref [] in
|
||||
+
|
||||
+ let iter_bus bus_name drive_prefix i = function
|
||||
+ | BusSlotEmpty -> ()
|
||||
+ | BusSlotDisk d ->
|
||||
+ (* Find the corresponding target disk. *)
|
||||
+ let t = find_target_disk targets d in
|
||||
+
|
||||
+ let target_file =
|
||||
+ match t.target_file with
|
||||
+ | TargetFile s -> s
|
||||
+ | TargetURI _ -> assert false in
|
||||
+
|
||||
+ let disk = [
|
||||
+ "dev", JSON.String (drive_prefix ^ drive_name i);
|
||||
+ "bus", JSON.String bus_name;
|
||||
+ "format", JSON.String t.target_format;
|
||||
+ "file", JSON.String (absolute_path target_file);
|
||||
+ ] in
|
||||
+
|
||||
+ List.push_back disks (JSON.Dict disk)
|
||||
+
|
||||
+ | BusSlotRemovable { s_removable_type = CDROM } ->
|
||||
+ let cdrom = [
|
||||
+ "type", JSON.String "cdrom";
|
||||
+ "dev", JSON.String (drive_prefix ^ drive_name i);
|
||||
+ "bus", JSON.String bus_name;
|
||||
+ ] in
|
||||
+
|
||||
+ List.push_back removables (JSON.Dict cdrom)
|
||||
+
|
||||
+ | BusSlotRemovable { s_removable_type = Floppy } ->
|
||||
+ let floppy = [
|
||||
+ "type", JSON.String "floppy";
|
||||
+ "dev", JSON.String (drive_prefix ^ drive_name i);
|
||||
+ ] in
|
||||
+
|
||||
+ List.push_back removables (JSON.Dict floppy)
|
||||
+ in
|
||||
+
|
||||
+ Array.iteri (iter_bus "virtio" "vd") target_buses.target_virtio_blk_bus;
|
||||
+ Array.iteri (iter_bus "ide" "hd") target_buses.target_ide_bus;
|
||||
+ Array.iteri (iter_bus "scsi" "sd") target_buses.target_scsi_bus;
|
||||
+ Array.iteri (iter_bus "floppy" "fd") target_buses.target_floppy_bus;
|
||||
+
|
||||
+ !disks, !removables in
|
||||
+ List.push_back doc ("disks", JSON.List disks);
|
||||
+ List.push_back doc ("removables", JSON.List removables);
|
||||
+
|
||||
+ let nics =
|
||||
+ List.map (
|
||||
+ fun { s_mac = mac; s_vnet_type = vnet_type; s_nic_model = nic_model;
|
||||
+ s_vnet = vnet; } ->
|
||||
+ let vnet_type_str =
|
||||
+ match vnet_type with
|
||||
+ | Bridge -> "bridge"
|
||||
+ | Network -> "network" in
|
||||
+
|
||||
+ let nic = ref [
|
||||
+ "vnet", JSON.String vnet;
|
||||
+ "vnet-type", JSON.String vnet_type_str;
|
||||
+ ] in
|
||||
+
|
||||
+ let nic_model_str = Option.map string_of_nic_model nic_model in
|
||||
+ push_optional_string nic "model" nic_model_str;
|
||||
+
|
||||
+ push_optional_string nic "mac" mac;
|
||||
+
|
||||
+ JSON.Dict !nic
|
||||
+ ) source.s_nics in
|
||||
+ List.push_back doc ("nics", JSON.List nics);
|
||||
+
|
||||
+ let guestcaps_dict =
|
||||
+ let block_bus =
|
||||
+ match guestcaps.gcaps_block_bus with
|
||||
+ | Virtio_blk -> "virtio-blk"
|
||||
+ | Virtio_SCSI -> "virtio-scsi"
|
||||
+ | IDE -> "ide" in
|
||||
+ let net_bus =
|
||||
+ match guestcaps.gcaps_net_bus with
|
||||
+ | Virtio_net -> "virtio-net"
|
||||
+ | E1000 -> "e1000"
|
||||
+ | RTL8139 -> "rtl8139" in
|
||||
+ let video =
|
||||
+ match guestcaps.gcaps_video with
|
||||
+ | QXL -> "qxl"
|
||||
+ | Cirrus -> "cirrus" in
|
||||
+ let machine =
|
||||
+ match guestcaps.gcaps_machine with
|
||||
+ | I440FX -> "i440fx"
|
||||
+ | Q35 -> "q35"
|
||||
+ | Virt -> "virt" in
|
||||
+
|
||||
+ [
|
||||
+ "block-bus", JSON.String block_bus;
|
||||
+ "net-bus", JSON.String net_bus;
|
||||
+ "video", JSON.String video;
|
||||
+ "machine", JSON.String machine;
|
||||
+ "arch", JSON.String guestcaps.gcaps_arch;
|
||||
+ "virtio-rng", JSON.Bool guestcaps.gcaps_virtio_rng;
|
||||
+ "virtio-balloon", JSON.Bool guestcaps.gcaps_virtio_balloon;
|
||||
+ "isa-pvpanic", JSON.Bool guestcaps.gcaps_isa_pvpanic;
|
||||
+ "acpi", JSON.Bool guestcaps.gcaps_acpi;
|
||||
+ ] in
|
||||
+ List.push_back doc ("guestcaps", JSON.Dict guestcaps_dict);
|
||||
+
|
||||
+ (match source.s_sound with
|
||||
+ | None -> ()
|
||||
+ | Some { s_sound_model = model } ->
|
||||
+ let sound = [
|
||||
+ "model", JSON.String (string_of_source_sound_model model);
|
||||
+ ] in
|
||||
+ List.push_back doc ("sound", JSON.Dict sound)
|
||||
+ );
|
||||
+
|
||||
+ (match source.s_display with
|
||||
+ | None -> ()
|
||||
+ | Some d ->
|
||||
+ let display_type =
|
||||
+ match d.s_display_type with
|
||||
+ | Window -> "window"
|
||||
+ | VNC -> "vnc"
|
||||
+ | Spice -> "spice" in
|
||||
+
|
||||
+ let display = ref [
|
||||
+ "type", JSON.String display_type;
|
||||
+ ] in
|
||||
+
|
||||
+ push_optional_string display "keymap" d.s_keymap;
|
||||
+ push_optional_string display "password" d.s_password;
|
||||
+
|
||||
+ let listen =
|
||||
+ match d.s_listen with
|
||||
+ | LNoListen -> None
|
||||
+ | LAddress address ->
|
||||
+ Some [
|
||||
+ "type", JSON.String "address";
|
||||
+ "address", JSON.String address;
|
||||
+ ]
|
||||
+ | LNetwork network ->
|
||||
+ Some [
|
||||
+ "type", JSON.String "network";
|
||||
+ "network", JSON.String network;
|
||||
+ ]
|
||||
+ | LSocket None ->
|
||||
+ Some [
|
||||
+ "type", JSON.String "socket";
|
||||
+ "socket", JSON.Null;
|
||||
+ ]
|
||||
+ | LSocket (Some socket) ->
|
||||
+ Some [
|
||||
+ "type", JSON.String "socket";
|
||||
+ "socket", JSON.String socket;
|
||||
+ ]
|
||||
+ | LNone ->
|
||||
+ Some [
|
||||
+ "type", JSON.String "none";
|
||||
+ ] in
|
||||
+ (match listen with
|
||||
+ | None -> ()
|
||||
+ | Some l -> List.push_back display ("listen", JSON.Dict l)
|
||||
+ );
|
||||
+
|
||||
+ push_optional_int display "port" d.s_port;
|
||||
+
|
||||
+ List.push_back doc ("display", JSON.Dict !display)
|
||||
+ );
|
||||
+
|
||||
+ let inspect_dict =
|
||||
+ let apps =
|
||||
+ List.map (
|
||||
+ fun { G.app2_name = name; app2_display_name = display_name;
|
||||
+ app2_epoch = epoch; app2_version = version;
|
||||
+ app2_release = release; app2_arch = arch; } ->
|
||||
+ JSON.Dict [
|
||||
+ "name", JSON.String name;
|
||||
+ "display-name", JSON.String display_name;
|
||||
+ "epoch", JSON.Int (Int64.of_int32 epoch);
|
||||
+ "version", JSON.String version;
|
||||
+ "release", JSON.String release;
|
||||
+ "arch", JSON.String arch;
|
||||
+ ]
|
||||
+ ) inspect.i_apps in
|
||||
+
|
||||
+ let firmware_dict =
|
||||
+ match inspect.i_firmware with
|
||||
+ | I_BIOS ->
|
||||
+ [
|
||||
+ "type", JSON.String "bios";
|
||||
+ ]
|
||||
+ | I_UEFI devices ->
|
||||
+ [
|
||||
+ "type", JSON.String "uefi";
|
||||
+ "devices", JSON.List (json_list_of_string_list devices);
|
||||
+ ] in
|
||||
+
|
||||
+ [
|
||||
+ "root", JSON.String inspect.i_root;
|
||||
+ "type", JSON.String inspect.i_type;
|
||||
+ "distro", json_unknown_string inspect.i_distro;
|
||||
+ "osinfo", json_unknown_string inspect.i_osinfo;
|
||||
+ "arch", JSON.String inspect.i_arch;
|
||||
+ "major-version", JSON.Int (Int64.of_int inspect.i_major_version);
|
||||
+ "minor-version", JSON.Int (Int64.of_int inspect.i_minor_version);
|
||||
+ "package-format", json_unknown_string inspect.i_package_format;
|
||||
+ "package-management", json_unknown_string inspect.i_package_management;
|
||||
+ "product-name", json_unknown_string inspect.i_product_name;
|
||||
+ "product-variant", json_unknown_string inspect.i_product_variant;
|
||||
+ "mountpoints", JSON.Dict (json_list_of_string_string_list inspect.i_mountpoints);
|
||||
+ "applications", JSON.List apps;
|
||||
+ "windows-systemroot", JSON.String inspect.i_windows_systemroot;
|
||||
+ "windows-software-hive", JSON.String inspect.i_windows_software_hive;
|
||||
+ "windows-system-hive", JSON.String inspect.i_windows_system_hive;
|
||||
+ "windows-current-control-set", JSON.String inspect.i_windows_current_control_set;
|
||||
+ "firmware", JSON.Dict firmware_dict;
|
||||
+ ] in
|
||||
+ List.push_back doc ("inspect", JSON.Dict inspect_dict);
|
||||
+
|
||||
+ !doc
|
||||
diff --git a/v2v/create_json.mli b/v2v/create_json.mli
|
||||
new file mode 100644
|
||||
index 000000000..6dbb6e48b
|
||||
--- /dev/null
|
||||
+++ b/v2v/create_json.mli
|
||||
@@ -0,0 +1,29 @@
|
||||
+(* virt-v2v
|
||||
+ * Copyright (C) 2019 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.
|
||||
+ *)
|
||||
+
|
||||
+(** Create JSON metadata for [-o json]. *)
|
||||
+
|
||||
+val create_json_metadata : Types.source -> Types.target list ->
|
||||
+ Types.target_buses ->
|
||||
+ Types.guestcaps ->
|
||||
+ Types.inspect ->
|
||||
+ Types.target_firmware ->
|
||||
+ JSON.doc
|
||||
+(** [create_json_metadata source targets target_buses guestcaps
|
||||
+ inspect target_firmware] creates the JSON with the majority
|
||||
+ of the data that virt-v2v used for the conversion. *)
|
||||
diff --git a/v2v/output_json.ml b/v2v/output_json.ml
|
||||
new file mode 100644
|
||||
index 000000000..ca0bda978
|
||||
--- /dev/null
|
||||
+++ b/v2v/output_json.ml
|
||||
@@ -0,0 +1,116 @@
|
||||
+(* virt-v2v
|
||||
+ * Copyright (C) 2019 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.
|
||||
+ *)
|
||||
+
|
||||
+open Printf
|
||||
+
|
||||
+open Std_utils
|
||||
+open Tools_utils
|
||||
+open Common_gettext.Gettext
|
||||
+
|
||||
+open Types
|
||||
+open Utils
|
||||
+
|
||||
+type json_options = {
|
||||
+ json_disks_pattern : string;
|
||||
+}
|
||||
+
|
||||
+let print_output_options () =
|
||||
+ printf (f_"Output options (-oo) which can be used with -o json:
|
||||
+
|
||||
+ -oo json-disks-pattern=PATTERN Pattern for the disks.
|
||||
+")
|
||||
+
|
||||
+let known_pattern_variables = ["DiskNo"; "DiskDeviceName"; "GuestName"]
|
||||
+
|
||||
+let parse_output_options options =
|
||||
+ let json_disks_pattern = ref None in
|
||||
+
|
||||
+ List.iter (
|
||||
+ function
|
||||
+ | "json-disks-pattern", v ->
|
||||
+ if !json_disks_pattern <> None then
|
||||
+ error (f_"-o json: -oo json-disks-pattern set more than once");
|
||||
+ let vars =
|
||||
+ try Var_expander.scan_variables v
|
||||
+ with Var_expander.Invalid_variable var ->
|
||||
+ error (f_"-o json: -oo json-disks-pattern: invalid variable %%{%s}")
|
||||
+ var in
|
||||
+ List.iter (
|
||||
+ fun var ->
|
||||
+ if not (List.mem var known_pattern_variables) then
|
||||
+ error (f_"-o json: -oo json-disks-pattern: unhandled variable %%{%s}")
|
||||
+ var
|
||||
+ ) vars;
|
||||
+ json_disks_pattern := Some v
|
||||
+ | k, _ ->
|
||||
+ error (f_"-o json: unknown output option ‘-oo %s’") k
|
||||
+ ) options;
|
||||
+
|
||||
+ let json_disks_pattern =
|
||||
+ Option.default "%{GuestName}-%{DiskDeviceName}" !json_disks_pattern in
|
||||
+
|
||||
+ { json_disks_pattern }
|
||||
+
|
||||
+class output_json dir json_options = object
|
||||
+ inherit output
|
||||
+
|
||||
+ method as_options = sprintf "-o json -os %s" dir
|
||||
+
|
||||
+ method prepare_targets source overlays _ _ _ _ =
|
||||
+ List.mapi (
|
||||
+ fun i (_, ov) ->
|
||||
+ let outname =
|
||||
+ let vars_fn = function
|
||||
+ | "DiskNo" -> Some (string_of_int (i+1))
|
||||
+ | "DiskDeviceName" -> Some ov.ov_sd
|
||||
+ | "GuestName" -> Some source.s_name
|
||||
+ | _ -> assert false
|
||||
+ in
|
||||
+ Var_expander.replace_fn json_options.json_disks_pattern vars_fn in
|
||||
+ let destname = dir // outname in
|
||||
+ mkdir_p (Filename.dirname destname) 0o755;
|
||||
+ TargetFile destname
|
||||
+ ) overlays
|
||||
+
|
||||
+ method supported_firmware = [ TargetBIOS; TargetUEFI ]
|
||||
+
|
||||
+ method create_metadata source targets
|
||||
+ target_buses guestcaps inspect target_firmware =
|
||||
+ let doc =
|
||||
+ Create_json.create_json_metadata source targets target_buses
|
||||
+ guestcaps inspect target_firmware in
|
||||
+ let doc_string = JSON.string_of_doc ~fmt:JSON.Indented doc in
|
||||
+
|
||||
+ if verbose () then (
|
||||
+ eprintf "resulting JSON:\n";
|
||||
+ output_string stderr doc_string;
|
||||
+ eprintf "\n\n%!";
|
||||
+ );
|
||||
+
|
||||
+ let name = source.s_name in
|
||||
+ let file = dir // name ^ ".json" in
|
||||
+
|
||||
+ with_open_out file (
|
||||
+ fun chan ->
|
||||
+ output_string chan doc_string;
|
||||
+ output_char chan '\n'
|
||||
+ )
|
||||
+end
|
||||
+
|
||||
+let output_json = new output_json
|
||||
+let () = Modules_list.register_output_module "json"
|
||||
diff --git a/v2v/output_json.mli b/v2v/output_json.mli
|
||||
new file mode 100644
|
||||
index 000000000..52f58f2d1
|
||||
--- /dev/null
|
||||
+++ b/v2v/output_json.mli
|
||||
@@ -0,0 +1,31 @@
|
||||
+(* virt-v2v
|
||||
+ * Copyright (C) 2019 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.
|
||||
+ *)
|
||||
+
|
||||
+(** [-o json] target. *)
|
||||
+
|
||||
+type json_options
|
||||
+(** Miscellaneous extra command line parameters used by json. *)
|
||||
+
|
||||
+val print_output_options : unit -> unit
|
||||
+val parse_output_options : (string * string) list -> json_options
|
||||
+(** Print and parse json -oo options. *)
|
||||
+
|
||||
+val output_json : string -> json_options -> Types.output
|
||||
+(** [output_json directory json_options] creates and returns a new
|
||||
+ {!Types.output} object specialized for writing output to local
|
||||
+ files with JSON metadata. *)
|
||||
diff --git a/v2v/virt-v2v-output-local.pod b/v2v/virt-v2v-output-local.pod
|
||||
index 7427b1ed7..7c397c0a4 100644
|
||||
--- a/v2v/virt-v2v-output-local.pod
|
||||
+++ b/v2v/virt-v2v-output-local.pod
|
||||
@@ -11,6 +11,9 @@ or libvirt
|
||||
|
||||
virt-v2v [-i* options] -o qemu -os DIRECTORY [--qemu-boot]
|
||||
|
||||
+ virt-v2v [-i* options] -o json -os DIRECTORY
|
||||
+ [-oo json-disks-pattern=PATTERN]
|
||||
+
|
||||
virt-v2v [-i* options] -o null
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@@ -54,6 +57,13 @@ above, a shell script is created which contains the raw qemu command
|
||||
you would need to boot the guest. However the shell script is not
|
||||
run, I<unless> you also add the I<--qemu-boot> option.
|
||||
|
||||
+=item B<-o json -os> C<DIRECTORY>
|
||||
+
|
||||
+This converts the guest to files in C<DIRECTORY>. The metadata
|
||||
+produced is a JSON file containing the majority of the data virt-v2v
|
||||
+gathers during the conversion.
|
||||
+See L</OUTPUT TO JSON> below.
|
||||
+
|
||||
=item B<-o null>
|
||||
|
||||
The guest is converted, but the final result is thrown away and no
|
||||
@@ -140,6 +150,51 @@ Define the final guest in libvirt:
|
||||
|
||||
=back
|
||||
|
||||
+=head1 OUTPUT TO JSON
|
||||
+
|
||||
+The I<-o json> option produces the following files by default:
|
||||
+
|
||||
+ NAME.json JSON metadata.
|
||||
+ NAME-sda, NAME-sdb, etc. Guest disk(s).
|
||||
+
|
||||
+where C<NAME> is the guest name.
|
||||
+
|
||||
+It is possible to change the pattern of the disks using the
|
||||
+I<-oo json-disks-pattern=...> option: it allows parameters in form of
|
||||
+C<%{...}> variables, for example:
|
||||
+
|
||||
+ -oo json-disks-pattern=disk%{DiskNo}.img
|
||||
+
|
||||
+Recognized variables are:
|
||||
+
|
||||
+=over 4
|
||||
+
|
||||
+=item C<%{DiskNo}>
|
||||
+
|
||||
+The index of the disk, starting from 1.
|
||||
+
|
||||
+=item C<%{DiskDeviceName}>
|
||||
+
|
||||
+The destination device of the disk, e.g. C<sda>, C<sdb>, etc.
|
||||
+
|
||||
+=item C<%{GuestName}>
|
||||
+
|
||||
+The name of the guest.
|
||||
+
|
||||
+=back
|
||||
+
|
||||
+Using a pattern it is possible use subdirectories for the disks,
|
||||
+even with names depending on variables; for example:
|
||||
+
|
||||
+ -oo json-disks-pattern=%{GuestName}-%{DiskNo}/disk.img
|
||||
+
|
||||
+The default pattern is C<%{GuestName}-%{DiskDeviceName}>.
|
||||
+
|
||||
+If the literal C<%{...}> text is needed, it is possible to avoid the
|
||||
+escape it with a leading C<%>; for example,
|
||||
+C<%%{GuestName}-%{DiskNo}.img> will create file names for the
|
||||
+disks like C<%%{GuestName}-1.img>, C<%%{GuestName}-2.img>, etc.
|
||||
+
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<virt-v2v(1)>.
|
||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
||||
index cf9464834..9a555c3be 100644
|
||||
--- a/v2v/virt-v2v.pod
|
||||
+++ b/v2v/virt-v2v.pod
|
||||
@@ -425,6 +425,17 @@ instead.
|
||||
Set the output method to OpenStack Glance. In this mode the converted
|
||||
guest is uploaded to Glance. See L<virt-v2v-output-openstack(1)>.
|
||||
|
||||
+=item B<-o> B<json>
|
||||
+
|
||||
+Set the output method to I<json>.
|
||||
+
|
||||
+In this mode, the converted guest is written to a local directory
|
||||
+specified by I<-os /dir> (the directory must exist), with a JSON file
|
||||
+containing the majority of the metadata that virt-v2v gathered during
|
||||
+the conversion.
|
||||
+
|
||||
+See L<virt-v2v-output-local(1)>.
|
||||
+
|
||||
=item B<-o> B<libvirt>
|
||||
|
||||
Set the output method to I<libvirt>. This is the default.
|
||||
@@ -696,8 +707,8 @@ The location of the storage for the converted guest.
|
||||
For I<-o libvirt>, this is a libvirt directory pool
|
||||
(see S<C<virsh pool-list>>) or pool UUID.
|
||||
|
||||
-For I<-o local> and I<-o qemu>, this is a directory name. The
|
||||
-directory must exist.
|
||||
+For I<-o json>, I<-o local> and I<-o qemu>, this is a directory name.
|
||||
+The directory must exist.
|
||||
|
||||
For I<-o rhv-upload>, this is the name of the destination Storage
|
||||
Domain.
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 9ff9ddf3c372acee3a31a9d9435b1f32e0932943 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 11 Feb 2019 19:28:00 +0100
|
||||
Subject: [PATCH] inspect: fix icon of RHEL
|
||||
|
||||
Use a better icon for RHEL guests, still provided by redhat-logos (or
|
||||
equivalent in downstream distributions), and which fits a better
|
||||
definition of logo for the distribution.
|
||||
|
||||
Thanks to Ray Strode for the hints.
|
||||
|
||||
(cherry picked from commit c648052690a4a07a59c741308e0e8497d6f18057)
|
||||
---
|
||||
lib/inspect-icon.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/inspect-icon.c b/lib/inspect-icon.c
|
||||
index 623591aa6..19f3f87af 100644
|
||||
--- a/lib/inspect-icon.c
|
||||
+++ b/lib/inspect-icon.c
|
||||
@@ -317,7 +317,7 @@ icon_rhel (guestfs_h *g, int major, size_t *size_r)
|
||||
if (major < 7)
|
||||
shadowman = "/usr/share/pixmaps/redhat/shadowman-transparent.png";
|
||||
else
|
||||
- shadowman = "/usr/share/pixmaps/fedora-logo-sprite.png";
|
||||
+ shadowman = "/usr/share/icons/hicolor/96x96/apps/system-logo-icon.png";
|
||||
|
||||
return get_png (g, shadowman, size_r, 102400);
|
||||
}
|
||||
--
|
||||
2.18.4
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,34 @@
|
||||
From 9664527c107d04aab416be87cc4fcd76dcbe5927 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 29 Mar 2021 18:25:13 +0100
|
||||
Subject: [PATCH] po/POTFILES: Fix list of files for translation.
|
||||
|
||||
Fixes: commit c9ee831affed55abe0f928134cbbd2ed83b2f510
|
||||
(cherry picked from commit df983200d76bac37c811fbd2fb67e7ebe830e759)
|
||||
---
|
||||
po/POTFILES | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/po/POTFILES b/po/POTFILES
|
||||
index 0782e8ceb..fdc6e8062 100644
|
||||
--- a/po/POTFILES
|
||||
+++ b/po/POTFILES
|
||||
@@ -128,6 +128,7 @@ daemon/pingdaemon.c
|
||||
daemon/proto.c
|
||||
daemon/readdir.c
|
||||
daemon/rename.c
|
||||
+daemon/rpm-c.c
|
||||
daemon/rsync.c
|
||||
daemon/scrub.c
|
||||
daemon/selinux-relabel.c
|
||||
@@ -353,7 +354,6 @@ lib/command.c
|
||||
lib/conn-socket.c
|
||||
lib/copy-in-out.c
|
||||
lib/create.c
|
||||
-lib/dbdump.c
|
||||
lib/drives.c
|
||||
lib/errors.c
|
||||
lib/event-string.c
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 573f551ff8ced48f4ea21ec7bbbad235092f36f2 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 12 Apr 2019 17:28:12 +0200
|
||||
Subject: [PATCH] v2v: warn when the guest has direct network interfaces
|
||||
(RHBZ#1518539)
|
||||
|
||||
virt-v2v obviously cannot convert this kind of devices, since they are
|
||||
specific to the host of the hypervisor. Thus, emit a warning about the
|
||||
presence of direct network interfaces, so at least this can be noticed
|
||||
when converting a guest.
|
||||
|
||||
(cherry picked from commit 1629ec6a5639cf5e226e80bcee749ae8851b1fae)
|
||||
---
|
||||
v2v/parse_libvirt_xml.ml | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
diff --git a/v2v/parse_libvirt_xml.ml b/v2v/parse_libvirt_xml.ml
|
||||
index d5d78d367..b9970cee8 100644
|
||||
--- a/v2v/parse_libvirt_xml.ml
|
||||
+++ b/v2v/parse_libvirt_xml.ml
|
||||
@@ -492,6 +492,24 @@ let parse_libvirt_xml ?conn xml =
|
||||
)
|
||||
in
|
||||
|
||||
+ (* Check for direct attachments to physical network interfaces.
|
||||
+ * (RHBZ#1518539)
|
||||
+ *)
|
||||
+ let () =
|
||||
+ let obj = Xml.xpath_eval_expression xpathctx "/domain/devices/interface[@type='direct']" in
|
||||
+ let nr_nodes = Xml.xpathobj_nr_nodes obj in
|
||||
+ if nr_nodes > 0 then (
|
||||
+ (* Sadly fn_ in ocaml-gettext seems broken, and always returns the
|
||||
+ * singular string no matter what. Work around this by using a simple
|
||||
+ * string with sn_ (which works), and outputting it as a whole.
|
||||
+ *)
|
||||
+ let msg = sn_ "this guest has a direct network interface which will be ignored"
|
||||
+ "this guest has direct network interfaces which will be ignored"
|
||||
+ nr_nodes in
|
||||
+ warning "%s" msg
|
||||
+ )
|
||||
+ in
|
||||
+
|
||||
({
|
||||
s_hypervisor = hypervisor;
|
||||
s_name = name; s_orig_name = name;
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,64 @@
|
||||
From 083856d9f9c8fccc629bf0f3a5237d26434c8940 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 29 Mar 2021 18:35:48 +0100
|
||||
Subject: [PATCH] m4/guestfs-find-db-tool.m4: Remove unused file.
|
||||
|
||||
Fixes: commit 42e5e7cfdbca01b2e9bd50c63a9fc65b6da9192f
|
||||
(cherry picked from commit 8317279c3539562ebad9de13c7ac515dded74e4d)
|
||||
---
|
||||
m4/guestfs-find-db-tool.m4 | 43 --------------------------------------
|
||||
1 file changed, 43 deletions(-)
|
||||
delete mode 100644 m4/guestfs-find-db-tool.m4
|
||||
|
||||
diff --git a/m4/guestfs-find-db-tool.m4 b/m4/guestfs-find-db-tool.m4
|
||||
deleted file mode 100644
|
||||
index b404148c6..000000000
|
||||
--- a/m4/guestfs-find-db-tool.m4
|
||||
+++ /dev/null
|
||||
@@ -1,43 +0,0 @@
|
||||
-# libguestfs
|
||||
-# Copyright (C) 2014 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.
|
||||
-
|
||||
-AC_DEFUN([GUESTFS_FIND_DB_TOOL],[
|
||||
- pushdef([VARIABLE],$1)
|
||||
- TOOL=$2
|
||||
-
|
||||
- db_tool_name="db_$TOOL"
|
||||
- db_versions="53 5.3 5.2 5.1 4.8 4.7 4.6"
|
||||
- db_tool_patterns="dbX_$TOOL dbX.Y_$TOOL"
|
||||
- db_tool_patterns="dbX_$TOOL db_$TOOL-X dbX.Y_$TOOL db_$TOOL-X.Y"
|
||||
-
|
||||
- AC_ARG_VAR(VARIABLE, [Absolute path to $db_tool_name executable])
|
||||
-
|
||||
- AS_IF(test -z "$VARIABLE", [
|
||||
- exe_list="db_$TOOL"
|
||||
- for ver in $db_versions ; do
|
||||
- ver_maj=`echo $ver | cut -d. -f1`
|
||||
- ver_min=`echo $ver | cut -d. -f2`
|
||||
- for pattern in $db_tool_patterns ; do
|
||||
- exe=`echo "$pattern" | sed -e "s/X/$ver_maj/g;s/Y/$ver_min/g"`
|
||||
- exe_list="$exe_list $exe"
|
||||
- done
|
||||
- done
|
||||
- AC_PATH_PROGS([]VARIABLE[], [$exe_list], [no])
|
||||
- ])
|
||||
-
|
||||
- popdef([VARIABLE])
|
||||
-])
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,55 +0,0 @@
|
||||
From 31ffb01b14ef809d4c5836e9244eb114e971c36e Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 12 Apr 2019 16:19:43 +0200
|
||||
Subject: [PATCH] v2v: update documentation on nbdkit (RHBZ#1605242)
|
||||
|
||||
nbdkit >= 1.6 ships a VDDK plugin always built, so recommend that
|
||||
version instead of recommending to build nbdkit from sources.
|
||||
|
||||
(cherry picked from commit 0704d8eb0bcc8139886eb4291f75a3ca49a91e58)
|
||||
---
|
||||
v2v/virt-v2v-input-vmware.pod | 28 ++--------------------------
|
||||
1 file changed, 2 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/v2v/virt-v2v-input-vmware.pod b/v2v/virt-v2v-input-vmware.pod
|
||||
index 2b6dbaeec..b3ebda182 100644
|
||||
--- a/v2v/virt-v2v-input-vmware.pod
|
||||
+++ b/v2v/virt-v2v-input-vmware.pod
|
||||
@@ -197,32 +197,8 @@ library is permitted by the license.
|
||||
|
||||
=item 2.
|
||||
|
||||
-You must also compile nbdkit, enabling the VDDK plugin. nbdkit E<ge>
|
||||
-1.1.25 is recommended, but it is usually best to compile from the git
|
||||
-tree.
|
||||
-
|
||||
-=over 4
|
||||
-
|
||||
-=item *
|
||||
-
|
||||
-L<https://github.com/libguestfs/nbdkit>
|
||||
-
|
||||
-=item *
|
||||
-
|
||||
-L<https://github.com/libguestfs/nbdkit/tree/master/plugins/vddk>
|
||||
-
|
||||
-=back
|
||||
-
|
||||
-Compile nbdkit as described in the sources (see link above).
|
||||
-
|
||||
-You do B<not> need to run C<make install> because you can run nbdkit
|
||||
-from its source directory. The source directory has a shell script
|
||||
-called F<nbdkit> which runs the locally built copy of nbdkit and its
|
||||
-plugins. So set C<$PATH> to point to the nbdkit top build directory
|
||||
-(that is, the directory containing the shell script called F<nbdkit>),
|
||||
-eg:
|
||||
-
|
||||
- export PATH=/path/to/nbdkit-1.1.x:$PATH
|
||||
+nbdkit E<ge> 1.6 is recommended, as it ships with the VDDK plugin
|
||||
+enabled unconditionally.
|
||||
|
||||
=item 3.
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,474 @@
|
||||
From f8ccce2c7a0c1323e0721f503322df525dd5b139 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 29 Mar 2021 12:22:12 +0100
|
||||
Subject: [PATCH] test-data/phony-guests: Fix phony RPM database, fix
|
||||
virt-inspector test.
|
||||
|
||||
libguestfs 1.45.3 now reads the RPM database using librpm, which means
|
||||
our old phony database created by db_dump can no longer work. Instead
|
||||
provide a real (but very minimal) sqlite database.
|
||||
|
||||
This commit also fixes the virt-inspector test since the RPM database
|
||||
contents are now different.
|
||||
|
||||
(cherry picked from commit 46bf6fb473889ed28bd7220476120edcda47ae07)
|
||||
---
|
||||
inspector/expected-fedora-luks.img.xml | 208 +++++++++++++++++++++++--
|
||||
inspector/expected-fedora.img.xml | 208 +++++++++++++++++++++++--
|
||||
2 files changed, 398 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/inspector/expected-fedora-luks.img.xml b/inspector/expected-fedora-luks.img.xml
|
||||
index df6060a73..72cddaf88 100644
|
||||
--- a/inspector/expected-fedora-luks.img.xml
|
||||
+++ b/inspector/expected-fedora-luks.img.xml
|
||||
@@ -30,22 +30,212 @@
|
||||
</filesystems>
|
||||
<applications>
|
||||
<application>
|
||||
- <name>test1</name>
|
||||
- <version>1.0</version>
|
||||
- <release>1.fc14</release>
|
||||
+ <name>basesystem</name>
|
||||
+ <version>11</version>
|
||||
+ <release>10.fc33</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>(none)</url>
|
||||
+ <summary>The skeleton package which defines a simple Fedora system</summary>
|
||||
+ <description>Basesystem defines the components of a basic Fedora system
|
||||
+(for example, the package installation order to use during bootstrapping).
|
||||
+Basesystem should be in every installation of a system, and it
|
||||
+should never be removed.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>bash</name>
|
||||
+ <version>5.0.17</version>
|
||||
+ <release>2.fc33</release>
|
||||
+ <arch>x86_64</arch>
|
||||
+ <url>https://www.gnu.org/software/bash</url>
|
||||
+ <summary>The GNU Bourne Again shell</summary>
|
||||
+ <description>The GNU Bourne Again shell (Bash) is a shell or command language
|
||||
+interpreter that is compatible with the Bourne shell (sh). Bash
|
||||
+incorporates useful features from the Korn shell (ksh) and the C shell
|
||||
+(csh). Most sh scripts can be run by bash without modification.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>fedora-gpg-keys</name>
|
||||
+ <version>33</version>
|
||||
+ <release>3</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://fedoraproject.org/</url>
|
||||
+ <summary>Fedora RPM keys</summary>
|
||||
+ <description>This package provides the RPM signature keys.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>fedora-release</name>
|
||||
+ <version>33</version>
|
||||
+ <release>3</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://fedoraproject.org/</url>
|
||||
+ <summary>Fedora release files</summary>
|
||||
+ <description>Fedora release files such as various /etc/ files that define the release
|
||||
+and systemd preset files that determine which services are enabled by default.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>fedora-release-common</name>
|
||||
+ <version>33</version>
|
||||
+ <release>3</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://fedoraproject.org/</url>
|
||||
+ <summary>Fedora release files</summary>
|
||||
+ <description>Release files common to all Editions and Spins of Fedora</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>fedora-release-identity-basic</name>
|
||||
+ <version>33</version>
|
||||
+ <release>3</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://fedoraproject.org/</url>
|
||||
+ <summary>Package providing the basic Fedora identity</summary>
|
||||
+ <description>Provides the necessary files for a Fedora installation that is not identifying
|
||||
+itself as a particular Edition or Spin.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>fedora-repos</name>
|
||||
+ <version>33</version>
|
||||
+ <release>3</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://fedoraproject.org/</url>
|
||||
+ <summary>Fedora package repositories</summary>
|
||||
+ <description>Fedora package repository files for yum and dnf along with gpg public keys.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>filesystem</name>
|
||||
+ <version>3.14</version>
|
||||
+ <release>3.fc33</release>
|
||||
+ <arch>x86_64</arch>
|
||||
+ <url>https://pagure.io/filesystem</url>
|
||||
+ <summary>The basic directory layout for a Linux system</summary>
|
||||
+ <description>The filesystem package is one of the basic packages that is installed
|
||||
+on a Linux system. Filesystem contains the basic directory layout
|
||||
+for a Linux operating system, including the correct permissions for
|
||||
+the directories.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>glibc</name>
|
||||
+ <version>2.32</version>
|
||||
+ <release>4.fc33</release>
|
||||
+ <arch>x86_64</arch>
|
||||
+ <url>http://www.gnu.org/software/glibc/</url>
|
||||
+ <summary>The GNU libc libraries</summary>
|
||||
+ <description>The glibc package contains standard libraries which are used by
|
||||
+multiple programs on the system. In order to save disk space and
|
||||
+memory, as well as to make upgrading easier, common system code is
|
||||
+kept in one place and shared between programs. This particular package
|
||||
+contains the most important sets of shared libraries: the standard C
|
||||
+library and the standard math library. Without these two libraries, a
|
||||
+Linux system will not function.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>glibc-all-langpacks</name>
|
||||
+ <version>2.32</version>
|
||||
+ <release>4.fc33</release>
|
||||
+ <arch>x86_64</arch>
|
||||
+ <url>http://www.gnu.org/software/glibc/</url>
|
||||
+ <summary>All language packs for glibc.</summary>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>glibc-common</name>
|
||||
+ <version>2.32</version>
|
||||
+ <release>4.fc33</release>
|
||||
<arch>x86_64</arch>
|
||||
+ <url>http://www.gnu.org/software/glibc/</url>
|
||||
+ <summary>Common binaries and locale data for glibc</summary>
|
||||
+ <description>The glibc-common package includes common binaries for the GNU libc
|
||||
+libraries, as well as national language (locale) support.</description>
|
||||
</application>
|
||||
<application>
|
||||
- <name>test2</name>
|
||||
- <version>2.0</version>
|
||||
- <release>2.fc14</release>
|
||||
+ <name>gpg-pubkey</name>
|
||||
+ <version>9570ff31</version>
|
||||
+ <release>5e3006fb</release>
|
||||
+ <arch>(none)</arch>
|
||||
+ <url>(none)</url>
|
||||
+ <summary>Fedora (33) <fedora-33-primary@fedoraproject.org> public key</summary>
|
||||
+ <description>-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
+Version: rpm-4.16.1.2 (NSS-3)
|
||||
+
|
||||
+mQINBF4wBvsBEADQmcGbVUbDRUoXADReRmOOEMeydHghtKC9uRs9YNpGYZIB+bie
|
||||
+bGYZmflQayfh/wEpO2W/IZfGpHPL42V7SbyvqMjwNls/fnXsCtf4LRofNK8Qd9fN
|
||||
+kYargc9R7BEz/mwXKMiRQVx+DzkmqGWy2gq4iD0/mCyf5FdJCE40fOWoIGJXaOI1
|
||||
+Tz1vWqKwLS5T0dfmi9U4Tp/XsKOZGvN8oi5h0KmqFk7LEZr1MXarhi2Va86sgxsF
|
||||
+QcZEKfu5tgD0r00vXzikoSjn3qA5JW5FW07F1pGP4bF5f9J3CZbQyOjTSWMmmfTm
|
||||
+2d2BURWzaDiJN9twY2yjzkoOMuPdXXvovg7KxLcQerKT+FbKbq8DySJX2rnOA77k
|
||||
+UG4c9BGf/L1uBkAT8dpHLk6Uf5BfmypxUkydSWT1xfTDnw1MqxO0MsLlAHOR3J7c
|
||||
+oW9kLcOLuCQn1hBEwfZv7VSWBkGXSmKfp0LLIxAFgRtv+Dh+rcMMRdJgKr1V3FU+
|
||||
+rZ1+ZAfYiBpQJFPjv70vx+rGEgS801D3PJxBZUEy4Ic4ZYaKNhK9x9PRQuWcIBuW
|
||||
+6eTe/6lKWZeyxCumLLdiS75mF2oTcBaWeoc3QxrPRV15eDKeYJMbhnUai/7lSrhs
|
||||
+EWCkKR1RivgF4slYmtNE5ZPGZ/d61zjwn2xi4xNJVs8q9WRPMpHp0vCyMwARAQAB
|
||||
+tDFGZWRvcmEgKDMzKSA8ZmVkb3JhLTMzLXByaW1hcnlAZmVkb3JhcHJvamVjdC5v
|
||||
+cmc+iQI4BBMBAgAiBQJeMAb7AhsPBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK
|
||||
+CRBJ/XdJlXD/MZm2D/9kriL43vd3+0DNMeA82n2v9mSR2PQqKny39xNlYPyy/1yZ
|
||||
+P/KXoa4NYSCA971LSd7lv4n/h5bEKgGHxZfttfOzOnWMVSSTfjRyM/df/NNzTUEV
|
||||
+7ORA5GW18g8PEtS7uRxVBf3cLvWu5q+8jmqES5HqTAdGVcuIFQeBXFN8Gy1Jinuz
|
||||
+AH8rJSdkUeZ0cehWbERq80BWM9dhad5dW+/+Gv0foFBvP15viwhWqajr8V0B8es+
|
||||
+2/tHI0k86FAujV5i0rrXl5UOoLilO57QQNDZH/qW9GsHwVI+2yecLstpUNLq+EZC
|
||||
+GqTZCYoxYRpl0gAMbDLztSL/8Bc0tJrCRG3tavJotFYlgUK60XnXlQzRkh9rgsfT
|
||||
+EXbQifWdQMMogzjCJr0hzJ+V1d0iozdUxB2ZEgTjukOvatkB77DY1FPZRkSFIQs+
|
||||
+fdcjazDIBLIxwJu5QwvTNW8lOLnJ46g4sf1WJoUdNTbR0BaC7HHj1inVWi0p7IuN
|
||||
+66EPGzJOSjLK+vW+J0ncPDEgLCV74RF/0nR5fVTdrmiopPrzFuguHf9S9gYI3Zun
|
||||
+Yl8FJUu4kRO6JPPTicUXWX+8XZmE94aK14RCJL23nOSi8T1eW8JLW43dCBRO8QUE
|
||||
+Aso1t2pypm/1zZexJdOV8yGME3g5l2W6PLgpz58DBECgqc/kda+VWgEAp7rO2A==
|
||||
+=EPL3
|
||||
+-----END PGP PUBLIC KEY BLOCK-----
|
||||
+</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>libgcc</name>
|
||||
+ <version>10.2.1</version>
|
||||
+ <release>9.fc33</release>
|
||||
<arch>x86_64</arch>
|
||||
+ <url>http://gcc.gnu.org</url>
|
||||
+ <summary>GCC version 10 shared support library</summary>
|
||||
+ <description>This package contains GCC shared support library which is needed
|
||||
+e.g. for exception handling support.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>ncurses-base</name>
|
||||
+ <version>6.2</version>
|
||||
+ <release>3.20200222.fc33</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://invisible-island.net/ncurses/ncurses.html</url>
|
||||
+ <summary>Descriptions of common terminals</summary>
|
||||
+ <description>This package contains descriptions of common terminals. Other terminal
|
||||
+descriptions are included in the ncurses-term package.</description>
|
||||
</application>
|
||||
<application>
|
||||
- <name>test3</name>
|
||||
- <version>3.0</version>
|
||||
- <release>3.fc14</release>
|
||||
+ <name>ncurses-libs</name>
|
||||
+ <version>6.2</version>
|
||||
+ <release>3.20200222.fc33</release>
|
||||
<arch>x86_64</arch>
|
||||
+ <url>https://invisible-island.net/ncurses/ncurses.html</url>
|
||||
+ <summary>Ncurses libraries</summary>
|
||||
+ <description>The curses library routines are a terminal-independent method of
|
||||
+updating character screens with reasonable optimization. The ncurses
|
||||
+(new curses) library is a freely distributable replacement for the
|
||||
+discontinued 4.4 BSD classic curses library.
|
||||
+
|
||||
+This package contains the ncurses libraries.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>setup</name>
|
||||
+ <version>2.13.7</version>
|
||||
+ <release>2.fc33</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://pagure.io/setup/</url>
|
||||
+ <summary>A set of system configuration and setup files</summary>
|
||||
+ <description>The setup package contains a set of important system configuration and
|
||||
+setup files, such as passwd, group, and profile.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>tzdata</name>
|
||||
+ <version>2021a</version>
|
||||
+ <release>1.fc33</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://www.iana.org/time-zones</url>
|
||||
+ <summary>Timezone data</summary>
|
||||
+ <description>This package contains data files with rules for various timezones around
|
||||
+the world.</description>
|
||||
</application>
|
||||
</applications>
|
||||
</operatingsystem>
|
||||
diff --git a/inspector/expected-fedora.img.xml b/inspector/expected-fedora.img.xml
|
||||
index df6060a73..72cddaf88 100644
|
||||
--- a/inspector/expected-fedora.img.xml
|
||||
+++ b/inspector/expected-fedora.img.xml
|
||||
@@ -30,22 +30,212 @@
|
||||
</filesystems>
|
||||
<applications>
|
||||
<application>
|
||||
- <name>test1</name>
|
||||
- <version>1.0</version>
|
||||
- <release>1.fc14</release>
|
||||
+ <name>basesystem</name>
|
||||
+ <version>11</version>
|
||||
+ <release>10.fc33</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>(none)</url>
|
||||
+ <summary>The skeleton package which defines a simple Fedora system</summary>
|
||||
+ <description>Basesystem defines the components of a basic Fedora system
|
||||
+(for example, the package installation order to use during bootstrapping).
|
||||
+Basesystem should be in every installation of a system, and it
|
||||
+should never be removed.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>bash</name>
|
||||
+ <version>5.0.17</version>
|
||||
+ <release>2.fc33</release>
|
||||
+ <arch>x86_64</arch>
|
||||
+ <url>https://www.gnu.org/software/bash</url>
|
||||
+ <summary>The GNU Bourne Again shell</summary>
|
||||
+ <description>The GNU Bourne Again shell (Bash) is a shell or command language
|
||||
+interpreter that is compatible with the Bourne shell (sh). Bash
|
||||
+incorporates useful features from the Korn shell (ksh) and the C shell
|
||||
+(csh). Most sh scripts can be run by bash without modification.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>fedora-gpg-keys</name>
|
||||
+ <version>33</version>
|
||||
+ <release>3</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://fedoraproject.org/</url>
|
||||
+ <summary>Fedora RPM keys</summary>
|
||||
+ <description>This package provides the RPM signature keys.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>fedora-release</name>
|
||||
+ <version>33</version>
|
||||
+ <release>3</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://fedoraproject.org/</url>
|
||||
+ <summary>Fedora release files</summary>
|
||||
+ <description>Fedora release files such as various /etc/ files that define the release
|
||||
+and systemd preset files that determine which services are enabled by default.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>fedora-release-common</name>
|
||||
+ <version>33</version>
|
||||
+ <release>3</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://fedoraproject.org/</url>
|
||||
+ <summary>Fedora release files</summary>
|
||||
+ <description>Release files common to all Editions and Spins of Fedora</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>fedora-release-identity-basic</name>
|
||||
+ <version>33</version>
|
||||
+ <release>3</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://fedoraproject.org/</url>
|
||||
+ <summary>Package providing the basic Fedora identity</summary>
|
||||
+ <description>Provides the necessary files for a Fedora installation that is not identifying
|
||||
+itself as a particular Edition or Spin.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>fedora-repos</name>
|
||||
+ <version>33</version>
|
||||
+ <release>3</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://fedoraproject.org/</url>
|
||||
+ <summary>Fedora package repositories</summary>
|
||||
+ <description>Fedora package repository files for yum and dnf along with gpg public keys.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>filesystem</name>
|
||||
+ <version>3.14</version>
|
||||
+ <release>3.fc33</release>
|
||||
+ <arch>x86_64</arch>
|
||||
+ <url>https://pagure.io/filesystem</url>
|
||||
+ <summary>The basic directory layout for a Linux system</summary>
|
||||
+ <description>The filesystem package is one of the basic packages that is installed
|
||||
+on a Linux system. Filesystem contains the basic directory layout
|
||||
+for a Linux operating system, including the correct permissions for
|
||||
+the directories.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>glibc</name>
|
||||
+ <version>2.32</version>
|
||||
+ <release>4.fc33</release>
|
||||
+ <arch>x86_64</arch>
|
||||
+ <url>http://www.gnu.org/software/glibc/</url>
|
||||
+ <summary>The GNU libc libraries</summary>
|
||||
+ <description>The glibc package contains standard libraries which are used by
|
||||
+multiple programs on the system. In order to save disk space and
|
||||
+memory, as well as to make upgrading easier, common system code is
|
||||
+kept in one place and shared between programs. This particular package
|
||||
+contains the most important sets of shared libraries: the standard C
|
||||
+library and the standard math library. Without these two libraries, a
|
||||
+Linux system will not function.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>glibc-all-langpacks</name>
|
||||
+ <version>2.32</version>
|
||||
+ <release>4.fc33</release>
|
||||
+ <arch>x86_64</arch>
|
||||
+ <url>http://www.gnu.org/software/glibc/</url>
|
||||
+ <summary>All language packs for glibc.</summary>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>glibc-common</name>
|
||||
+ <version>2.32</version>
|
||||
+ <release>4.fc33</release>
|
||||
<arch>x86_64</arch>
|
||||
+ <url>http://www.gnu.org/software/glibc/</url>
|
||||
+ <summary>Common binaries and locale data for glibc</summary>
|
||||
+ <description>The glibc-common package includes common binaries for the GNU libc
|
||||
+libraries, as well as national language (locale) support.</description>
|
||||
</application>
|
||||
<application>
|
||||
- <name>test2</name>
|
||||
- <version>2.0</version>
|
||||
- <release>2.fc14</release>
|
||||
+ <name>gpg-pubkey</name>
|
||||
+ <version>9570ff31</version>
|
||||
+ <release>5e3006fb</release>
|
||||
+ <arch>(none)</arch>
|
||||
+ <url>(none)</url>
|
||||
+ <summary>Fedora (33) <fedora-33-primary@fedoraproject.org> public key</summary>
|
||||
+ <description>-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
+Version: rpm-4.16.1.2 (NSS-3)
|
||||
+
|
||||
+mQINBF4wBvsBEADQmcGbVUbDRUoXADReRmOOEMeydHghtKC9uRs9YNpGYZIB+bie
|
||||
+bGYZmflQayfh/wEpO2W/IZfGpHPL42V7SbyvqMjwNls/fnXsCtf4LRofNK8Qd9fN
|
||||
+kYargc9R7BEz/mwXKMiRQVx+DzkmqGWy2gq4iD0/mCyf5FdJCE40fOWoIGJXaOI1
|
||||
+Tz1vWqKwLS5T0dfmi9U4Tp/XsKOZGvN8oi5h0KmqFk7LEZr1MXarhi2Va86sgxsF
|
||||
+QcZEKfu5tgD0r00vXzikoSjn3qA5JW5FW07F1pGP4bF5f9J3CZbQyOjTSWMmmfTm
|
||||
+2d2BURWzaDiJN9twY2yjzkoOMuPdXXvovg7KxLcQerKT+FbKbq8DySJX2rnOA77k
|
||||
+UG4c9BGf/L1uBkAT8dpHLk6Uf5BfmypxUkydSWT1xfTDnw1MqxO0MsLlAHOR3J7c
|
||||
+oW9kLcOLuCQn1hBEwfZv7VSWBkGXSmKfp0LLIxAFgRtv+Dh+rcMMRdJgKr1V3FU+
|
||||
+rZ1+ZAfYiBpQJFPjv70vx+rGEgS801D3PJxBZUEy4Ic4ZYaKNhK9x9PRQuWcIBuW
|
||||
+6eTe/6lKWZeyxCumLLdiS75mF2oTcBaWeoc3QxrPRV15eDKeYJMbhnUai/7lSrhs
|
||||
+EWCkKR1RivgF4slYmtNE5ZPGZ/d61zjwn2xi4xNJVs8q9WRPMpHp0vCyMwARAQAB
|
||||
+tDFGZWRvcmEgKDMzKSA8ZmVkb3JhLTMzLXByaW1hcnlAZmVkb3JhcHJvamVjdC5v
|
||||
+cmc+iQI4BBMBAgAiBQJeMAb7AhsPBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAK
|
||||
+CRBJ/XdJlXD/MZm2D/9kriL43vd3+0DNMeA82n2v9mSR2PQqKny39xNlYPyy/1yZ
|
||||
+P/KXoa4NYSCA971LSd7lv4n/h5bEKgGHxZfttfOzOnWMVSSTfjRyM/df/NNzTUEV
|
||||
+7ORA5GW18g8PEtS7uRxVBf3cLvWu5q+8jmqES5HqTAdGVcuIFQeBXFN8Gy1Jinuz
|
||||
+AH8rJSdkUeZ0cehWbERq80BWM9dhad5dW+/+Gv0foFBvP15viwhWqajr8V0B8es+
|
||||
+2/tHI0k86FAujV5i0rrXl5UOoLilO57QQNDZH/qW9GsHwVI+2yecLstpUNLq+EZC
|
||||
+GqTZCYoxYRpl0gAMbDLztSL/8Bc0tJrCRG3tavJotFYlgUK60XnXlQzRkh9rgsfT
|
||||
+EXbQifWdQMMogzjCJr0hzJ+V1d0iozdUxB2ZEgTjukOvatkB77DY1FPZRkSFIQs+
|
||||
+fdcjazDIBLIxwJu5QwvTNW8lOLnJ46g4sf1WJoUdNTbR0BaC7HHj1inVWi0p7IuN
|
||||
+66EPGzJOSjLK+vW+J0ncPDEgLCV74RF/0nR5fVTdrmiopPrzFuguHf9S9gYI3Zun
|
||||
+Yl8FJUu4kRO6JPPTicUXWX+8XZmE94aK14RCJL23nOSi8T1eW8JLW43dCBRO8QUE
|
||||
+Aso1t2pypm/1zZexJdOV8yGME3g5l2W6PLgpz58DBECgqc/kda+VWgEAp7rO2A==
|
||||
+=EPL3
|
||||
+-----END PGP PUBLIC KEY BLOCK-----
|
||||
+</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>libgcc</name>
|
||||
+ <version>10.2.1</version>
|
||||
+ <release>9.fc33</release>
|
||||
<arch>x86_64</arch>
|
||||
+ <url>http://gcc.gnu.org</url>
|
||||
+ <summary>GCC version 10 shared support library</summary>
|
||||
+ <description>This package contains GCC shared support library which is needed
|
||||
+e.g. for exception handling support.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>ncurses-base</name>
|
||||
+ <version>6.2</version>
|
||||
+ <release>3.20200222.fc33</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://invisible-island.net/ncurses/ncurses.html</url>
|
||||
+ <summary>Descriptions of common terminals</summary>
|
||||
+ <description>This package contains descriptions of common terminals. Other terminal
|
||||
+descriptions are included in the ncurses-term package.</description>
|
||||
</application>
|
||||
<application>
|
||||
- <name>test3</name>
|
||||
- <version>3.0</version>
|
||||
- <release>3.fc14</release>
|
||||
+ <name>ncurses-libs</name>
|
||||
+ <version>6.2</version>
|
||||
+ <release>3.20200222.fc33</release>
|
||||
<arch>x86_64</arch>
|
||||
+ <url>https://invisible-island.net/ncurses/ncurses.html</url>
|
||||
+ <summary>Ncurses libraries</summary>
|
||||
+ <description>The curses library routines are a terminal-independent method of
|
||||
+updating character screens with reasonable optimization. The ncurses
|
||||
+(new curses) library is a freely distributable replacement for the
|
||||
+discontinued 4.4 BSD classic curses library.
|
||||
+
|
||||
+This package contains the ncurses libraries.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>setup</name>
|
||||
+ <version>2.13.7</version>
|
||||
+ <release>2.fc33</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://pagure.io/setup/</url>
|
||||
+ <summary>A set of system configuration and setup files</summary>
|
||||
+ <description>The setup package contains a set of important system configuration and
|
||||
+setup files, such as passwd, group, and profile.</description>
|
||||
+ </application>
|
||||
+ <application>
|
||||
+ <name>tzdata</name>
|
||||
+ <version>2021a</version>
|
||||
+ <release>1.fc33</release>
|
||||
+ <arch>noarch</arch>
|
||||
+ <url>https://www.iana.org/time-zones</url>
|
||||
+ <summary>Timezone data</summary>
|
||||
+ <description>This package contains data files with rules for various timezones around
|
||||
+the world.</description>
|
||||
</application>
|
||||
</applications>
|
||||
</operatingsystem>
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,57 +0,0 @@
|
||||
From 9857aa4f951dd289b54e5693946b3f7adbe5c98b Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Wed, 27 Feb 2019 17:51:59 +0100
|
||||
Subject: [PATCH] v2v: linux: do not uninstall open-vm-tools w/ ubuntu-server
|
||||
|
||||
ubuntu-server depends on open-vm-tools on Ubuntu, so if v2v tries to
|
||||
uninstall open-vm-tools then dpkg will (rightfully) fail with a
|
||||
dependency issue.
|
||||
|
||||
Since open-vm-tools is harmless after the conversion anyway (it will
|
||||
not even run), then do not attempt to uninstall it if ubuntu-server is
|
||||
installed too.
|
||||
|
||||
Followup of commit 2bebacf8bf611f0f80a66915f78653ce30b38129.
|
||||
|
||||
Thanks to: Ming Xie.
|
||||
|
||||
(cherry picked from commit 1a4fd822ef057764f809cddce642b3223756629e)
|
||||
---
|
||||
v2v/convert_linux.ml | 14 +++++++++++++-
|
||||
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
|
||||
index 3d61400b5..b4b2f24c4 100644
|
||||
--- a/v2v/convert_linux.ml
|
||||
+++ b/v2v/convert_linux.ml
|
||||
@@ -289,6 +289,18 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
||||
|
||||
(* Uninstall VMware Tools. *)
|
||||
let remove = ref [] and libraries = ref [] in
|
||||
+ (* On Ubuntu, the ubuntu-server metapackage depends on
|
||||
+ * open-vm-tools, and thus any attempt to remove it will cause
|
||||
+ * dependency issues. Hence, special case this situation, and
|
||||
+ * leave open-vm-tools installed in this case.
|
||||
+ *)
|
||||
+ let has_ubuntu_server =
|
||||
+ if family = `Debian_family then
|
||||
+ List.exists (
|
||||
+ fun { G.app2_name = name } ->
|
||||
+ name = "ubuntu-server"
|
||||
+ ) inspect.i_apps
|
||||
+ else false in
|
||||
List.iter (
|
||||
fun { G.app2_name = name } ->
|
||||
if String.is_prefix name "vmware-tools-libraries-" then
|
||||
@@ -301,7 +313,7 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
||||
List.push_front name remove
|
||||
else if String.is_prefix name "open-vm-tools-" then
|
||||
List.push_front name remove
|
||||
- else if name = "open-vm-tools" then
|
||||
+ else if name = "open-vm-tools" && not has_ubuntu_server then
|
||||
List.push_front name remove
|
||||
) inspect.i_apps;
|
||||
let libraries = !libraries in
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,65 @@
|
||||
From 6657d0c1018ab44ae680376463ac3f0421548fb4 Mon Sep 17 00:00:00 2001
|
||||
From: Laszlo Ersek <lersek@redhat.com>
|
||||
Date: Thu, 23 Dec 2021 11:36:59 +0100
|
||||
Subject: [PATCH] launch-libvirt: place our virtio-net-pci device in slot 0x1e
|
||||
|
||||
The <qemu:commandline> trick we use for adding our virtio-net-pci device
|
||||
in the libvirt backend can conflict with libvirtd's and QEMU's PCI address
|
||||
assignment. Try to mitigate that by placing our device in slot 0x1e on the
|
||||
root bus. In practice this could only conflict with a "dmi-to-pci-bridge"
|
||||
device model, which libvirtd itself places in slot 0x1e. However, given
|
||||
the XMLs we generate, and modern QEMU versions, libvirtd has no reason to
|
||||
auto-add "dmi-to-pci-bridge". Refer to
|
||||
<https://libvirt.org/formatdomain.html#controllers>.
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2034160
|
||||
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
||||
Message-Id: <20211223103701.12702-2-lersek@redhat.com>
|
||||
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
|
||||
Tested-by: Richard W.M. Jones <rjones@redhat.com>
|
||||
(cherry picked from commit 5ce5ef6a97a58c5e906083ad4e944545712b3f3f)
|
||||
---
|
||||
lib/guestfs-internal.h | 11 +++++++++++
|
||||
lib/launch-libvirt.c | 4 +++-
|
||||
2 files changed, 14 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
|
||||
index 4799ee0a1..0b46f0070 100644
|
||||
--- a/lib/guestfs-internal.h
|
||||
+++ b/lib/guestfs-internal.h
|
||||
@@ -147,6 +147,17 @@
|
||||
#define VIRTIO_DEVICE_NAME(type) type "-pci"
|
||||
#endif
|
||||
|
||||
+/* Place the virtio-net controller in slot 0x1e on the root bus, on normal
|
||||
+ * hardware with PCI. Refer to RHBZ#2034160.
|
||||
+ */
|
||||
+#ifdef HAVE_LIBVIRT_BACKEND
|
||||
+#if defined(__arm__) || defined(__s390x__)
|
||||
+#define VIRTIO_NET_PCI_ADDR ""
|
||||
+#else
|
||||
+#define VIRTIO_NET_PCI_ADDR ",addr=1e.0"
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
/* Guestfs handle and associated structures. */
|
||||
|
||||
/* State. */
|
||||
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
|
||||
index 026dc6b26..5842319df 100644
|
||||
--- a/lib/launch-libvirt.c
|
||||
+++ b/lib/launch-libvirt.c
|
||||
@@ -1834,7 +1834,9 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g,
|
||||
} end_element ();
|
||||
|
||||
start_element ("qemu:arg") {
|
||||
- attribute ("value", VIRTIO_DEVICE_NAME ("virtio-net") ",netdev=usernet");
|
||||
+ attribute ("value", (VIRTIO_DEVICE_NAME ("virtio-net")
|
||||
+ ",netdev=usernet"
|
||||
+ VIRTIO_NET_PCI_ADDR));
|
||||
} end_element ();
|
||||
}
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 999180eca864baf0a82267448de120d2ed0e4787 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Wed, 20 Mar 2019 16:55:05 +0100
|
||||
Subject: [PATCH] v2v: linux: canonicalize module path for arch detection
|
||||
(RHBZ#1690574)
|
||||
|
||||
Kernel modules can be also symlinks to files available outside the
|
||||
"canonical" module directory; the "file" API, used by the
|
||||
"file-architecture" API, return the actual type of a file (so symlinks,
|
||||
block devices, etc), and thus "file-architecture" fails on symlinks.
|
||||
|
||||
To prevent this situation, canonicalize the path of the module picked
|
||||
for architecture detection: this way, "file-architecture" will act on a
|
||||
real file.
|
||||
|
||||
(cherry picked from commit 0a093035d485b3c2e66d56541ebe159f1b632ba6)
|
||||
---
|
||||
v2v/linux_kernels.ml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/linux_kernels.ml b/v2v/linux_kernels.ml
|
||||
index 3313aabc7..889ec2f2a 100644
|
||||
--- a/v2v/linux_kernels.ml
|
||||
+++ b/v2v/linux_kernels.ml
|
||||
@@ -189,7 +189,7 @@ let detect_kernels (g : G.guestfs) inspect family bootloader =
|
||||
*)
|
||||
let arch =
|
||||
let any_module = modpath ^ List.hd modules in
|
||||
- g#file_architecture any_module in
|
||||
+ g#file_architecture (g#realpath any_module) in
|
||||
|
||||
(* Just return the module names, without path or extension. *)
|
||||
let modules = List.filter_map (
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,70 @@
|
||||
From 4b9eac11db3e2cc9ace397ed4c804356a7d9adbf Mon Sep 17 00:00:00 2001
|
||||
From: Laszlo Ersek <lersek@redhat.com>
|
||||
Date: Thu, 23 Dec 2021 11:37:00 +0100
|
||||
Subject: [PATCH] lib: extract NETWORK_ADDRESS and NETWORK_PREFIX as macros
|
||||
|
||||
The 169.254.0.0/16 network specification (for the appliance) is currently
|
||||
duplicated between the direct backend and the libvirt backend. In a
|
||||
subsequent patch, we're going to need the network specification in yet
|
||||
another spot; extract it now to the NETWORK_ADDRESS and NETWORK_PREFIX
|
||||
macros (simply as strings).
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2034160
|
||||
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
||||
Message-Id: <20211223103701.12702-3-lersek@redhat.com>
|
||||
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
|
||||
Tested-by: Richard W.M. Jones <rjones@redhat.com>
|
||||
(cherry picked from commit 216de164e091a5c36403f24901698044a43ae0d9)
|
||||
---
|
||||
lib/guestfs-internal.h | 6 ++++++
|
||||
lib/launch-direct.c | 2 +-
|
||||
lib/launch-libvirt.c | 3 ++-
|
||||
3 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
|
||||
index 0b46f0070..97a13ff2c 100644
|
||||
--- a/lib/guestfs-internal.h
|
||||
+++ b/lib/guestfs-internal.h
|
||||
@@ -158,6 +158,12 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+/* Network address and network mask (expressed as address prefix) that the
|
||||
+ * appliance will see (if networking is enabled).
|
||||
+ */
|
||||
+#define NETWORK_ADDRESS "169.254.0.0"
|
||||
+#define NETWORK_PREFIX "16"
|
||||
+
|
||||
/* Guestfs handle and associated structures. */
|
||||
|
||||
/* State. */
|
||||
diff --git a/lib/launch-direct.c b/lib/launch-direct.c
|
||||
index b6ed9766f..de17d2167 100644
|
||||
--- a/lib/launch-direct.c
|
||||
+++ b/lib/launch-direct.c
|
||||
@@ -681,7 +681,7 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
|
||||
start_list ("-netdev") {
|
||||
append_list ("user");
|
||||
append_list ("id=usernet");
|
||||
- append_list ("net=169.254.0.0/16");
|
||||
+ append_list ("net=" NETWORK_ADDRESS "/" NETWORK_PREFIX);
|
||||
} end_list ();
|
||||
start_list ("-device") {
|
||||
append_list (VIRTIO_DEVICE_NAME ("virtio-net"));
|
||||
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
|
||||
index 5842319df..0f38f0aec 100644
|
||||
--- a/lib/launch-libvirt.c
|
||||
+++ b/lib/launch-libvirt.c
|
||||
@@ -1826,7 +1826,8 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g,
|
||||
} end_element ();
|
||||
|
||||
start_element ("qemu:arg") {
|
||||
- attribute ("value", "user,id=usernet,net=169.254.0.0/16");
|
||||
+ attribute ("value",
|
||||
+ "user,id=usernet,net=" NETWORK_ADDRESS "/" NETWORK_PREFIX);
|
||||
} end_element ();
|
||||
|
||||
start_element ("qemu:arg") {
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,61 +0,0 @@
|
||||
From de9ebcaf0784c464a3ca3b2686935ce2bddcc281 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Wed, 20 Mar 2019 12:32:02 +0100
|
||||
Subject: [PATCH] v2v: linux: improve arch detection from modules
|
||||
(RHBZ#1690574)
|
||||
|
||||
Try to look for a well known kernel module (so far only virtio, or kvm)
|
||||
to use for detecting the architecture of a kernel. This way, we can
|
||||
avoid picking 3rd party modules that cause troubles.
|
||||
|
||||
(cherry picked from commit 363b5e0b4ecebe861a9aafe8bce5a8390b54571c)
|
||||
---
|
||||
v2v/linux_kernels.ml | 30 +++++++++++++++++++++++++++---
|
||||
1 file changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/v2v/linux_kernels.ml b/v2v/linux_kernels.ml
|
||||
index 889ec2f2a..30160f0da 100644
|
||||
--- a/v2v/linux_kernels.ml
|
||||
+++ b/v2v/linux_kernels.ml
|
||||
@@ -185,11 +185,35 @@ let detect_kernels (g : G.guestfs) inspect family bootloader =
|
||||
assert (List.length modules > 0);
|
||||
|
||||
(* Determine the kernel architecture by looking at the
|
||||
- * architecture of an arbitrary kernel module.
|
||||
+ * architecture of a kernel module.
|
||||
+ *
|
||||
+ * To avoid architecture detection issues with 3rd party
|
||||
+ * modules (RHBZ#1690574), try to pick one of the well
|
||||
+ * known modules, if available. Otherwise, an arbitrary
|
||||
+ * module is used.
|
||||
*)
|
||||
let arch =
|
||||
- let any_module = modpath ^ List.hd modules in
|
||||
- g#file_architecture (g#realpath any_module) in
|
||||
+ (* Well known kernel modules. *)
|
||||
+ let candidates = [ "virtio"; "kvm" ] in
|
||||
+ let all_candidates = List.flatten (
|
||||
+ List.map (
|
||||
+ fun f ->
|
||||
+ [ "/" ^ f ^ ".o"; "/" ^ f ^ ".ko"; "/" ^ f ^ ".ko.xz" ]
|
||||
+ ) candidates
|
||||
+ ) in
|
||||
+ let candidate =
|
||||
+ try
|
||||
+ List.find (
|
||||
+ fun m ->
|
||||
+ List.exists (String.is_suffix m) all_candidates
|
||||
+ ) modules
|
||||
+ with Not_found ->
|
||||
+ (* No known module found, pick an arbitrary one
|
||||
+ * (the first).
|
||||
+ *)
|
||||
+ List.hd modules in
|
||||
+ let candidate = modpath ^ candidate in
|
||||
+ g#file_architecture (g#realpath candidate) in
|
||||
|
||||
(* Just return the module names, without path or extension. *)
|
||||
let modules = List.filter_map (
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,63 +0,0 @@
|
||||
From 19c52dffc48af65eb07e6e1f8a85fc093ede9eb2 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Kletzander <mkletzan@redhat.com>
|
||||
Date: Mon, 27 May 2019 13:30:05 +0200
|
||||
Subject: [PATCH] Use proper label for nbdkit sockets
|
||||
|
||||
While svirt_t can be used for sockets it does not always guarantee that it will
|
||||
be accessible from a virtual machine. The VM might be running under svirt_tcg_t
|
||||
context which will need a svirt_tcg_t label on the socket in order to access it.
|
||||
|
||||
There is, however, another label, svirt_socket_t, which is accessible from
|
||||
virt_domain:
|
||||
|
||||
# sesearch -A -s svirt_t -c unix_stream_socket -p connectto
|
||||
...
|
||||
allow virt_domain svirt_socket_t:unix_stream_socket { ... connectto ... };
|
||||
...
|
||||
|
||||
And virt_domain is a type attribute of both svirt_t and svirt_tcg_t:
|
||||
|
||||
# seinfo -x -a virt_domain
|
||||
Type Attributes: 1
|
||||
attribute virt_domain;
|
||||
svirt_t
|
||||
svirt_tcg_t
|
||||
|
||||
Resolves: https://bugzilla.redhat.com/1698437
|
||||
|
||||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||
(cherry picked from commit c2918b8b74506523a723b804d452816a059c5e50)
|
||||
---
|
||||
v2v/input_libvirt_vddk.ml | 2 +-
|
||||
v2v/output_rhv_upload.ml | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml
|
||||
index 97c7cb532..567233d58 100644
|
||||
--- a/v2v/input_libvirt_vddk.ml
|
||||
+++ b/v2v/input_libvirt_vddk.ml
|
||||
@@ -290,7 +290,7 @@ object
|
||||
add_arg "--newstyle"; (* use newstyle NBD protocol *)
|
||||
add_arg "--exportname"; add_arg "/";
|
||||
if have_selinux then ( (* label the socket so qemu can open it *)
|
||||
- add_arg "--selinux-label"; add_arg "system_u:object_r:svirt_t:s0"
|
||||
+ add_arg "--selinux-label"; add_arg "system_u:object_r:svirt_socket_t:s0"
|
||||
);
|
||||
|
||||
(* Name of the plugin. Everything following is a plugin parameter. *)
|
||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||
index 77c39107e..c2a5c72c7 100644
|
||||
--- a/v2v/output_rhv_upload.ml
|
||||
+++ b/v2v/output_rhv_upload.ml
|
||||
@@ -217,7 +217,7 @@ See also the virt-v2v-output-rhv(1) manual.")
|
||||
let args =
|
||||
(* label the socket so qemu can open it *)
|
||||
if have_selinux then
|
||||
- args @ ["--selinux-label"; "system_u:object_r:svirt_t:s0"]
|
||||
+ args @ ["--selinux-label"; "system_u:object_r:svirt_socket_t:s0"]
|
||||
else args in
|
||||
args in
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,91 @@
|
||||
From 8570de6e766297e4c9feab1c54ae05037f33edeb Mon Sep 17 00:00:00 2001
|
||||
From: Laszlo Ersek <lersek@redhat.com>
|
||||
Date: Thu, 23 Dec 2021 11:37:01 +0100
|
||||
Subject: [PATCH] launch-libvirt: add virtio-net via the standard <interface>
|
||||
element
|
||||
|
||||
Starting with version 3.8.0, libvirt allows us to specify the network
|
||||
address and network mask (as prefix) for SLIRP directly via the
|
||||
<interface> element in the domain XML:
|
||||
<https://libvirt.org/formatdomain.html#userspace-slirp-stack>. This means
|
||||
we don't need the <qemu:commandline> hack for virtio-net on such versions.
|
||||
|
||||
Restrict the hack in construct_libvirt_xml_qemu_cmdline() to
|
||||
libvirt<3.8.0, and generate the proper <interface> element in
|
||||
construct_libvirt_xml_devices() on libvirt>=3.8.0.
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2034160
|
||||
Suggested-by: Richard W.M. Jones <rjones@redhat.com>
|
||||
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
||||
Message-Id: <20211223103701.12702-4-lersek@redhat.com>
|
||||
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
|
||||
Tested-by: Richard W.M. Jones <rjones@redhat.com>
|
||||
(cherry picked from commit 5858c2cf6c24b3776e3867eafd9d86a1f4912d9c)
|
||||
---
|
||||
lib/guestfs-internal.h | 3 ++-
|
||||
lib/launch-libvirt.c | 27 +++++++++++++++++++++++++--
|
||||
2 files changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
|
||||
index 97a13ff2c..b11c945e9 100644
|
||||
--- a/lib/guestfs-internal.h
|
||||
+++ b/lib/guestfs-internal.h
|
||||
@@ -148,7 +148,8 @@
|
||||
#endif
|
||||
|
||||
/* Place the virtio-net controller in slot 0x1e on the root bus, on normal
|
||||
- * hardware with PCI. Refer to RHBZ#2034160.
|
||||
+ * hardware with PCI. Necessary only before libvirt 3.8.0. Refer to
|
||||
+ * RHBZ#2034160.
|
||||
*/
|
||||
#ifdef HAVE_LIBVIRT_BACKEND
|
||||
#if defined(__arm__) || defined(__s390x__)
|
||||
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
|
||||
index 0f38f0aec..f6bb39d99 100644
|
||||
--- a/lib/launch-libvirt.c
|
||||
+++ b/lib/launch-libvirt.c
|
||||
@@ -1396,6 +1396,28 @@ construct_libvirt_xml_devices (guestfs_h *g,
|
||||
} end_element ();
|
||||
} end_element ();
|
||||
|
||||
+ /* Virtio-net NIC with SLIRP (= userspace) back-end, if networking is
|
||||
+ * enabled. Starting with libvirt 3.8.0, we can specify the network address
|
||||
+ * and prefix for SLIRP in the domain XML. Therefore, we can add the NIC
|
||||
+ * via the standard <interface> element rather than <qemu:commandline>, and
|
||||
+ * so libvirt can manage the PCI address of the virtio-net NIC like the PCI
|
||||
+ * addresses of all other devices. Refer to RHBZ#2034160.
|
||||
+ */
|
||||
+ if (g->enable_network &&
|
||||
+ guestfs_int_version_ge (¶ms->data->libvirt_version, 3, 8, 0)) {
|
||||
+ start_element ("interface") {
|
||||
+ attribute ("type", "user");
|
||||
+ start_element ("model") {
|
||||
+ attribute ("type", "virtio");
|
||||
+ } end_element ();
|
||||
+ start_element ("ip") {
|
||||
+ attribute ("family", "ipv4");
|
||||
+ attribute ("address", NETWORK_ADDRESS);
|
||||
+ attribute ("prefix", NETWORK_PREFIX);
|
||||
+ } end_element ();
|
||||
+ } end_element ();
|
||||
+ }
|
||||
+
|
||||
/* Libvirt adds some devices by default. Indicate to libvirt
|
||||
* that we don't want them.
|
||||
*/
|
||||
@@ -1818,9 +1840,10 @@ construct_libvirt_xml_qemu_cmdline (guestfs_h *g,
|
||||
} end_element ();
|
||||
|
||||
/* Workaround because libvirt user networking cannot specify "net="
|
||||
- * parameter.
|
||||
+ * parameter. Necessary only before libvirt 3.8.0; refer to RHBZ#2034160.
|
||||
*/
|
||||
- if (g->enable_network) {
|
||||
+ if (g->enable_network &&
|
||||
+ !guestfs_int_version_ge (¶ms->data->libvirt_version, 3, 8, 0)) {
|
||||
start_element ("qemu:arg") {
|
||||
attribute ("value", "-netdev");
|
||||
} end_element ();
|
||||
--
|
||||
2.31.1
|
||||
|
86
SOURCES/0020-appliance-Use-cpu-max.patch
Normal file
86
SOURCES/0020-appliance-Use-cpu-max.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From fbb053fc71c0c072acb3fbf6e5fbbfc3b0667fd2 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 28 Jan 2021 12:20:49 +0000
|
||||
Subject: [PATCH] appliance: Use -cpu max.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
QEMU has a newish feature (from about 2017 / qemu 2.9) called -cpu max
|
||||
which is supposed to select the best CPU, ideal for libguestfs.
|
||||
|
||||
After this change, on x86-64:
|
||||
|
||||
KVM TCG
|
||||
|
||||
Direct -cpu max -cpu max
|
||||
(non-libvirt)
|
||||
|
||||
Libvirt <cpu mode="host-passthrough"> <cpu mode="host-model">
|
||||
<model fallback="allow"/> <model fallback="allow"/>
|
||||
</cpu> </cpu>
|
||||
|
||||
Thanks: Daniel Berrangé
|
||||
(cherry picked from commit 30f74f38bd6e42e783ba80895f4d6826abddd417)
|
||||
---
|
||||
lib/appliance-cpu.c | 16 ++++++++--------
|
||||
lib/launch-libvirt.c | 9 +++++++++
|
||||
2 files changed, 17 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/lib/appliance-cpu.c b/lib/appliance-cpu.c
|
||||
index 5ef9f5c72..54ac6e2e3 100644
|
||||
--- a/lib/appliance-cpu.c
|
||||
+++ b/lib/appliance-cpu.c
|
||||
@@ -38,6 +38,11 @@
|
||||
*
|
||||
* The literal string C<"host"> means use C<-cpu host>.
|
||||
*
|
||||
+ * =item C<"max">
|
||||
+ *
|
||||
+ * The literal string C<"max"> means use C<-cpu max> (the best
|
||||
+ * possible). This requires awkward translation for libvirt.
|
||||
+ *
|
||||
* =item some string
|
||||
*
|
||||
* Some string such as C<"cortex-a57"> means use C<-cpu cortex-a57>.
|
||||
@@ -80,14 +85,9 @@ guestfs_int_get_cpu_model (int kvm)
|
||||
/* See discussion in https://bugzilla.redhat.com/show_bug.cgi?id=1605071 */
|
||||
return NULL;
|
||||
#else
|
||||
- /* On most architectures, it is faster to pass the CPU host model to
|
||||
- * the appliance, allowing maximum speed for things like checksums
|
||||
- * and encryption. Only do this with KVM. It is broken in subtle
|
||||
- * ways on TCG, and fairly pointless when you're emulating anyway.
|
||||
+ /* On most architectures we can use "max" to get the best possible CPU.
|
||||
+ * For recent qemu this should work even on TCG.
|
||||
*/
|
||||
- if (kvm)
|
||||
- return "host";
|
||||
- else
|
||||
- return NULL;
|
||||
+ return "max";
|
||||
#endif
|
||||
}
|
||||
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
|
||||
index f6bb39d99..e3ff1ffe0 100644
|
||||
--- a/lib/launch-libvirt.c
|
||||
+++ b/lib/launch-libvirt.c
|
||||
@@ -1169,6 +1169,15 @@ construct_libvirt_xml_cpu (guestfs_h *g,
|
||||
attribute ("fallback", "allow");
|
||||
} end_element ();
|
||||
}
|
||||
+ else if (STREQ (cpu_model, "max")) {
|
||||
+ if (params->data->is_kvm)
|
||||
+ attribute ("mode", "host-passthrough");
|
||||
+ else
|
||||
+ attribute ("mode", "host-model");
|
||||
+ start_element ("model") {
|
||||
+ attribute ("fallback", "allow");
|
||||
+ } end_element ();
|
||||
+ }
|
||||
else
|
||||
single_element ("model", cpu_model);
|
||||
} end_element ();
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 3fe15743f316f1576115e30ebd0a512b3667e2f1 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 8 Apr 2019 18:23:27 +0200
|
||||
Subject: [PATCH] v2v: start reading the new libvirt firmware autoselect
|
||||
|
||||
Starting with 5.2.0, libvirt has a way to select automatically the
|
||||
firmware for a guest using an attribute of the <os> tag. Hence, use
|
||||
this information (when available, of course) to flag the firmware used
|
||||
by the guest.
|
||||
|
||||
(cherry picked from commit fb7983f999004c1f8100776819ea65b21990956d)
|
||||
---
|
||||
v2v/parse_libvirt_xml.ml | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/parse_libvirt_xml.ml b/v2v/parse_libvirt_xml.ml
|
||||
index b9970cee8..14cd82afd 100644
|
||||
--- a/v2v/parse_libvirt_xml.ml
|
||||
+++ b/v2v/parse_libvirt_xml.ml
|
||||
@@ -476,6 +476,13 @@ let parse_libvirt_xml ?conn xml =
|
||||
done;
|
||||
List.rev !nics in
|
||||
|
||||
+ (* Firmware. *)
|
||||
+ let firmware =
|
||||
+ match xpath_string "/domain/os/@firmware" with
|
||||
+ | Some "bios" -> BIOS
|
||||
+ | Some "efi" -> UEFI
|
||||
+ | None | Some _ -> UnknownFirmware in
|
||||
+
|
||||
(* Check for hostdev devices. (RHBZ#1472719) *)
|
||||
let () =
|
||||
let obj = Xml.xpath_eval_expression xpathctx "/domain/devices/hostdev" in
|
||||
@@ -520,7 +527,7 @@ let parse_libvirt_xml ?conn xml =
|
||||
s_cpu_model = cpu_model;
|
||||
s_cpu_topology = cpu_topology;
|
||||
s_features = features;
|
||||
- s_firmware = UnknownFirmware; (* XXX until RHBZ#1217444 is fixed *)
|
||||
+ s_firmware = firmware;
|
||||
s_display = display;
|
||||
s_video = video;
|
||||
s_sound = sound;
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,48 @@
|
||||
From 7dde1007525ec235e769351be15ca5de34eeda4a Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 18 Mar 2021 12:32:26 +0000
|
||||
Subject: [PATCH] appliance: Use <cpu mode="maximum"/> for -cpu max on libvirt.
|
||||
|
||||
Note this requires libvirt >= 7.1.0 which was only released in March 2021.
|
||||
|
||||
With an older libvirt you will see this error:
|
||||
|
||||
Original error from libvirt: unsupported configuration: Invalid mode attribute 'maximum' [code=67 int1=-1]
|
||||
|
||||
In theory we could check if this is supported by looking at the
|
||||
libvirt capabilities and fall back, but this commit does not do that,
|
||||
in the expectation that most people will be using the default backend
|
||||
(direct) and on Fedora/RHEL we will add an explicit minimum version
|
||||
dependency to the package.
|
||||
|
||||
qemu support has been around quite a bit longer (at least since 2017).
|
||||
|
||||
Fixes: commit 30f74f38bd6e42e783ba80895f4d6826abddd417
|
||||
(cherry picked from commit 13ceb6a87b2869909a6a0e3c8caa962b72e4cb0e)
|
||||
---
|
||||
lib/launch-libvirt.c | 9 ++-------
|
||||
1 file changed, 2 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
|
||||
index e3ff1ffe0..db619910f 100644
|
||||
--- a/lib/launch-libvirt.c
|
||||
+++ b/lib/launch-libvirt.c
|
||||
@@ -1170,13 +1170,8 @@ construct_libvirt_xml_cpu (guestfs_h *g,
|
||||
} end_element ();
|
||||
}
|
||||
else if (STREQ (cpu_model, "max")) {
|
||||
- if (params->data->is_kvm)
|
||||
- attribute ("mode", "host-passthrough");
|
||||
- else
|
||||
- attribute ("mode", "host-model");
|
||||
- start_element ("model") {
|
||||
- attribute ("fallback", "allow");
|
||||
- } end_element ();
|
||||
+ /* https://bugzilla.redhat.com/show_bug.cgi?id=1935572#c11 */
|
||||
+ attribute ("mode", "maximum");
|
||||
}
|
||||
else
|
||||
single_element ("model", cpu_model);
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,96 +0,0 @@
|
||||
From 7ac3289d64b37348f29de9db4d71c3286836066b Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Thu, 21 Mar 2019 17:16:37 +0100
|
||||
Subject: [PATCH] common/mltools: move the code for machine readable up
|
||||
|
||||
Move the code for handling machine readable up in the file, so it can be
|
||||
used by other functions.
|
||||
|
||||
Only code motion, no behaviour changes.
|
||||
|
||||
(cherry picked from commit 8b06ea0ebc9534e4fda9cc9a33c98f939401af79)
|
||||
---
|
||||
common/mltools/tools_utils.ml | 60 +++++++++++++++++------------------
|
||||
1 file changed, 30 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml
|
||||
index 24641369e..5a35708cd 100644
|
||||
--- a/common/mltools/tools_utils.ml
|
||||
+++ b/common/mltools/tools_utils.ml
|
||||
@@ -33,6 +33,36 @@ external c_inspect_decrypt : Guestfs.t -> int64 -> (string * key_store_key) list
|
||||
external c_set_echo_keys : unit -> unit = "guestfs_int_mllib_set_echo_keys" "noalloc"
|
||||
external c_set_keys_from_stdin : unit -> unit = "guestfs_int_mllib_set_keys_from_stdin" "noalloc"
|
||||
|
||||
+type machine_readable_fn = {
|
||||
+ pr : 'a. ('a, unit, string, unit) format4 -> 'a;
|
||||
+} (* [@@unboxed] *)
|
||||
+
|
||||
+type machine_readable_output_type =
|
||||
+ | NoOutput
|
||||
+ | Channel of out_channel
|
||||
+ | File of string
|
||||
+let machine_readable_output = ref NoOutput
|
||||
+let machine_readable_channel = ref None
|
||||
+let machine_readable () =
|
||||
+ let chan =
|
||||
+ if !machine_readable_channel = None then (
|
||||
+ let chan =
|
||||
+ match !machine_readable_output with
|
||||
+ | NoOutput -> None
|
||||
+ | Channel chan -> Some chan
|
||||
+ | File f -> Some (open_out f) in
|
||||
+ machine_readable_channel := chan
|
||||
+ );
|
||||
+ !machine_readable_channel
|
||||
+ in
|
||||
+ match chan with
|
||||
+ | None -> None
|
||||
+ | Some chan ->
|
||||
+ let pr fs =
|
||||
+ ksprintf (output_string chan) fs
|
||||
+ in
|
||||
+ Some { pr }
|
||||
+
|
||||
(* ANSI terminal colours. *)
|
||||
let istty chan =
|
||||
Unix.isatty (Unix.descr_of_out_channel chan)
|
||||
@@ -236,36 +266,6 @@ let human_size i =
|
||||
)
|
||||
)
|
||||
|
||||
-type machine_readable_fn = {
|
||||
- pr : 'a. ('a, unit, string, unit) format4 -> 'a;
|
||||
-} (* [@@unboxed] *)
|
||||
-
|
||||
-type machine_readable_output_type =
|
||||
- | NoOutput
|
||||
- | Channel of out_channel
|
||||
- | File of string
|
||||
-let machine_readable_output = ref NoOutput
|
||||
-let machine_readable_channel = ref None
|
||||
-let machine_readable () =
|
||||
- let chan =
|
||||
- if !machine_readable_channel = None then (
|
||||
- let chan =
|
||||
- match !machine_readable_output with
|
||||
- | NoOutput -> None
|
||||
- | Channel chan -> Some chan
|
||||
- | File f -> Some (open_out f) in
|
||||
- machine_readable_channel := chan
|
||||
- );
|
||||
- !machine_readable_channel
|
||||
- in
|
||||
- match chan with
|
||||
- | None -> None
|
||||
- | Some chan ->
|
||||
- let pr fs =
|
||||
- ksprintf (output_string chan) fs
|
||||
- in
|
||||
- Some { pr }
|
||||
-
|
||||
type cmdline_options = {
|
||||
getopt : Getopt.t;
|
||||
ks : key_store;
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,34 +0,0 @@
|
||||
From d60ef2eca9c0e51944a9c17806d6936af45907f5 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 22 Mar 2019 11:36:41 +0100
|
||||
Subject: [PATCH] common/mltools: make sure machine readable output is flushed
|
||||
|
||||
Enhance the helper printf function for machine readable output to always
|
||||
flush after each string: this way, readers of the machine readable
|
||||
stream can get the output as soon as it is outputted.
|
||||
|
||||
(cherry picked from commit abf1607f46ddc3d829a3688b9499a9bcd2319d19)
|
||||
---
|
||||
common/mltools/tools_utils.ml | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml
|
||||
index 5a35708cd..ade4cb37f 100644
|
||||
--- a/common/mltools/tools_utils.ml
|
||||
+++ b/common/mltools/tools_utils.ml
|
||||
@@ -59,7 +59,11 @@ let machine_readable () =
|
||||
| None -> None
|
||||
| Some chan ->
|
||||
let pr fs =
|
||||
- ksprintf (output_string chan) fs
|
||||
+ let out s =
|
||||
+ output_string chan s;
|
||||
+ flush chan
|
||||
+ in
|
||||
+ ksprintf out fs
|
||||
in
|
||||
Some { pr }
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -0,0 +1,92 @@
|
||||
From bb19cc0cdd43619ccf830e1e608f79e46f8ddf86 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 12 May 2022 08:36:37 +0100
|
||||
Subject: [PATCH] lib: Disable 5-level page tables when using -cpu max
|
||||
|
||||
In https://bugzilla.redhat.com/show_bug.cgi?id=2082806 we've been
|
||||
tracking an insidious qemu bug which intermittently prevents the
|
||||
libguestfs appliance from starting. The symptoms are that SeaBIOS
|
||||
starts and displays its messages, but the kernel isn't reached. We
|
||||
found that the kernel does in fact start, but when it tries to set up
|
||||
page tables and jump to protected mode it gets a triple fault which
|
||||
causes the emulated CPU in qemu to reset (qemu exits).
|
||||
|
||||
This seems to only affect TCG (not KVM).
|
||||
|
||||
Yesterday I found that this is caused by using -cpu max which enables
|
||||
the "la57" feature (5-level page tables[0]), and that we can make the
|
||||
problem go away using -cpu max,la57=off. Note that I still don't
|
||||
fully understand the qemu bug, so this is only a workaround.
|
||||
|
||||
I chose to disable 5-level page tables for both TCG and KVM, partly to
|
||||
make the patch simpler, and partly because I guess it's not a feature
|
||||
(ie. 57 bit linear addresses) that is useful for the libguestfs
|
||||
appliance case, where we have limited physical memory and no need to
|
||||
run any programs with huge address spaces.
|
||||
|
||||
I tested this by running both the direct & libvirt paths overnight. I
|
||||
expect that this patch will fail with old qemu/libvirt which doesn't
|
||||
understand the "la57" feature, but this is only intended as a
|
||||
temporary workaround.
|
||||
|
||||
[0] Article about 5-level page tables as background:
|
||||
https://lwn.net/Articles/717293/
|
||||
|
||||
Thanks: Laszlo Ersek
|
||||
Fixes: https://answers.launchpad.net/ubuntu/+source/libguestfs/+question/701625
|
||||
|
||||
[RHEL 8.7: Patch is not upstream. This is the initial patch as posted
|
||||
to the mailing list here:
|
||||
https://listman.redhat.com/archives/libguestfs/2022-May/028853.html]
|
||||
---
|
||||
lib/launch-direct.c | 15 +++++++++++++--
|
||||
lib/launch-libvirt.c | 7 +++++++
|
||||
2 files changed, 20 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/launch-direct.c b/lib/launch-direct.c
|
||||
index de17d2167..6b28e4724 100644
|
||||
--- a/lib/launch-direct.c
|
||||
+++ b/lib/launch-direct.c
|
||||
@@ -534,8 +534,19 @@ launch_direct (guestfs_h *g, void *datav, const char *arg)
|
||||
} end_list ();
|
||||
|
||||
cpu_model = guestfs_int_get_cpu_model (has_kvm && !force_tcg);
|
||||
- if (cpu_model)
|
||||
- arg ("-cpu", cpu_model);
|
||||
+ if (cpu_model) {
|
||||
+#if defined(__x86_64__)
|
||||
+ /* Temporary workaround for RHBZ#2082806 */
|
||||
+ if (STREQ (cpu_model, "max")) {
|
||||
+ start_list ("-cpu") {
|
||||
+ append_list (cpu_model);
|
||||
+ append_list ("la57=off");
|
||||
+ } end_list ();
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ arg ("-cpu", cpu_model);
|
||||
+ }
|
||||
|
||||
if (g->smp > 1)
|
||||
arg_format ("-smp", "%d", g->smp);
|
||||
diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
|
||||
index db619910f..bad4a54ea 100644
|
||||
--- a/lib/launch-libvirt.c
|
||||
+++ b/lib/launch-libvirt.c
|
||||
@@ -1172,6 +1172,13 @@ construct_libvirt_xml_cpu (guestfs_h *g,
|
||||
else if (STREQ (cpu_model, "max")) {
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1935572#c11 */
|
||||
attribute ("mode", "maximum");
|
||||
+#if defined(__x86_64__)
|
||||
+ /* Temporary workaround for RHBZ#2082806 */
|
||||
+ start_element ("feature") {
|
||||
+ attribute ("policy", "disable");
|
||||
+ attribute ("name", "la57");
|
||||
+ } end_element ();
|
||||
+#endif
|
||||
}
|
||||
else
|
||||
single_element ("model", cpu_model);
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,87 +0,0 @@
|
||||
From f7acb14822f1a962a211c0d11488ffceadde2b68 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 22 Mar 2019 12:59:11 +0100
|
||||
Subject: [PATCH] common/mltools: allow fd for machine readable output
|
||||
|
||||
Allow to specify a file descriptor for the machine readable output.
|
||||
|
||||
Use the same assumption as done in v2v, i.e. that Unix.file_descr is
|
||||
simply the int file descriptor.
|
||||
|
||||
(cherry picked from commit 70514dfaf1e45b5ad34f20f3297af9782099cf80)
|
||||
---
|
||||
common/mltools/test-machine-readable.sh | 7 +++++++
|
||||
common/mltools/tools_utils.ml | 11 ++++++++++-
|
||||
lib/guestfs.pod | 5 +++++
|
||||
3 files changed, 22 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/common/mltools/test-machine-readable.sh b/common/mltools/test-machine-readable.sh
|
||||
index 1162c58e9..824460e6d 100755
|
||||
--- a/common/mltools/test-machine-readable.sh
|
||||
+++ b/common/mltools/test-machine-readable.sh
|
||||
@@ -65,3 +65,10 @@ test $($t --machine-readable=stream:stdout |& wc -l) -eq 3
|
||||
# Output "stream:stderr".
|
||||
$t --machine-readable=stream:stderr 2>&1 >/dev/null | grep 'machine-readable'
|
||||
test $($t --machine-readable=stream:stderr 2>&1 >/dev/null | wc -l) -eq 2
|
||||
+
|
||||
+# Output "fd:".
|
||||
+fn="$tmpdir/fdfile"
|
||||
+exec 4>"$fn"
|
||||
+$t --machine-readable=fd:4
|
||||
+exec 4>&-
|
||||
+test $(cat "$fn" | wc -l) -eq 1
|
||||
diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml
|
||||
index ade4cb37f..35478f39e 100644
|
||||
--- a/common/mltools/tools_utils.ml
|
||||
+++ b/common/mltools/tools_utils.ml
|
||||
@@ -41,6 +41,7 @@ type machine_readable_output_type =
|
||||
| NoOutput
|
||||
| Channel of out_channel
|
||||
| File of string
|
||||
+ | Fd of int
|
||||
let machine_readable_output = ref NoOutput
|
||||
let machine_readable_channel = ref None
|
||||
let machine_readable () =
|
||||
@@ -50,7 +51,10 @@ let machine_readable () =
|
||||
match !machine_readable_output with
|
||||
| NoOutput -> None
|
||||
| Channel chan -> Some chan
|
||||
- | File f -> Some (open_out f) in
|
||||
+ | File f -> Some (open_out f)
|
||||
+ | Fd fd ->
|
||||
+ (* Note that Unix.file_descr is really just an int. *)
|
||||
+ Some (Unix.out_channel_of_descr (Obj.magic fd)) in
|
||||
machine_readable_channel := chan
|
||||
);
|
||||
!machine_readable_channel
|
||||
@@ -296,6 +300,11 @@ let create_standard_options argspec ?anon_fun ?(key_opts = false) ?(machine_read
|
||||
| n ->
|
||||
error (f_"invalid output stream for --machine-readable: %s") fmt in
|
||||
machine_readable_output := Channel chan
|
||||
+ | "fd" ->
|
||||
+ (try
|
||||
+ machine_readable_output := Fd (int_of_string outname)
|
||||
+ with Failure _ ->
|
||||
+ error (f_"invalid output fd for --machine-readable: %s") fmt)
|
||||
| n ->
|
||||
error (f_"invalid output for --machine-readable: %s") fmt
|
||||
)
|
||||
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
|
||||
index 53cece2da..f11028466 100644
|
||||
--- a/lib/guestfs.pod
|
||||
+++ b/lib/guestfs.pod
|
||||
@@ -3287,6 +3287,11 @@ The possible values are:
|
||||
|
||||
=over 4
|
||||
|
||||
+=item B<fd:>I<fd>
|
||||
+
|
||||
+The output goes to the specified I<fd>, which is a file descriptor
|
||||
+already opened for writing.
|
||||
+
|
||||
=item B<file:>F<filename>
|
||||
|
||||
The output goes to the specified F<filename>.
|
||||
--
|
||||
2.18.4
|
||||
|
103
SOURCES/0023-docs-guestfs-security-document-CVE-2022-2211.patch
Normal file
103
SOURCES/0023-docs-guestfs-security-document-CVE-2022-2211.patch
Normal file
@ -0,0 +1,103 @@
|
||||
From 22d779d5982dc82d629710d41973ed6545707bd9 Mon Sep 17 00:00:00 2001
|
||||
From: Laszlo Ersek <lersek@redhat.com>
|
||||
Date: Tue, 28 Jun 2022 13:54:16 +0200
|
||||
Subject: [PATCH] docs/guestfs-security: document CVE-2022-2211
|
||||
|
||||
Short log for the common submodule, commit range
|
||||
f8de5508fe75..35467027f657:
|
||||
|
||||
Laszlo Ersek (2):
|
||||
mlcustomize: factor out pkg install/update/uninstall from guestfs-tools
|
||||
options: fix buffer overflow in get_keys() [CVE-2022-2211]
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1809453
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2100862
|
||||
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
||||
Message-Id: <20220628115418.5376-2-lersek@redhat.com>
|
||||
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
|
||||
|
||||
Cherry picked from commit 99844660b48ed809e37378262c65d63df6ce4a53.
|
||||
For the cherry pick I only added one submodule commit:
|
||||
|
||||
options: fix buffer overflow in get_keys() [CVE-2022-2211]
|
||||
---
|
||||
common | 2 +-
|
||||
docs/guestfs-security.pod | 28 ++++++++++++++++++++++++++++
|
||||
2 files changed, 29 insertions(+), 1 deletion(-)
|
||||
|
||||
Submodule common be09523d6..1174b443a:
|
||||
diff --git a/common/options/keys.c b/common/options/keys.c
|
||||
index 798315c..d27a712 100644
|
||||
--- a/common/options/keys.c
|
||||
+++ b/common/options/keys.c
|
||||
@@ -128,17 +128,23 @@ read_first_line_from_file (const char *filename)
|
||||
char **
|
||||
get_keys (struct key_store *ks, const char *device, const char *uuid)
|
||||
{
|
||||
- size_t i, j, len;
|
||||
+ size_t i, j, nmemb;
|
||||
char **r;
|
||||
char *s;
|
||||
|
||||
/* We know the returned list must have at least one element and not
|
||||
* more than ks->nr_keys.
|
||||
*/
|
||||
- len = 1;
|
||||
- if (ks)
|
||||
- len = MIN (1, ks->nr_keys);
|
||||
- r = calloc (len+1, sizeof (char *));
|
||||
+ nmemb = 1;
|
||||
+ if (ks && ks->nr_keys > nmemb)
|
||||
+ nmemb = ks->nr_keys;
|
||||
+
|
||||
+ /* make room for the terminating NULL */
|
||||
+ if (nmemb == (size_t)-1)
|
||||
+ error (EXIT_FAILURE, 0, _("size_t overflow"));
|
||||
+ nmemb++;
|
||||
+
|
||||
+ r = calloc (nmemb, sizeof (char *));
|
||||
if (r == NULL)
|
||||
error (EXIT_FAILURE, errno, "calloc");
|
||||
|
||||
diff --git a/docs/guestfs-security.pod b/docs/guestfs-security.pod
|
||||
index 9ceef5623..efa35b29d 100644
|
||||
--- a/docs/guestfs-security.pod
|
||||
+++ b/docs/guestfs-security.pod
|
||||
@@ -406,6 +406,34 @@ The libvirt backend is not affected.
|
||||
The solution is to update qemu to a version containing the fix (see
|
||||
L<https://lists.gnu.org/archive/html/qemu-devel/2018-06/msg01012.html>).
|
||||
|
||||
+=head2 CVE-2022-2211
|
||||
+
|
||||
+L<https://bugzilla.redhat.com/CVE-2022-2211>
|
||||
+
|
||||
+The C<get_keys> function in F<libguestfs-common/options/keys.c> collects
|
||||
+those I<--key> options from the command line into a new array that match
|
||||
+a particular block device that's being decrypted for inspection. The
|
||||
+function intends to size the result array such that potentially all
|
||||
+I<--key> options, plus a terminating C<NULL> element, fit into it. The
|
||||
+code mistakenly uses the C<MIN> macro instead of C<MAX>, and therefore
|
||||
+only one element is allocated before the C<NULL> terminator.
|
||||
+
|
||||
+Passing precisely two I<--key ID:...> options on the command line for
|
||||
+the encrypted block device C<ID> causes C<get_keys> to overwrite the
|
||||
+terminating C<NULL>, leading to an out-of-bounds read in
|
||||
+C<decrypt_mountables>, file F<libguestfs-common/options/decrypt.c>.
|
||||
+
|
||||
+Passing more than two I<--key ID:...> options on the command line for
|
||||
+the encrypted block device C<ID> causes C<get_keys> itself to perform
|
||||
+out-of-bounds writes. The most common symptom is a crash with C<SIGSEGV>
|
||||
+later on.
|
||||
+
|
||||
+This issue affects -- broadly speaking -- all libguestfs-based utilities
|
||||
+that accept I<--key>, namely: C<guestfish>, C<guestmount>, C<virt-cat>,
|
||||
+C<virt-customize>, C<virt-diff>, C<virt-edit>, C<virt-get-kernel>,
|
||||
+C<virt-inspector>, C<virt-log>, C<virt-ls>, C<virt-sparsify>,
|
||||
+C<virt-sysprep>, C<virt-tail>, C<virt-v2v>.
|
||||
+
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<guestfs(3)>,
|
||||
--
|
||||
2.31.1
|
||||
|
@ -1,514 +0,0 @@
|
||||
From e34b3a6aca9e7e51888416c57f768522597a2df1 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 22 Mar 2019 16:24:25 +0100
|
||||
Subject: [PATCH] OCaml tools: output messages into JSON for machine readable
|
||||
|
||||
When the machine readable mode is enabled, print all the messages
|
||||
(progress, info, warning, and errors) also as JSON in the machine
|
||||
readable stream: this way, users can easily parse the status of the
|
||||
OCaml tool, and report that back.
|
||||
|
||||
The formatting of the current date time into the RFC 3999 format is done
|
||||
in C, because of the lack of OCaml APIs for this.
|
||||
|
||||
(cherry picked from commit f79129b8dc92470e3a5597daf53c84038bd6859e)
|
||||
---
|
||||
.gitignore | 1 +
|
||||
common/mltools/Makefile.am | 39 ++++++-
|
||||
common/mltools/parse_tools_messages_test.py | 118 ++++++++++++++++++++
|
||||
common/mltools/test-tools-messages.sh | 28 +++++
|
||||
common/mltools/tools_messages_tests.ml | 46 ++++++++
|
||||
common/mltools/tools_utils-c.c | 51 +++++++++
|
||||
common/mltools/tools_utils.ml | 16 +++
|
||||
lib/guestfs.pod | 19 ++++
|
||||
8 files changed, 316 insertions(+), 2 deletions(-)
|
||||
create mode 100644 common/mltools/parse_tools_messages_test.py
|
||||
create mode 100755 common/mltools/test-tools-messages.sh
|
||||
create mode 100644 common/mltools/tools_messages_tests.ml
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index f2efcdde2..db1dbb7cc 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -147,6 +147,7 @@ Makefile.in
|
||||
/common/mltools/JSON_tests
|
||||
/common/mltools/JSON_parser_tests
|
||||
/common/mltools/machine_readable_tests
|
||||
+/common/mltools/tools_messages_tests
|
||||
/common/mltools/tools_utils_tests
|
||||
/common/mltools/oUnit-*
|
||||
/common/mlutils/.depend
|
||||
diff --git a/common/mltools/Makefile.am b/common/mltools/Makefile.am
|
||||
index 37d10e610..ae78b84b7 100644
|
||||
--- a/common/mltools/Makefile.am
|
||||
+++ b/common/mltools/Makefile.am
|
||||
@@ -27,6 +27,8 @@ EXTRA_DIST = \
|
||||
machine_readable_tests.ml \
|
||||
test-getopt.sh \
|
||||
test-machine-readable.sh \
|
||||
+ test-tools-messages.sh \
|
||||
+ tools_messages_tests.ml \
|
||||
tools_utils_tests.ml
|
||||
|
||||
SOURCES_MLI = \
|
||||
@@ -45,12 +47,12 @@ SOURCES_MLI = \
|
||||
|
||||
SOURCES_ML = \
|
||||
getopt.ml \
|
||||
+ JSON.ml \
|
||||
tools_utils.ml \
|
||||
URI.ml \
|
||||
planner.ml \
|
||||
registry.ml \
|
||||
regedit.ml \
|
||||
- JSON.ml \
|
||||
JSON_parser.ml \
|
||||
curl.ml \
|
||||
checksums.ml \
|
||||
@@ -196,6 +198,15 @@ machine_readable_tests_CPPFLAGS = \
|
||||
machine_readable_tests_BOBJECTS = machine_readable_tests.cmo
|
||||
machine_readable_tests_XOBJECTS = $(machine_readable_tests_BOBJECTS:.cmo=.cmx)
|
||||
|
||||
+tools_messages_tests_SOURCES = dummy.c
|
||||
+tools_messages_tests_CPPFLAGS = \
|
||||
+ -I. \
|
||||
+ -I$(top_builddir) \
|
||||
+ -I$(shell $(OCAMLC) -where) \
|
||||
+ -I$(top_srcdir)/lib
|
||||
+tools_messages_tests_BOBJECTS = tools_messages_tests.cmo
|
||||
+tools_messages_tests_XOBJECTS = $(tools_messages_tests_BOBJECTS:.cmo=.cmx)
|
||||
+
|
||||
# Can't call the following as <test>_OBJECTS because automake gets confused.
|
||||
if !HAVE_OCAMLOPT
|
||||
tools_utils_tests_THEOBJECTS = $(tools_utils_tests_BOBJECTS)
|
||||
@@ -212,6 +223,9 @@ JSON_parser_tests.cmo: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
|
||||
machine_readable_tests_THEOBJECTS = $(machine_readable_tests_BOBJECTS)
|
||||
machine_readable_tests.cmo: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
+
|
||||
+tools_messages_tests_THEOBJECTS = $(tools_messages_tests_tests_BOBJECTS)
|
||||
+tools_messages_tests.cmo: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
else
|
||||
tools_utils_tests_THEOBJECTS = $(tools_utils_tests_XOBJECTS)
|
||||
tools_utils_tests.cmx: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
@@ -227,6 +241,9 @@ JSON_parser_tests.cmx: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
|
||||
machine_readable_tests_THEOBJECTS = $(machine_readable_tests_XOBJECTS)
|
||||
machine_readable_tests.cmx: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
+
|
||||
+tools_messages_tests_THEOBJECTS = $(tools_messages_tests_XOBJECTS)
|
||||
+tools_messages_tests.cmx: OCAMLPACKAGES += $(OCAMLPACKAGES_TESTS)
|
||||
endif
|
||||
|
||||
OCAMLLINKFLAGS = \
|
||||
@@ -302,14 +319,32 @@ machine_readable_tests_LINK = \
|
||||
$(OCAMLPACKAGES) $(OCAMLPACKAGES_TESTS) \
|
||||
$(machine_readable_tests_THEOBJECTS) -o $@
|
||||
|
||||
+tools_messages_tests_DEPENDENCIES = \
|
||||
+ $(tools_messages_tests_THEOBJECTS) \
|
||||
+ ../mlstdutils/mlstdutils.$(MLARCHIVE) \
|
||||
+ ../mlgettext/mlgettext.$(MLARCHIVE) \
|
||||
+ ../mlpcre/mlpcre.$(MLARCHIVE) \
|
||||
+ $(MLTOOLS_CMA) \
|
||||
+ $(top_srcdir)/ocaml-link.sh
|
||||
+tools_messages_tests_LINK = \
|
||||
+ $(top_srcdir)/ocaml-link.sh -cclib '-lutils -lgnu' -- \
|
||||
+ $(OCAMLFIND) $(BEST) $(OCAMLFLAGS) $(OCAMLLINKFLAGS) \
|
||||
+ $(OCAMLPACKAGES) $(OCAMLPACKAGES_TESTS) \
|
||||
+ $(tools_messages_tests_THEOBJECTS) -o $@
|
||||
+
|
||||
TESTS_ENVIRONMENT = $(top_builddir)/run --test
|
||||
|
||||
TESTS = \
|
||||
test-getopt.sh \
|
||||
test-machine-readable.sh
|
||||
+if HAVE_PYTHON
|
||||
+TESTS += \
|
||||
+ test-tools-messages.sh
|
||||
+endif
|
||||
check_PROGRAMS = \
|
||||
getopt_tests \
|
||||
- machine_readable_tests
|
||||
+ machine_readable_tests \
|
||||
+ tools_messages_tests
|
||||
|
||||
if HAVE_OCAML_PKG_OUNIT
|
||||
check_PROGRAMS += JSON_tests JSON_parser_tests tools_utils_tests
|
||||
diff --git a/common/mltools/parse_tools_messages_test.py b/common/mltools/parse_tools_messages_test.py
|
||||
new file mode 100644
|
||||
index 000000000..9dcd6cae6
|
||||
--- /dev/null
|
||||
+++ b/common/mltools/parse_tools_messages_test.py
|
||||
@@ -0,0 +1,118 @@
|
||||
+# Copyright (C) 2019 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.
|
||||
+
|
||||
+import datetime
|
||||
+import json
|
||||
+import os
|
||||
+import sys
|
||||
+import unittest
|
||||
+
|
||||
+exe = "tools_messages_tests"
|
||||
+
|
||||
+if sys.version_info >= (3, 4):
|
||||
+ def set_fd_inheritable(fd):
|
||||
+ os.set_inheritable(fd, True)
|
||||
+else:
|
||||
+ def set_fd_inheritable(fd):
|
||||
+ pass
|
||||
+
|
||||
+
|
||||
+if sys.version_info >= (3, 0):
|
||||
+ def fdopen(fd, mode):
|
||||
+ return open(fd, mode)
|
||||
+
|
||||
+ def isModuleInstalled(mod):
|
||||
+ import importlib
|
||||
+ return bool(importlib.util.find_spec(mod))
|
||||
+else:
|
||||
+ def fdopen(fd, mode):
|
||||
+ return os.fdopen(fd, mode)
|
||||
+
|
||||
+ def isModuleInstalled(mod):
|
||||
+ import imp
|
||||
+ try:
|
||||
+ imp.find_module(mod)
|
||||
+ return True
|
||||
+ except ImportError:
|
||||
+ return False
|
||||
+
|
||||
+
|
||||
+def skipUnlessHasModule(mod):
|
||||
+ if not isModuleInstalled(mod):
|
||||
+ return unittest.skip("%s not available" % mod)
|
||||
+ return lambda func: func
|
||||
+
|
||||
+
|
||||
+def iterload(stream):
|
||||
+ dec = json.JSONDecoder()
|
||||
+ for line in stream:
|
||||
+ yield dec.raw_decode(line)
|
||||
+
|
||||
+
|
||||
+def loadJsonFromCommand(extraargs):
|
||||
+ r, w = os.pipe()
|
||||
+ set_fd_inheritable(r)
|
||||
+ r = fdopen(r, "r")
|
||||
+ set_fd_inheritable(w)
|
||||
+ w = fdopen(w, "w")
|
||||
+ pid = os.fork()
|
||||
+ if pid:
|
||||
+ w.close()
|
||||
+ l = list(iterload(r))
|
||||
+ l = [o[0] for o in l]
|
||||
+ r.close()
|
||||
+ return l
|
||||
+ else:
|
||||
+ r.close()
|
||||
+ args = ["tools_messages_tests",
|
||||
+ "--machine-readable=fd:%d" % w.fileno()] + extraargs
|
||||
+ os.execvp("./" + exe, args)
|
||||
+
|
||||
+
|
||||
+@skipUnlessHasModule('iso8601')
|
||||
+class TestParseToolsMessages(unittest.TestCase):
|
||||
+ def check_json(self, json, typ, msg):
|
||||
+ import iso8601
|
||||
+ # Check the type.
|
||||
+ jsontype = json.pop("type")
|
||||
+ self.assertEqual(jsontype, typ)
|
||||
+ # Check the message.
|
||||
+ jsonmsg = json.pop("message")
|
||||
+ self.assertEqual(jsonmsg, msg)
|
||||
+ # Check the timestamp.
|
||||
+ jsonts = json.pop("timestamp")
|
||||
+ dt = iso8601.parse_date(jsonts)
|
||||
+ now = datetime.datetime.now(dt.tzinfo)
|
||||
+ self.assertGreater(now, dt)
|
||||
+ # Check there are no more keys left (and thus not previously tested).
|
||||
+ self.assertEqual(len(json), 0)
|
||||
+
|
||||
+ def test_messages(self):
|
||||
+ objects = loadJsonFromCommand([])
|
||||
+ self.assertEqual(len(objects), 4)
|
||||
+ self.check_json(objects[0], "message", "Starting")
|
||||
+ self.check_json(objects[1], "info", "An information message")
|
||||
+ self.check_json(objects[2], "warning", "Warning: message here")
|
||||
+ self.check_json(objects[3], "message", "Finishing")
|
||||
+
|
||||
+ def test_error(self):
|
||||
+ objects = loadJsonFromCommand(["--error"])
|
||||
+ self.assertEqual(len(objects), 1)
|
||||
+ self.check_json(objects[0], "error", "Error!")
|
||||
+
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ unittest.main()
|
||||
diff --git a/common/mltools/test-tools-messages.sh b/common/mltools/test-tools-messages.sh
|
||||
new file mode 100755
|
||||
index 000000000..0e24d6ce9
|
||||
--- /dev/null
|
||||
+++ b/common/mltools/test-tools-messages.sh
|
||||
@@ -0,0 +1,28 @@
|
||||
+#!/bin/bash -
|
||||
+# libguestfs
|
||||
+# Copyright (C) 2019 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.
|
||||
+
|
||||
+# Test the --machine-readable functionality of the module Tools_utils.
|
||||
+# See also: machine_readable_tests.ml
|
||||
+
|
||||
+set -e
|
||||
+set -x
|
||||
+
|
||||
+$TEST_FUNCTIONS
|
||||
+skip_if_skipped
|
||||
+
|
||||
+$PYTHON parse_tools_messages_test.py
|
||||
diff --git a/common/mltools/tools_messages_tests.ml b/common/mltools/tools_messages_tests.ml
|
||||
new file mode 100644
|
||||
index 000000000..d5f9be89b
|
||||
--- /dev/null
|
||||
+++ b/common/mltools/tools_messages_tests.ml
|
||||
@@ -0,0 +1,46 @@
|
||||
+(*
|
||||
+ * Copyright (C) 2019 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.
|
||||
+ *)
|
||||
+
|
||||
+(* Test the message output for tools of the module Tools_utils.
|
||||
+ * The tests are controlled by the test-tools-messages.sh script.
|
||||
+ *)
|
||||
+
|
||||
+open Printf
|
||||
+
|
||||
+open Std_utils
|
||||
+open Tools_utils
|
||||
+open Getopt.OptionName
|
||||
+
|
||||
+let is_error = ref false
|
||||
+
|
||||
+let args = [
|
||||
+ [ L "error" ], Getopt.Set is_error, "Only print the error";
|
||||
+]
|
||||
+let usage_msg = sprintf "%s: test the message outputs" prog
|
||||
+
|
||||
+let opthandle = create_standard_options args ~machine_readable:true usage_msg
|
||||
+let () =
|
||||
+ Getopt.parse opthandle.getopt;
|
||||
+
|
||||
+ if !is_error then
|
||||
+ error "Error!";
|
||||
+
|
||||
+ message "Starting";
|
||||
+ info "An information message";
|
||||
+ warning "Warning: message here";
|
||||
+ message "Finishing"
|
||||
diff --git a/common/mltools/tools_utils-c.c b/common/mltools/tools_utils-c.c
|
||||
index c88c95082..b015dcace 100644
|
||||
--- a/common/mltools/tools_utils-c.c
|
||||
+++ b/common/mltools/tools_utils-c.c
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
+#include <time.h>
|
||||
+#include <string.h>
|
||||
|
||||
#include <caml/alloc.h>
|
||||
#include <caml/fail.h>
|
||||
@@ -37,6 +39,7 @@
|
||||
extern value guestfs_int_mllib_inspect_decrypt (value gv, value gpv, value keysv);
|
||||
extern value guestfs_int_mllib_set_echo_keys (value unitv);
|
||||
extern value guestfs_int_mllib_set_keys_from_stdin (value unitv);
|
||||
+extern value guestfs_int_mllib_rfc3999_date_time_string (value unitv);
|
||||
|
||||
/* Interface with the guestfish inspection and decryption code. */
|
||||
int echo_keys = 0;
|
||||
@@ -103,3 +106,51 @@ guestfs_int_mllib_set_keys_from_stdin (value unitv)
|
||||
keys_from_stdin = 1;
|
||||
return Val_unit;
|
||||
}
|
||||
+
|
||||
+value
|
||||
+guestfs_int_mllib_rfc3999_date_time_string (value unitv)
|
||||
+{
|
||||
+ CAMLparam1 (unitv);
|
||||
+ char buf[64];
|
||||
+ struct timespec ts;
|
||||
+ struct tm tm;
|
||||
+ size_t ret;
|
||||
+ size_t total = 0;
|
||||
+
|
||||
+ if (clock_gettime (CLOCK_REALTIME, &ts) == -1)
|
||||
+ unix_error (errno, (char *) "clock_gettime", Val_unit);
|
||||
+
|
||||
+ if (localtime_r (&ts.tv_sec, &tm) == NULL)
|
||||
+ unix_error (errno, (char *) "localtime_r", caml_copy_int64 (ts.tv_sec));
|
||||
+
|
||||
+ /* Sadly strftime does not support nanoseconds, so what we do is:
|
||||
+ * - stringify everything before the nanoseconds
|
||||
+ * - print the nanoseconds
|
||||
+ * - stringify the rest (i.e. the timezone)
|
||||
+ * then place ':' between the hours, and the minutes of the
|
||||
+ * timezone offset.
|
||||
+ */
|
||||
+
|
||||
+ ret = strftime (buf, sizeof (buf), "%Y-%m-%dT%H:%M:%S.", &tm);
|
||||
+ if (ret == 0)
|
||||
+ unix_error (errno, (char *) "strftime", Val_unit);
|
||||
+ total += ret;
|
||||
+
|
||||
+ ret = snprintf (buf + total, sizeof (buf) - total, "%09ld", ts.tv_nsec);
|
||||
+ if (ret == 0)
|
||||
+ unix_error (errno, (char *) "sprintf", caml_copy_int64 (ts.tv_nsec));
|
||||
+ total += ret;
|
||||
+
|
||||
+ ret = strftime (buf + total, sizeof (buf) - total, "%z", &tm);
|
||||
+ if (ret == 0)
|
||||
+ unix_error (errno, (char *) "strftime", Val_unit);
|
||||
+ total += ret;
|
||||
+
|
||||
+ /* Move the timezone minutes one character to the right, moving the
|
||||
+ * null character too.
|
||||
+ */
|
||||
+ memmove (buf + total - 1, buf + total - 2, 3);
|
||||
+ buf[total - 2] = ':';
|
||||
+
|
||||
+ CAMLreturn (caml_copy_string (buf));
|
||||
+}
|
||||
diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml
|
||||
index 35478f39e..de42df600 100644
|
||||
--- a/common/mltools/tools_utils.ml
|
||||
+++ b/common/mltools/tools_utils.ml
|
||||
@@ -32,6 +32,7 @@ and key_store_key =
|
||||
external c_inspect_decrypt : Guestfs.t -> int64 -> (string * key_store_key) list -> unit = "guestfs_int_mllib_inspect_decrypt"
|
||||
external c_set_echo_keys : unit -> unit = "guestfs_int_mllib_set_echo_keys" "noalloc"
|
||||
external c_set_keys_from_stdin : unit -> unit = "guestfs_int_mllib_set_keys_from_stdin" "noalloc"
|
||||
+external c_rfc3999_date_time_string : unit -> string = "guestfs_int_mllib_rfc3999_date_time_string"
|
||||
|
||||
type machine_readable_fn = {
|
||||
pr : 'a. ('a, unit, string, unit) format4 -> 'a;
|
||||
@@ -86,12 +87,24 @@ let ansi_magenta ?(chan = stdout) () =
|
||||
let ansi_restore ?(chan = stdout) () =
|
||||
if colours () || istty chan then output_string chan "\x1b[0m"
|
||||
|
||||
+let log_as_json msgtype msg =
|
||||
+ match machine_readable () with
|
||||
+ | None -> ()
|
||||
+ | Some { pr } ->
|
||||
+ let json = [
|
||||
+ "message", JSON.String msg;
|
||||
+ "timestamp", JSON.String (c_rfc3999_date_time_string ());
|
||||
+ "type", JSON.String msgtype;
|
||||
+ ] in
|
||||
+ pr "%s\n" (JSON.string_of_doc ~fmt:JSON.Compact json)
|
||||
+
|
||||
(* Timestamped progress messages, used for ordinary messages when not
|
||||
* --quiet.
|
||||
*)
|
||||
let start_t = Unix.gettimeofday ()
|
||||
let message fs =
|
||||
let display str =
|
||||
+ log_as_json "message" str;
|
||||
if not (quiet ()) then (
|
||||
let t = sprintf "%.1f" (Unix.gettimeofday () -. start_t) in
|
||||
printf "[%6s] " t;
|
||||
@@ -106,6 +119,7 @@ let message fs =
|
||||
(* Error messages etc. *)
|
||||
let error ?(exit_code = 1) fs =
|
||||
let display str =
|
||||
+ log_as_json "error" str;
|
||||
let chan = stderr in
|
||||
ansi_red ~chan ();
|
||||
wrap ~chan (sprintf (f_"%s: error: %s") prog str);
|
||||
@@ -124,6 +138,7 @@ let error ?(exit_code = 1) fs =
|
||||
|
||||
let warning fs =
|
||||
let display str =
|
||||
+ log_as_json "warning" str;
|
||||
let chan = stdout in
|
||||
ansi_blue ~chan ();
|
||||
wrap ~chan (sprintf (f_"%s: warning: %s") prog str);
|
||||
@@ -134,6 +149,7 @@ let warning fs =
|
||||
|
||||
let info fs =
|
||||
let display str =
|
||||
+ log_as_json "info" str;
|
||||
let chan = stdout in
|
||||
ansi_magenta ~chan ();
|
||||
wrap ~chan (sprintf (f_"%s: %s") prog str);
|
||||
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
|
||||
index f11028466..3c1d635c5 100644
|
||||
--- a/lib/guestfs.pod
|
||||
+++ b/lib/guestfs.pod
|
||||
@@ -3279,6 +3279,25 @@ Some of the tools support a I<--machine-readable> option, which is
|
||||
generally used to make the output more machine friendly, for easier
|
||||
parsing for example. By default, this output goes to stdout.
|
||||
|
||||
+When using the I<--machine-readable> option, the progress,
|
||||
+information, warning, and error messages are also printed in JSON
|
||||
+format for easier log tracking. Thus, it is highly recommended to
|
||||
+redirect the machine-readable output to a different stream. The
|
||||
+format of these JSON messages is like the following (actually printed
|
||||
+within a single line, below it is indented for readability):
|
||||
+
|
||||
+ {
|
||||
+ "message": "Finishing off",
|
||||
+ "timestamp": "2019-03-22T14:46:49.067294446+01:00",
|
||||
+ "type": "message"
|
||||
+ }
|
||||
+
|
||||
+C<type> can be: C<message> for progress messages, C<info> for
|
||||
+information messages, C<warning> for warning messages, and C<error>
|
||||
+for error message.
|
||||
+C<timestamp> is the L<RFC 3999|https://www.ietf.org/rfc/rfc3339.txt>
|
||||
+timestamp of the message.
|
||||
+
|
||||
In addition to that, a subset of these tools support an extra string
|
||||
passed to the I<--machine-readable> option: this string specifies
|
||||
where the machine-readable output will go.
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,77 +0,0 @@
|
||||
From 1d6f775d8826915f9547c7dcac0fd10e702c3d80 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 1 Apr 2019 17:01:44 +0200
|
||||
Subject: [PATCH] OCaml tools: fix 3999 -> 3339 typo
|
||||
|
||||
RFC 3339 is the actual RFC for date/time strings.
|
||||
Typo found by Martin 'eagle eyes' Kletzander.
|
||||
|
||||
Fixes commit f79129b8dc92470e3a5597daf53c84038bd6859e.
|
||||
|
||||
(cherry picked from commit 1086599ad8eeb8be299d5ffbcb2efb1024ff9ab8)
|
||||
---
|
||||
common/mltools/tools_utils-c.c | 4 ++--
|
||||
common/mltools/tools_utils.ml | 4 ++--
|
||||
lib/guestfs.pod | 2 +-
|
||||
3 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/common/mltools/tools_utils-c.c b/common/mltools/tools_utils-c.c
|
||||
index b015dcace..3b80091c0 100644
|
||||
--- a/common/mltools/tools_utils-c.c
|
||||
+++ b/common/mltools/tools_utils-c.c
|
||||
@@ -39,7 +39,7 @@
|
||||
extern value guestfs_int_mllib_inspect_decrypt (value gv, value gpv, value keysv);
|
||||
extern value guestfs_int_mllib_set_echo_keys (value unitv);
|
||||
extern value guestfs_int_mllib_set_keys_from_stdin (value unitv);
|
||||
-extern value guestfs_int_mllib_rfc3999_date_time_string (value unitv);
|
||||
+extern value guestfs_int_mllib_rfc3339_date_time_string (value unitv);
|
||||
|
||||
/* Interface with the guestfish inspection and decryption code. */
|
||||
int echo_keys = 0;
|
||||
@@ -108,7 +108,7 @@ guestfs_int_mllib_set_keys_from_stdin (value unitv)
|
||||
}
|
||||
|
||||
value
|
||||
-guestfs_int_mllib_rfc3999_date_time_string (value unitv)
|
||||
+guestfs_int_mllib_rfc3339_date_time_string (value unitv)
|
||||
{
|
||||
CAMLparam1 (unitv);
|
||||
char buf[64];
|
||||
diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml
|
||||
index de42df600..127180225 100644
|
||||
--- a/common/mltools/tools_utils.ml
|
||||
+++ b/common/mltools/tools_utils.ml
|
||||
@@ -32,7 +32,7 @@ and key_store_key =
|
||||
external c_inspect_decrypt : Guestfs.t -> int64 -> (string * key_store_key) list -> unit = "guestfs_int_mllib_inspect_decrypt"
|
||||
external c_set_echo_keys : unit -> unit = "guestfs_int_mllib_set_echo_keys" "noalloc"
|
||||
external c_set_keys_from_stdin : unit -> unit = "guestfs_int_mllib_set_keys_from_stdin" "noalloc"
|
||||
-external c_rfc3999_date_time_string : unit -> string = "guestfs_int_mllib_rfc3999_date_time_string"
|
||||
+external c_rfc3339_date_time_string : unit -> string = "guestfs_int_mllib_rfc3339_date_time_string"
|
||||
|
||||
type machine_readable_fn = {
|
||||
pr : 'a. ('a, unit, string, unit) format4 -> 'a;
|
||||
@@ -93,7 +93,7 @@ let log_as_json msgtype msg =
|
||||
| Some { pr } ->
|
||||
let json = [
|
||||
"message", JSON.String msg;
|
||||
- "timestamp", JSON.String (c_rfc3999_date_time_string ());
|
||||
+ "timestamp", JSON.String (c_rfc3339_date_time_string ());
|
||||
"type", JSON.String msgtype;
|
||||
] in
|
||||
pr "%s\n" (JSON.string_of_doc ~fmt:JSON.Compact json)
|
||||
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
|
||||
index 3c1d635c5..af944ddb7 100644
|
||||
--- a/lib/guestfs.pod
|
||||
+++ b/lib/guestfs.pod
|
||||
@@ -3295,7 +3295,7 @@ within a single line, below it is indented for readability):
|
||||
C<type> can be: C<message> for progress messages, C<info> for
|
||||
information messages, C<warning> for warning messages, and C<error>
|
||||
for error message.
|
||||
-C<timestamp> is the L<RFC 3999|https://www.ietf.org/rfc/rfc3339.txt>
|
||||
+C<timestamp> is the L<RFC 3339|https://www.ietf.org/rfc/rfc3339.txt>
|
||||
timestamp of the message.
|
||||
|
||||
In addition to that, a subset of these tools support an extra string
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,31 +0,0 @@
|
||||
From ee414298417aa570df4f1c77a5d47672c2871629 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Thu, 18 Jul 2019 15:38:53 +0200
|
||||
Subject: [PATCH] v2v: remove extra nbdkit bit from documentation
|
||||
(RHBZ#1723305)
|
||||
|
||||
Since there is no more need to build nbdkit from sources, then there is
|
||||
no need to set $PATH with a custom build of nbdkit.
|
||||
|
||||
Followup of commit 0704d8eb0bcc8139886eb4291f75a3ca49a91e58.
|
||||
|
||||
(cherry picked from commit 6d251e3828ff94deac7589b5892df174430e01f9)
|
||||
---
|
||||
v2v/virt-v2v-input-vmware.pod | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/virt-v2v-input-vmware.pod b/v2v/virt-v2v-input-vmware.pod
|
||||
index b3ebda182..3acdd773e 100644
|
||||
--- a/v2v/virt-v2v-input-vmware.pod
|
||||
+++ b/v2v/virt-v2v-input-vmware.pod
|
||||
@@ -293,7 +293,6 @@ To import a particular guest from vCenter server or ESXi hypervisor,
|
||||
use a command like the following, substituting the URI, guest name and
|
||||
SSL thumbprint:
|
||||
|
||||
- $ export PATH=/path/to/nbdkit-1.1.x:$PATH
|
||||
$ virt-v2v \
|
||||
-ic 'vpx://root@vcenter.example.com/Datacenter/esxi?no_verify=1' \
|
||||
-it vddk \
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,49 +0,0 @@
|
||||
From f36bb1b9c44cda46afa1a34522202a5319fd0a5a Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 25 Jul 2019 14:52:42 +0100
|
||||
Subject: [PATCH] v2v: -i vmx: Use scp -T option if available to unbreak scp
|
||||
(RHBZ#1733168).
|
||||
|
||||
Tested using:
|
||||
|
||||
cd v2v
|
||||
LIBGUESTFS_BACKEND=direct ../run virt-v2v -i vmx -it ssh "ssh://localhost/$PWD/test-v2v-i-vmx-1.vmx" -o null -v -x
|
||||
|
||||
and manually examining the debug output.
|
||||
|
||||
Thanks: Ming Xie, Jakub Jelen.
|
||||
(cherry picked from commit 7692c31494f7b1d37e380eed9eb99c5952940dbf)
|
||||
---
|
||||
v2v/input_vmx.ml | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml
|
||||
index b169b2537..e3469308d 100644
|
||||
--- a/v2v/input_vmx.ml
|
||||
+++ b/v2v/input_vmx.ml
|
||||
@@ -61,6 +61,11 @@ let server_of_uri { Xml.uri_server } =
|
||||
let path_of_uri { Xml.uri_path } =
|
||||
match uri_path with None -> assert false | Some p -> p
|
||||
|
||||
+let scp_supports_T_option = lazy (
|
||||
+ let cmd = "LANG=C scp -T |& grep \"unknown option\"" in
|
||||
+ shell_command cmd <> 0
|
||||
+)
|
||||
+
|
||||
(* 'scp' a remote file into a temporary local file, returning the path
|
||||
* of the temporary local file.
|
||||
*)
|
||||
@@ -68,8 +73,9 @@ let scp_from_remote_to_temporary uri tmpdir filename =
|
||||
let localfile = tmpdir // filename in
|
||||
|
||||
let cmd =
|
||||
- sprintf "scp%s%s %s%s:%s %s"
|
||||
+ sprintf "scp%s%s%s %s%s:%s %s"
|
||||
(if verbose () then "" else " -q")
|
||||
+ (if Lazy.force scp_supports_T_option then " -T" else "")
|
||||
(match port_of_uri uri with
|
||||
| None -> ""
|
||||
| Some port -> sprintf " -P %d" port)
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,28 +0,0 @@
|
||||
From 9a9270b0156cf30d98c26eaffb8b12c98d0d9bf4 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 4 Jul 2019 15:51:25 +0100
|
||||
Subject: [PATCH] v2v: Allow Windows virtio ISO to be a block device as well as
|
||||
a regular file.
|
||||
|
||||
Thanks: Steven Rosenberg
|
||||
(cherry picked from commit c22a8b68fe5729d3a8907b41eef287cd9f3a55c0)
|
||||
---
|
||||
v2v/windows_virtio.ml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
|
||||
index 92bf3ec60..a6dc29f2c 100644
|
||||
--- a/v2v/windows_virtio.ml
|
||||
+++ b/v2v/windows_virtio.ml
|
||||
@@ -330,7 +330,7 @@ and copy_from_virtio_win g inspect srcdir destdir filter missing =
|
||||
) paths
|
||||
)
|
||||
)
|
||||
- else if is_regular_file virtio_win then (
|
||||
+ else if is_regular_file virtio_win || is_block_device virtio_win then (
|
||||
debug "windows: copy_from_virtio_win: guest tools source ISO %s" virtio_win;
|
||||
|
||||
try
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,46 +0,0 @@
|
||||
From c49492cf218f4e6c1e90979c8d50ce3557642c42 Mon Sep 17 00:00:00 2001
|
||||
From: Nir Soffer <nirsof@gmail.com>
|
||||
Date: Mon, 2 Sep 2019 17:45:13 +0100
|
||||
Subject: [PATCH] v2v: Set DISKTYPE=2 in RHV and VDSM meta files
|
||||
(RHBZ#1746699).
|
||||
|
||||
Added in virt-p2v commit:
|
||||
|
||||
commit e83b6f50af34ce650063ecc520bfabab400e8e73
|
||||
Author: Matthew Booth <mbooth@redhat.com>
|
||||
Date: Fri Mar 26 09:40:20 2010 +0000
|
||||
|
||||
Add export to RHEV
|
||||
|
||||
Allow guests to be written to a RHEV NFS export storage domain.
|
||||
|
||||
Add 'rhev' output method and -osd command-line option.
|
||||
Example command line:
|
||||
|
||||
virt-v2v -f virt-v2v.conf -ic 'esx://yellow.rhev.marston/' \
|
||||
-o rhev -osd blue:/export/export RHEL3-32
|
||||
|
||||
This will connect to an ESX server and write the guest 'RHEL3-32' to
|
||||
blue:/export/export, which is a pre-initialised RHEV export storage domain.
|
||||
|
||||
(cherry picked from commit fcfdbc9420b07e3003df38481afb9ccd22045e1a)
|
||||
---
|
||||
v2v/create_ovf.ml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
|
||||
index 91ff5198d..9aad5dd15 100644
|
||||
--- a/v2v/create_ovf.ml
|
||||
+++ b/v2v/create_ovf.ml
|
||||
@@ -501,7 +501,7 @@ let create_meta_files output_alloc sd_uuid image_uuids overlays =
|
||||
bpf "CTIME=%.0f\n" time;
|
||||
bpf "MTIME=%.0f\n" time;
|
||||
bpf "IMAGE=%s\n" image_uuid;
|
||||
- bpf "DISKTYPE=1\n";
|
||||
+ bpf "DISKTYPE=2\n";
|
||||
bpf "PUUID=00000000-0000-0000-0000-000000000000\n";
|
||||
bpf "LEGALITY=LEGAL\n";
|
||||
bpf "POOL_UUID=\n";
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,55 +0,0 @@
|
||||
From 1a601b248f347b2237ff458376a010eeb46d005d Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Erez <derez@redhat.com>
|
||||
Date: Mon, 18 Mar 2019 18:51:26 +0200
|
||||
Subject: [PATCH] v2v: rhv-upload-plugin - improve wait logic after finalize
|
||||
(RHBZ#1680361)
|
||||
|
||||
After invoking transfer_service.finalize, check operation status by
|
||||
examining DiskStatus. This is done instead of failing after a
|
||||
predefined timeout regardless the status.
|
||||
|
||||
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1680361
|
||||
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
|
||||
Tested-by: Ilanit Stein <istein@redhat.com>
|
||||
(cherry picked from commit eeabb3fdc7756887b53106f455a7b54309130637)
|
||||
---
|
||||
v2v/rhv-upload-plugin.py | 19 +++++++++++++------
|
||||
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
||||
index 2a950c5ed..4d61a089b 100644
|
||||
--- a/v2v/rhv-upload-plugin.py
|
||||
+++ b/v2v/rhv-upload-plugin.py
|
||||
@@ -523,16 +523,23 @@ def close(h):
|
||||
# waiting for the transfer object to cease to exist, which
|
||||
# falls through to the exception case and then we can
|
||||
# continue.
|
||||
- endt = time.time() + timeout
|
||||
+ disk_id = disk.id
|
||||
+ start = time.time()
|
||||
try:
|
||||
while True:
|
||||
time.sleep(1)
|
||||
- tmp = transfer_service.get()
|
||||
- if time.time() > endt:
|
||||
- raise RuntimeError("timed out waiting for transfer "
|
||||
- "to finalize")
|
||||
+ disk_service = h['disk_service']
|
||||
+ disk = disk_service.get()
|
||||
+ if disk.status == types.DiskStatus.LOCKED:
|
||||
+ if time.time() > start + timeout:
|
||||
+ raise RuntimeError("timed out waiting for transfer "
|
||||
+ "to finalize")
|
||||
+ continue
|
||||
+ if disk.status == types.DiskStatus.OK:
|
||||
+ debug("finalized after %s seconds" % (time.time() - start))
|
||||
+ break
|
||||
except sdk.NotFoundError:
|
||||
- pass
|
||||
+ raise RuntimeError("transfer failed: disk %s not found" % disk_id)
|
||||
|
||||
# Write the disk ID file. Only do this on successful completion.
|
||||
with builtins.open(params['diskid_file'], 'w') as fp:
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,61 +0,0 @@
|
||||
From fed5b4195b1b220e43964aa61d01634b307f09a4 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 15 Apr 2019 17:24:42 +0200
|
||||
Subject: [PATCH] v2v: -o rhv-upload: check whether the cluster exists
|
||||
|
||||
In the precheck script, check that the target cluster actually exists.
|
||||
This will avoid errors when creating the VM after the data copying.
|
||||
|
||||
(cherry picked from commit 05e559549dab75f17e147f4a4eafbac868a7aa5d)
|
||||
---
|
||||
v2v/rhv-upload-precheck.py | 10 ++++++++++
|
||||
v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py | 7 +++++++
|
||||
2 files changed, 17 insertions(+)
|
||||
|
||||
diff --git a/v2v/rhv-upload-precheck.py b/v2v/rhv-upload-precheck.py
|
||||
index 2798a29dd..b79f91b4a 100644
|
||||
--- a/v2v/rhv-upload-precheck.py
|
||||
+++ b/v2v/rhv-upload-precheck.py
|
||||
@@ -70,4 +70,14 @@ if len(vms) > 0:
|
||||
raise RuntimeError("VM already exists with name ‘%s’, id ‘%s’" %
|
||||
(params['output_name'], vm.id))
|
||||
|
||||
+# Check whether the specified cluster exists.
|
||||
+clusters_service = system_service.clusters_service()
|
||||
+clusters = clusters_service.list(
|
||||
+ search='name=%s' % params['rhv_cluster'],
|
||||
+ case_sensitive=True,
|
||||
+)
|
||||
+if len(clusters) == 0:
|
||||
+ raise RuntimeError("The cluster ‘%s’ does not exist" %
|
||||
+ (params['rhv_cluster']))
|
||||
+
|
||||
# Otherwise everything is OK, exit with no error.
|
||||
diff --git a/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py b/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py
|
||||
index 8d1058d67..cc4224ccd 100644
|
||||
--- a/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py
|
||||
+++ b/v2v/test-v2v-o-rhv-upload-module/ovirtsdk4/__init__.py
|
||||
@@ -39,6 +39,9 @@ class Connection(object):
|
||||
return SystemService()
|
||||
|
||||
class SystemService(object):
|
||||
+ def clusters_service(self):
|
||||
+ return ClustersService()
|
||||
+
|
||||
def data_centers_service(self):
|
||||
return DataCentersService()
|
||||
|
||||
@@ -54,6 +57,10 @@ class SystemService(object):
|
||||
def vms_service(self):
|
||||
return VmsService()
|
||||
|
||||
+class ClustersService(object):
|
||||
+ def list(self, search=None, case_sensitive=False):
|
||||
+ return ["Default"]
|
||||
+
|
||||
class DataCentersService(object):
|
||||
def list(self, search=None, case_sensitive=False):
|
||||
return []
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,264 +0,0 @@
|
||||
From fb5e3592a94b535abe686b65e51577ad0e36fcd0 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Thu, 12 Sep 2019 13:19:48 +0200
|
||||
Subject: [PATCH] v2v: -o rhv-upload: split vmcheck out of precheck
|
||||
|
||||
Split the VM existance check out of the precheck script to a new vmcheck
|
||||
script, and invoke that in #prepare_targets. Invoke the precheck script
|
||||
in #precheck, as now it can be run with only values of command line
|
||||
options.
|
||||
|
||||
This does not change which checks are performed; however, an invalid
|
||||
cluster name will make virt-v2v fail way earlier (even before connecting
|
||||
to the source).
|
||||
|
||||
(cherry picked from commit 6499fdc199790619745eee28fcae3421c32c4735)
|
||||
---
|
||||
v2v/Makefile.am | 8 ++-
|
||||
v2v/output_rhv_upload.ml | 14 +++--
|
||||
v2v/output_rhv_upload_precheck_source.mli | 2 +-
|
||||
v2v/output_rhv_upload_vmcheck_source.mli | 19 ++++++
|
||||
v2v/rhv-upload-precheck.py | 12 +---
|
||||
v2v/rhv-upload-vmcheck.py | 73 +++++++++++++++++++++++
|
||||
6 files changed, 111 insertions(+), 17 deletions(-)
|
||||
create mode 100644 v2v/output_rhv_upload_vmcheck_source.mli
|
||||
create mode 100644 v2v/rhv-upload-vmcheck.py
|
||||
|
||||
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
|
||||
index 53c137fc6..30f040d3e 100644
|
||||
--- a/v2v/Makefile.am
|
||||
+++ b/v2v/Makefile.am
|
||||
@@ -26,7 +26,8 @@ BUILT_SOURCES = \
|
||||
config.ml \
|
||||
output_rhv_upload_createvm_source.ml \
|
||||
output_rhv_upload_plugin_source.ml \
|
||||
- output_rhv_upload_precheck_source.ml
|
||||
+ output_rhv_upload_precheck_source.ml \
|
||||
+ output_rhv_upload_vmcheck_source.ml
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(SOURCES_MLI) $(SOURCES_ML) $(SOURCES_C) \
|
||||
@@ -36,6 +37,7 @@ EXTRA_DIST = \
|
||||
rhv-upload-createvm.py \
|
||||
rhv-upload-plugin.py \
|
||||
rhv-upload-precheck.py \
|
||||
+ rhv-upload-vmcheck.py \
|
||||
v2v_unit_tests.ml \
|
||||
virt-v2v.pod \
|
||||
virt-v2v-copy-to-local.pod \
|
||||
@@ -87,6 +89,7 @@ SOURCES_MLI = \
|
||||
output_rhv_upload_createvm_source.mli \
|
||||
output_rhv_upload_plugin_source.mli \
|
||||
output_rhv_upload_precheck_source.mli \
|
||||
+ output_rhv_upload_vmcheck_source.mli \
|
||||
output_vdsm.mli \
|
||||
parse_ova.mli \
|
||||
parse_ovf_from_ova.mli \
|
||||
@@ -152,6 +155,7 @@ SOURCES_ML = \
|
||||
output_rhv_upload_createvm_source.ml \
|
||||
output_rhv_upload_plugin_source.ml \
|
||||
output_rhv_upload_precheck_source.ml \
|
||||
+ output_rhv_upload_vmcheck_source.ml \
|
||||
output_rhv_upload.ml \
|
||||
output_vdsm.ml \
|
||||
output_openstack.ml \
|
||||
@@ -173,6 +177,8 @@ output_rhv_upload_plugin_source.ml: $(srcdir)/rhv-upload-plugin.py
|
||||
$(srcdir)/embed.sh code $^ $@
|
||||
output_rhv_upload_precheck_source.ml: $(srcdir)/rhv-upload-precheck.py
|
||||
$(srcdir)/embed.sh code $^ $@
|
||||
+output_rhv_upload_vmcheck_source.ml: $(srcdir)/rhv-upload-vmcheck.py
|
||||
+ $(srcdir)/embed.sh code $^ $@
|
||||
|
||||
if HAVE_OCAML
|
||||
|
||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||
index c2a5c72c7..adcbdf25f 100644
|
||||
--- a/v2v/output_rhv_upload.ml
|
||||
+++ b/v2v/output_rhv_upload.ml
|
||||
@@ -94,10 +94,13 @@ class output_rhv_upload output_alloc output_conn
|
||||
|
||||
let diskid_file_of_id id = tmpdir // sprintf "diskid.%d" id in
|
||||
|
||||
- (* Create Python scripts for precheck, plugin and create VM. *)
|
||||
+ (* Create Python scripts for precheck, vmcheck, plugin and create VM. *)
|
||||
let precheck_script =
|
||||
Python_script.create ~name:"rhv-upload-precheck.py"
|
||||
Output_rhv_upload_precheck_source.code in
|
||||
+ let vmcheck_script =
|
||||
+ Python_script.create ~name:"rhv-upload-vmcheck.py"
|
||||
+ Output_rhv_upload_vmcheck_source.code in
|
||||
let plugin_script =
|
||||
Python_script.create ~name:"rhv-upload-plugin.py"
|
||||
Output_rhv_upload_plugin_source.code in
|
||||
@@ -230,6 +233,9 @@ object
|
||||
error_unless_nbdkit_working ();
|
||||
error_unless_nbdkit_python_plugin_working ();
|
||||
error_unless_output_alloc_sparse ();
|
||||
+ (* Python code prechecks. *)
|
||||
+ if Python_script.run_command precheck_script json_params [] <> 0 then
|
||||
+ error (f_"failed server prechecks, see earlier errors");
|
||||
if have_selinux then
|
||||
error_unless_nbdkit_compiled_with_selinux ()
|
||||
|
||||
@@ -251,11 +257,11 @@ object
|
||||
let json_params =
|
||||
("output_name", JSON.String output_name) :: json_params in
|
||||
|
||||
- (* Python code prechecks. These can't run in #precheck because
|
||||
+ (* Check that the VM does not exist. This can't run in #precheck because
|
||||
* we need to know the name of the virtual machine.
|
||||
*)
|
||||
- if Python_script.run_command precheck_script json_params [] <> 0 then
|
||||
- error (f_"failed server prechecks, see earlier errors");
|
||||
+ if Python_script.run_command vmcheck_script json_params [] <> 0 then
|
||||
+ error (f_"failed vmchecks, see earlier errors");
|
||||
|
||||
(* Create an nbdkit instance for each disk and set the
|
||||
* target URI to point to the NBD socket.
|
||||
diff --git a/v2v/output_rhv_upload_precheck_source.mli b/v2v/output_rhv_upload_precheck_source.mli
|
||||
index c1bafa15b..aa33bc548 100644
|
||||
--- a/v2v/output_rhv_upload_precheck_source.mli
|
||||
+++ b/v2v/output_rhv_upload_precheck_source.mli
|
||||
@@ -1,5 +1,5 @@
|
||||
(* virt-v2v
|
||||
- * Copyright (C) 2018 Red Hat Inc.
|
||||
+ * Copyright (C) 2019 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
|
||||
diff --git a/v2v/output_rhv_upload_vmcheck_source.mli b/v2v/output_rhv_upload_vmcheck_source.mli
|
||||
new file mode 100644
|
||||
index 000000000..c1bafa15b
|
||||
--- /dev/null
|
||||
+++ b/v2v/output_rhv_upload_vmcheck_source.mli
|
||||
@@ -0,0 +1,19 @@
|
||||
+(* virt-v2v
|
||||
+ * Copyright (C) 2018 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.
|
||||
+ *)
|
||||
+
|
||||
+val code : string
|
||||
diff --git a/v2v/rhv-upload-precheck.py b/v2v/rhv-upload-precheck.py
|
||||
index b79f91b4a..d6a58f0fc 100644
|
||||
--- a/v2v/rhv-upload-precheck.py
|
||||
+++ b/v2v/rhv-upload-precheck.py
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- python -*-
|
||||
# oVirt or RHV pre-upload checks used by ‘virt-v2v -o rhv-upload’
|
||||
-# Copyright (C) 2018 Red Hat Inc.
|
||||
+# Copyright (C) 2018-2019 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
|
||||
@@ -60,16 +60,6 @@ connection = sdk.Connection(
|
||||
|
||||
system_service = connection.system_service()
|
||||
|
||||
-# Find if a virtual machine already exists with that name.
|
||||
-vms_service = system_service.vms_service()
|
||||
-vms = vms_service.list(
|
||||
- search = ("name=%s" % params['output_name']),
|
||||
-)
|
||||
-if len(vms) > 0:
|
||||
- vm = vms[0]
|
||||
- raise RuntimeError("VM already exists with name ‘%s’, id ‘%s’" %
|
||||
- (params['output_name'], vm.id))
|
||||
-
|
||||
# Check whether the specified cluster exists.
|
||||
clusters_service = system_service.clusters_service()
|
||||
clusters = clusters_service.list(
|
||||
diff --git a/v2v/rhv-upload-vmcheck.py b/v2v/rhv-upload-vmcheck.py
|
||||
new file mode 100644
|
||||
index 000000000..fbb884b94
|
||||
--- /dev/null
|
||||
+++ b/v2v/rhv-upload-vmcheck.py
|
||||
@@ -0,0 +1,73 @@
|
||||
+# -*- python -*-
|
||||
+# oVirt or RHV VM existance check used by ‘virt-v2v -o rhv-upload’
|
||||
+# Copyright (C) 2018-2019 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.
|
||||
+
|
||||
+import json
|
||||
+import logging
|
||||
+import sys
|
||||
+import time
|
||||
+
|
||||
+from http.client import HTTPSConnection
|
||||
+from urllib.parse import urlparse
|
||||
+
|
||||
+import ovirtsdk4 as sdk
|
||||
+import ovirtsdk4.types as types
|
||||
+
|
||||
+# Parameters are passed in via a JSON doc from the OCaml code.
|
||||
+# Because this Python code ships embedded inside virt-v2v there
|
||||
+# is no formal API here.
|
||||
+params = None
|
||||
+
|
||||
+if len(sys.argv) != 2:
|
||||
+ raise RuntimeError("incorrect number of parameters")
|
||||
+
|
||||
+# Parameters are passed in via a JSON document.
|
||||
+with open(sys.argv[1], 'r') as fp:
|
||||
+ params = json.load(fp)
|
||||
+
|
||||
+# What is passed in is a password file, read the actual password.
|
||||
+with open(params['output_password'], 'r') as fp:
|
||||
+ output_password = fp.read()
|
||||
+output_password = output_password.rstrip()
|
||||
+
|
||||
+# Parse out the username from the output_conn URL.
|
||||
+parsed = urlparse(params['output_conn'])
|
||||
+username = parsed.username or "admin@internal"
|
||||
+
|
||||
+# Connect to the server.
|
||||
+connection = sdk.Connection(
|
||||
+ url = params['output_conn'],
|
||||
+ username = username,
|
||||
+ password = output_password,
|
||||
+ ca_file = params['rhv_cafile'],
|
||||
+ log = logging.getLogger(),
|
||||
+ insecure = params['insecure'],
|
||||
+)
|
||||
+
|
||||
+system_service = connection.system_service()
|
||||
+
|
||||
+# Find if a virtual machine already exists with that name.
|
||||
+vms_service = system_service.vms_service()
|
||||
+vms = vms_service.list(
|
||||
+ search = ("name=%s" % params['output_name']),
|
||||
+)
|
||||
+if len(vms) > 0:
|
||||
+ vm = vms[0]
|
||||
+ raise RuntimeError("VM already exists with name ‘%s’, id ‘%s’" %
|
||||
+ (params['output_name'], vm.id))
|
||||
+
|
||||
+# Otherwise everything is OK, exit with no error.
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,53 +0,0 @@
|
||||
From bb04eba9683c4143f9b5880238f006af3b13c05c Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Thu, 12 Sep 2019 14:17:36 +0200
|
||||
Subject: [PATCH] v2v: -o rhv-upload: change precheck script to return a JSON
|
||||
|
||||
This way it is possible to communicate data from the precheck script
|
||||
back to virt-v2v.
|
||||
|
||||
For now there are no results, so the resulting JSON is discarded.
|
||||
|
||||
(cherry picked from commit cc6e2a7f9ea53258c2edb758e3ec9beb7baa1fc6)
|
||||
---
|
||||
v2v/output_rhv_upload.ml | 8 +++++++-
|
||||
v2v/rhv-upload-precheck.py | 6 +++++-
|
||||
2 files changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||
index adcbdf25f..fd6f2e3e6 100644
|
||||
--- a/v2v/output_rhv_upload.ml
|
||||
+++ b/v2v/output_rhv_upload.ml
|
||||
@@ -234,8 +234,14 @@ object
|
||||
error_unless_nbdkit_python_plugin_working ();
|
||||
error_unless_output_alloc_sparse ();
|
||||
(* Python code prechecks. *)
|
||||
- if Python_script.run_command precheck_script json_params [] <> 0 then
|
||||
+ let precheck_fn = tmpdir // "v2vprecheck.json" in
|
||||
+ let fd = Unix.openfile precheck_fn [O_WRONLY; O_CREAT] 0o600 in
|
||||
+ if Python_script.run_command ~stdout_fd:fd
|
||||
+ precheck_script json_params [] <> 0 then
|
||||
error (f_"failed server prechecks, see earlier errors");
|
||||
+ let json = JSON_parser.json_parser_tree_parse_file precheck_fn in
|
||||
+ debug "precheck output parsed as: %s"
|
||||
+ (JSON.string_of_doc ~fmt:JSON.Indented ["", json]);
|
||||
if have_selinux then
|
||||
error_unless_nbdkit_compiled_with_selinux ()
|
||||
|
||||
diff --git a/v2v/rhv-upload-precheck.py b/v2v/rhv-upload-precheck.py
|
||||
index d6a58f0fc..de8a66c05 100644
|
||||
--- a/v2v/rhv-upload-precheck.py
|
||||
+++ b/v2v/rhv-upload-precheck.py
|
||||
@@ -70,4 +70,8 @@ if len(clusters) == 0:
|
||||
raise RuntimeError("The cluster ‘%s’ does not exist" %
|
||||
(params['rhv_cluster']))
|
||||
|
||||
-# Otherwise everything is OK, exit with no error.
|
||||
+# Otherwise everything is OK, print a JSON with the results.
|
||||
+results = {
|
||||
+}
|
||||
+
|
||||
+json.dump(results, sys.stdout)
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,169 +0,0 @@
|
||||
From 07348a7d9a7533b11513706a91d8eb8b91ce8518 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Thu, 12 Sep 2019 15:21:26 +0200
|
||||
Subject: [PATCH] v2v: -o rhv-upload: improve lookup of specified resources
|
||||
(RHBZ#1612653)
|
||||
|
||||
Improve the way the precheck script checks for the specified resources:
|
||||
- look directly for a data center with the specified storage domain
|
||||
- get the storage domain object from the storage domains attached to the
|
||||
data center found
|
||||
- similarly, look for the specified cluster among the ones attached to
|
||||
the data center found
|
||||
When everything is found, return the UUID of the storage domain, and of
|
||||
the cluster back to virt-v2v, which will store them.
|
||||
|
||||
Similarly, rework the createvm script to directly get the requested
|
||||
cluster, instead of looking for it once again. Also, since the UUID of
|
||||
the storage domain is available in virt-v2v already, use it directly
|
||||
instead of using a placeholder.
|
||||
|
||||
This should fix a number of issues:
|
||||
- unexisting/unattached storage domains are rejected outright
|
||||
- the cluster is rejected if not part of the same data center of the
|
||||
selected storage domain
|
||||
- renaming the specified storage domain during the data copying will not
|
||||
cause the conversion to fail (which will still use the specified
|
||||
storage domain, no matter the new name)
|
||||
|
||||
Based on the hints by Daniel Erez in RHBZ#1612653.
|
||||
|
||||
(cherry picked from commit c49aa4fe01aac82d4776dd2a3524ce16e6deed06)
|
||||
---
|
||||
v2v/output_rhv_upload.ml | 24 +++++++++++++++++++-----
|
||||
v2v/rhv-upload-createvm.py | 11 ++++-------
|
||||
v2v/rhv-upload-precheck.py | 30 ++++++++++++++++++++++++------
|
||||
3 files changed, 47 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||
index fd6f2e3e6..19bdfcf05 100644
|
||||
--- a/v2v/output_rhv_upload.ml
|
||||
+++ b/v2v/output_rhv_upload.ml
|
||||
@@ -227,6 +227,11 @@ See also the virt-v2v-output-rhv(1) manual.")
|
||||
object
|
||||
inherit output
|
||||
|
||||
+ (* The storage domain UUID. *)
|
||||
+ val mutable rhv_storagedomain_uuid = None
|
||||
+ (* The cluster UUID. *)
|
||||
+ val mutable rhv_cluster_uuid = None
|
||||
+
|
||||
method precheck () =
|
||||
Python_script.error_unless_python_interpreter_found ();
|
||||
error_unless_ovirtsdk4_module_available ();
|
||||
@@ -242,6 +247,10 @@ object
|
||||
let json = JSON_parser.json_parser_tree_parse_file precheck_fn in
|
||||
debug "precheck output parsed as: %s"
|
||||
(JSON.string_of_doc ~fmt:JSON.Indented ["", json]);
|
||||
+ rhv_storagedomain_uuid <-
|
||||
+ Some (JSON_parser.object_get_string "rhv_storagedomain_uuid" json);
|
||||
+ rhv_cluster_uuid <-
|
||||
+ Some (JSON_parser.object_get_string "rhv_cluster_uuid" json);
|
||||
if have_selinux then
|
||||
error_unless_nbdkit_compiled_with_selinux ()
|
||||
|
||||
@@ -388,11 +397,11 @@ If the messages above are not sufficient to diagnose the problem then add the
|
||||
diskid
|
||||
) targets in
|
||||
|
||||
- (* We don't have the storage domain UUID, but instead we write
|
||||
- * in a magic value which the Python code (which can get it)
|
||||
- * will substitute.
|
||||
- *)
|
||||
- let sd_uuid = "@SD_UUID@" in
|
||||
+ (* The storage domain UUID. *)
|
||||
+ let sd_uuid =
|
||||
+ match rhv_storagedomain_uuid with
|
||||
+ | None -> assert false
|
||||
+ | Some uuid -> uuid in
|
||||
|
||||
(* The volume and VM UUIDs are made up. *)
|
||||
let vol_uuids = List.map (fun _ -> uuidgen ()) targets
|
||||
@@ -406,6 +415,11 @@ If the messages above are not sufficient to diagnose the problem then add the
|
||||
OVirt in
|
||||
let ovf = DOM.doc_to_string ovf in
|
||||
|
||||
+ let json_params =
|
||||
+ match rhv_cluster_uuid with
|
||||
+ | None -> assert false
|
||||
+ | Some uuid -> ("rhv_cluster_uuid", JSON.String uuid) :: json_params in
|
||||
+
|
||||
let ovf_file = tmpdir // "vm.ovf" in
|
||||
with_open_out ovf_file (fun chan -> output_string chan ovf);
|
||||
if Python_script.run_command createvm_script json_params [ovf_file] <> 0
|
||||
diff --git a/v2v/rhv-upload-createvm.py b/v2v/rhv-upload-createvm.py
|
||||
index 1d0e8c95d..ed57a9b20 100644
|
||||
--- a/v2v/rhv-upload-createvm.py
|
||||
+++ b/v2v/rhv-upload-createvm.py
|
||||
@@ -65,17 +65,14 @@ connection = sdk.Connection(
|
||||
|
||||
system_service = connection.system_service()
|
||||
|
||||
-# Get the storage domain UUID and substitute it into the OVF doc.
|
||||
-sds_service = system_service.storage_domains_service()
|
||||
-sd = sds_service.list(search=("name=%s" % params['output_storage']))[0]
|
||||
-sd_uuid = sd.id
|
||||
-
|
||||
-ovf = ovf.replace("@SD_UUID@", sd_uuid)
|
||||
+# Get the cluster.
|
||||
+cluster = system_service.clusters_service().cluster_service(params['rhv_cluster_uuid'])
|
||||
+cluster = cluster.get()
|
||||
|
||||
vms_service = system_service.vms_service()
|
||||
vm = vms_service.add(
|
||||
types.Vm(
|
||||
- cluster=types.Cluster(name = params['rhv_cluster']),
|
||||
+ cluster=cluster,
|
||||
initialization=types.Initialization(
|
||||
configuration = types.Configuration(
|
||||
type = types.ConfigurationType.OVA,
|
||||
diff --git a/v2v/rhv-upload-precheck.py b/v2v/rhv-upload-precheck.py
|
||||
index de8a66c05..725a8dc9e 100644
|
||||
--- a/v2v/rhv-upload-precheck.py
|
||||
+++ b/v2v/rhv-upload-precheck.py
|
||||
@@ -60,18 +60,36 @@ connection = sdk.Connection(
|
||||
|
||||
system_service = connection.system_service()
|
||||
|
||||
-# Check whether the specified cluster exists.
|
||||
-clusters_service = system_service.clusters_service()
|
||||
-clusters = clusters_service.list(
|
||||
- search='name=%s' % params['rhv_cluster'],
|
||||
+# Check whether there is a datacenter for the specified storage.
|
||||
+data_centers = system_service.data_centers_service().list(
|
||||
+ search='storage.name=%s' % params['output_storage'],
|
||||
case_sensitive=True,
|
||||
)
|
||||
+if len(data_centers) == 0:
|
||||
+ # The storage domain is not attached to a datacenter
|
||||
+ # (shouldn't happen, would fail on disk creation).
|
||||
+ raise RuntimeError("The storage domain ‘%s’ is not attached to a DC" %
|
||||
+ (params['output_storage']))
|
||||
+datacenter = data_centers[0]
|
||||
+
|
||||
+# Get the storage domain.
|
||||
+storage_domains = connection.follow_link(datacenter.storage_domains)
|
||||
+storage_domain = [sd for sd in storage_domains if sd.name == params['output_storage']][0]
|
||||
+
|
||||
+# Get the cluster.
|
||||
+clusters = connection.follow_link(datacenter.clusters)
|
||||
+clusters = [cluster for cluster in clusters if cluster.name == params['rhv_cluster']]
|
||||
if len(clusters) == 0:
|
||||
- raise RuntimeError("The cluster ‘%s’ does not exist" %
|
||||
- (params['rhv_cluster']))
|
||||
+ raise RuntimeError("The cluster ‘%s’ is not part of the DC ‘%s’, "
|
||||
+ "where the storage domain ‘%s’ is" %
|
||||
+ (params['rhv_cluster'], datacenter.name,
|
||||
+ params['output_storage']))
|
||||
+cluster = clusters[0]
|
||||
|
||||
# Otherwise everything is OK, print a JSON with the results.
|
||||
results = {
|
||||
+ "rhv_storagedomain_uuid": storage_domain.id,
|
||||
+ "rhv_cluster_uuid": cluster.id,
|
||||
}
|
||||
|
||||
json.dump(results, sys.stdout)
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,36 +0,0 @@
|
||||
From e7b94193f29d7a2715a860deb6db0708eef8c107 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 13 Sep 2019 12:40:34 +0200
|
||||
Subject: [PATCH] v2v: -o rhv-upload: tell whether a SD actually exists
|
||||
|
||||
If there is no DC with the specified storage domain attached to it, it
|
||||
can mean that the SD does not exist.
|
||||
|
||||
(cherry picked from commit 2b39c27b7f1e72f3a3bf3a616e4576af691beb88)
|
||||
---
|
||||
v2v/rhv-upload-precheck.py | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/v2v/rhv-upload-precheck.py b/v2v/rhv-upload-precheck.py
|
||||
index 725a8dc9e..1b344ba27 100644
|
||||
--- a/v2v/rhv-upload-precheck.py
|
||||
+++ b/v2v/rhv-upload-precheck.py
|
||||
@@ -66,6 +66,15 @@ data_centers = system_service.data_centers_service().list(
|
||||
case_sensitive=True,
|
||||
)
|
||||
if len(data_centers) == 0:
|
||||
+ storage_domains = system_service.storage_domains_service().list(
|
||||
+ search='name=%s' % params['output_storage'],
|
||||
+ case_sensitive=True,
|
||||
+ )
|
||||
+ if len(storage_domains) == 0:
|
||||
+ # The storage domain does not even exist.
|
||||
+ raise RuntimeError("The storage domain ‘%s’ does not exist" %
|
||||
+ (params['output_storage']))
|
||||
+
|
||||
# The storage domain is not attached to a datacenter
|
||||
# (shouldn't happen, would fail on disk creation).
|
||||
raise RuntimeError("The storage domain ‘%s’ is not attached to a DC" %
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,76 +0,0 @@
|
||||
From fbb0daf1ee29cda6d9117be2430c7d5d66463eca Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 16 Sep 2019 14:01:14 +0200
|
||||
Subject: [PATCH] v2v: add output#disk_copied hook
|
||||
|
||||
Add a simple method in the Output class to do work right after a disk
|
||||
was successfully copied.
|
||||
|
||||
(cherry picked from commit 74ee936505acf56d01f9b819588e7902a9401e81)
|
||||
---
|
||||
v2v/types.ml | 1 +
|
||||
v2v/types.mli | 8 ++++++++
|
||||
v2v/v2v.ml | 9 ++++++++-
|
||||
3 files changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/types.ml b/v2v/types.ml
|
||||
index 77f879200..714b30014 100644
|
||||
--- a/v2v/types.ml
|
||||
+++ b/v2v/types.ml
|
||||
@@ -521,6 +521,7 @@ class virtual output = object
|
||||
method override_output_format (_ : overlay) = (None : string option)
|
||||
method virtual prepare_targets : source -> (string * overlay) list -> target_buses -> guestcaps -> inspect -> target_firmware -> target_file list
|
||||
method disk_create = (open_guestfs ())#disk_create
|
||||
+ method disk_copied (_ : target) (_ : int) (_ : int) = ()
|
||||
method virtual create_metadata : source -> target list -> target_buses -> guestcaps -> inspect -> target_firmware -> unit
|
||||
method keep_serial_console = true
|
||||
method install_rhev_apt = false
|
||||
diff --git a/v2v/types.mli b/v2v/types.mli
|
||||
index be9406100..f595ab0ef 100644
|
||||
--- a/v2v/types.mli
|
||||
+++ b/v2v/types.mli
|
||||
@@ -441,6 +441,10 @@ end
|
||||
│ by running ‘qemu-img convert’.
|
||||
│
|
||||
▼
|
||||
+ output#disk_copied The output mode is notified about the
|
||||
+ │ successful copy of each disk.
|
||||
+ │
|
||||
+ ▼
|
||||
output#create_metadata VM should be created from the metadata
|
||||
supplied. Also any finalization can
|
||||
be done here.
|
||||
@@ -485,6 +489,10 @@ class virtual output : object
|
||||
(** Called in order to create disks on the target. The method has the
|
||||
same signature as Guestfs#disk_create. Normally you should {b not}
|
||||
define this since the default method calls Guestfs#disk_create. *)
|
||||
+ method disk_copied : target -> int -> int -> unit
|
||||
+ (** Called after a disk was successfully copied on the target.
|
||||
+ The second parameter is the index of the copied disk (starting
|
||||
+ from 0), and the third is the number of disks in total. *)
|
||||
method virtual create_metadata : source -> target list -> target_buses -> guestcaps -> inspect -> target_firmware -> unit
|
||||
(** Called after conversion and copying to create metadata and
|
||||
do any finalization. *)
|
||||
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
|
||||
index 277d8f2c7..63e809030 100644
|
||||
--- a/v2v/v2v.ml
|
||||
+++ b/v2v/v2v.ml
|
||||
@@ -798,7 +798,14 @@ and copy_targets cmdline targets input output =
|
||||
pc;
|
||||
if pc < 0. then eprintf " ! ESTIMATE TOO LOW !";
|
||||
eprintf "\n%!";
|
||||
- )
|
||||
+ );
|
||||
+
|
||||
+ (* Let the output mode know that the disk was copied successfully,
|
||||
+ * so it can perform any operations without waiting for all the
|
||||
+ * other disks to be copied (i.e. before the metadata is actually
|
||||
+ * created).
|
||||
+ *)
|
||||
+ output#disk_copied t i nr_disks
|
||||
) targets
|
||||
|
||||
(* Update the target_actual_size field in the target structure. *)
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,84 +0,0 @@
|
||||
From 8f8fbe96bfcb6f284590ddd17b960247ec87bde9 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 16 Sep 2019 14:07:22 +0200
|
||||
Subject: [PATCH] v2v: -o rhv-upload: collect disks UUIDs right after copy
|
||||
|
||||
Instead of waiting for the completion of the nbdkit transfers to get the
|
||||
UUIDs of the disks, use the new #disk_copied hook to do that after each
|
||||
disk is copied.
|
||||
|
||||
This has almost no behaviour on rhv-upload, except for the --no-copy
|
||||
mode:
|
||||
- previously it used to hit the 5 minute timeout while waiting for the
|
||||
finalization of the first disk
|
||||
- now it asserts on the different number of collected UUIDs vs the
|
||||
actual targets; at the moment there is nothing else that can be done,
|
||||
as this assumption is needed e.g. when creating the OVF file
|
||||
|
||||
(cherry picked from commit 7b93ad6a32f09043bf870202b59bea83d47e0c3a)
|
||||
---
|
||||
v2v/output_rhv_upload.ml | 32 ++++++++++++++++----------------
|
||||
1 file changed, 16 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||
index 19bdfcf05..382ad0d93 100644
|
||||
--- a/v2v/output_rhv_upload.ml
|
||||
+++ b/v2v/output_rhv_upload.ml
|
||||
@@ -231,6 +231,8 @@ object
|
||||
val mutable rhv_storagedomain_uuid = None
|
||||
(* The cluster UUID. *)
|
||||
val mutable rhv_cluster_uuid = None
|
||||
+ (* List of disk UUIDs. *)
|
||||
+ val mutable disks_uuids = []
|
||||
|
||||
method precheck () =
|
||||
Python_script.error_unless_python_interpreter_found ();
|
||||
@@ -379,23 +381,21 @@ If the messages above are not sufficient to diagnose the problem then add the
|
||||
TargetURI ("json:" ^ JSON.string_of_doc json_params)
|
||||
) overlays
|
||||
|
||||
- method create_metadata source targets _ guestcaps inspect target_firmware =
|
||||
- (* Get the UUIDs of each disk image. These files are written
|
||||
- * out by the nbdkit plugins on successful finalization of the
|
||||
+ method disk_copied t i nr_disks =
|
||||
+ (* Get the UUID of the disk image. This file is written
|
||||
+ * out by the nbdkit plugin on successful finalization of the
|
||||
* transfer.
|
||||
*)
|
||||
- let nr_disks = List.length targets in
|
||||
- let image_uuids =
|
||||
- List.mapi (
|
||||
- fun i t ->
|
||||
- let id = t.target_overlay.ov_source.s_disk_id in
|
||||
- let diskid_file = diskid_file_of_id id in
|
||||
- if not (wait_for_file diskid_file finalization_timeout) then
|
||||
- error (f_"transfer of disk %d/%d failed, see earlier error messages")
|
||||
- (i+1) nr_disks;
|
||||
- let diskid = read_whole_file diskid_file in
|
||||
- diskid
|
||||
- ) targets in
|
||||
+ let id = t.target_overlay.ov_source.s_disk_id in
|
||||
+ let diskid_file = diskid_file_of_id id in
|
||||
+ if not (wait_for_file diskid_file finalization_timeout) then
|
||||
+ error (f_"transfer of disk %d/%d failed, see earlier error messages")
|
||||
+ (i+1) nr_disks;
|
||||
+ let diskid = read_whole_file diskid_file in
|
||||
+ disks_uuids <- disks_uuids @ [diskid];
|
||||
+
|
||||
+ method create_metadata source targets _ guestcaps inspect target_firmware =
|
||||
+ assert (List.length disks_uuids = List.length targets);
|
||||
|
||||
(* The storage domain UUID. *)
|
||||
let sd_uuid =
|
||||
@@ -411,7 +411,7 @@ If the messages above are not sufficient to diagnose the problem then add the
|
||||
let ovf =
|
||||
Create_ovf.create_ovf source targets guestcaps inspect
|
||||
target_firmware output_alloc
|
||||
- sd_uuid image_uuids vol_uuids vm_uuid
|
||||
+ sd_uuid disks_uuids vol_uuids vm_uuid
|
||||
OVirt in
|
||||
let ovf = DOM.doc_to_string ovf in
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,201 +0,0 @@
|
||||
From 9d7b3e53fd4346bbb2abfb046df224de03f5b92f Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Thu, 19 Sep 2019 12:19:09 +0200
|
||||
Subject: [PATCH] v2v: -o rhv-upload: add -oo rhv-disk-uuid option
|
||||
|
||||
This way it is possible to override the UUIDs of the uploaded disks,
|
||||
instead of letting RHV generate them.
|
||||
|
||||
This can be useful to force certain UUIDs, and to specify the disks in
|
||||
--no-copy mode (which now can be used).
|
||||
|
||||
(cherry picked from commit 537ba8357e44ca3aa8878a2ac98e9476a570d3f4)
|
||||
---
|
||||
v2v/output_rhv_upload.ml | 43 ++++++++++++++++++++++++++++++++-----
|
||||
v2v/rhv-upload-plugin.py | 2 ++
|
||||
v2v/virt-v2v-output-rhv.pod | 24 +++++++++++++++++++++
|
||||
3 files changed, 64 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||
index 382ad0d93..206657a2b 100644
|
||||
--- a/v2v/output_rhv_upload.ml
|
||||
+++ b/v2v/output_rhv_upload.ml
|
||||
@@ -32,6 +32,7 @@ type rhv_options = {
|
||||
rhv_cluster : string option;
|
||||
rhv_direct : bool;
|
||||
rhv_verifypeer : bool;
|
||||
+ rhv_disk_uuids : string list option;
|
||||
}
|
||||
|
||||
let print_output_options () =
|
||||
@@ -41,6 +42,11 @@ let print_output_options () =
|
||||
-oo rhv-cluster=CLUSTERNAME Set RHV cluster name.
|
||||
-oo rhv-direct[=true|false] Use direct transfer mode (default: false).
|
||||
-oo rhv-verifypeer[=true|false] Verify server identity (default: false).
|
||||
+
|
||||
+You can override the UUIDs of the disks, instead of using autogenerated UUIDs
|
||||
+after their uploads (if you do, you must supply one for each disk):
|
||||
+
|
||||
+ -oo rhv-disk-uuid=UUID Disk UUID
|
||||
")
|
||||
|
||||
let parse_output_options options =
|
||||
@@ -48,6 +54,7 @@ let parse_output_options options =
|
||||
let rhv_cluster = ref None in
|
||||
let rhv_direct = ref false in
|
||||
let rhv_verifypeer = ref false in
|
||||
+ let rhv_disk_uuids = ref None in
|
||||
|
||||
List.iter (
|
||||
function
|
||||
@@ -63,6 +70,8 @@ let parse_output_options options =
|
||||
| "rhv-direct", v -> rhv_direct := bool_of_string v
|
||||
| "rhv-verifypeer", "" -> rhv_verifypeer := true
|
||||
| "rhv-verifypeer", v -> rhv_verifypeer := bool_of_string v
|
||||
+ | "rhv-disk-uuid", v ->
|
||||
+ rhv_disk_uuids := Some (v :: (Option.default [] !rhv_disk_uuids))
|
||||
| k, _ ->
|
||||
error (f_"-o rhv-upload: unknown output option ‘-oo %s’") k
|
||||
) options;
|
||||
@@ -75,8 +84,9 @@ let parse_output_options options =
|
||||
let rhv_cluster = !rhv_cluster in
|
||||
let rhv_direct = !rhv_direct in
|
||||
let rhv_verifypeer = !rhv_verifypeer in
|
||||
+ let rhv_disk_uuids = Option.map List.rev !rhv_disk_uuids in
|
||||
|
||||
- { rhv_cafile; rhv_cluster; rhv_direct; rhv_verifypeer }
|
||||
+ { rhv_cafile; rhv_cluster; rhv_direct; rhv_verifypeer; rhv_disk_uuids }
|
||||
|
||||
let nbdkit_python_plugin = Config.virt_v2v_nbdkit_python_plugin
|
||||
let pidfile_timeout = 30
|
||||
@@ -270,6 +280,16 @@ object
|
||||
method install_rhev_apt = true
|
||||
|
||||
method prepare_targets source overlays _ _ _ _ =
|
||||
+ let uuids =
|
||||
+ match rhv_options.rhv_disk_uuids with
|
||||
+ | None ->
|
||||
+ List.map (fun _ -> None) overlays
|
||||
+ | Some uuids ->
|
||||
+ if List.length uuids <> List.length overlays then
|
||||
+ error (f_"the number of ‘-oo rhv-disk-uuid’ parameters passed on the command line has to match the number of guest disk images (for this guest: %d)")
|
||||
+ (List.length overlays);
|
||||
+ List.map (fun uuid -> Some uuid) uuids in
|
||||
+
|
||||
let output_name = source.s_name in
|
||||
let json_params =
|
||||
("output_name", JSON.String output_name) :: json_params in
|
||||
@@ -284,7 +304,7 @@ object
|
||||
* target URI to point to the NBD socket.
|
||||
*)
|
||||
List.map (
|
||||
- fun (target_format, ov) ->
|
||||
+ fun ((target_format, ov), uuid) ->
|
||||
let id = ov.ov_source.s_disk_id in
|
||||
let disk_name = sprintf "%s-%03d" output_name id in
|
||||
let json_params =
|
||||
@@ -310,6 +330,12 @@ object
|
||||
let json_params =
|
||||
("diskid_file", JSON.String diskid_file) :: json_params in
|
||||
|
||||
+ let json_params =
|
||||
+ match uuid with
|
||||
+ | None -> json_params
|
||||
+ | Some uuid ->
|
||||
+ ("rhv_disk_uuid", JSON.String uuid) :: json_params in
|
||||
+
|
||||
(* Write the JSON parameters to a file. *)
|
||||
let json_param_file = tmpdir // sprintf "params%d.json" id in
|
||||
with_open_out
|
||||
@@ -379,7 +405,7 @@ If the messages above are not sufficient to diagnose the problem then add the
|
||||
"file.export", JSON.String "/";
|
||||
] in
|
||||
TargetURI ("json:" ^ JSON.string_of_doc json_params)
|
||||
- ) overlays
|
||||
+ ) (List.combine overlays uuids)
|
||||
|
||||
method disk_copied t i nr_disks =
|
||||
(* Get the UUID of the disk image. This file is written
|
||||
@@ -395,7 +421,14 @@ If the messages above are not sufficient to diagnose the problem then add the
|
||||
disks_uuids <- disks_uuids @ [diskid];
|
||||
|
||||
method create_metadata source targets _ guestcaps inspect target_firmware =
|
||||
- assert (List.length disks_uuids = List.length targets);
|
||||
+ let image_uuids =
|
||||
+ match rhv_options.rhv_disk_uuids, disks_uuids with
|
||||
+ | None, [] ->
|
||||
+ error (f_"there must be ‘-oo rhv-disk-uuid’ parameters passed on the command line to specify the UUIDs of guest disk images (for this guest: %d)")
|
||||
+ (List.length targets)
|
||||
+ | Some uuids, _ -> uuids
|
||||
+ | None, uuids -> uuids in
|
||||
+ assert (List.length image_uuids = List.length targets);
|
||||
|
||||
(* The storage domain UUID. *)
|
||||
let sd_uuid =
|
||||
@@ -411,7 +444,7 @@ If the messages above are not sufficient to diagnose the problem then add the
|
||||
let ovf =
|
||||
Create_ovf.create_ovf source targets guestcaps inspect
|
||||
target_firmware output_alloc
|
||||
- sd_uuid disks_uuids vol_uuids vm_uuid
|
||||
+ sd_uuid image_uuids vol_uuids vm_uuid
|
||||
OVirt in
|
||||
let ovf = DOM.doc_to_string ovf in
|
||||
|
||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
||||
index 4d61a089b..6ec74a5d4 100644
|
||||
--- a/v2v/rhv-upload-plugin.py
|
||||
+++ b/v2v/rhv-upload-plugin.py
|
||||
@@ -135,6 +135,8 @@ def open(readonly):
|
||||
disk_format = types.DiskFormat.COW
|
||||
disk = disks_service.add(
|
||||
disk = types.Disk(
|
||||
+ # The ID is optional.
|
||||
+ id = params.get('rhv_disk_uuid'),
|
||||
name = params['disk_name'],
|
||||
description = "Uploaded by virt-v2v",
|
||||
format = disk_format,
|
||||
diff --git a/v2v/virt-v2v-output-rhv.pod b/v2v/virt-v2v-output-rhv.pod
|
||||
index 651f61dae..e840ca78d 100644
|
||||
--- a/v2v/virt-v2v-output-rhv.pod
|
||||
+++ b/v2v/virt-v2v-output-rhv.pod
|
||||
@@ -9,6 +9,7 @@ virt-v2v-output-rhv - Using virt-v2v to convert guests to oVirt or RHV
|
||||
[-oo rhv-cafile=FILE]
|
||||
[-oo rhv-cluster=CLUSTER]
|
||||
[-oo rhv-direct]
|
||||
+ [-oo rhv-disk-uuid=UUID ...]
|
||||
[-oo rhv-verifypeer]
|
||||
|
||||
virt-v2v [-i* options] -o rhv -os [esd:/path|/path]
|
||||
@@ -104,6 +105,29 @@ F</etc/pki/ovirt-engine/ca.pem> on the oVirt engine.
|
||||
|
||||
Set the RHV Cluster Name. If not given it uses C<Default>.
|
||||
|
||||
+=item I<-oo rhv-disk-uuid=>C<UUID>
|
||||
+
|
||||
+This option can used to manually specify UUIDs for the disks when
|
||||
+creating the virtual machine. If not specified, the oVirt engine will
|
||||
+generate random UUIDs for the disks. Please note that:
|
||||
+
|
||||
+=over 4
|
||||
+
|
||||
+=item *
|
||||
+
|
||||
+you B<must> pass as many I<-oo rhv-disk-uuid=UUID> options as the
|
||||
+amount of disks in the guest
|
||||
+
|
||||
+=item *
|
||||
+
|
||||
+the specified UUIDs are used as they are, without checking whether
|
||||
+they are already used by other disks
|
||||
+
|
||||
+=back
|
||||
+
|
||||
+This option is considered advanced, and to be used mostly in
|
||||
+combination with I<--no-copy>.
|
||||
+
|
||||
=item I<-oo rhv-direct>
|
||||
|
||||
If this option is given then virt-v2v will attempt to directly upload
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,87 +0,0 @@
|
||||
From 971f3c3239a9d6433fa351ceb983db9cce2ab4ac Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 27 Sep 2019 13:56:42 +0200
|
||||
Subject: [PATCH] v2v: -o rhv-upload: make -oo rhv-cafile optional
|
||||
|
||||
It makes little sense to require the oVirt certificate, especially when
|
||||
the verification of the connection (-oo rhv-verifypeer) is disabled by
|
||||
default. The only work done with the certificate in that case is
|
||||
checking that it is a valid certificate file.
|
||||
|
||||
Hence, make -oo rhv-cafile optional, requiring it only when
|
||||
-oo rhv-verifypeer is enabled.
|
||||
|
||||
(cherry picked from commit 0a5eaad7db3c9b9a03fa88102a9e6142c855bfd1)
|
||||
---
|
||||
v2v/output_rhv_upload.ml | 16 +++++++++-------
|
||||
v2v/virt-v2v-output-rhv.pod | 2 ++
|
||||
2 files changed, 11 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||
index 206657a2b..2c8c18732 100644
|
||||
--- a/v2v/output_rhv_upload.ml
|
||||
+++ b/v2v/output_rhv_upload.ml
|
||||
@@ -28,7 +28,7 @@ open Types
|
||||
open Utils
|
||||
|
||||
type rhv_options = {
|
||||
- rhv_cafile : string;
|
||||
+ rhv_cafile : string option;
|
||||
rhv_cluster : string option;
|
||||
rhv_direct : bool;
|
||||
rhv_verifypeer : bool;
|
||||
@@ -76,15 +76,13 @@ let parse_output_options options =
|
||||
error (f_"-o rhv-upload: unknown output option ‘-oo %s’") k
|
||||
) options;
|
||||
|
||||
- let rhv_cafile =
|
||||
- match !rhv_cafile with
|
||||
- | Some s -> s
|
||||
- | None ->
|
||||
- error (f_"-o rhv-upload: must use ‘-oo rhv-cafile’ to supply the path to the oVirt or RHV user’s ‘ca.pem’ file") in
|
||||
+ let rhv_cafile = !rhv_cafile in
|
||||
let rhv_cluster = !rhv_cluster in
|
||||
let rhv_direct = !rhv_direct in
|
||||
let rhv_verifypeer = !rhv_verifypeer in
|
||||
let rhv_disk_uuids = Option.map List.rev !rhv_disk_uuids in
|
||||
+ if rhv_verifypeer && rhv_cafile = None then
|
||||
+ error (f_"-o rhv-upload: must use ‘-oo rhv-cafile’ to supply the path to the oVirt or RHV user’s ‘ca.pem’ file");
|
||||
|
||||
{ rhv_cafile; rhv_cluster; rhv_direct; rhv_verifypeer; rhv_disk_uuids }
|
||||
|
||||
@@ -92,6 +90,10 @@ let nbdkit_python_plugin = Config.virt_v2v_nbdkit_python_plugin
|
||||
let pidfile_timeout = 30
|
||||
let finalization_timeout = 5*60
|
||||
|
||||
+let json_optstring = function
|
||||
+ | Some s -> JSON.String s
|
||||
+ | None -> JSON.Null
|
||||
+
|
||||
class output_rhv_upload output_alloc output_conn
|
||||
output_password output_storage
|
||||
rhv_options =
|
||||
@@ -200,7 +202,7 @@ See also the virt-v2v-output-rhv(1) manual.")
|
||||
"output_sparse", JSON.Bool (match output_alloc with
|
||||
| Sparse -> true
|
||||
| Preallocated -> false);
|
||||
- "rhv_cafile", JSON.String rhv_options.rhv_cafile;
|
||||
+ "rhv_cafile", json_optstring rhv_options.rhv_cafile;
|
||||
"rhv_cluster",
|
||||
JSON.String (Option.default "Default" rhv_options.rhv_cluster);
|
||||
"rhv_direct", JSON.Bool rhv_options.rhv_direct;
|
||||
diff --git a/v2v/virt-v2v-output-rhv.pod b/v2v/virt-v2v-output-rhv.pod
|
||||
index e840ca78d..04a894268 100644
|
||||
--- a/v2v/virt-v2v-output-rhv.pod
|
||||
+++ b/v2v/virt-v2v-output-rhv.pod
|
||||
@@ -101,6 +101,8 @@ The storage domain.
|
||||
The F<ca.pem> file (Certificate Authority), copied from
|
||||
F</etc/pki/ovirt-engine/ca.pem> on the oVirt engine.
|
||||
|
||||
+This option must be specified if I<-oo rhv-verifypeer> is enabled.
|
||||
+
|
||||
=item I<-oo rhv-cluster=>C<CLUSTERNAME>
|
||||
|
||||
Set the RHV Cluster Name. If not given it uses C<Default>.
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,40 +0,0 @@
|
||||
From 14f47e2084688af0d67807f2a5cfbd90759d8e7f Mon Sep 17 00:00:00 2001
|
||||
From: Mike Latimer <mlatimer@suse.com>
|
||||
Date: Mon, 25 Mar 2019 14:38:00 +0000
|
||||
Subject: [PATCH] v2v: Fix default graphics driver for SUSE guests.
|
||||
|
||||
See discussion in this upstream thread:
|
||||
https://www.redhat.com/archives/libguestfs/2019-February/thread.html#00047
|
||||
|
||||
Thanks: Mike Latimer, Pino Toscano.
|
||||
(cherry picked from commit 612f170e6062f2ff74643b6096b7e0765b52cfbd)
|
||||
---
|
||||
v2v/convert_linux.ml | 5 +----
|
||||
1 file changed, 1 insertion(+), 4 deletions(-)
|
||||
|
||||
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
|
||||
index b4b2f24c4..f9e811c8d 100644
|
||||
--- a/v2v/convert_linux.ml
|
||||
+++ b/v2v/convert_linux.ml
|
||||
@@ -104,7 +104,7 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
||||
|
||||
let video =
|
||||
match rcaps.rcaps_video with
|
||||
- | None -> get_display_driver ()
|
||||
+ | None -> QXL
|
||||
| Some video -> video in
|
||||
|
||||
let block_type =
|
||||
@@ -783,9 +783,6 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
||||
else
|
||||
true
|
||||
|
||||
- and get_display_driver () =
|
||||
- if family = `SUSE_family then Cirrus else QXL
|
||||
-
|
||||
and configure_display_driver video =
|
||||
let video_driver = match video with QXL -> "qxl" | Cirrus -> "cirrus" in
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,73 +0,0 @@
|
||||
From d875df20c30868db210396b64f6dcec2cb6d57b4 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 4 Dec 2018 16:09:42 +0000
|
||||
Subject: [PATCH] v2v: windows: Add a helper function for installing Powershell
|
||||
firstboot scripts.
|
||||
|
||||
(cherry picked from commit e1e9b3845e76a4bb406d16b96283ac38677cd91f)
|
||||
---
|
||||
v2v/Makefile.am | 1 +
|
||||
v2v/windows.ml | 23 +++++++++++++++++++++++
|
||||
v2v/windows.mli | 6 ++++++
|
||||
3 files changed, 30 insertions(+)
|
||||
|
||||
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
|
||||
index 30f040d3e..6568c9a6b 100644
|
||||
--- a/v2v/Makefile.am
|
||||
+++ b/v2v/Makefile.am
|
||||
@@ -667,6 +667,7 @@ check_PROGRAMS += v2v_unit_tests var_expander_tests
|
||||
endif
|
||||
|
||||
v2v_unit_tests_BOBJECTS = \
|
||||
+ $(top_builddir)/customize/firstboot.cmo \
|
||||
types.cmo \
|
||||
uefi.cmo \
|
||||
utils.cmo \
|
||||
diff --git a/v2v/windows.ml b/v2v/windows.ml
|
||||
index 23d589b00..d83f77b7f 100644
|
||||
--- a/v2v/windows.ml
|
||||
+++ b/v2v/windows.ml
|
||||
@@ -45,3 +45,26 @@ and check_app { Guestfs.app2_name = name;
|
||||
publisher =~ rex_avg_tech
|
||||
|
||||
and (=~) str rex = PCRE.matches rex str
|
||||
+
|
||||
+(* Unfortunately Powershell scripts cannot be directly executed
|
||||
+ * (unless some system config changes are made which for other
|
||||
+ * reasons we don't want to do) and so we have to run this via
|
||||
+ * a regular batch file.
|
||||
+ *)
|
||||
+let install_firstboot_powershell g { Types.i_windows_systemroot; i_root }
|
||||
+ filename code =
|
||||
+ let tempdir = sprintf "%s/Temp" i_windows_systemroot in
|
||||
+ g#mkdir_p tempdir;
|
||||
+ let code = String.concat "\r\n" code ^ "\r\n" in
|
||||
+ g#write (sprintf "%s/%s" tempdir filename) code;
|
||||
+
|
||||
+ (* Powershell interpreter. Should we check this exists? XXX *)
|
||||
+ let ps_exe =
|
||||
+ i_windows_systemroot ^
|
||||
+ "\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" in
|
||||
+
|
||||
+ (* Windows path to the Powershell script. *)
|
||||
+ let ps_path = i_windows_systemroot ^ "\\Temp\\" ^ filename in
|
||||
+
|
||||
+ let fb = sprintf "%s -ExecutionPolicy ByPass -file %s" ps_exe ps_path in
|
||||
+ Firstboot.add_firstboot_script g i_root filename fb
|
||||
diff --git a/v2v/windows.mli b/v2v/windows.mli
|
||||
index 016ef2a78..6db7874b0 100644
|
||||
--- a/v2v/windows.mli
|
||||
+++ b/v2v/windows.mli
|
||||
@@ -21,3 +21,9 @@
|
||||
val detect_antivirus : Types.inspect -> bool
|
||||
(** Return [true] if anti-virus (AV) software was detected in
|
||||
this Windows guest. *)
|
||||
+
|
||||
+val install_firstboot_powershell : Guestfs.guestfs -> Types.inspect ->
|
||||
+ string -> string list -> unit
|
||||
+(** [install_powershell_firstboot g inspect filename code] installs a
|
||||
+ Powershell script (the lines of code) as a firstboot script in
|
||||
+ the Windows VM. *)
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,423 +0,0 @@
|
||||
From 77606e831f8891b65350effb6502d233d74f8cfc Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 4 Dec 2018 16:09:42 +0000
|
||||
Subject: [PATCH] v2v: Copy static IP address information over for Windows
|
||||
guests (RHBZ#1626503).
|
||||
|
||||
For Linux the guest itself remembers the IP address associated with
|
||||
each MAC address. Thus it doesn't matter if the interface type
|
||||
changes (ie. to virtio-net), because as long as we preserve the MAC
|
||||
address the guest will use the same IP address or the same DHCP
|
||||
configuration.
|
||||
|
||||
However on Windows this association is not maintained by MAC address.
|
||||
In fact the MAC address isn't saved anywhere in the guest registry.
|
||||
(It seems instead this is likely done through PCI device type and
|
||||
address which we don't record at the moment and is almost impossible
|
||||
to preserve.) When a guest which doesn't use DHCP is migrated, the
|
||||
guest sees the brand new virtio-net devices and doesn't know what to
|
||||
do with them, and meanwhile the right static IPs are still associated
|
||||
with the old and now-defunct interfaces in the registry.
|
||||
|
||||
We cannot collect the required information from within the guest.
|
||||
However we can collect it outside the tool by some other means
|
||||
(eg. using VMware Tools APIs) and present this information to virt-v2v
|
||||
which then writes it into the Windows guest at firstboot time.
|
||||
|
||||
This commit adds the --mac ..:ip:.. sub-option which creates a
|
||||
Powershell script to set network adapters at firstboot. An option
|
||||
such as:
|
||||
|
||||
--mac 00:0c:29:e6:3d:9d:ip:192.168.0.89,192.168.0.1,24,192.168.0.254
|
||||
|
||||
approximately turns into this script:
|
||||
|
||||
# Wait for the netkvm (virtio-net) driver to become active.
|
||||
$adapters = @()
|
||||
While (-Not $adapters) {
|
||||
Start-Sleep -Seconds 5
|
||||
$adapters = Get-NetAdapter -Physical |
|
||||
Where DriverFileName -eq "netkvm.sys"
|
||||
}
|
||||
$mac_address = '00-0c-29-e6-3d-9d'
|
||||
$ifindex = (Get-NetAdapter -Physical |
|
||||
Where MacAddress -eq $mac_address).ifIndex
|
||||
if ($ifindex) {
|
||||
New-NetIPAddress -InterfaceIndex $ifindex
|
||||
-IPAddress '192.168.0.89'
|
||||
-DefaultGateway '192.168.0.1'
|
||||
-PrefixLength 24
|
||||
Set-DnsClientServerAddress -InterfaceIndex $ifindex
|
||||
-ServerAddresses ('192.168.0.254')
|
||||
}
|
||||
|
||||
Thanks: Brett Thurber for diagnosing the problem and suggesting paths
|
||||
towards a fix.
|
||||
|
||||
(cherry picked from commit dfd9fac7435cf2f9293961b6cc1fe316af4feebc)
|
||||
---
|
||||
v2v/cmdline.ml | 41 ++++++++++++++++++-----
|
||||
v2v/cmdline.mli | 1 +
|
||||
v2v/convert_linux.ml | 2 +-
|
||||
v2v/convert_windows.ml | 76 +++++++++++++++++++++++++++++++++++++++++-
|
||||
v2v/modules_list.ml | 2 +-
|
||||
v2v/modules_list.mli | 2 +-
|
||||
v2v/types.ml | 8 +++++
|
||||
v2v/types.mli | 9 +++++
|
||||
v2v/v2v.ml | 7 ++--
|
||||
v2v/virt-v2v.pod | 18 ++++++++++
|
||||
10 files changed, 150 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
|
||||
index 4d390f249..686631271 100644
|
||||
--- a/v2v/cmdline.ml
|
||||
+++ b/v2v/cmdline.ml
|
||||
@@ -40,11 +40,12 @@ type cmdline = {
|
||||
print_estimate : bool;
|
||||
print_source : bool;
|
||||
root_choice : root_choice;
|
||||
+ static_ips : static_ip list;
|
||||
ks : Tools_utils.key_store;
|
||||
}
|
||||
|
||||
(* Matches --mac command line parameters. *)
|
||||
-let mac_re = PCRE.compile ~anchored:true "([[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}):(network|bridge):(.*)"
|
||||
+let mac_re = PCRE.compile ~anchored:true "([[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}):(network|bridge|ip):(.*)"
|
||||
|
||||
let parse_cmdline () =
|
||||
let compressed = ref false in
|
||||
@@ -97,6 +98,7 @@ let parse_cmdline () =
|
||||
in
|
||||
|
||||
let network_map = Networks.create () in
|
||||
+ let static_ips = ref [] in
|
||||
let add_network str =
|
||||
match String.split ":" str with
|
||||
| "", "" ->
|
||||
@@ -119,11 +121,30 @@ let parse_cmdline () =
|
||||
if not (PCRE.matches mac_re str) then
|
||||
error (f_"cannot parse --mac \"%s\" parameter") str;
|
||||
let mac = PCRE.sub 1 and out = PCRE.sub 3 in
|
||||
- let vnet_type =
|
||||
- match PCRE.sub 2 with
|
||||
- | "network" -> Network | "bridge" -> Bridge
|
||||
- | _ -> assert false in
|
||||
- Networks.add_mac network_map mac vnet_type out
|
||||
+ match PCRE.sub 2 with
|
||||
+ | "network" ->
|
||||
+ Networks.add_mac network_map mac Network out
|
||||
+ | "bridge" ->
|
||||
+ Networks.add_mac network_map mac Bridge out
|
||||
+ | "ip" ->
|
||||
+ let add if_mac_addr if_ip_address if_default_gateway
|
||||
+ if_prefix_length if_nameservers =
|
||||
+ List.push_back static_ips
|
||||
+ { if_mac_addr; if_ip_address; if_default_gateway;
|
||||
+ if_prefix_length; if_nameservers }
|
||||
+ in
|
||||
+ (match String.nsplit "," out with
|
||||
+ | [] ->
|
||||
+ error (f_"invalid --mac ip option")
|
||||
+ | [ip] -> add mac ip None None []
|
||||
+ | [ip; gw] -> add mac ip (Some gw) None []
|
||||
+ | ip :: gw :: len :: nameservers ->
|
||||
+ let len =
|
||||
+ try int_of_string len with
|
||||
+ | Failure _ -> error (f_"cannot parse --mac ip prefix length field as an integer: %s") len in
|
||||
+ add mac ip (Some gw) (Some len) nameservers
|
||||
+ );
|
||||
+ | _ -> assert false
|
||||
in
|
||||
|
||||
let no_trim_warning _ =
|
||||
@@ -211,8 +232,8 @@ let parse_cmdline () =
|
||||
s_"Input transport";
|
||||
[ L"in-place" ], Getopt.Set in_place,
|
||||
s_"Only tune the guest in the input VM";
|
||||
- [ L"mac" ], Getopt.String ("mac:network|bridge:out", add_mac),
|
||||
- s_"Map NIC to network or bridge";
|
||||
+ [ L"mac" ], Getopt.String ("mac:network|bridge|ip:out", add_mac),
|
||||
+ s_"Map NIC to network or bridge or assign static IP";
|
||||
[ S 'n'; L"network" ], Getopt.String ("in:out", add_network),
|
||||
s_"Map network ‘in’ to ‘out’";
|
||||
[ L"no-copy" ], Getopt.Clear do_copy,
|
||||
@@ -335,6 +356,7 @@ read the man page virt-v2v(1).
|
||||
let print_source = !print_source in
|
||||
let qemu_boot = !qemu_boot in
|
||||
let root_choice = !root_choice in
|
||||
+ let static_ips = !static_ips in
|
||||
|
||||
(* No arguments and machine-readable mode? Print out some facts
|
||||
* about what this binary supports.
|
||||
@@ -351,6 +373,7 @@ read the man page virt-v2v(1).
|
||||
pr "in-place\n";
|
||||
pr "io/oo\n";
|
||||
pr "mac-option\n";
|
||||
+ pr "mac-ip-option\n";
|
||||
List.iter (pr "input:%s\n") (Modules_list.input_modules ());
|
||||
List.iter (pr "output:%s\n") (Modules_list.output_modules ());
|
||||
List.iter (pr "convert:%s\n") (Modules_list.convert_modules ());
|
||||
@@ -685,7 +708,7 @@ read the man page virt-v2v(1).
|
||||
{
|
||||
compressed; debug_overlays; do_copy; in_place; network_map;
|
||||
output_alloc; output_format; output_name;
|
||||
- print_estimate; print_source; root_choice;
|
||||
+ print_estimate; print_source; root_choice; static_ips;
|
||||
ks = opthandle.ks;
|
||||
},
|
||||
input, output
|
||||
diff --git a/v2v/cmdline.mli b/v2v/cmdline.mli
|
||||
index 78601e191..a009e9888 100644
|
||||
--- a/v2v/cmdline.mli
|
||||
+++ b/v2v/cmdline.mli
|
||||
@@ -30,6 +30,7 @@ type cmdline = {
|
||||
print_estimate : bool;
|
||||
print_source : bool;
|
||||
root_choice : Types.root_choice;
|
||||
+ static_ips : Types.static_ip list;
|
||||
ks : Tools_utils.key_store;
|
||||
}
|
||||
|
||||
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
|
||||
index f9e811c8d..1ada36115 100644
|
||||
--- a/v2v/convert_linux.ml
|
||||
+++ b/v2v/convert_linux.ml
|
||||
@@ -34,7 +34,7 @@ open Linux_kernels
|
||||
module G = Guestfs
|
||||
|
||||
(* The conversion function. *)
|
||||
-let convert (g : G.guestfs) inspect source output rcaps =
|
||||
+let convert (g : G.guestfs) inspect source output rcaps _ =
|
||||
(*----------------------------------------------------------------------*)
|
||||
(* Inspect the guest first. We already did some basic inspection in
|
||||
* the common v2v.ml code, but that has to deal with generic guests
|
||||
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
||||
index 1db3c0ea6..75e609d61 100644
|
||||
--- a/v2v/convert_windows.ml
|
||||
+++ b/v2v/convert_windows.ml
|
||||
@@ -38,7 +38,7 @@ module G = Guestfs
|
||||
* time the Windows VM is booted on KVM.
|
||||
*)
|
||||
|
||||
-let convert (g : G.guestfs) inspect source output rcaps =
|
||||
+let convert (g : G.guestfs) inspect source output rcaps static_ips =
|
||||
(*----------------------------------------------------------------------*)
|
||||
(* Inspect the Windows guest. *)
|
||||
|
||||
@@ -228,6 +228,8 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
||||
Registry.with_hive_write g inspect.i_windows_software_hive
|
||||
update_software_hive;
|
||||
|
||||
+ configure_network_interfaces net_driver;
|
||||
+
|
||||
fix_ntfs_heads ();
|
||||
|
||||
fix_win_esp ();
|
||||
@@ -603,6 +605,78 @@ if errorlevel 3010 exit /b 0
|
||||
| None ->
|
||||
warning (f_"could not find registry key HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion")
|
||||
|
||||
+ and configure_network_interfaces net_driver =
|
||||
+ (* If we were asked to force network interfaces to have particular
|
||||
+ * static IP addresses then it is done here by installing a
|
||||
+ * Powershell script which runs at boot.
|
||||
+ *)
|
||||
+ if static_ips <> [] then (
|
||||
+ let psh_filename = "v2vnetcf.ps1" in
|
||||
+ let psh = ref [] in
|
||||
+ let add = List.push_back psh in
|
||||
+
|
||||
+ add "# Uncomment this line for lots of debug output.";
|
||||
+ add "# Set-PSDebug -Trace 1";
|
||||
+ add "";
|
||||
+
|
||||
+ (* If virtio-net was added to the registry, we must wait for
|
||||
+ * it to be installed at runtime.
|
||||
+ *)
|
||||
+ if net_driver = Virtio_net then (
|
||||
+ add "# Wait for the netkvm (virtio-net) driver to become active.";
|
||||
+ add "$adapters = @()";
|
||||
+ add "While (-Not $adapters) {";
|
||||
+ add " Start-Sleep -Seconds 5";
|
||||
+ add " $adapters = Get-NetAdapter -Physical | Where DriverFileName -eq \"netkvm.sys\"";
|
||||
+ add " Write-Host \"adapters = '$adapters'\"";
|
||||
+ add "}";
|
||||
+ add ""
|
||||
+ );
|
||||
+
|
||||
+ List.iter (
|
||||
+ fun { if_mac_addr; if_ip_address; if_default_gateway;
|
||||
+ if_prefix_length; if_nameservers } ->
|
||||
+ add (sprintf "$mac_address = '%s'"
|
||||
+ (String.replace if_mac_addr ":" "-"));
|
||||
+ add "$ifindex = (Get-NetAdapter -Physical | Where MacAddress -eq $mac_address).ifIndex";
|
||||
+ add "if ($ifindex) {";
|
||||
+
|
||||
+ add " Write-Host \"setting IP address of adapter at $ifindex\"";
|
||||
+
|
||||
+ (* New-NetIPAddress command *)
|
||||
+ let args = ref [] in
|
||||
+ List.push_back args "-InterfaceIndex";
|
||||
+ List.push_back args "$ifindex";
|
||||
+ List.push_back args "-IPAddress";
|
||||
+ List.push_back args (sprintf "'%s'" if_ip_address);
|
||||
+ (match if_default_gateway with
|
||||
+ | None -> ()
|
||||
+ | Some gw ->
|
||||
+ List.push_back args "-DefaultGateway";
|
||||
+ List.push_back args (sprintf "'%s'" gw)
|
||||
+ );
|
||||
+ (match if_prefix_length with
|
||||
+ | None -> ()
|
||||
+ | Some len ->
|
||||
+ List.push_back args "-PrefixLength";
|
||||
+ List.push_back args (string_of_int len)
|
||||
+ );
|
||||
+ let cmd1 = "New-NetIPAddress " ^ String.concat " " !args in
|
||||
+ add (" " ^ cmd1);
|
||||
+
|
||||
+ (* Set-DnsClientServerAddress command *)
|
||||
+ if if_nameservers <> [] then (
|
||||
+ add (sprintf " Set-DnsClientServerAddress -InterfaceIndex $ifindex -ServerAddresses (%s)"
|
||||
+ (String.concat "," (List.map (sprintf "'%s'") if_nameservers)))
|
||||
+ );
|
||||
+ add "}";
|
||||
+ add ""
|
||||
+ ) static_ips;
|
||||
+
|
||||
+ (* Install the Powershell script to run at firstboot. *)
|
||||
+ Windows.install_firstboot_powershell g inspect psh_filename !psh
|
||||
+ ) (* static_ips <> [] *)
|
||||
+
|
||||
and fix_ntfs_heads () =
|
||||
(* NTFS hardcodes the number of heads on the drive which created
|
||||
it in the filesystem header. Modern versions of Windows
|
||||
diff --git a/v2v/modules_list.ml b/v2v/modules_list.ml
|
||||
index a0a74aaf2..76b3def5d 100644
|
||||
--- a/v2v/modules_list.ml
|
||||
+++ b/v2v/modules_list.ml
|
||||
@@ -38,7 +38,7 @@ type inspection_fn = Types.inspect -> bool
|
||||
|
||||
type conversion_fn =
|
||||
Guestfs.guestfs -> Types.inspect -> Types.source -> Types.output_settings ->
|
||||
- Types.requested_guestcaps -> Types.guestcaps
|
||||
+ Types.requested_guestcaps -> Types.static_ip list -> Types.guestcaps
|
||||
|
||||
let convert_modules = ref []
|
||||
|
||||
diff --git a/v2v/modules_list.mli b/v2v/modules_list.mli
|
||||
index 3e80d3e23..ad2024755 100644
|
||||
--- a/v2v/modules_list.mli
|
||||
+++ b/v2v/modules_list.mli
|
||||
@@ -34,7 +34,7 @@ type inspection_fn = Types.inspect -> bool
|
||||
|
||||
type conversion_fn =
|
||||
Guestfs.guestfs -> Types.inspect -> Types.source -> Types.output_settings ->
|
||||
- Types.requested_guestcaps -> Types.guestcaps
|
||||
+ Types.requested_guestcaps -> Types.static_ip list -> Types.guestcaps
|
||||
|
||||
val register_convert_module : inspection_fn -> string -> conversion_fn -> unit
|
||||
(** [register_convert_module inspect_fn name fn] registers a
|
||||
diff --git a/v2v/types.ml b/v2v/types.ml
|
||||
index 714b30014..4ba6117fd 100644
|
||||
--- a/v2v/types.ml
|
||||
+++ b/v2v/types.ml
|
||||
@@ -506,6 +506,14 @@ type root_choice = AskRoot | SingleRoot | FirstRoot | RootDev of string
|
||||
|
||||
type output_allocation = Sparse | Preallocated
|
||||
|
||||
+type static_ip = {
|
||||
+ if_mac_addr : string;
|
||||
+ if_ip_address : string;
|
||||
+ if_default_gateway : string option;
|
||||
+ if_prefix_length : int option;
|
||||
+ if_nameservers : string list;
|
||||
+}
|
||||
+
|
||||
class virtual input = object
|
||||
method precheck () = ()
|
||||
method virtual as_options : string
|
||||
diff --git a/v2v/types.mli b/v2v/types.mli
|
||||
index f595ab0ef..528d77965 100644
|
||||
--- a/v2v/types.mli
|
||||
+++ b/v2v/types.mli
|
||||
@@ -361,6 +361,15 @@ type root_choice = AskRoot | SingleRoot | FirstRoot | RootDev of string
|
||||
type output_allocation = Sparse | Preallocated
|
||||
(** Type of [-oa] (output allocation) option. *)
|
||||
|
||||
+type static_ip = {
|
||||
+ if_mac_addr : string;
|
||||
+ if_ip_address : string;
|
||||
+ if_default_gateway : string option;
|
||||
+ if_prefix_length : int option;
|
||||
+ if_nameservers : string list;
|
||||
+}
|
||||
+(** [--mac ..:ip:..] option. *)
|
||||
+
|
||||
(** {2 Input object}
|
||||
|
||||
This is subclassed for the various input [-i] options.
|
||||
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
|
||||
index 63e809030..d7a868659 100644
|
||||
--- a/v2v/v2v.ml
|
||||
+++ b/v2v/v2v.ml
|
||||
@@ -133,7 +133,7 @@ let rec main () =
|
||||
| In_place ->
|
||||
rcaps_from_source source in
|
||||
|
||||
- do_convert g inspect source output rcaps in
|
||||
+ do_convert g inspect source output rcaps cmdline.static_ips in
|
||||
|
||||
g#umount_all ();
|
||||
|
||||
@@ -556,7 +556,7 @@ and estimate_target_size mpstats overlays =
|
||||
)
|
||||
|
||||
(* Conversion. *)
|
||||
-and do_convert g inspect source output rcaps =
|
||||
+and do_convert g inspect source output rcaps interfaces =
|
||||
(match inspect.i_product_name with
|
||||
| "unknown" ->
|
||||
message (f_"Converting the guest to run on KVM")
|
||||
@@ -572,7 +572,8 @@ and do_convert g inspect source output rcaps =
|
||||
debug "picked conversion module %s" conversion_name;
|
||||
debug "requested caps: %s" (string_of_requested_guestcaps rcaps);
|
||||
let guestcaps =
|
||||
- convert g inspect source (output :> Types.output_settings) rcaps in
|
||||
+ convert g inspect source (output :> Types.output_settings) rcaps
|
||||
+ interfaces in
|
||||
debug "%s" (string_of_guestcaps guestcaps);
|
||||
|
||||
(* Did we manage to install virtio drivers? *)
|
||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
||||
index 9a555c3be..0642d158f 100644
|
||||
--- a/v2v/virt-v2v.pod
|
||||
+++ b/v2v/virt-v2v.pod
|
||||
@@ -368,6 +368,24 @@ Map source NIC MAC address to a network or bridge.
|
||||
|
||||
See L</Networks and bridges> below.
|
||||
|
||||
+=item B<--mac> aa:bb:cc:dd:ee:ffB<:ip:>ipaddr[,gw[,len[,ns,ns,...]]]
|
||||
+
|
||||
+Force a particular interface (controlled by its MAC address) to have a
|
||||
+static IP address after boot.
|
||||
+
|
||||
+The fields in the parameter are: C<ipaddr> is the IP address. C<gw>
|
||||
+is the optional gateway IP address. C<len> is the subnet mask length
|
||||
+(an integer). The final parameters are zero or more nameserver IP
|
||||
+addresses.
|
||||
+
|
||||
+This option can be supplied zero or more times.
|
||||
+
|
||||
+You only need to use this option for certain broken guests such as
|
||||
+Windows which are unable to preserve MAC to static IP address mappings
|
||||
+automatically. You don't need to use it if Windows is using DHCP. It
|
||||
+is currently ignored for Linux guests since they do not have this
|
||||
+problem.
|
||||
+
|
||||
=item B<--machine-readable>
|
||||
|
||||
=item B<--machine-readable>=format
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,87 +0,0 @@
|
||||
From c31eaba4d6b36d90cfd835a4750e50f6a5256b73 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 29 Nov 2019 11:48:59 +0100
|
||||
Subject: [PATCH] New API: luks_uuid
|
||||
|
||||
Return the UUID of a LUKS device.
|
||||
|
||||
(cherry picked from commit 206ce8bbf1bc3332dc019e553d17d6a36f74b725)
|
||||
---
|
||||
daemon/luks.c | 25 +++++++++++++++++++++++++
|
||||
generator/actions_core.ml | 8 ++++++++
|
||||
generator/proc_nr.ml | 1 +
|
||||
lib/MAX_PROC_NR | 2 +-
|
||||
4 files changed, 35 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemon/luks.c b/daemon/luks.c
|
||||
index 5c48a91eb..d631cb100 100644
|
||||
--- a/daemon/luks.c
|
||||
+++ b/daemon/luks.c
|
||||
@@ -292,3 +292,28 @@ do_luks_kill_slot (const char *device, const char *key, int keyslot)
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+char *
|
||||
+do_luks_uuid (const char *device)
|
||||
+{
|
||||
+ const char *argv[MAX_ARGS];
|
||||
+ size_t i = 0;
|
||||
+
|
||||
+ ADD_ARG (argv, i, "cryptsetup");
|
||||
+ ADD_ARG (argv, i, "luksUUID");
|
||||
+ ADD_ARG (argv, i, device);
|
||||
+ ADD_ARG (argv, i, NULL);
|
||||
+
|
||||
+ char *out = NULL;
|
||||
+ CLEANUP_FREE char *err = NULL;
|
||||
+ int r = commandv (&out, &err, (const char * const *) argv);
|
||||
+
|
||||
+ if (r == -1) {
|
||||
+ reply_with_error ("%s", err);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ trim (out);
|
||||
+
|
||||
+ return out;
|
||||
+}
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index 7b6568b90..deda483a9 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -9728,4 +9728,12 @@ it is useful when you have added a new device or deleted an
|
||||
existing device (such as when the C<guestfs_luks_open> API
|
||||
is used)." };
|
||||
|
||||
+ { defaults with
|
||||
+ name = "luks_uuid"; added = (1, 41, 9);
|
||||
+ style = RString (RPlainString, "uuid"), [String (Device, "device")], [];
|
||||
+ optional = Some "luks";
|
||||
+ shortdesc = "get the UUID of a LUKS device";
|
||||
+ longdesc = "\
|
||||
+This returns the UUID of the LUKS device C<device>." };
|
||||
+
|
||||
]
|
||||
diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
|
||||
index efa8c5d21..11a557076 100644
|
||||
--- a/generator/proc_nr.ml
|
||||
+++ b/generator/proc_nr.ml
|
||||
@@ -514,6 +514,7 @@ let proc_nr = [
|
||||
504, "part_get_gpt_attributes";
|
||||
505, "f2fs_expand";
|
||||
506, "lvm_scan";
|
||||
+507, "luks_uuid";
|
||||
]
|
||||
|
||||
(* End of list. If adding a new entry, add it at the end of the list
|
||||
diff --git a/lib/MAX_PROC_NR b/lib/MAX_PROC_NR
|
||||
index 80e3e6eab..055b6671a 100644
|
||||
--- a/lib/MAX_PROC_NR
|
||||
+++ b/lib/MAX_PROC_NR
|
||||
@@ -1 +1 @@
|
||||
-506
|
||||
+507
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,47 +0,0 @@
|
||||
From a7fe83c678520aca2289eab2af6d8aebdf225bb7 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 12 Nov 2019 18:15:44 +0000
|
||||
Subject: [PATCH] options: Fix segfault when multiple --key parameters given.
|
||||
|
||||
Easily reproducible using:
|
||||
|
||||
$ guestfish --key dev1:key:key1 --key dev2:key:key2
|
||||
|
||||
causing this stack trace (or others depending on where the memory
|
||||
corruption was caught):
|
||||
|
||||
Program received signal SIGABRT, Aborted.
|
||||
0x00007ffff7905625 in raise () from /lib64/libc.so.6
|
||||
(gdb) bt
|
||||
#0 0x00007ffff7905625 in raise () from /lib64/libc.so.6
|
||||
#1 0x00007ffff78ee8d9 in abort () from /lib64/libc.so.6
|
||||
#2 0x00007ffff79494af in __libc_message () from /lib64/libc.so.6
|
||||
#3 0x00007ffff7950a6c in malloc_printerr () from /lib64/libc.so.6
|
||||
#4 0x00007ffff79528d0 in _int_free () from /lib64/libc.so.6
|
||||
#5 0x00005555555bdd6e in free_key_store ()
|
||||
#6 0x0000555555589027 in main ()
|
||||
(gdb) quit
|
||||
|
||||
(cherry picked from commit 8c42f772614b44a8cb974afa904ec9f518431ab2
|
||||
in libguestfs-common)
|
||||
---
|
||||
common/options/keys.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/common/options/keys.c b/common/options/keys.c
|
||||
index 7f689866b..f783066ff 100644
|
||||
--- a/common/options/keys.c
|
||||
+++ b/common/options/keys.c
|
||||
@@ -216,7 +216,8 @@ key_store_import_key (struct key_store *ks, const struct key_store_key *key)
|
||||
}
|
||||
assert (ks != NULL);
|
||||
|
||||
- new_keys = realloc (ks->keys, sizeof (*ks->keys) + 1);
|
||||
+ new_keys = realloc (ks->keys,
|
||||
+ (ks->nr_keys + 1) * sizeof (struct key_store_key));
|
||||
if (!new_keys)
|
||||
error (EXIT_FAILURE, errno, "realloc");
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,85 +0,0 @@
|
||||
From c74aa1326061723bd87e599699096d1085472772 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 26 Nov 2019 12:12:45 +0000
|
||||
Subject: [PATCH] options: Simplify selector parsing for --key options.
|
||||
|
||||
Refactor this code to use guestfs_int_split_string function which
|
||||
slightly simplifies it. This should have no effect.
|
||||
|
||||
(cherry picked from commit 530d0beef74d48617717463a5b585f21e2ed62be
|
||||
in libguestfs-common)
|
||||
---
|
||||
common/options/keys.c | 35 ++++++++++++++---------------------
|
||||
1 file changed, 14 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/common/options/keys.c b/common/options/keys.c
|
||||
index f783066ff..74b549731 100644
|
||||
--- a/common/options/keys.c
|
||||
+++ b/common/options/keys.c
|
||||
@@ -153,49 +153,42 @@ get_key (struct key_store *ks, const char *device)
|
||||
}
|
||||
|
||||
struct key_store *
|
||||
-key_store_add_from_selector (struct key_store *ks, const char *selector_orig)
|
||||
+key_store_add_from_selector (struct key_store *ks, const char *selector)
|
||||
{
|
||||
- CLEANUP_FREE char *selector = strdup (selector_orig);
|
||||
- const char *elem;
|
||||
- char *saveptr;
|
||||
+ CLEANUP_FREE_STRING_LIST char **fields =
|
||||
+ guestfs_int_split_string (':', selector);
|
||||
struct key_store_key key;
|
||||
|
||||
- if (!selector)
|
||||
- error (EXIT_FAILURE, errno, "strdup");
|
||||
+ if (!fields)
|
||||
+ error (EXIT_FAILURE, errno, "guestfs_int_split_string");
|
||||
|
||||
- /* 1: device */
|
||||
- elem = strtok_r (selector, ":", &saveptr);
|
||||
- if (!elem) {
|
||||
+ if (guestfs_int_count_strings (fields) != 3) {
|
||||
invalid_selector:
|
||||
- error (EXIT_FAILURE, 0, "invalid selector for --key: %s", selector_orig);
|
||||
+ error (EXIT_FAILURE, 0, "invalid selector for --key: %s", selector);
|
||||
}
|
||||
- key.device = strdup (elem);
|
||||
+
|
||||
+ /* 1: device */
|
||||
+ key.device = strdup (fields[0]);
|
||||
if (!key.device)
|
||||
error (EXIT_FAILURE, errno, "strdup");
|
||||
|
||||
/* 2: key type */
|
||||
- elem = strtok_r (NULL, ":", &saveptr);
|
||||
- if (!elem)
|
||||
- goto invalid_selector;
|
||||
- else if (STREQ (elem, "key"))
|
||||
+ if (STREQ (fields[1], "key"))
|
||||
key.type = key_string;
|
||||
- else if (STREQ (elem, "file"))
|
||||
+ else if (STREQ (fields[1], "file"))
|
||||
key.type = key_file;
|
||||
else
|
||||
goto invalid_selector;
|
||||
|
||||
/* 3: actual key */
|
||||
- elem = strtok_r (NULL, ":", &saveptr);
|
||||
- if (!elem)
|
||||
- goto invalid_selector;
|
||||
switch (key.type) {
|
||||
case key_string:
|
||||
- key.string.s = strdup (elem);
|
||||
+ key.string.s = strdup (fields[2]);
|
||||
if (!key.string.s)
|
||||
error (EXIT_FAILURE, errno, "strdup");
|
||||
break;
|
||||
case key_file:
|
||||
- key.file.name = strdup (elem);
|
||||
+ key.file.name = strdup (fields[2]);
|
||||
if (!key.file.name)
|
||||
error (EXIT_FAILURE, errno, "strdup");
|
||||
break;
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,180 +0,0 @@
|
||||
From 0267ad921c3be8a780342b052264666cef2cc1b1 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 12 Nov 2019 17:50:17 +0000
|
||||
Subject: [PATCH] options: Allow multiple --key parameters.
|
||||
|
||||
This allows multiple --key parameters on the command line to match a
|
||||
single device. For example:
|
||||
|
||||
tool --key /dev/sda1:key:trykey1 --key /dev/sda1:key:trykey2
|
||||
|
||||
would try "trykey1" and "trykey2" against /dev/sda1.
|
||||
|
||||
(cherry picked from commit c10c8baedb88e7c2988a01b70fc5f81fa8e4885c
|
||||
in libguestfs-common)
|
||||
---
|
||||
common/options/decrypt.c | 35 ++++++++++++++++++++++++-------
|
||||
common/options/keys.c | 45 +++++++++++++++++++++++++++++++---------
|
||||
common/options/options.h | 6 ++++--
|
||||
3 files changed, 66 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/common/options/decrypt.c b/common/options/decrypt.c
|
||||
index 234163d8c..3511d9fe9 100644
|
||||
--- a/common/options/decrypt.c
|
||||
+++ b/common/options/decrypt.c
|
||||
@@ -26,6 +26,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
+#include <libintl.h>
|
||||
+#include <error.h>
|
||||
+#include <assert.h>
|
||||
|
||||
#include "c-ctype.h"
|
||||
|
||||
@@ -74,21 +77,37 @@ inspect_do_decrypt (guestfs_h *g, struct key_store *ks)
|
||||
if (partitions == NULL)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
- int need_rescan = 0;
|
||||
- size_t i;
|
||||
+ int need_rescan = 0, r;
|
||||
+ size_t i, j;
|
||||
+
|
||||
for (i = 0; partitions[i] != NULL; ++i) {
|
||||
CLEANUP_FREE char *type = guestfs_vfs_type (g, partitions[i]);
|
||||
if (type && STREQ (type, "crypto_LUKS")) {
|
||||
char mapname[32];
|
||||
make_mapname (partitions[i], mapname, sizeof mapname);
|
||||
|
||||
- CLEANUP_FREE char *key = get_key (ks, partitions[i]);
|
||||
- /* XXX Should we call guestfs_luks_open_ro if readonly flag
|
||||
- * is set? This might break 'mount_ro'.
|
||||
- */
|
||||
- if (guestfs_luks_open (g, partitions[i], key, mapname) == -1)
|
||||
- exit (EXIT_FAILURE);
|
||||
+ CLEANUP_FREE_STRING_LIST char **keys = get_keys (ks, partitions[i]);
|
||||
+ assert (guestfs_int_count_strings (keys) > 0);
|
||||
|
||||
+ /* Try each key in turn. */
|
||||
+ for (j = 0; keys[j] != NULL; ++j) {
|
||||
+ /* XXX Should we call guestfs_luks_open_ro if readonly flag
|
||||
+ * is set? This might break 'mount_ro'.
|
||||
+ */
|
||||
+ guestfs_push_error_handler (g, NULL, NULL);
|
||||
+ r = guestfs_luks_open (g, partitions[i], keys[j], mapname);
|
||||
+ guestfs_pop_error_handler (g);
|
||||
+ if (r == 0)
|
||||
+ goto opened;
|
||||
+ }
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ _("could not find key to open LUKS encrypted %s.\n\n"
|
||||
+ "Try using --key on the command line.\n\n"
|
||||
+ "Original error: %s (%d)"),
|
||||
+ partitions[i], guestfs_last_error (g),
|
||||
+ guestfs_last_errno (g));
|
||||
+
|
||||
+ opened:
|
||||
need_rescan = 1;
|
||||
}
|
||||
}
|
||||
diff --git a/common/options/keys.c b/common/options/keys.c
|
||||
index 74b549731..782bdb67f 100644
|
||||
--- a/common/options/keys.c
|
||||
+++ b/common/options/keys.c
|
||||
@@ -121,15 +121,32 @@ read_first_line_from_file (const char *filename)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-char *
|
||||
-get_key (struct key_store *ks, const char *device)
|
||||
+/* Return the key(s) matching this particular device from the
|
||||
+ * keystore. There may be multiple. If none are read from the
|
||||
+ * keystore, ask the user.
|
||||
+ */
|
||||
+char **
|
||||
+get_keys (struct key_store *ks, const char *device)
|
||||
{
|
||||
- size_t i;
|
||||
+ size_t i, j, len;
|
||||
+ char **r;
|
||||
+ char *s;
|
||||
+
|
||||
+ /* We know the returned list must have at least one element and not
|
||||
+ * more than ks->nr_keys.
|
||||
+ */
|
||||
+ len = 1;
|
||||
+ if (ks)
|
||||
+ len = MIN (1, ks->nr_keys);
|
||||
+ r = calloc (len+1, sizeof (char *));
|
||||
+ if (r == NULL)
|
||||
+ error (EXIT_FAILURE, errno, "calloc");
|
||||
+
|
||||
+ j = 0;
|
||||
|
||||
if (ks) {
|
||||
for (i = 0; i < ks->nr_keys; ++i) {
|
||||
struct key_store_key *key = &ks->keys[i];
|
||||
- char *s;
|
||||
|
||||
if (STRNEQ (key->device, device))
|
||||
continue;
|
||||
@@ -139,17 +156,25 @@ get_key (struct key_store *ks, const char *device)
|
||||
s = strdup (key->string.s);
|
||||
if (!s)
|
||||
error (EXIT_FAILURE, errno, "strdup");
|
||||
- return s;
|
||||
+ r[j++] = s;
|
||||
+ break;
|
||||
case key_file:
|
||||
- return read_first_line_from_file (key->file.name);
|
||||
+ s = read_first_line_from_file (key->file.name);
|
||||
+ r[j++] = s;
|
||||
+ break;
|
||||
}
|
||||
-
|
||||
- /* Key not found in the key store, ask the user for it. */
|
||||
- break;
|
||||
}
|
||||
}
|
||||
|
||||
- return read_key (device);
|
||||
+ if (j == 0) {
|
||||
+ /* Key not found in the key store, ask the user for it. */
|
||||
+ s = read_key (device);
|
||||
+ if (!s)
|
||||
+ error (EXIT_FAILURE, 0, _("could not read key from user"));
|
||||
+ r[0] = s;
|
||||
+ }
|
||||
+
|
||||
+ return r;
|
||||
}
|
||||
|
||||
struct key_store *
|
||||
diff --git a/common/options/options.h b/common/options/options.h
|
||||
index 6fadf1e76..510e8a8a9 100644
|
||||
--- a/common/options/options.h
|
||||
+++ b/common/options/options.h
|
||||
@@ -104,7 +104,9 @@ struct mp {
|
||||
|
||||
/* A key in the key store. */
|
||||
struct key_store_key {
|
||||
- /* The device this key refers to. */
|
||||
+ /* The device this key refers to. There may be multiple matching
|
||||
+ * devices in the list.
|
||||
+ */
|
||||
char *device;
|
||||
|
||||
enum {
|
||||
@@ -146,7 +148,7 @@ extern void print_inspect_prompt (void);
|
||||
|
||||
/* in key.c */
|
||||
extern char *read_key (const char *param);
|
||||
-extern char *get_key (struct key_store *ks, const char *device);
|
||||
+extern char **get_keys (struct key_store *ks, const char *device);
|
||||
extern struct key_store *key_store_add_from_selector (struct key_store *ks, const char *selector);
|
||||
extern struct key_store *key_store_import_key (struct key_store *ks, const struct key_store_key *key);
|
||||
extern void free_key_store (struct key_store *ks);
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,437 +0,0 @@
|
||||
From dd28c27df30c5a41bec97181a297d4df95aad0ab Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 29 Nov 2019 12:06:20 +0100
|
||||
Subject: [PATCH] options: rename key.device as key.id
|
||||
|
||||
In the future it will be also something else other than the device name.
|
||||
|
||||
(cherry picked from commit c863ee5e1df5e1eca7ad6821bd2db3796277a6bd
|
||||
in libguestfs-common)
|
||||
|
||||
PT: the documentation was amended manually.
|
||||
---
|
||||
cat/virt-cat.pod | 7 ++++---
|
||||
cat/virt-log.pod | 7 ++++---
|
||||
cat/virt-ls.pod | 7 ++++---
|
||||
cat/virt-tail.pod | 7 ++++---
|
||||
common/mltools/tools_utils-c.c | 4 ++--
|
||||
common/options/keys.c | 8 ++++----
|
||||
common/options/options.h | 8 +++++---
|
||||
customize/virt-customize.pod | 7 ++++---
|
||||
diff/virt-diff.pod | 7 ++++---
|
||||
edit/virt-edit.pod | 7 ++++---
|
||||
fish/guestfish.pod | 7 ++++---
|
||||
fuse/guestmount.pod | 7 ++++---
|
||||
get-kernel/virt-get-kernel.pod | 7 ++++---
|
||||
inspector/virt-inspector.pod | 7 ++++---
|
||||
sparsify/virt-sparsify.pod | 7 ++++---
|
||||
sysprep/virt-sysprep.pod | 7 ++++---
|
||||
v2v/virt-v2v.pod | 7 ++++---
|
||||
17 files changed, 67 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/cat/virt-cat.pod b/cat/virt-cat.pod
|
||||
index 745d4a4b6..b0301d636 100644
|
||||
--- a/cat/virt-cat.pod
|
||||
+++ b/cat/virt-cat.pod
|
||||
@@ -124,15 +124,16 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/cat/virt-log.pod b/cat/virt-log.pod
|
||||
index 8de000c5f..0d447b3b5 100644
|
||||
--- a/cat/virt-log.pod
|
||||
+++ b/cat/virt-log.pod
|
||||
@@ -108,15 +108,16 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/cat/virt-ls.pod b/cat/virt-ls.pod
|
||||
index 8d6a9fe37..de02a473d 100644
|
||||
--- a/cat/virt-ls.pod
|
||||
+++ b/cat/virt-ls.pod
|
||||
@@ -355,15 +355,16 @@ L</RECURSIVE LONG LISTING> above.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/cat/virt-tail.pod b/cat/virt-tail.pod
|
||||
index cf8700d1a..f00384f5d 100644
|
||||
--- a/cat/virt-tail.pod
|
||||
+++ b/cat/virt-tail.pod
|
||||
@@ -126,15 +126,16 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/common/mltools/tools_utils-c.c b/common/mltools/tools_utils-c.c
|
||||
index 3b80091c0..6c43b8d74 100644
|
||||
--- a/common/mltools/tools_utils-c.c
|
||||
+++ b/common/mltools/tools_utils-c.c
|
||||
@@ -57,8 +57,8 @@ guestfs_int_mllib_inspect_decrypt (value gv, value gpv, value keysv)
|
||||
struct key_store_key key;
|
||||
|
||||
elemv = Field (keysv, 0);
|
||||
- key.device = strdup (String_val (Field (elemv, 0)));
|
||||
- if (!key.device)
|
||||
+ key.id = strdup (String_val (Field (elemv, 0)));
|
||||
+ if (!key.id)
|
||||
caml_raise_out_of_memory ();
|
||||
|
||||
v = Field (elemv, 1);
|
||||
diff --git a/common/options/keys.c b/common/options/keys.c
|
||||
index 782bdb67f..7c391acde 100644
|
||||
--- a/common/options/keys.c
|
||||
+++ b/common/options/keys.c
|
||||
@@ -148,7 +148,7 @@ get_keys (struct key_store *ks, const char *device)
|
||||
for (i = 0; i < ks->nr_keys; ++i) {
|
||||
struct key_store_key *key = &ks->keys[i];
|
||||
|
||||
- if (STRNEQ (key->device, device))
|
||||
+ if (STRNEQ (key->id, device))
|
||||
continue;
|
||||
|
||||
switch (key->type) {
|
||||
@@ -193,8 +193,8 @@ key_store_add_from_selector (struct key_store *ks, const char *selector)
|
||||
}
|
||||
|
||||
/* 1: device */
|
||||
- key.device = strdup (fields[0]);
|
||||
- if (!key.device)
|
||||
+ key.id = strdup (fields[0]);
|
||||
+ if (!key.id)
|
||||
error (EXIT_FAILURE, errno, "strdup");
|
||||
|
||||
/* 2: key type */
|
||||
@@ -265,6 +265,6 @@ free_key_store (struct key_store *ks)
|
||||
free (key->file.name);
|
||||
break;
|
||||
}
|
||||
- free (key->device);
|
||||
+ free (key->id);
|
||||
}
|
||||
}
|
||||
diff --git a/common/options/options.h b/common/options/options.h
|
||||
index 510e8a8a9..b83a92b06 100644
|
||||
--- a/common/options/options.h
|
||||
+++ b/common/options/options.h
|
||||
@@ -104,10 +104,12 @@ struct mp {
|
||||
|
||||
/* A key in the key store. */
|
||||
struct key_store_key {
|
||||
- /* The device this key refers to. There may be multiple matching
|
||||
- * devices in the list.
|
||||
+ /* An ID for the device this key refers to. It must be the libguestfs
|
||||
+ * device name.
|
||||
+ *
|
||||
+ * There may be multiple matching devices in the list.
|
||||
*/
|
||||
- char *device;
|
||||
+ char *id;
|
||||
|
||||
enum {
|
||||
key_string, /* key specified as string */
|
||||
diff --git a/customize/virt-customize.pod b/customize/virt-customize.pod
|
||||
index d1b568040..491606591 100644
|
||||
--- a/customize/virt-customize.pod
|
||||
+++ b/customize/virt-customize.pod
|
||||
@@ -141,15 +141,16 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/diff/virt-diff.pod b/diff/virt-diff.pod
|
||||
index 36ee10ced..22658072d 100644
|
||||
--- a/diff/virt-diff.pod
|
||||
+++ b/diff/virt-diff.pod
|
||||
@@ -169,15 +169,16 @@ Display file sizes in human-readable format.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/edit/virt-edit.pod b/edit/virt-edit.pod
|
||||
index 3cb3ce6da..5a63cd05f 100644
|
||||
--- a/edit/virt-edit.pod
|
||||
+++ b/edit/virt-edit.pod
|
||||
@@ -156,15 +156,16 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/fish/guestfish.pod b/fish/guestfish.pod
|
||||
index 06644c5b8..ccb57b159 100644
|
||||
--- a/fish/guestfish.pod
|
||||
+++ b/fish/guestfish.pod
|
||||
@@ -283,15 +283,16 @@ were found.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/fuse/guestmount.pod b/fuse/guestmount.pod
|
||||
index 9319d093c..d9e957b8b 100644
|
||||
--- a/fuse/guestmount.pod
|
||||
+++ b/fuse/guestmount.pod
|
||||
@@ -249,15 +249,16 @@ mounted on the real virtual machine.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/get-kernel/virt-get-kernel.pod b/get-kernel/virt-get-kernel.pod
|
||||
index 3802412e2..f0ace2d6d 100644
|
||||
--- a/get-kernel/virt-get-kernel.pod
|
||||
+++ b/get-kernel/virt-get-kernel.pod
|
||||
@@ -92,15 +92,16 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/inspector/virt-inspector.pod b/inspector/virt-inspector.pod
|
||||
index 98b278f26..eac9dc3cd 100644
|
||||
--- a/inspector/virt-inspector.pod
|
||||
+++ b/inspector/virt-inspector.pod
|
||||
@@ -117,15 +117,16 @@ ensure the format is always specified.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/sparsify/virt-sparsify.pod b/sparsify/virt-sparsify.pod
|
||||
index 3f5f9995f..cf7970a5f 100644
|
||||
--- a/sparsify/virt-sparsify.pod
|
||||
+++ b/sparsify/virt-sparsify.pod
|
||||
@@ -233,15 +233,16 @@ See L</IN-PLACE SPARSIFICATION> below.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/sysprep/virt-sysprep.pod b/sysprep/virt-sysprep.pod
|
||||
index 8d248db94..d7ad7ee33 100644
|
||||
--- a/sysprep/virt-sysprep.pod
|
||||
+++ b/sysprep/virt-sysprep.pod
|
||||
@@ -189,15 +189,16 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
||||
index 0642d158f..8c2867814 100644
|
||||
--- a/v2v/virt-v2v.pod
|
||||
+++ b/v2v/virt-v2v.pod
|
||||
@@ -337,15 +337,16 @@ through VDDK.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<SELECTOR> can be in one of the following formats:
|
||||
+the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
+device.
|
||||
|
||||
=over 4
|
||||
|
||||
-=item B<--key> C<DEVICE>:key:KEY_STRING
|
||||
+=item B<--key> C<ID>:key:KEY_STRING
|
||||
|
||||
Use the specified C<KEY_STRING> as passphrase.
|
||||
|
||||
-=item B<--key> C<DEVICE>:file:FILENAME
|
||||
+=item B<--key> C<ID>:file:FILENAME
|
||||
|
||||
Read the passphrase from F<FILENAME>.
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,313 +0,0 @@
|
||||
From 88c4dc1e5b9f9e545c89e8b8ee6878f57df3139c Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 29 Nov 2019 12:07:13 +0100
|
||||
Subject: [PATCH] options: allow a UUID as identifier for --key
|
||||
|
||||
This way it is possible to specify the UUID of the LUKS device instead
|
||||
of the libguestfs device name to decrypt a device during the inspection.
|
||||
|
||||
Make the usage of the new luks_uuid API conditional, so other projects
|
||||
using the common submodule do not require a libguestfs version bump.
|
||||
|
||||
(cherry picked from commit bb4a2dc17a78b53437896d4215ae82df8e11b788
|
||||
in libguestfs-common)
|
||||
|
||||
PT: the documentation was amended manually.
|
||||
---
|
||||
cat/virt-cat.pod | 4 ++--
|
||||
cat/virt-log.pod | 4 ++--
|
||||
cat/virt-ls.pod | 4 ++--
|
||||
cat/virt-tail.pod | 4 ++--
|
||||
common/options/decrypt.c | 8 +++++++-
|
||||
common/options/keys.c | 4 ++--
|
||||
common/options/options.h | 6 +++---
|
||||
customize/virt-customize.pod | 4 ++--
|
||||
diff/virt-diff.pod | 4 ++--
|
||||
edit/virt-edit.pod | 4 ++--
|
||||
fish/guestfish.pod | 4 ++--
|
||||
fuse/guestmount.pod | 4 ++--
|
||||
get-kernel/virt-get-kernel.pod | 4 ++--
|
||||
inspector/virt-inspector.pod | 4 ++--
|
||||
sparsify/virt-sparsify.pod | 4 ++--
|
||||
sysprep/virt-sysprep.pod | 4 ++--
|
||||
v2v/virt-v2v.pod | 4 ++--
|
||||
17 files changed, 40 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/cat/virt-cat.pod b/cat/virt-cat.pod
|
||||
index b0301d636..2cea291ac 100644
|
||||
--- a/cat/virt-cat.pod
|
||||
+++ b/cat/virt-cat.pod
|
||||
@@ -124,8 +124,8 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/cat/virt-log.pod b/cat/virt-log.pod
|
||||
index 0d447b3b5..888108d5f 100644
|
||||
--- a/cat/virt-log.pod
|
||||
+++ b/cat/virt-log.pod
|
||||
@@ -108,8 +108,8 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/cat/virt-ls.pod b/cat/virt-ls.pod
|
||||
index de02a473d..307e79395 100644
|
||||
--- a/cat/virt-ls.pod
|
||||
+++ b/cat/virt-ls.pod
|
||||
@@ -355,8 +355,8 @@ L</RECURSIVE LONG LISTING> above.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/cat/virt-tail.pod b/cat/virt-tail.pod
|
||||
index f00384f5d..a804f4cf3 100644
|
||||
--- a/cat/virt-tail.pod
|
||||
+++ b/cat/virt-tail.pod
|
||||
@@ -126,8 +126,8 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/common/options/decrypt.c b/common/options/decrypt.c
|
||||
index 3511d9fe9..683cf5ed4 100644
|
||||
--- a/common/options/decrypt.c
|
||||
+++ b/common/options/decrypt.c
|
||||
@@ -86,7 +86,13 @@ inspect_do_decrypt (guestfs_h *g, struct key_store *ks)
|
||||
char mapname[32];
|
||||
make_mapname (partitions[i], mapname, sizeof mapname);
|
||||
|
||||
- CLEANUP_FREE_STRING_LIST char **keys = get_keys (ks, partitions[i]);
|
||||
+#ifdef GUESTFS_HAVE_LUKS_UUID
|
||||
+ CLEANUP_FREE char *uuid = guestfs_luks_uuid (g, partitions[i]);
|
||||
+#else
|
||||
+ const char *uuid = NULL;
|
||||
+#endif
|
||||
+
|
||||
+ CLEANUP_FREE_STRING_LIST char **keys = get_keys (ks, partitions[i], uuid);
|
||||
assert (guestfs_int_count_strings (keys) > 0);
|
||||
|
||||
/* Try each key in turn. */
|
||||
diff --git a/common/options/keys.c b/common/options/keys.c
|
||||
index 7c391acde..798315c2e 100644
|
||||
--- a/common/options/keys.c
|
||||
+++ b/common/options/keys.c
|
||||
@@ -126,7 +126,7 @@ read_first_line_from_file (const char *filename)
|
||||
* keystore, ask the user.
|
||||
*/
|
||||
char **
|
||||
-get_keys (struct key_store *ks, const char *device)
|
||||
+get_keys (struct key_store *ks, const char *device, const char *uuid)
|
||||
{
|
||||
size_t i, j, len;
|
||||
char **r;
|
||||
@@ -148,7 +148,7 @@ get_keys (struct key_store *ks, const char *device)
|
||||
for (i = 0; i < ks->nr_keys; ++i) {
|
||||
struct key_store_key *key = &ks->keys[i];
|
||||
|
||||
- if (STRNEQ (key->id, device))
|
||||
+ if (STRNEQ (key->id, device) && (uuid && STRNEQ (key->id, uuid)))
|
||||
continue;
|
||||
|
||||
switch (key->type) {
|
||||
diff --git a/common/options/options.h b/common/options/options.h
|
||||
index b83a92b06..9b7830220 100644
|
||||
--- a/common/options/options.h
|
||||
+++ b/common/options/options.h
|
||||
@@ -104,8 +104,8 @@ struct mp {
|
||||
|
||||
/* A key in the key store. */
|
||||
struct key_store_key {
|
||||
- /* An ID for the device this key refers to. It must be the libguestfs
|
||||
- * device name.
|
||||
+ /* An ID for the device this key refers to. It can be either the libguestfs
|
||||
+ * device name, or the UUID.
|
||||
*
|
||||
* There may be multiple matching devices in the list.
|
||||
*/
|
||||
@@ -150,7 +150,7 @@ extern void print_inspect_prompt (void);
|
||||
|
||||
/* in key.c */
|
||||
extern char *read_key (const char *param);
|
||||
-extern char **get_keys (struct key_store *ks, const char *device);
|
||||
+extern char **get_keys (struct key_store *ks, const char *device, const char *uuid);
|
||||
extern struct key_store *key_store_add_from_selector (struct key_store *ks, const char *selector);
|
||||
extern struct key_store *key_store_import_key (struct key_store *ks, const struct key_store_key *key);
|
||||
extern void free_key_store (struct key_store *ks);
|
||||
diff --git a/customize/virt-customize.pod b/customize/virt-customize.pod
|
||||
index 491606591..5d92486a2 100644
|
||||
--- a/customize/virt-customize.pod
|
||||
+++ b/customize/virt-customize.pod
|
||||
@@ -141,8 +141,8 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/diff/virt-diff.pod b/diff/virt-diff.pod
|
||||
index 22658072d..e67d09101 100644
|
||||
--- a/diff/virt-diff.pod
|
||||
+++ b/diff/virt-diff.pod
|
||||
@@ -169,8 +169,8 @@ Display file sizes in human-readable format.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/edit/virt-edit.pod b/edit/virt-edit.pod
|
||||
index 5a63cd05f..918fa66f2 100644
|
||||
--- a/edit/virt-edit.pod
|
||||
+++ b/edit/virt-edit.pod
|
||||
@@ -156,8 +156,8 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/fish/guestfish.pod b/fish/guestfish.pod
|
||||
index ccb57b159..f1fdf094d 100644
|
||||
--- a/fish/guestfish.pod
|
||||
+++ b/fish/guestfish.pod
|
||||
@@ -283,8 +283,8 @@ were found.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/fuse/guestmount.pod b/fuse/guestmount.pod
|
||||
index d9e957b8b..3a02c087c 100644
|
||||
--- a/fuse/guestmount.pod
|
||||
+++ b/fuse/guestmount.pod
|
||||
@@ -249,8 +249,8 @@ mounted on the real virtual machine.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/get-kernel/virt-get-kernel.pod b/get-kernel/virt-get-kernel.pod
|
||||
index f0ace2d6d..78fe66df4 100644
|
||||
--- a/get-kernel/virt-get-kernel.pod
|
||||
+++ b/get-kernel/virt-get-kernel.pod
|
||||
@@ -92,8 +92,8 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/inspector/virt-inspector.pod b/inspector/virt-inspector.pod
|
||||
index eac9dc3cd..625da876c 100644
|
||||
--- a/inspector/virt-inspector.pod
|
||||
+++ b/inspector/virt-inspector.pod
|
||||
@@ -117,8 +117,8 @@ ensure the format is always specified.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/sparsify/virt-sparsify.pod b/sparsify/virt-sparsify.pod
|
||||
index cf7970a5f..0767d07e6 100644
|
||||
--- a/sparsify/virt-sparsify.pod
|
||||
+++ b/sparsify/virt-sparsify.pod
|
||||
@@ -233,8 +233,8 @@ See L</IN-PLACE SPARSIFICATION> below.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/sysprep/virt-sysprep.pod b/sysprep/virt-sysprep.pod
|
||||
index d7ad7ee33..b38c76c70 100644
|
||||
--- a/sysprep/virt-sysprep.pod
|
||||
+++ b/sysprep/virt-sysprep.pod
|
||||
@@ -189,8 +189,8 @@ security problem with malicious guests (CVE-2010-3851).
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
||||
index 8c2867814..25041d0ec 100644
|
||||
--- a/v2v/virt-v2v.pod
|
||||
+++ b/v2v/virt-v2v.pod
|
||||
@@ -337,8 +337,8 @@ through VDDK.
|
||||
=item B<--key> SELECTOR
|
||||
|
||||
Specify a key for LUKS, to automatically open a LUKS device when using
|
||||
-the inspection. C<ID> must be the libguestfs device name of the LUKS
|
||||
-device.
|
||||
+the inspection. C<ID> can be either the libguestfs device name, or
|
||||
+the UUID of the LUKS device.
|
||||
|
||||
=over 4
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,82 +0,0 @@
|
||||
From 14c456c0f5d9caad9aedc5abb7b6a025ac09e7bd Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Wed, 18 Dec 2019 12:12:26 +0100
|
||||
Subject: [PATCH] docs: remove paragraph about VMware tools on Windows
|
||||
(RHBZ#1785528)
|
||||
|
||||
Starting from libguestfs/virt-v2v 1.39.12, virt-v2v attempts to
|
||||
uninstall the VMware tools from Windows guests, so there is no need to
|
||||
remove them manually before the conversion.
|
||||
|
||||
Thanks to: Ming Xie.
|
||||
|
||||
(cherry picked from commit 397b4a90d16f4eb116d55605cbdf3bd844108315
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/virt-v2v-input-vmware.pod | 36 -----------------------------------
|
||||
1 file changed, 36 deletions(-)
|
||||
|
||||
diff --git a/v2v/virt-v2v-input-vmware.pod b/v2v/virt-v2v-input-vmware.pod
|
||||
index 3acdd773e..16ddb045f 100644
|
||||
--- a/v2v/virt-v2v-input-vmware.pod
|
||||
+++ b/v2v/virt-v2v-input-vmware.pod
|
||||
@@ -106,18 +106,6 @@ If you find a folder of files called F<I<guest>.vmx>,
|
||||
F<I<guest>.vmxf>, F<I<guest>.nvram> and one or more F<.vmdk> disk
|
||||
images, then you can use this method.
|
||||
|
||||
-=head2 VMX: Remove VMware tools from Windows guests
|
||||
-
|
||||
-For Windows guests, you should remove VMware tools before conversion.
|
||||
-Although this is not strictly necessary, and the guest will still be
|
||||
-able to run, if you don't do this then the converted guest will
|
||||
-complain on every boot. The tools cannot be removed after conversion
|
||||
-because the uninstaller checks if it is running on VMware and refuses
|
||||
-to start (which is also the reason that virt-v2v cannot remove them).
|
||||
-
|
||||
-This is not necessary for Linux guests, as virt-v2v is able to remove
|
||||
-VMware tools.
|
||||
-
|
||||
=head2 VMX: Guest must be shut down
|
||||
|
||||
B<The guest must be shut down before conversion starts>. If you don't
|
||||
@@ -319,18 +307,6 @@ Virt-v2v is able to import guests from VMware’s OVA (Open
|
||||
Virtualization Appliance) files. Only OVAs exported from VMware
|
||||
vSphere will work.
|
||||
|
||||
-=head2 OVA: Remove VMware tools from Windows guests
|
||||
-
|
||||
-For Windows guests, you should remove VMware tools before conversion.
|
||||
-Although this is not strictly necessary, and the guest will still be
|
||||
-able to run, if you don't do this then the converted guest will
|
||||
-complain on every boot. The tools cannot be removed after conversion
|
||||
-because the uninstaller checks if it is running on VMware and refuses
|
||||
-to start (which is also the reason that virt-v2v cannot remove them).
|
||||
-
|
||||
-This is not necessary for Linux guests, as virt-v2v is able to remove
|
||||
-VMware tools.
|
||||
-
|
||||
=head2 OVA: Create OVA
|
||||
|
||||
To create an OVA in vSphere, use the "Export OVF Template" option
|
||||
@@ -383,18 +359,6 @@ Virt-v2v uses libvirt for access to vCenter, and therefore the input
|
||||
mode should be I<-i libvirt>. As this is the default, you don't need
|
||||
to specify it on the command line.
|
||||
|
||||
-=head2 vCenter: Remove VMware tools from Windows guests
|
||||
-
|
||||
-For Windows guests, you should remove VMware tools before conversion.
|
||||
-Although this is not strictly necessary, and the guest will still be
|
||||
-able to run, if you don't do this then the converted guest will
|
||||
-complain on every boot. The tools cannot be removed after conversion
|
||||
-because the uninstaller checks if it is running on VMware and refuses
|
||||
-to start (which is also the reason that virt-v2v cannot remove them).
|
||||
-
|
||||
-This is not necessary for Linux guests, as virt-v2v is able to remove
|
||||
-VMware tools.
|
||||
-
|
||||
=head2 vCenter: URI
|
||||
|
||||
The libvirt URI of a vCenter server looks something like this:
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,29 +0,0 @@
|
||||
From 931846b8f08e5e763141cadfc5e9b194b69303e3 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Kletzander <mkletzan@redhat.com>
|
||||
Date: Mon, 24 Feb 2020 13:12:03 +0100
|
||||
Subject: [PATCH] mlcustomize: Trim whitespaces from commands read from file
|
||||
(RHBZ#1351000)
|
||||
|
||||
The first split does not care about the whole string, it is just trying to get
|
||||
the command name in front, so triml is just right.
|
||||
|
||||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||
---
|
||||
generator/customize.ml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/generator/customize.ml b/generator/customize.ml
|
||||
index c278347c1..0b256e2d2 100644
|
||||
--- a/generator/customize.ml
|
||||
+++ b/generator/customize.ml
|
||||
@@ -873,6 +873,7 @@ let rec argspec () =
|
||||
pr " ] in
|
||||
let lines = read_whole_file filename in
|
||||
let lines = String.lines_split lines in
|
||||
+ let lines = List.map String.triml lines in
|
||||
let lines = List.filter (
|
||||
fun line ->
|
||||
String.length line > 0 && line.[0] <> '#'
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,43 +0,0 @@
|
||||
From 7cfbc1e0fac86b1139c59945f74eab8906ec18bc Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 4 Feb 2020 14:39:39 +0000
|
||||
Subject: [PATCH] openstack: Increase Cinder volume attach timeout to 5 minutes
|
||||
(RHBZ#1685032).
|
||||
|
||||
In some cases we have observed the time taken for a Cinder volume to
|
||||
attach to the conversion appliance can be longer than the current 60
|
||||
seconds. Increase the timeout to 5 minutes.
|
||||
|
||||
Thanks: Ming Xie.
|
||||
|
||||
(cherry picked from commit e2ce290f6e366716f857eeaddc1dc680e5608c80
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/output_openstack.ml | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/v2v/output_openstack.ml b/v2v/output_openstack.ml
|
||||
index d187f1d5d..bebf9af18 100644
|
||||
--- a/v2v/output_openstack.ml
|
||||
+++ b/v2v/output_openstack.ml
|
||||
@@ -38,7 +38,7 @@ let openstack_binary = "openstack"
|
||||
let available_timeout = 300 (* seconds *)
|
||||
|
||||
(* Timeout waiting for Cinder volumes to attach to the appliance. *)
|
||||
-let attach_timeout = 60 (* seconds *)
|
||||
+let attach_timeout = 300 (* seconds *)
|
||||
|
||||
(* The -oo options supported by this output method. *)
|
||||
type os_options = {
|
||||
@@ -336,7 +336,7 @@ class output_openstack output_conn output_password output_storage
|
||||
if String.length id > prefix_len then String.sub id 0 prefix_len
|
||||
else id in
|
||||
|
||||
- with_timeout
|
||||
+ with_timeout ~sleep:5
|
||||
(sprintf (f_"waiting for cinder volume %s to attach to the conversion appliance") id)
|
||||
attach_timeout
|
||||
(fun () ->
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,35 +0,0 @@
|
||||
From 303ecfdf662a2fd80b115a1e2f20560e6f97d953 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Thu, 19 Sep 2019 09:52:41 +0200
|
||||
Subject: [PATCH] v2v: -o rhv-upload: check for a valid image transfer right
|
||||
away
|
||||
|
||||
Check for the INITIALIZING state of the image transfer right away,
|
||||
without waiting 5 seconds even before the first time: this way, if the
|
||||
transfer is already in the right state then there is no need to wait.
|
||||
---
|
||||
v2v/rhv-upload-plugin.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
||||
index 6ec74a5d4..7f62b4e3b 100644
|
||||
--- a/v2v/rhv-upload-plugin.py
|
||||
+++ b/v2v/rhv-upload-plugin.py
|
||||
@@ -190,13 +190,13 @@ def open(readonly):
|
||||
# actual transfer can start when its status is "Transferring".
|
||||
endt = time.time() + timeout
|
||||
while True:
|
||||
- time.sleep(5)
|
||||
transfer = transfer_service.get()
|
||||
if transfer.phase != types.ImageTransferPhase.INITIALIZING:
|
||||
break
|
||||
if time.time() > endt:
|
||||
raise RuntimeError("timed out waiting for transfer status "
|
||||
"!= INITIALIZING")
|
||||
+ time.sleep(5)
|
||||
|
||||
# Now we have permission to start the transfer.
|
||||
if params['rhv_direct']:
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,49 +0,0 @@
|
||||
From 7a4b425471223234fde5a65ca5fe5abc87fb0276 Mon Sep 17 00:00:00 2001
|
||||
From: Nir Soffer <nirsof@gmail.com>
|
||||
Date: Mon, 18 Nov 2019 01:04:24 +0200
|
||||
Subject: [PATCH] rhv-upload: Check status more frequently
|
||||
|
||||
Checking status more frequently save a couple of seconds. Here is
|
||||
an example flow tested with oVirt upload_disk.py example:
|
||||
|
||||
With 5 seconds wait:
|
||||
|
||||
Created disk in 11.085111 seconds
|
||||
Created transfer in 1.857502 seconds
|
||||
|
||||
With 1 second wait:
|
||||
|
||||
Created disk in 4.991227 seconds
|
||||
Created transfer in 1.961243 seconds
|
||||
|
||||
(cherry picked from commit 8816c5db220f518ef70beec7ac543290e3d5c0c7
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/rhv-upload-plugin.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
||||
index 7f62b4e3b..f13405df1 100644
|
||||
--- a/v2v/rhv-upload-plugin.py
|
||||
+++ b/v2v/rhv-upload-plugin.py
|
||||
@@ -161,7 +161,7 @@ def open(readonly):
|
||||
|
||||
endt = time.time() + timeout
|
||||
while True:
|
||||
- time.sleep(5)
|
||||
+ time.sleep(1)
|
||||
disk = disk_service.get()
|
||||
if disk.status == types.DiskStatus.OK:
|
||||
break
|
||||
@@ -196,7 +196,7 @@ def open(readonly):
|
||||
if time.time() > endt:
|
||||
raise RuntimeError("timed out waiting for transfer status "
|
||||
"!= INITIALIZING")
|
||||
- time.sleep(5)
|
||||
+ time.sleep(1)
|
||||
|
||||
# Now we have permission to start the transfer.
|
||||
if params['rhv_direct']:
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 8659766f3559177edf60f7ed6e1ed834f5d4d4a0 Mon Sep 17 00:00:00 2001
|
||||
From: Nir Soffer <nirsof@gmail.com>
|
||||
Date: Mon, 18 Nov 2019 23:53:46 +0200
|
||||
Subject: [PATCH] rhv-upload: Show transfer id in error message
|
||||
|
||||
(cherry picked from commit d4ca9b6ca42d4ad3c717f5c59402ca6ff5d322bb
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/rhv-upload-plugin.py | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
||||
index f13405df1..9b83d1cfa 100644
|
||||
--- a/v2v/rhv-upload-plugin.py
|
||||
+++ b/v2v/rhv-upload-plugin.py
|
||||
@@ -194,8 +194,10 @@ def open(readonly):
|
||||
if transfer.phase != types.ImageTransferPhase.INITIALIZING:
|
||||
break
|
||||
if time.time() > endt:
|
||||
- raise RuntimeError("timed out waiting for transfer status "
|
||||
- "!= INITIALIZING")
|
||||
+ raise RuntimeError(
|
||||
+ "timed out waiting for transfer %s status != INITIALIZING"
|
||||
+ % transfer.id)
|
||||
+
|
||||
time.sleep(1)
|
||||
|
||||
# Now we have permission to start the transfer.
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,89 +0,0 @@
|
||||
From 79a7e239ca55bffb2af059e1cfe07206d37cb858 Mon Sep 17 00:00:00 2001
|
||||
From: Nir Soffer <nsoffer@redhat.com>
|
||||
Date: Thu, 28 Nov 2019 20:36:32 +0200
|
||||
Subject: [PATCH] rhv-upload: Fix waiting for transfer
|
||||
|
||||
We were not considering failures while initializing the transfer. In
|
||||
this case the transfer phase can change to PAUSED_SYSTEM or
|
||||
FINISHED_FAILURE, and transfer_url will be None, which failed the
|
||||
upload with a misleading error:
|
||||
|
||||
RuntimeError: direct upload to host not supported, requires
|
||||
ovirt-engine >= 4.2 and only works when virt-v2v is run within the
|
||||
oVirt/RHV environment, eg. on an oVirt node
|
||||
|
||||
Change the wait loop to consider all cases:
|
||||
- Transfer failed and was removed
|
||||
- Transfer failed and will be removed soon
|
||||
- Transfer paused by the system (cancel required)
|
||||
- Unexpected transfer phase (cancel required)
|
||||
- Timeout waiting for TRANSFERRING state (cancel required)
|
||||
|
||||
Reported-by: Xiaodai Wang
|
||||
|
||||
(cherry picked from commit 40e1844827e4d096b1919a2159f9effc41915a73
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/rhv-upload-plugin.py | 41 +++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 32 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
||||
index 9b83d1cfa..14d4e37fb 100644
|
||||
--- a/v2v/rhv-upload-plugin.py
|
||||
+++ b/v2v/rhv-upload-plugin.py
|
||||
@@ -185,20 +185,43 @@ def open(readonly):
|
||||
# Get a reference to the created transfer service.
|
||||
transfer_service = transfers_service.image_transfer_service(transfer.id)
|
||||
|
||||
- # After adding a new transfer for the disk, the transfer's status
|
||||
- # will be INITIALIZING. Wait until the init phase is over. The
|
||||
- # actual transfer can start when its status is "Transferring".
|
||||
+ # Wait until transfer's phase change from INITIALIZING to TRANSFERRING. On
|
||||
+ # errors transfer's phase can change to PAUSED_SYSTEM or FINISHED_FAILURE.
|
||||
+ # If the transfer was paused, we need to cancel it to remove the disk,
|
||||
+ # otherwise the system will remove the disk and transfer shortly after.
|
||||
+
|
||||
endt = time.time() + timeout
|
||||
while True:
|
||||
- transfer = transfer_service.get()
|
||||
+ time.sleep(1)
|
||||
+ try:
|
||||
+ transfer = transfer_service.get()
|
||||
+ except sdk.NotFoundError:
|
||||
+ # The system has removed the disk and the transfer.
|
||||
+ raise RuntimeError("transfer %s was removed" % transfer.id)
|
||||
+
|
||||
+ if transfer.phase == types.ImageTransferPhase.FINISHED_FAILURE:
|
||||
+ # The system will remove the disk and the transfer soon.
|
||||
+ raise RuntimeError(
|
||||
+ "transfer %s has failed" % transfer.id)
|
||||
+
|
||||
+ if transfer.phase == types.ImageTransferPhase.PAUSED_SYSTEM:
|
||||
+ transfer_service.cancel()
|
||||
+ raise RuntimeError(
|
||||
+ "transfer %s was paused by system" % transfer.id)
|
||||
+
|
||||
+ if transfer.phase == types.ImageTransferPhase.TRANSFERRING:
|
||||
+ break
|
||||
+
|
||||
if transfer.phase != types.ImageTransferPhase.INITIALIZING:
|
||||
- break
|
||||
- if time.time() > endt:
|
||||
+ transfer_service.cancel()
|
||||
raise RuntimeError(
|
||||
- "timed out waiting for transfer %s status != INITIALIZING"
|
||||
- % transfer.id)
|
||||
+ "unexpected transfer %s phase %s"
|
||||
+ % (transfer.id, transfer.phase))
|
||||
|
||||
- time.sleep(1)
|
||||
+ if time.time() > endt:
|
||||
+ transfer_service.cancel()
|
||||
+ raise RuntimeError(
|
||||
+ "timed out waiting for transfer %s" % transfer.id)
|
||||
|
||||
# Now we have permission to start the transfer.
|
||||
if params['rhv_direct']:
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,84 +0,0 @@
|
||||
From 48718639cc7fc5f93260b00553397ccb3faa7bbc Mon Sep 17 00:00:00 2001
|
||||
From: Nir Soffer <nirsof@gmail.com>
|
||||
Date: Fri, 1 Nov 2019 22:56:18 +0100
|
||||
Subject: [PATCH] v2v: Optimize convert for images with small holes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
"qemu-img convert" detects zeroes in allocated areas and punch holes in
|
||||
the destination image. This may save space on the destination image, but
|
||||
slows down conversion when using outputs such as rhv-upload, which have
|
||||
very large overhead per requests.
|
||||
|
||||
Using the -S flag, we can treat small areas filled with zeroes as data,
|
||||
limiting the number of requests, and speeding the operation.
|
||||
|
||||
Here is an example converting Fedora 30 image:
|
||||
|
||||
$ virt-builder fedora-30 -o src.img
|
||||
...
|
||||
|
||||
$ qemu-img map -f raw --output json src.img | wc -l
|
||||
213
|
||||
|
||||
$ qemu-img convert -f raw -O raw -t none -T none src.img dst.img
|
||||
|
||||
$ qemu-img map -f raw --output json dst.img | wc -l
|
||||
1443
|
||||
|
||||
$ ls -lhs *.img
|
||||
1.2G -rw-r--r--. 1 nsoffer nsoffer 6.0G Nov 1 21:48 dst.img
|
||||
1.2G -rw-r--r--. 1 nsoffer nsoffer 6.0G Nov 1 21:46 src.img
|
||||
|
||||
Qemu did 1443 writes instead of 213 (5.8X). Lets repeat this conversion
|
||||
with the -S option:
|
||||
|
||||
$ qemu-img convert -f raw -O raw -t none -T none -S 64k src.img dst.img
|
||||
|
||||
$ qemu-img map -f raw --output json dst.img | wc -l
|
||||
213
|
||||
|
||||
$ ls -lhs *.img
|
||||
1.2G -rw-r--r--. 1 nsoffer nsoffer 6.0G Nov 1 21:48 dst.img
|
||||
1.2G -rw-r--r--. 1 nsoffer nsoffer 6.0G Nov 1 21:46 src.img
|
||||
|
||||
Picking a good value for -S is not easy. Testing show that 64k is best
|
||||
value for this test image for limiting the number of requests:
|
||||
|
||||
$ for size in 4k 8k 16k 32k 64k; do \
|
||||
printf "%5s: " $size; \
|
||||
qemu-img convert -f raw -O raw -t none -T none -S $size src.img dst.img; \
|
||||
qemu-img map -f raw --output json dst.img | wc -l; \
|
||||
done
|
||||
4k: 1443
|
||||
8k: 731
|
||||
16k: 521
|
||||
32k: 387
|
||||
64k: 213
|
||||
|
||||
We need more testing with oVirt to measure the performance improvement
|
||||
and pick a good value. This should probably be an option, but lets start
|
||||
with a minimal change.
|
||||
|
||||
(cherry picked from commit 2aa78ade2d48e926b7b04050338ebd8a0c5e3f05
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/v2v.ml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
|
||||
index d7a868659..a81a2320a 100644
|
||||
--- a/v2v/v2v.ml
|
||||
+++ b/v2v/v2v.ml
|
||||
@@ -754,6 +754,7 @@ and copy_targets cmdline targets input output =
|
||||
(if not (quiet ()) then [ "-p" ] else []) @
|
||||
[ "-n"; "-f"; "qcow2"; "-O"; t.target_format ] @
|
||||
(if cmdline.compressed then [ "-c" ] else []) @
|
||||
+ [ "-S"; "64k" ] @
|
||||
[ overlay_file; filename ] in
|
||||
let start_time = gettimeofday () in
|
||||
if run_command cmd <> 0 then
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,49 +0,0 @@
|
||||
From fdf461e88c464de697c14adea2e8e61644811844 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Wed, 15 Jan 2020 11:12:17 +0000
|
||||
Subject: [PATCH] v2v: -o rhv-upload: Make -oo rhv-cafile optional in all cases
|
||||
(RHBZ#1791240).
|
||||
|
||||
This is actually not required, because ovirtsdk4 will use the system's
|
||||
global trust store if necessary. Therefore we can make it optional in
|
||||
all cases.
|
||||
|
||||
(cherry picked from commit 65ee9387d4be0e3c5cd214b967fef7a1a8841233
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/output_rhv_upload.ml | 2 --
|
||||
v2v/virt-v2v-output-rhv.pod | 5 ++++-
|
||||
2 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||
index 2c8c18732..e1d06867b 100644
|
||||
--- a/v2v/output_rhv_upload.ml
|
||||
+++ b/v2v/output_rhv_upload.ml
|
||||
@@ -81,8 +81,6 @@ let parse_output_options options =
|
||||
let rhv_direct = !rhv_direct in
|
||||
let rhv_verifypeer = !rhv_verifypeer in
|
||||
let rhv_disk_uuids = Option.map List.rev !rhv_disk_uuids in
|
||||
- if rhv_verifypeer && rhv_cafile = None then
|
||||
- error (f_"-o rhv-upload: must use ‘-oo rhv-cafile’ to supply the path to the oVirt or RHV user’s ‘ca.pem’ file");
|
||||
|
||||
{ rhv_cafile; rhv_cluster; rhv_direct; rhv_verifypeer; rhv_disk_uuids }
|
||||
|
||||
diff --git a/v2v/virt-v2v-output-rhv.pod b/v2v/virt-v2v-output-rhv.pod
|
||||
index 04a894268..4520c9184 100644
|
||||
--- a/v2v/virt-v2v-output-rhv.pod
|
||||
+++ b/v2v/virt-v2v-output-rhv.pod
|
||||
@@ -101,7 +101,10 @@ The storage domain.
|
||||
The F<ca.pem> file (Certificate Authority), copied from
|
||||
F</etc/pki/ovirt-engine/ca.pem> on the oVirt engine.
|
||||
|
||||
-This option must be specified if I<-oo rhv-verifypeer> is enabled.
|
||||
+If I<-oo rhv-verifypeer> is enabled then this option can
|
||||
+be used to control which CA is used to verify the client’s
|
||||
+identity. If this option is not used then the system’s
|
||||
+global trust store is used.
|
||||
|
||||
=item I<-oo rhv-cluster=>C<CLUSTERNAME>
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 99de55c364d95ae50a6d6cd6865e52a6737738c5 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Wed, 15 Jan 2020 10:55:27 +0000
|
||||
Subject: [PATCH] docs: Fix update-crypto-policies command (RHBZ#1791257).
|
||||
|
||||
The command as documented was wrong. We need to use the --set option
|
||||
to change the policy.
|
||||
|
||||
Fixes commit d5cbe7b4bee5dec9e28b1db03e933c97ef6d11e0.
|
||||
Thanks: Xiaodai Wang
|
||||
|
||||
(cherry picked from commit 0edf419e983fe75daef9eaa7bd0578cbcada2e73
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/virt-v2v-input-xen.pod | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/virt-v2v-input-xen.pod b/v2v/virt-v2v-input-xen.pod
|
||||
index 4bb5d2dc2..9fd5065f1 100644
|
||||
--- a/v2v/virt-v2v-input-xen.pod
|
||||
+++ b/v2v/virt-v2v-input-xen.pod
|
||||
@@ -37,7 +37,7 @@ to interoperate with RHEL 5 sshd are disabled. To enable them you may
|
||||
need to run this command on the conversion server (ie. ssh client),
|
||||
but read L<update-crypto-policies(8)> first:
|
||||
|
||||
- # update-crypto-policies LEGACY
|
||||
+ # update-crypto-policies --set LEGACY
|
||||
|
||||
=head2 Test libvirt connection to remote Xen host
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,35 +0,0 @@
|
||||
From 2a08f0f71b92a2489b873c7cef5aae2b2cec88d2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Thu, 16 Jan 2020 16:05:10 +0100
|
||||
Subject: [PATCH] add versioned directory for guest agent on EL8
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There was no source directory for EL8 guest agent (only EL6 and EL7).
|
||||
|
||||
RHBZ#1791802
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
|
||||
(cherry picked from commit 79dd6a6bbb7e95691be18f54d601318d7d713702
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/windows_virtio.ml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
|
||||
index a6dc29f2c..7be63a316 100644
|
||||
--- a/v2v/windows_virtio.ml
|
||||
+++ b/v2v/windows_virtio.ml
|
||||
@@ -192,6 +192,7 @@ and install_linux_tools g inspect =
|
||||
(match inspect.i_major_version with
|
||||
| 6 -> Some "el6"
|
||||
| 7 -> Some "el7"
|
||||
+ | 8 -> Some "el8"
|
||||
| _ -> None)
|
||||
| "sles" | "suse-based" | "opensuse" -> Some "lp151"
|
||||
| _ -> None in
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,41 +0,0 @@
|
||||
From 66cd34e84e41d3f70e95fa745637ba6eb4779aec Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Fri, 8 Feb 2019 11:44:41 +0100
|
||||
Subject: [PATCH] v2v: fix path to source when copying files from guest tools
|
||||
directory
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The debug message was slightly changed too to better match the similar
|
||||
message for ISO case. It refers to the root directory instead of the
|
||||
specific subdirectory inside guest tools.
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
(cherry picked from commit f4bda5571a36da42bdc800c10f2c85cf20bf5c85)
|
||||
---
|
||||
v2v/windows_virtio.ml | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
|
||||
index 7be63a316..70f0bf09d 100644
|
||||
--- a/v2v/windows_virtio.ml
|
||||
+++ b/v2v/windows_virtio.ml
|
||||
@@ -309,10 +309,11 @@ and copy_drivers g inspect driverdir =
|
||||
and copy_from_virtio_win g inspect srcdir destdir filter missing =
|
||||
let ret = ref [] in
|
||||
if is_directory virtio_win then (
|
||||
+ debug "windows: copy_from_virtio_win: guest tools source directory %s"
|
||||
+ virtio_win;
|
||||
+
|
||||
let dir = virtio_win // srcdir in
|
||||
- debug "windows: copy_from_virtio_win: guest tools source directory %s" dir;
|
||||
-
|
||||
- if not (is_directory srcdir) then missing ()
|
||||
+ if not (is_directory dir) then missing ()
|
||||
else (
|
||||
let cmd = sprintf "cd %s && find -L -type f" (quote dir) in
|
||||
let paths = external_command cmd in
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,119 +0,0 @@
|
||||
From cf06f1d264a8832aa31265da5b2a28547b0faf49 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Tue, 8 Oct 2019 13:16:38 +0200
|
||||
Subject: [PATCH] v2v: windows: install QEMU Guest Agent MSI
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Use firstboot script to install MSI with QEMU-GA from virtio-win ISO or
|
||||
oVirt/RHV guest tools ISO.
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
(cherry picked from commit 00b4ed312b0ba179e9901b73c099724c3f6606b4)
|
||||
---
|
||||
v2v/convert_windows.ml | 19 +++++++++++++++++++
|
||||
v2v/windows_virtio.ml | 27 +++++++++++++++++++++++++++
|
||||
v2v/windows_virtio.mli | 4 ++++
|
||||
3 files changed, 50 insertions(+)
|
||||
|
||||
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
||||
index 75e609d61..bdb0092c3 100644
|
||||
--- a/v2v/convert_windows.ml
|
||||
+++ b/v2v/convert_windows.ml
|
||||
@@ -293,6 +293,13 @@ let convert (g : G.guestfs) inspect source output rcaps static_ips =
|
||||
if Sys.file_exists tool_path then
|
||||
configure_vmdp tool_path;
|
||||
|
||||
+ (* Install QEMU Guest Agent unconditionally and warn if missing *)
|
||||
+ let qemu_ga_files = Windows_virtio.copy_qemu_ga g inspect in
|
||||
+ if qemu_ga_files <> [] then
|
||||
+ configure_qemu_ga qemu_ga_files
|
||||
+ else
|
||||
+ warning (f_"QEMU Guest Agent MSI not found on tools ISO/directory. You may want to install the guest agent manually after conversion.");
|
||||
+
|
||||
unconfigure_xenpv ();
|
||||
unconfigure_prltools ();
|
||||
unconfigure_vmwaretools ()
|
||||
@@ -418,6 +425,18 @@ popd
|
||||
Firstboot.add_firstboot_script g inspect.i_root
|
||||
"finish vmdp setup" fb_recover_script
|
||||
|
||||
+ and configure_qemu_ga files =
|
||||
+ List.iter (
|
||||
+ fun msi_path ->
|
||||
+ let fb_script = "\
|
||||
+echo Installing qemu-ga from " ^ msi_path ^ "
|
||||
+\"\\" ^ msi_path ^ "\" /qn /forcerestart /l+*vx \"%cd%\\qemu-ga.log\"
|
||||
+" in
|
||||
+ Firstboot.add_firstboot_script g inspect.i_root
|
||||
+ ("install " ^ msi_path) fb_script;
|
||||
+ ) files
|
||||
+
|
||||
+
|
||||
and unconfigure_xenpv () =
|
||||
match xenpv_uninst with
|
||||
| None -> () (* nothing to be uninstalled *)
|
||||
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
|
||||
index 70f0bf09d..ea7e5c02d 100644
|
||||
--- a/v2v/windows_virtio.ml
|
||||
+++ b/v2v/windows_virtio.ml
|
||||
@@ -296,6 +296,13 @@ and copy_drivers g inspect driverdir =
|
||||
(fun () ->
|
||||
error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log."))
|
||||
|
||||
+and copy_qemu_ga g inspect =
|
||||
+ copy_from_virtio_win g inspect "/" "/"
|
||||
+ virtio_iso_path_matches_qemu_ga
|
||||
+ (fun () ->
|
||||
+ error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log."))
|
||||
+
|
||||
+
|
||||
(* Copy all files from virtio_win directory/ISO located in [srcdir]
|
||||
* subdirectory and all its subdirectories to the [destdir]. The directory
|
||||
* hierarchy is not preserved, meaning all files will be directly in [destdir].
|
||||
@@ -427,6 +434,26 @@ and virtio_iso_path_matches_guest_os path inspect =
|
||||
|
||||
with Not_found -> false
|
||||
|
||||
+(* Given a path of a file relative to the root of the directory tree
|
||||
+ * with virtio-win drivers, figure out if it's suitable for the
|
||||
+ * specific Windows flavor of the current guest.
|
||||
+ *)
|
||||
+and virtio_iso_path_matches_qemu_ga path inspect =
|
||||
+ let { i_arch = arch } = inspect in
|
||||
+ (* Lowercased path, since the ISO may contain upper or lowercase path
|
||||
+ * elements.
|
||||
+ *)
|
||||
+ let lc_name = String.lowercase_ascii (Filename.basename path) in
|
||||
+ lc_name = "rhev-qga.msi" ||
|
||||
+ match arch, lc_name with
|
||||
+ | ("i386", "qemu-ga-x86.msi")
|
||||
+ | ("i386", "qemu-ga-i386.msi")
|
||||
+ | ("i386", "RHEV-QGA.msi")
|
||||
+ | ("x86_64", "qemu-ga-x64.msi")
|
||||
+ | ("x86_64", "qemu-ga-x86_64.msi")
|
||||
+ | ("x86_64", "RHEV-QGA64.msi") -> true
|
||||
+ | _ -> false
|
||||
+
|
||||
(* The following function is only exported for unit tests. *)
|
||||
module UNIT_TESTS = struct
|
||||
let virtio_iso_path_matches_guest_os = virtio_iso_path_matches_guest_os
|
||||
diff --git a/v2v/windows_virtio.mli b/v2v/windows_virtio.mli
|
||||
index ae3b7e865..731dbd6f0 100644
|
||||
--- a/v2v/windows_virtio.mli
|
||||
+++ b/v2v/windows_virtio.mli
|
||||
@@ -44,6 +44,10 @@ val install_linux_tools : Guestfs.guestfs -> Types.inspect -> unit
|
||||
(** installs QEMU Guest Agent on Linux guest OS from the driver directory or
|
||||
driver ISO. It is not fatal if we fail to install the agent. *)
|
||||
|
||||
+val copy_qemu_ga : Guestfs.guestfs -> Types.inspect -> string list
|
||||
+(** copy MSIs (idealy just one) with QEMU Guest Agent to Windows guest. The
|
||||
+ MSIs are not installed by this function. *)
|
||||
+
|
||||
(**/**)
|
||||
|
||||
(* The following function is only exported for unit tests. *)
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,42 +0,0 @@
|
||||
From ab6076b6fe33cfe9a7b5d29bea5b8c24553894cc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Wed, 5 Feb 2020 14:11:36 +0100
|
||||
Subject: [PATCH] windows: small tweaks of qemu-ga firstboot script
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
- match log file with script name
|
||||
- restart manually only after successfull install, this also helps
|
||||
debugging because we can log the installer return code
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
|
||||
(cherry picked from commit 59f9ff40621240a6eed28c4425d3d69d8b21bc0e
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/convert_windows.ml | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
||||
index bdb0092c3..43c1f85de 100644
|
||||
--- a/v2v/convert_windows.ml
|
||||
+++ b/v2v/convert_windows.ml
|
||||
@@ -430,7 +430,13 @@ popd
|
||||
fun msi_path ->
|
||||
let fb_script = "\
|
||||
echo Installing qemu-ga from " ^ msi_path ^ "
|
||||
-\"\\" ^ msi_path ^ "\" /qn /forcerestart /l+*vx \"%cd%\\qemu-ga.log\"
|
||||
+\"\\" ^ msi_path ^ "\" /norestart /qn /l+*vx \"%~dpn0.log\"
|
||||
+set elvl=!errorlevel!
|
||||
+echo Done installing qemu-ga error_level=!elvl!
|
||||
+if !elvl! == 0 (
|
||||
+ echo Restarting Windows...
|
||||
+ shutdown /r /f /c \"rebooted by firstboot script\"
|
||||
+)
|
||||
" in
|
||||
Firstboot.add_firstboot_script g inspect.i_root
|
||||
("install " ^ msi_path) fb_script;
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,43 +0,0 @@
|
||||
From 52a4f93f1d8bb150167885c94df890af0d00d76d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Wed, 5 Feb 2020 14:11:35 +0100
|
||||
Subject: [PATCH] windows: fix detection of qemu-ga installer on RHV
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The detection was incorrectly matching only 32-bit installer on all
|
||||
architectures.
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
|
||||
(cherry picked from commit 45acf8d0557bee948c035305a6bafc6c9963a467
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/windows_virtio.ml | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
|
||||
index ea7e5c02d..9a7297344 100644
|
||||
--- a/v2v/windows_virtio.ml
|
||||
+++ b/v2v/windows_virtio.ml
|
||||
@@ -444,14 +444,13 @@ and virtio_iso_path_matches_qemu_ga path inspect =
|
||||
* elements.
|
||||
*)
|
||||
let lc_name = String.lowercase_ascii (Filename.basename path) in
|
||||
- lc_name = "rhev-qga.msi" ||
|
||||
match arch, lc_name with
|
||||
| ("i386", "qemu-ga-x86.msi")
|
||||
| ("i386", "qemu-ga-i386.msi")
|
||||
- | ("i386", "RHEV-QGA.msi")
|
||||
+ | ("i386", "rhev-qga.msi")
|
||||
| ("x86_64", "qemu-ga-x64.msi")
|
||||
| ("x86_64", "qemu-ga-x86_64.msi")
|
||||
- | ("x86_64", "RHEV-QGA64.msi") -> true
|
||||
+ | ("x86_64", "rhev-qga64.msi") -> true
|
||||
| _ -> false
|
||||
|
||||
(* The following function is only exported for unit tests. *)
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,67 +0,0 @@
|
||||
From 898b0654a0c4ef55af147a5ca081d2399ce05855 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Thu, 5 Mar 2020 15:37:13 +0100
|
||||
Subject: [PATCH] windows: delay installation of qemu-ga MSI
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Instead of running firstboot script during early boot schedule a task
|
||||
delayed for 2 minutes.
|
||||
|
||||
During the first boot, after virt-v2v conversion, Windows installs the
|
||||
drivers injected by virt-v2v. When this installation is finished
|
||||
Windows enforces some kind of internal reboot. This unfortunately
|
||||
terminates any running firstboot scripts thus killing the installation
|
||||
of qemu-ga MSI.
|
||||
|
||||
This is just a best-effort mitigation. It can still happen (e.g. with
|
||||
slow disk drives) that the drivers are not yet installed when the
|
||||
delayed installation starts. On the other hand we cannot delay it too
|
||||
much otherwise we risk that the users logs in and will be doing some
|
||||
work when the MSI installation starts. After MSI installation finishes
|
||||
the VM needs to be rebooted which would be annoying if that would happen
|
||||
under users hands. Although this is not a best fix (that may come later
|
||||
as it is more complex, e.g. introducing waiting mechanism), the delay as
|
||||
it is defined works in most cases. And it dramaticaly improves the
|
||||
situations -- originaly I experienced more than 90% failure rate.
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
|
||||
(cherry picked from commit dc66e78fa37db33e3c7358b7f7c7fa809cf62f9d
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/convert_windows.ml | 17 +++++++----------
|
||||
1 file changed, 7 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
||||
index 43c1f85de..088cd33d9 100644
|
||||
--- a/v2v/convert_windows.ml
|
||||
+++ b/v2v/convert_windows.ml
|
||||
@@ -428,16 +428,13 @@ popd
|
||||
and configure_qemu_ga files =
|
||||
List.iter (
|
||||
fun msi_path ->
|
||||
- let fb_script = "\
|
||||
-echo Installing qemu-ga from " ^ msi_path ^ "
|
||||
-\"\\" ^ msi_path ^ "\" /norestart /qn /l+*vx \"%~dpn0.log\"
|
||||
-set elvl=!errorlevel!
|
||||
-echo Done installing qemu-ga error_level=!elvl!
|
||||
-if !elvl! == 0 (
|
||||
- echo Restarting Windows...
|
||||
- shutdown /r /f /c \"rebooted by firstboot script\"
|
||||
-)
|
||||
-" in
|
||||
+ let fb_script = sprintf "\
|
||||
+echo Removing any previously scheduled qemu-ga installation
|
||||
+schtasks.exe /Delete /TN Firstboot-qemu-ga /F
|
||||
+echo Scheduling delayed installation of qemu-ga from %s
|
||||
+powershell.exe -command \"$d = (get-date).AddSeconds(120); schtasks.exe /Create /SC ONCE /ST $d.ToString('HH:mm') /SD $d.ToString('MM/dd/yyyy') /RU SYSTEM /TN Firstboot-qemu-ga /TR \\\"C:\\%s /forcerestart /qn /l+*vx C:\\%s.log\\\"\"
|
||||
+ "
|
||||
+ msi_path msi_path msi_path in
|
||||
Firstboot.add_firstboot_script g inspect.i_root
|
||||
("install " ^ msi_path) fb_script;
|
||||
) files
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,283 +0,0 @@
|
||||
From a13f9b06370a6fef6f671f5aa7c23df0f0fd542e Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 12 Mar 2020 13:57:06 +0000
|
||||
Subject: [PATCH] daemon: xattr: Refactor code which splits attr names from the
|
||||
kernel.
|
||||
|
||||
The kernel returns xattr names in a slightly peculiar format. We
|
||||
parsed this format several times in the code. Refactor this parsing
|
||||
so we only do it in one place.
|
||||
|
||||
(cherry picked from commit 5c175fe73264bbf1d3ef79bb066dfb6aff902ad1)
|
||||
---
|
||||
daemon/xattr.c | 127 ++++++++++++++++++++++++++++++-------------------
|
||||
1 file changed, 79 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/daemon/xattr.c b/daemon/xattr.c
|
||||
index bc5c2df97..3e1144963 100644
|
||||
--- a/daemon/xattr.c
|
||||
+++ b/daemon/xattr.c
|
||||
@@ -89,6 +89,36 @@ do_lremovexattr (const char *xattr, const char *path)
|
||||
return _removexattr (xattr, path, lremovexattr);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * L<listxattr(2)> returns the string C<"foo\0bar\0baz"> of length
|
||||
+ * C<len>. (The last string in the list is \0-terminated but the \0
|
||||
+ * is not included in C<len>).
|
||||
+ *
|
||||
+ * This function splits it into a regular list of strings.
|
||||
+ *
|
||||
+ * B<Note> that the returned list contains pointers to the original
|
||||
+ * strings in C<buf> so be careful that you do not double-free them.
|
||||
+ */
|
||||
+static char **
|
||||
+split_attr_names (char *buf, size_t len)
|
||||
+{
|
||||
+ size_t i;
|
||||
+ DECLARE_STRINGSBUF (ret);
|
||||
+
|
||||
+ for (i = 0; i < len; i += strlen (&buf[i]) + 1) {
|
||||
+ if (add_string_nodup (&ret, &buf[i]) == -1) {
|
||||
+ free (ret.argv);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ if (end_stringsbuf (&ret) == -1) {
|
||||
+ free (ret.argv);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return take_stringsbuf (&ret);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
compare_xattrs (const void *vxa1, const void *vxa2)
|
||||
{
|
||||
@@ -106,7 +136,8 @@ getxattrs (const char *path,
|
||||
{
|
||||
ssize_t len, vlen;
|
||||
CLEANUP_FREE char *buf = NULL;
|
||||
- size_t i, j;
|
||||
+ CLEANUP_FREE /* not string list */ char **names = NULL;
|
||||
+ size_t i;
|
||||
guestfs_int_xattr_list *r = NULL;
|
||||
|
||||
buf = _listxattrs (path, listxattr, &len);
|
||||
@@ -114,18 +145,17 @@ getxattrs (const char *path,
|
||||
/* _listxattrs issues reply_with_perror already. */
|
||||
goto error;
|
||||
|
||||
+ names = split_attr_names (buf, len);
|
||||
+ if (names == NULL)
|
||||
+ goto error;
|
||||
+
|
||||
r = calloc (1, sizeof (*r));
|
||||
if (r == NULL) {
|
||||
reply_with_perror ("calloc");
|
||||
goto error;
|
||||
}
|
||||
|
||||
- /* What we get from the kernel is a string "foo\0bar\0baz" of length
|
||||
- * len. First count the strings.
|
||||
- */
|
||||
- r->guestfs_int_xattr_list_len = 0;
|
||||
- for (i = 0; i < (size_t) len; i += strlen (&buf[i]) + 1)
|
||||
- r->guestfs_int_xattr_list_len++;
|
||||
+ r->guestfs_int_xattr_list_len = guestfs_int_count_strings (names);
|
||||
|
||||
r->guestfs_int_xattr_list_val =
|
||||
calloc (r->guestfs_int_xattr_list_len, sizeof (guestfs_int_xattr));
|
||||
@@ -134,34 +164,34 @@ getxattrs (const char *path,
|
||||
goto error;
|
||||
}
|
||||
|
||||
- for (i = 0, j = 0; i < (size_t) len; i += strlen (&buf[i]) + 1, ++j) {
|
||||
+ for (i = 0; names[i] != NULL; ++i) {
|
||||
CHROOT_IN;
|
||||
- vlen = getxattr (path, &buf[i], NULL, 0);
|
||||
+ vlen = getxattr (path, names[i], NULL, 0);
|
||||
CHROOT_OUT;
|
||||
if (vlen == -1) {
|
||||
- reply_with_perror ("getxattr");
|
||||
+ reply_with_perror ("getxattr: %s", names[i]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (vlen > XATTR_SIZE_MAX) {
|
||||
/* The next call to getxattr will fail anyway, so ... */
|
||||
- reply_with_error ("extended attribute is too large");
|
||||
+ reply_with_error ("%s: extended attribute is too large", names[i]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
- r->guestfs_int_xattr_list_val[j].attrname = strdup (&buf[i]);
|
||||
- r->guestfs_int_xattr_list_val[j].attrval.attrval_val = malloc (vlen);
|
||||
- r->guestfs_int_xattr_list_val[j].attrval.attrval_len = vlen;
|
||||
+ r->guestfs_int_xattr_list_val[i].attrname = strdup (names[i]);
|
||||
+ r->guestfs_int_xattr_list_val[i].attrval.attrval_val = malloc (vlen);
|
||||
+ r->guestfs_int_xattr_list_val[i].attrval.attrval_len = vlen;
|
||||
|
||||
- if (r->guestfs_int_xattr_list_val[j].attrname == NULL ||
|
||||
- r->guestfs_int_xattr_list_val[j].attrval.attrval_val == NULL) {
|
||||
+ if (r->guestfs_int_xattr_list_val[i].attrname == NULL ||
|
||||
+ r->guestfs_int_xattr_list_val[i].attrval.attrval_val == NULL) {
|
||||
reply_with_perror ("malloc");
|
||||
goto error;
|
||||
}
|
||||
|
||||
CHROOT_IN;
|
||||
- vlen = getxattr (path, &buf[i],
|
||||
- r->guestfs_int_xattr_list_val[j].attrval.attrval_val,
|
||||
+ vlen = getxattr (path, names[i],
|
||||
+ r->guestfs_int_xattr_list_val[i].attrval.attrval_val,
|
||||
vlen);
|
||||
CHROOT_OUT;
|
||||
if (vlen == -1) {
|
||||
@@ -276,7 +306,7 @@ guestfs_int_xattr_list *
|
||||
do_internal_lxattrlist (const char *path, char *const *names)
|
||||
{
|
||||
guestfs_int_xattr_list *ret = NULL;
|
||||
- size_t i, j;
|
||||
+ size_t i;
|
||||
size_t k, m, nr_attrs;
|
||||
ssize_t len, vlen;
|
||||
|
||||
@@ -293,6 +323,7 @@ do_internal_lxattrlist (const char *path, char *const *names)
|
||||
void *newptr;
|
||||
CLEANUP_FREE char *pathname = NULL;
|
||||
CLEANUP_FREE char *buf = NULL;
|
||||
+ CLEANUP_FREE /* not string list */ char **attrnames = NULL;
|
||||
|
||||
/* Be careful in this loop about which errors cause the whole call
|
||||
* to abort, and which errors allow us to continue processing
|
||||
@@ -350,12 +381,10 @@ do_internal_lxattrlist (const char *path, char *const *names)
|
||||
if (len == -1)
|
||||
continue; /* not fatal */
|
||||
|
||||
- /* What we get from the kernel is a string "foo\0bar\0baz" of length
|
||||
- * len. First count the strings.
|
||||
- */
|
||||
- nr_attrs = 0;
|
||||
- for (i = 0; i < (size_t) len; i += strlen (&buf[i]) + 1)
|
||||
- nr_attrs++;
|
||||
+ attrnames = split_attr_names (buf, len);
|
||||
+ if (attrnames == NULL)
|
||||
+ goto error;
|
||||
+ nr_attrs = guestfs_int_count_strings (attrnames);
|
||||
|
||||
newptr =
|
||||
realloc (ret->guestfs_int_xattr_list_val,
|
||||
@@ -378,36 +407,36 @@ do_internal_lxattrlist (const char *path, char *const *names)
|
||||
entry[m].attrval.attrval_val = NULL;
|
||||
}
|
||||
|
||||
- for (i = 0, j = 0; i < (size_t) len; i += strlen (&buf[i]) + 1, ++j) {
|
||||
+ for (i = 0; attrnames[i] != NULL; ++i) {
|
||||
CHROOT_IN;
|
||||
- vlen = lgetxattr (pathname, &buf[i], NULL, 0);
|
||||
+ vlen = lgetxattr (pathname, attrnames[i], NULL, 0);
|
||||
CHROOT_OUT;
|
||||
if (vlen == -1) {
|
||||
- reply_with_perror ("getxattr");
|
||||
+ reply_with_perror ("getxattr: %s", attrnames[i]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (vlen > XATTR_SIZE_MAX) {
|
||||
- reply_with_error ("extended attribute is too large");
|
||||
+ reply_with_error ("%s: extended attribute is too large", attrnames[i]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
- entry[j+1].attrname = strdup (&buf[i]);
|
||||
- entry[j+1].attrval.attrval_val = malloc (vlen);
|
||||
- entry[j+1].attrval.attrval_len = vlen;
|
||||
+ entry[i+1].attrname = strdup (attrnames[i]);
|
||||
+ entry[i+1].attrval.attrval_val = malloc (vlen);
|
||||
+ entry[i+1].attrval.attrval_len = vlen;
|
||||
|
||||
- if (entry[j+1].attrname == NULL ||
|
||||
- entry[j+1].attrval.attrval_val == NULL) {
|
||||
+ if (entry[i+1].attrname == NULL ||
|
||||
+ entry[i+1].attrval.attrval_val == NULL) {
|
||||
reply_with_perror ("malloc");
|
||||
goto error;
|
||||
}
|
||||
|
||||
CHROOT_IN;
|
||||
- vlen = lgetxattr (pathname, &buf[i],
|
||||
- entry[j+1].attrval.attrval_val, vlen);
|
||||
+ vlen = lgetxattr (pathname, attrnames[i],
|
||||
+ entry[i+1].attrval.attrval_val, vlen);
|
||||
CHROOT_OUT;
|
||||
if (vlen == -1) {
|
||||
- reply_with_perror ("getxattr");
|
||||
+ reply_with_perror ("getxattr: %s", attrnames[i]);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@@ -510,6 +539,7 @@ copy_xattrs (const char *src, const char *dest)
|
||||
{
|
||||
ssize_t len, vlen, ret, attrval_len = 0;
|
||||
CLEANUP_FREE char *buf = NULL, *attrval = NULL;
|
||||
+ CLEANUP_FREE /* not string list */ char **names = NULL;
|
||||
size_t i;
|
||||
|
||||
buf = _listxattrs (src, listxattr, &len);
|
||||
@@ -517,21 +547,22 @@ copy_xattrs (const char *src, const char *dest)
|
||||
/* _listxattrs issues reply_with_perror already. */
|
||||
goto error;
|
||||
|
||||
- /* What we get from the kernel is a string "foo\0bar\0baz" of length
|
||||
- * len.
|
||||
- */
|
||||
- for (i = 0; i < (size_t) len; i += strlen (&buf[i]) + 1) {
|
||||
+ names = split_attr_names (buf, len);
|
||||
+ if (names == NULL)
|
||||
+ goto error;
|
||||
+
|
||||
+ for (i = 0; names[i] != NULL; ++i) {
|
||||
CHROOT_IN;
|
||||
- vlen = getxattr (src, &buf[i], NULL, 0);
|
||||
+ vlen = getxattr (src, names[i], NULL, 0);
|
||||
CHROOT_OUT;
|
||||
if (vlen == -1) {
|
||||
- reply_with_perror ("getxattr: %s, %s", src, &buf[i]);
|
||||
+ reply_with_perror ("getxattr: %s, %s", src, names[i]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (vlen > XATTR_SIZE_MAX) {
|
||||
/* The next call to getxattr will fail anyway, so ... */
|
||||
- reply_with_error ("extended attribute is too large");
|
||||
+ reply_with_error ("%s: extended attribute is too large", names[i]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -546,18 +577,18 @@ copy_xattrs (const char *src, const char *dest)
|
||||
}
|
||||
|
||||
CHROOT_IN;
|
||||
- vlen = getxattr (src, &buf[i], attrval, vlen);
|
||||
+ vlen = getxattr (src, names[i], attrval, vlen);
|
||||
CHROOT_OUT;
|
||||
if (vlen == -1) {
|
||||
- reply_with_perror ("getxattr: %s, %s", src, &buf[i]);
|
||||
+ reply_with_perror ("getxattr: %s, %s", src, names[i]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
CHROOT_IN;
|
||||
- ret = setxattr (dest, &buf[i], attrval, vlen, 0);
|
||||
+ ret = setxattr (dest, names[i], attrval, vlen, 0);
|
||||
CHROOT_OUT;
|
||||
if (ret == -1) {
|
||||
- reply_with_perror ("setxattr: %s, %s", dest, &buf[i]);
|
||||
+ reply_with_perror ("setxattr: %s, %s", dest, names[i]);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,84 +0,0 @@
|
||||
From 2e5a8775941b5767abcfcf93f9f84c9560e0f378 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 12 Mar 2020 13:59:05 +0000
|
||||
Subject: [PATCH] daemon: Add filter_list utility function.
|
||||
|
||||
For filtering lists of strings based on a predicate.
|
||||
|
||||
(cherry picked from commit af8ed266a282bb20882a9ffb611bd64243d19218)
|
||||
---
|
||||
daemon/daemon.h | 2 ++
|
||||
daemon/utils.c | 30 ++++++++++++++++++++++++++++++
|
||||
2 files changed, 32 insertions(+)
|
||||
|
||||
diff --git a/daemon/daemon.h b/daemon/daemon.h
|
||||
index 66bfdc49e..115591728 100644
|
||||
--- a/daemon/daemon.h
|
||||
+++ b/daemon/daemon.h
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
+#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -74,6 +75,7 @@ extern void free_stringsbuf (struct stringsbuf *sb);
|
||||
extern struct stringsbuf split_lines_sb (char *str);
|
||||
extern char **split_lines (char *str);
|
||||
extern char **empty_list (void);
|
||||
+extern char **filter_list (bool (*p) (const char *), char **strs);
|
||||
extern int is_power_of_2 (unsigned long v);
|
||||
extern void trim (char *str);
|
||||
extern int parse_btrfsvol (const char *desc, mountable_t *mountable);
|
||||
diff --git a/daemon/utils.c b/daemon/utils.c
|
||||
index c3f88bcab..e87233d0f 100644
|
||||
--- a/daemon/utils.c
|
||||
+++ b/daemon/utils.c
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
+#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <rpc/types.h>
|
||||
@@ -482,6 +483,35 @@ empty_list (void)
|
||||
return ret.argv;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Filter a list of strings. Returns a newly allocated list of only
|
||||
+ * the strings where C<p (str) == true>.
|
||||
+ *
|
||||
+ * B<Note> it does not copy the strings, be careful not to double-free
|
||||
+ * them.
|
||||
+ */
|
||||
+char **
|
||||
+filter_list (bool (*p) (const char *str), char **strs)
|
||||
+{
|
||||
+ DECLARE_STRINGSBUF (ret);
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; strs[i] != NULL; ++i) {
|
||||
+ if (p (strs[i])) {
|
||||
+ if (add_string_nodup (&ret, strs[i]) == -1) {
|
||||
+ free (ret.argv);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (end_stringsbuf (&ret) == -1) {
|
||||
+ free (ret.argv);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return take_stringsbuf (&ret);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Skip leading and trailing whitespace, updating the original string
|
||||
* in-place.
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,120 +0,0 @@
|
||||
From fb3136e8abe5fec9e8a749e5879b75c696f7ba0e Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 12 Mar 2020 14:40:05 +0000
|
||||
Subject: [PATCH] daemon: xattr: Filter out user.WofCompressedData from xattrs
|
||||
(RHBZ#1811539).
|
||||
|
||||
See comment in code for justification.
|
||||
|
||||
Thanks: Yongkui Guo for finding the bug.
|
||||
(cherry picked from commit c2c11382bbeb4500f3388a31ffd08cfc18b0de40)
|
||||
---
|
||||
daemon/xattr.c | 43 ++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 40 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/daemon/xattr.c b/daemon/xattr.c
|
||||
index 3e1144963..43e49384f 100644
|
||||
--- a/daemon/xattr.c
|
||||
+++ b/daemon/xattr.c
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -119,6 +121,29 @@ split_attr_names (char *buf, size_t len)
|
||||
return take_stringsbuf (&ret);
|
||||
}
|
||||
|
||||
+/* We hide one extended attribute automatically. This is used by NTFS
|
||||
+ * to store the compressed contents of a file when using "CompactOS"
|
||||
+ * (per-file compression). I justify this by:
|
||||
+ *
|
||||
+ * (1) The attribute is only used internally by NTFS. The actual file
|
||||
+ * contents are still available.
|
||||
+ *
|
||||
+ * (2) It's probably not valid to copy this attribute when copying the
|
||||
+ * other attributes of a file. ntfs-3g-system-compression doesn't
|
||||
+ * support writing compressed files.
|
||||
+ *
|
||||
+ * (3) This file isn't readable by the Linux kernel. Reading it will
|
||||
+ * always return -E2BIG (RHBZ#1811539). So we can't read it even if
|
||||
+ * we wanted to.
|
||||
+ *
|
||||
+ * (4) The Linux kernel itself hides other attributes.
|
||||
+ */
|
||||
+static bool
|
||||
+not_hidden_xattr (const char *attrname)
|
||||
+{
|
||||
+ return STRNEQ (attrname, "user.WofCompressedData");
|
||||
+}
|
||||
+
|
||||
static int
|
||||
compare_xattrs (const void *vxa1, const void *vxa2)
|
||||
{
|
||||
@@ -136,6 +161,7 @@ getxattrs (const char *path,
|
||||
{
|
||||
ssize_t len, vlen;
|
||||
CLEANUP_FREE char *buf = NULL;
|
||||
+ CLEANUP_FREE /* not string list */ char **names_unfiltered = NULL;
|
||||
CLEANUP_FREE /* not string list */ char **names = NULL;
|
||||
size_t i;
|
||||
guestfs_int_xattr_list *r = NULL;
|
||||
@@ -145,7 +171,10 @@ getxattrs (const char *path,
|
||||
/* _listxattrs issues reply_with_perror already. */
|
||||
goto error;
|
||||
|
||||
- names = split_attr_names (buf, len);
|
||||
+ names_unfiltered = split_attr_names (buf, len);
|
||||
+ if (names_unfiltered == NULL)
|
||||
+ goto error;
|
||||
+ names = filter_list (not_hidden_xattr, names_unfiltered);
|
||||
if (names == NULL)
|
||||
goto error;
|
||||
|
||||
@@ -323,6 +352,7 @@ do_internal_lxattrlist (const char *path, char *const *names)
|
||||
void *newptr;
|
||||
CLEANUP_FREE char *pathname = NULL;
|
||||
CLEANUP_FREE char *buf = NULL;
|
||||
+ CLEANUP_FREE /* not string list */ char **attrnames_unfiltered = NULL;
|
||||
CLEANUP_FREE /* not string list */ char **attrnames = NULL;
|
||||
|
||||
/* Be careful in this loop about which errors cause the whole call
|
||||
@@ -381,7 +411,10 @@ do_internal_lxattrlist (const char *path, char *const *names)
|
||||
if (len == -1)
|
||||
continue; /* not fatal */
|
||||
|
||||
- attrnames = split_attr_names (buf, len);
|
||||
+ attrnames_unfiltered = split_attr_names (buf, len);
|
||||
+ if (attrnames_unfiltered == NULL)
|
||||
+ goto error;
|
||||
+ attrnames = filter_list (not_hidden_xattr, attrnames_unfiltered);
|
||||
if (attrnames == NULL)
|
||||
goto error;
|
||||
nr_attrs = guestfs_int_count_strings (attrnames);
|
||||
@@ -539,6 +572,7 @@ copy_xattrs (const char *src, const char *dest)
|
||||
{
|
||||
ssize_t len, vlen, ret, attrval_len = 0;
|
||||
CLEANUP_FREE char *buf = NULL, *attrval = NULL;
|
||||
+ CLEANUP_FREE /* not string list */ char **names_unfiltered = NULL;
|
||||
CLEANUP_FREE /* not string list */ char **names = NULL;
|
||||
size_t i;
|
||||
|
||||
@@ -547,7 +581,10 @@ copy_xattrs (const char *src, const char *dest)
|
||||
/* _listxattrs issues reply_with_perror already. */
|
||||
goto error;
|
||||
|
||||
- names = split_attr_names (buf, len);
|
||||
+ names_unfiltered = split_attr_names (buf, len);
|
||||
+ if (names_unfiltered == NULL)
|
||||
+ goto error;
|
||||
+ names = filter_list (not_hidden_xattr, names_unfiltered);
|
||||
if (names == NULL)
|
||||
goto error;
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,95 +0,0 @@
|
||||
From 9a8246e91ac0fa38d96691dc6025cb8b117f9cb2 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 4 May 2020 15:14:46 +0200
|
||||
Subject: [PATCH] mltools: add run_in_guest_command helper
|
||||
|
||||
Add an helper function to run a command in the guest, checking for the
|
||||
host/guest compatibility. This is mostly extracted from the internal
|
||||
do_run helper currently in the Customize_run module of virt-customize.
|
||||
|
||||
(cherry picked from commit e73eca3b73f7d0a54615c5dc55eadd09dc170035
|
||||
in libguestfs-common)
|
||||
---
|
||||
common/mltools/tools_utils.ml | 50 ++++++++++++++++++++++++++++++++++
|
||||
common/mltools/tools_utils.mli | 10 +++++++
|
||||
2 files changed, 60 insertions(+)
|
||||
|
||||
diff --git a/common/mltools/tools_utils.ml b/common/mltools/tools_utils.ml
|
||||
index 127180225..d54ec581e 100644
|
||||
--- a/common/mltools/tools_utils.ml
|
||||
+++ b/common/mltools/tools_utils.ml
|
||||
@@ -679,3 +679,53 @@ let with_timeout op timeout ?(sleep = 2) fn =
|
||||
loop ()
|
||||
in
|
||||
loop ()
|
||||
+
|
||||
+let run_in_guest_command g root ?logfile ?incompatible_fn cmd =
|
||||
+ (* Is the host_cpu compatible with the guest arch? ie. Can we
|
||||
+ * run commands in this guest?
|
||||
+ *)
|
||||
+ let guest_arch = g#inspect_get_arch root in
|
||||
+ let guest_arch_compatible = guest_arch_compatible guest_arch in
|
||||
+ if not guest_arch_compatible then (
|
||||
+ match incompatible_fn with
|
||||
+ | None -> ()
|
||||
+ | Some fn -> fn ()
|
||||
+ )
|
||||
+ else (
|
||||
+ (* Add a prologue to the scripts:
|
||||
+ * - Pass environment variables through from the host.
|
||||
+ * - Optionally send stdout and stderr to a log file so we capture
|
||||
+ * all output in error messages.
|
||||
+ * - Use setarch when running x86_64 host + i686 guest.
|
||||
+ *)
|
||||
+ let env_vars =
|
||||
+ List.filter_map (
|
||||
+ fun name ->
|
||||
+ try Some (sprintf "export %s=%s" name (quote (Sys.getenv name)))
|
||||
+ with Not_found -> None
|
||||
+ ) [ "http_proxy"; "https_proxy"; "ftp_proxy"; "no_proxy" ] in
|
||||
+ let env_vars = String.concat "\n" env_vars ^ "\n" in
|
||||
+
|
||||
+ let cmd =
|
||||
+ match Guestfs_config.host_cpu, guest_arch with
|
||||
+ | "x86_64", ("i386"|"i486"|"i586"|"i686") ->
|
||||
+ sprintf "setarch i686 <<\"__EOCMD\"
|
||||
+%s
|
||||
+__EOCMD
|
||||
+" cmd
|
||||
+ | _ -> cmd in
|
||||
+
|
||||
+ let logfile_redirect =
|
||||
+ match logfile with
|
||||
+ | None -> ""
|
||||
+ | Some logfile -> sprintf "exec >>%s 2>&1" (quote logfile) in
|
||||
+
|
||||
+ let cmd = sprintf "\
|
||||
+%s
|
||||
+%s
|
||||
+%s
|
||||
+" (logfile_redirect) env_vars cmd in
|
||||
+
|
||||
+ debug "running command:\n%s" cmd;
|
||||
+ ignore (g#sh cmd)
|
||||
+ )
|
||||
diff --git a/common/mltools/tools_utils.mli b/common/mltools/tools_utils.mli
|
||||
index ab70f583e..102abff4d 100644
|
||||
--- a/common/mltools/tools_utils.mli
|
||||
+++ b/common/mltools/tools_utils.mli
|
||||
@@ -212,3 +212,13 @@ val with_timeout : string -> int -> ?sleep:int -> (unit -> 'a option) -> 'a
|
||||
calls {!error} and the program exits. The error message will
|
||||
contain the diagnostic string [op] to identify the operation
|
||||
which timed out. *)
|
||||
+
|
||||
+val run_in_guest_command : Guestfs.guestfs -> string -> ?logfile:string -> ?incompatible_fn:(unit -> unit) -> string -> unit
|
||||
+(** [run_in_guest_command g root ?incompatible_archs_fn cmd]
|
||||
+ runs a command in the guest, which is already mounted for the
|
||||
+ specified [root]. The command is run directly in case the
|
||||
+ architecture of the host and the guest are compatible, optionally
|
||||
+ calling [?incompatible_fn] in case they are not.
|
||||
+
|
||||
+ [?logfile] is an optional file in the guest to where redirect
|
||||
+ stdout and stderr of the command. *)
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,82 +0,0 @@
|
||||
From 02f8969558ecadc13726068ccb732595c5d29565 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 4 May 2020 11:55:41 +0200
|
||||
Subject: [PATCH] customize: port do_run to run_in_guest_command
|
||||
|
||||
Make use of the new helper function in Tools_utils to run commands in
|
||||
the guest.
|
||||
|
||||
(cherry picked from commit b25e3495f522378f59d201526d7d2d02c2bf6f3f)
|
||||
---
|
||||
customize/customize_run.ml | 46 +++++---------------------------------
|
||||
1 file changed, 6 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/customize/customize_run.ml b/customize/customize_run.ml
|
||||
index 3eacdaca0..f2ee20413 100644
|
||||
--- a/customize/customize_run.ml
|
||||
+++ b/customize/customize_run.ml
|
||||
@@ -30,12 +30,6 @@ open Append_line
|
||||
module G = Guestfs
|
||||
|
||||
let run (g : G.guestfs) root (ops : ops) =
|
||||
- (* Is the host_cpu compatible with the guest arch? ie. Can we
|
||||
- * run commands in this guest?
|
||||
- *)
|
||||
- let guest_arch = g#inspect_get_arch root in
|
||||
- let guest_arch_compatible = guest_arch_compatible guest_arch in
|
||||
-
|
||||
(* Based on the guest type, choose a log file location. *)
|
||||
let logfile =
|
||||
match g#inspect_get_type root with
|
||||
@@ -54,42 +48,14 @@ let run (g : G.guestfs) root (ops : ops) =
|
||||
|
||||
(* Useful wrapper for scripts. *)
|
||||
let do_run ~display ?(warn_failed_no_network = false) cmd =
|
||||
- if not guest_arch_compatible then
|
||||
+ let incompatible_fn () =
|
||||
+ let guest_arch = g#inspect_get_arch root in
|
||||
error (f_"host cpu (%s) and guest arch (%s) are not compatible, so you cannot use command line options that involve running commands in the guest. Use --firstboot scripts instead.")
|
||||
- Guestfs_config.host_cpu guest_arch;
|
||||
+ Guestfs_config.host_cpu guest_arch
|
||||
+ in
|
||||
|
||||
- (* Add a prologue to the scripts:
|
||||
- * - Pass environment variables through from the host.
|
||||
- * - Send stdout and stderr to a log file so we capture all output
|
||||
- * in error messages.
|
||||
- * - Use setarch when running x86_64 host + i686 guest.
|
||||
- * Also catch errors and dump the log file completely on error.
|
||||
- *)
|
||||
- let env_vars =
|
||||
- List.filter_map (
|
||||
- fun name ->
|
||||
- try Some (sprintf "export %s=%s" name (quote (Sys.getenv name)))
|
||||
- with Not_found -> None
|
||||
- ) [ "http_proxy"; "https_proxy"; "ftp_proxy"; "no_proxy" ] in
|
||||
- let env_vars = String.concat "\n" env_vars ^ "\n" in
|
||||
-
|
||||
- let cmd =
|
||||
- match Guestfs_config.host_cpu, guest_arch with
|
||||
- | "x86_64", ("i386"|"i486"|"i586"|"i686") ->
|
||||
- sprintf "setarch i686 <<\"__EOCMD\"
|
||||
-%s
|
||||
-__EOCMD
|
||||
-" cmd
|
||||
- | _ -> cmd in
|
||||
-
|
||||
- let cmd = sprintf "\
|
||||
-exec >>%s 2>&1
|
||||
-%s
|
||||
-%s
|
||||
-" (quote logfile) env_vars cmd in
|
||||
-
|
||||
- debug "running command:\n%s" cmd;
|
||||
- try ignore (g#sh cmd)
|
||||
+ try
|
||||
+ run_in_guest_command g root ~logfile ~incompatible_fn cmd
|
||||
with
|
||||
G.Error msg ->
|
||||
debug_logfile ();
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,138 +0,0 @@
|
||||
From f4613f408e4584741d08aa39c950de304f5e18db Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 4 May 2020 12:05:18 +0200
|
||||
Subject: [PATCH] sysprep: add a update_system_ca_store side effect
|
||||
|
||||
Add a simple side effect to make operation flag that a regeneration of
|
||||
the system CA store is needed. In case it is flagged, regenerate the
|
||||
system CA store directly, or using a firstboot script in case of
|
||||
incompatible architectures.
|
||||
|
||||
This change is almost a no-op, since no operation requires the
|
||||
regeneration of the system CA store yet.
|
||||
|
||||
(cherry picked from commit bb7fc6d0a1ed670d16a92d2afd9ff2f876edc595)
|
||||
---
|
||||
sysprep/main.ml | 5 +++++
|
||||
sysprep/sysprep_operation.ml | 3 +++
|
||||
sysprep/sysprep_operation.mli | 2 ++
|
||||
sysprep/utils.ml | 32 ++++++++++++++++++++++++++++++++
|
||||
sysprep/utils.mli | 4 ++++
|
||||
5 files changed, 46 insertions(+)
|
||||
|
||||
diff --git a/sysprep/main.ml b/sysprep/main.ml
|
||||
index 04fd7b23c..4b03d5b48 100644
|
||||
--- a/sysprep/main.ml
|
||||
+++ b/sysprep/main.ml
|
||||
@@ -25,6 +25,7 @@ open Common_gettext.Gettext
|
||||
open Getopt.OptionName
|
||||
|
||||
open Sysprep_operation
|
||||
+open Utils
|
||||
|
||||
module G = Guestfs
|
||||
|
||||
@@ -236,6 +237,10 @@ read the man page virt-sysprep(1).
|
||||
Sysprep_operation.perform_operations_on_filesystems
|
||||
?operations g root side_effects;
|
||||
|
||||
+ (* Do we need to update the system CA store? *)
|
||||
+ if side_effects#get_update_system_ca_store then
|
||||
+ update_system_ca_store g root;
|
||||
+
|
||||
(* Unmount everything in this guest. *)
|
||||
g#umount_all ();
|
||||
|
||||
diff --git a/sysprep/sysprep_operation.ml b/sysprep/sysprep_operation.ml
|
||||
index 0013ff504..53f042402 100644
|
||||
--- a/sysprep/sysprep_operation.ml
|
||||
+++ b/sysprep/sysprep_operation.ml
|
||||
@@ -27,10 +27,13 @@ class filesystem_side_effects =
|
||||
object
|
||||
val mutable m_created_file = false
|
||||
val mutable m_changed_file = false
|
||||
+ val mutable m_update_system_ca_store = false
|
||||
method created_file () = m_created_file <- true
|
||||
method get_created_file = m_created_file
|
||||
method changed_file () = m_changed_file <- true
|
||||
method get_changed_file = m_changed_file
|
||||
+ method update_system_ca_store () = m_update_system_ca_store <- true
|
||||
+ method get_update_system_ca_store = m_update_system_ca_store
|
||||
end
|
||||
|
||||
class device_side_effects = object end
|
||||
diff --git a/sysprep/sysprep_operation.mli b/sysprep/sysprep_operation.mli
|
||||
index 3d9f12550..2a02d5e79 100644
|
||||
--- a/sysprep/sysprep_operation.mli
|
||||
+++ b/sysprep/sysprep_operation.mli
|
||||
@@ -23,6 +23,8 @@ class filesystem_side_effects : object
|
||||
method get_created_file : bool
|
||||
method changed_file : unit -> unit
|
||||
method get_changed_file : bool
|
||||
+ method update_system_ca_store : unit -> unit
|
||||
+ method get_update_system_ca_store : bool
|
||||
end
|
||||
(** The callback should indicate if it has side effects by calling
|
||||
methods in this class. *)
|
||||
diff --git a/sysprep/utils.ml b/sysprep/utils.ml
|
||||
index 4c45d42de..29460b3c0 100644
|
||||
--- a/sysprep/utils.ml
|
||||
+++ b/sysprep/utils.ml
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
open Printf
|
||||
|
||||
+open Tools_utils
|
||||
+open Common_gettext.Gettext
|
||||
+
|
||||
let rec pod_of_list ?(style = `Dot) xs =
|
||||
match style with
|
||||
| `Verbatim -> String.concat "\n" (List.map ((^) " ") xs)
|
||||
@@ -31,3 +34,32 @@ and _pod_of_list delim xs =
|
||||
"=over 4\n\n" ^
|
||||
String.concat "" (List.map (sprintf "=item %s\n\n%s\n\n" delim) xs) ^
|
||||
"=back"
|
||||
+
|
||||
+let rec update_system_ca_store g root =
|
||||
+ let cmd = update_system_ca_store_command g root in
|
||||
+ match cmd with
|
||||
+ | None -> ()
|
||||
+ | Some cmd ->
|
||||
+ (* Try to run the command directly if possible, adding it as
|
||||
+ * firstboot script in case of incompatible architectures.
|
||||
+ *)
|
||||
+ let cmd = String.concat " " cmd in
|
||||
+ let incompatible_fn () =
|
||||
+ Firstboot.add_firstboot_script g root cmd cmd
|
||||
+ in
|
||||
+
|
||||
+ run_in_guest_command g root ~incompatible_fn cmd
|
||||
+
|
||||
+and update_system_ca_store_command g root =
|
||||
+ let typ = g#inspect_get_type root in
|
||||
+ let distro = g#inspect_get_distro root in
|
||||
+ match typ, distro with
|
||||
+ | "linux", ("fedora"|"rhel"|"centos"|"scientificlinux"|"oraclelinux"|"redhat-based") ->
|
||||
+ Some [ "update-ca-trust"; "extract" ]
|
||||
+
|
||||
+ | "linux", ("debian"|"ubuntu"|"kalilinux") ->
|
||||
+ Some [ "update-ca-certificates" ]
|
||||
+
|
||||
+ | _, _ ->
|
||||
+ warning (f_"updating the system CA store on this guest %s/%s is not supported") typ distro;
|
||||
+ None
|
||||
diff --git a/sysprep/utils.mli b/sysprep/utils.mli
|
||||
index a57a0d876..82779620e 100644
|
||||
--- a/sysprep/utils.mli
|
||||
+++ b/sysprep/utils.mli
|
||||
@@ -26,3 +26,7 @@ val pod_of_list : ?style:[`Verbatim|`Star|`Dash|`Dot] -> string list -> string
|
||||
use a space-indented (verbatim) block. [`Star], [`Dash] or [`Dot]
|
||||
meaning use a real list with [*], [-] or [·]. The default
|
||||
style is [·] ([`Dot]). *)
|
||||
+
|
||||
+val update_system_ca_store : Guestfs.guestfs -> string -> unit
|
||||
+(** Update the system CA store on the guest for the specified root
|
||||
+ (which is fully mounted). *)
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,42 +0,0 @@
|
||||
From 315bf96d182d5626e5935aaf57b0787fedffc62b Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 4 May 2020 12:15:43 +0200
|
||||
Subject: [PATCH] sysprep: ca-certificates: request system CA store update
|
||||
|
||||
In case any certificate is removed from the guest, regenerate the system
|
||||
CA store.
|
||||
|
||||
(cherry picked from commit b9065fa7adc93123c53f4827e11dad6b210b7d4b)
|
||||
---
|
||||
sysprep/sysprep_operation_ca_certificates.ml | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sysprep/sysprep_operation_ca_certificates.ml b/sysprep/sysprep_operation_ca_certificates.ml
|
||||
index e481cebf8..a2b7986c1 100644
|
||||
--- a/sysprep/sysprep_operation_ca_certificates.ml
|
||||
+++ b/sysprep/sysprep_operation_ca_certificates.ml
|
||||
@@ -39,7 +39,11 @@ let ca_certificates_perform (g : Guestfs.guestfs) root side_effects =
|
||||
let set = StringSet.diff set excepts in
|
||||
StringSet.iter (
|
||||
fun filename ->
|
||||
- try g#rm filename with G.Error _ -> ()
|
||||
+ try
|
||||
+ g#rm filename;
|
||||
+ side_effects#update_system_ca_store ()
|
||||
+ with
|
||||
+ G.Error _ -> ()
|
||||
) set
|
||||
)
|
||||
|
||||
@@ -48,6 +52,8 @@ let op = {
|
||||
name = "ca-certificates";
|
||||
enabled_by_default = false;
|
||||
heading = s_"Remove CA certificates in the guest";
|
||||
+ pod_description = Some (s_"\
|
||||
+In case any certificate is removed, the system CA store is updated.");
|
||||
perform_on_filesystems = Some ca_certificates_perform;
|
||||
}
|
||||
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,107 +0,0 @@
|
||||
From 90bb3cd1793275da50d509570d07d279989e2c45 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Thu, 7 May 2020 13:53:21 +0200
|
||||
Subject: [PATCH] sysprep: add IPA offline unenrollment (RHBZ#1789592)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This new operation unenrolls the guest from a IPA server offline, by
|
||||
removing the configuration files and certificates.
|
||||
|
||||
Thanks to Christian Heimes and François Cami for the hints.
|
||||
|
||||
(cherry picked from commit 0a53e2c7fc4fe2aa69052134230db0804849b470)
|
||||
---
|
||||
sysprep/Makefile.am | 1 +
|
||||
sysprep/sysprep_operation_ipa_client.ml | 66 +++++++++++++++++++++++++
|
||||
2 files changed, 67 insertions(+)
|
||||
create mode 100644 sysprep/sysprep_operation_ipa_client.ml
|
||||
|
||||
diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am
|
||||
index e6269c3f7..79266314b 100644
|
||||
--- a/sysprep/Makefile.am
|
||||
+++ b/sysprep/Makefile.am
|
||||
@@ -43,6 +43,7 @@ operations = \
|
||||
flag_reconfiguration \
|
||||
firewall_rules \
|
||||
fs_uuids \
|
||||
+ ipa_client \
|
||||
kerberos_data \
|
||||
lvm_uuids \
|
||||
logfiles \
|
||||
diff --git a/sysprep/sysprep_operation_ipa_client.ml b/sysprep/sysprep_operation_ipa_client.ml
|
||||
new file mode 100644
|
||||
index 000000000..6e64a754a
|
||||
--- /dev/null
|
||||
+++ b/sysprep/sysprep_operation_ipa_client.ml
|
||||
@@ -0,0 +1,66 @@
|
||||
+(* virt-sysprep
|
||||
+ * Copyright (C) 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.
|
||||
+ *)
|
||||
+
|
||||
+open Sysprep_operation
|
||||
+open Common_gettext.Gettext
|
||||
+
|
||||
+module G = Guestfs
|
||||
+
|
||||
+let ipa_client_perform (g : Guestfs.guestfs) root side_effects =
|
||||
+ let typ = g#inspect_get_type root in
|
||||
+ if typ = "linux" then (
|
||||
+ (* Simple paths with no side effects. *)
|
||||
+ let paths = [ "/etc/ipa/ca.crt";
|
||||
+ "/etc/ipa/default.conf";
|
||||
+ "/var/lib/ipa-client/sysrestore/*";
|
||||
+ "/var/lib/ipa-client/pki/*" ] in
|
||||
+ let paths = List.concat (List.map Array.to_list (List.map g#glob_expand paths)) in
|
||||
+ List.iter (
|
||||
+ fun filename ->
|
||||
+ try g#rm filename with G.Error _ -> ()
|
||||
+ ) paths;
|
||||
+
|
||||
+ (* Certificates in the system CA store. *)
|
||||
+ let certs = [ "/etc/pki/ca-trust/source/anchors/ipa-ca.crt";
|
||||
+ "/usr/local/share/ca-certificates/ipa-ca.crt";
|
||||
+ "/etc/pki/ca-trust/source/ipa.p11-kit" ] in
|
||||
+ List.iter (
|
||||
+ fun filename ->
|
||||
+ try
|
||||
+ g#rm filename;
|
||||
+ side_effects#update_system_ca_store ()
|
||||
+ with
|
||||
+ G.Error _ -> ()
|
||||
+ ) certs
|
||||
+ )
|
||||
+
|
||||
+let op = {
|
||||
+ defaults with
|
||||
+ name = "ipa-client";
|
||||
+ enabled_by_default = true;
|
||||
+ heading = s_"Remove the IPA files";
|
||||
+ pod_description = Some (s_"\
|
||||
+Remove all the files related to an IPA (Identity, Policy, Audit) system.
|
||||
+This effectively unenrolls the guest from an IPA server without interacting
|
||||
+with it.
|
||||
+
|
||||
+This operation does not run C<ipa-client>.");
|
||||
+ perform_on_filesystems = Some ipa_client_perform;
|
||||
+}
|
||||
+
|
||||
+let () = register_operation op
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,81 +0,0 @@
|
||||
From c8dc0b229b3cbcb72ca90ddf025087586a7d2e38 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Thu, 7 May 2020 14:02:30 +0200
|
||||
Subject: [PATCH] sysprep: add Kerberos keytab file removal
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This new operation removes the Kerberos /etc/krb5.keytab file from the
|
||||
guest.
|
||||
|
||||
Thanks to Christian Heimes and François Cami for the hints.
|
||||
|
||||
Related to RHBZ#1789592.
|
||||
|
||||
(cherry picked from commit faa5d8507f552e05435312f16d9e50f613a13615)
|
||||
---
|
||||
sysprep/Makefile.am | 1 +
|
||||
.../sysprep_operation_kerberos_hostkeytab.ml | 38 +++++++++++++++++++
|
||||
2 files changed, 39 insertions(+)
|
||||
create mode 100644 sysprep/sysprep_operation_kerberos_hostkeytab.ml
|
||||
|
||||
diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am
|
||||
index 79266314b..a99957306 100644
|
||||
--- a/sysprep/Makefile.am
|
||||
+++ b/sysprep/Makefile.am
|
||||
@@ -45,6 +45,7 @@ operations = \
|
||||
fs_uuids \
|
||||
ipa_client \
|
||||
kerberos_data \
|
||||
+ kerberos_hostkeytab \
|
||||
lvm_uuids \
|
||||
logfiles \
|
||||
machine_id \
|
||||
diff --git a/sysprep/sysprep_operation_kerberos_hostkeytab.ml b/sysprep/sysprep_operation_kerberos_hostkeytab.ml
|
||||
new file mode 100644
|
||||
index 000000000..cb3023353
|
||||
--- /dev/null
|
||||
+++ b/sysprep/sysprep_operation_kerberos_hostkeytab.ml
|
||||
@@ -0,0 +1,38 @@
|
||||
+(* virt-sysprep
|
||||
+ * Copyright (C) 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.
|
||||
+ *)
|
||||
+
|
||||
+open Sysprep_operation
|
||||
+open Common_gettext.Gettext
|
||||
+
|
||||
+module G = Guestfs
|
||||
+
|
||||
+let kerberos_hostkeytab_perform (g : Guestfs.guestfs) root side_effects =
|
||||
+ let typ = g#inspect_get_type root in
|
||||
+ if typ <> "windows" then (
|
||||
+ (try g#rm "/etc/krb5.keytab" with G.Error _ -> ())
|
||||
+ )
|
||||
+
|
||||
+let op = {
|
||||
+ defaults with
|
||||
+ name = "kerberos-hostkeytab";
|
||||
+ enabled_by_default = true;
|
||||
+ heading = s_"Remove the Kerberos host keytab file in the guest";
|
||||
+ perform_on_filesystems = Some kerberos_hostkeytab_perform;
|
||||
+}
|
||||
+
|
||||
+let () = register_operation op
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,35 +0,0 @@
|
||||
From 318aa975b212c9b8778606ce440c95682f99c700 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Tue, 19 May 2020 12:14:18 +0200
|
||||
Subject: [PATCH] vCenter: fix parsing of HTTP status string (RHBZ#1837328)
|
||||
|
||||
vCenter 7 answers with an HTTP/2 status string, so we cannot extract
|
||||
the status code from it by using fixed positions in that string.
|
||||
Hence, pick the status code by reading what's after the whitespace.
|
||||
|
||||
Tested with vCenter 6.5 and 7.
|
||||
|
||||
(cherry picked from commit d2aa82317964d62fcc8dc7b6737773003d04b998
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/vCenter.ml | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/vCenter.ml b/v2v/vCenter.ml
|
||||
index b1b9f9b15..b15e2f7d0 100644
|
||||
--- a/v2v/vCenter.ml
|
||||
+++ b/v2v/vCenter.ml
|
||||
@@ -213,7 +213,9 @@ and fetch_headers_from_url password_file uri sslverify https_url =
|
||||
| [] ->
|
||||
dump_response stderr;
|
||||
error (f_"vcenter: no status code in output of ‘curl’ command. Is ‘curl’ installed?")
|
||||
- | ss -> String.sub (List.hd (List.rev ss)) 9 3 in
|
||||
+ | ss ->
|
||||
+ let s = List.hd (List.rev ss) in
|
||||
+ String.sub s (String.index s ' ' + 1) 3 in
|
||||
|
||||
let headers =
|
||||
List.map (
|
||||
--
|
||||
2.18.4
|
||||
|
@ -1,33 +0,0 @@
|
||||
From a2c0ccac7b1bcb451987b6c1b85e3a5ee48b8949 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Sun, 28 Sep 2014 19:14:43 +0100
|
||||
Subject: [PATCH] RHEL 8: v2v: Select correct qemu binary for -o qemu mode
|
||||
(RHBZ#1147313).
|
||||
|
||||
RHEL 8 does not have qemu-system-x86_64 (etc), and in addition the
|
||||
qemu binary is located in /usr/libexec. Encode the path to this
|
||||
binary directly in the script.
|
||||
|
||||
Note that we don't support people running qemu directly like this.
|
||||
It's just for quick testing of converted VMs, and to help us with
|
||||
support cases.
|
||||
---
|
||||
v2v/output_qemu.ml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml
|
||||
index 1f6798aaf..8665d7b5c 100644
|
||||
--- a/v2v/output_qemu.ml
|
||||
+++ b/v2v/output_qemu.ml
|
||||
@@ -81,7 +81,7 @@ object
|
||||
* module deals with shell and qemu comma quoting.
|
||||
*)
|
||||
let cmd = Qemuopts.create () in
|
||||
- Qemuopts.set_binary_by_arch cmd (Some guestcaps.gcaps_arch);
|
||||
+ Qemuopts.set_binary cmd "/usr/libexec/qemu-kvm";
|
||||
|
||||
let flag = Qemuopts.flag cmd
|
||||
and arg = Qemuopts.arg cmd
|
||||
--
|
||||
2.18.4
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user