import libguestfs-1.40.2-24.module+el8.3.0+7176+57f10f42
This commit is contained in:
parent
8211d91639
commit
f87f6f5988
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +1,4 @@
|
|||||||
SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-3
|
SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-5
|
||||||
SOURCES/libguestfs-1.38.4.tar.gz
|
SOURCES/libguestfs-1.40.2.tar.gz
|
||||||
SOURCES/libguestfs.keyring
|
SOURCES/libguestfs.keyring
|
||||||
SOURCES/rhsrvany.exe
|
SOURCES/rhsrvany.exe
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
ac8722917cc31c36836e241bd7a4beb5f8a8b0c8 SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-3
|
130adbc011dc0af736465b813c2b22a600c128c1 SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-5
|
||||||
15c8f487ee163374cb7be9436fb1bb697cef7d9e SOURCES/libguestfs-1.38.4.tar.gz
|
45755f0f73b503790974484053ff482f32665b13 SOURCES/libguestfs-1.40.2.tar.gz
|
||||||
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring
|
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring
|
||||||
2bd96e478fc004cd323b5bd754c856641877dac6 SOURCES/rhsrvany.exe
|
2bd96e478fc004cd323b5bd754c856641877dac6 SOURCES/rhsrvany.exe
|
||||||
|
@ -1,974 +0,0 @@
|
|||||||
From 21f0a22072f0543c416c440665bcf75ae09e6233 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Mon, 12 Feb 2018 11:24:06 +0100
|
|
||||||
Subject: [PATCH] Switch from YAJL to Jansson
|
|
||||||
|
|
||||||
While YAJL mostly works fine, it did not see any active development in
|
|
||||||
the last 3 years. OTOH, Jansson is another JSON C implementation, with
|
|
||||||
a very liberal license, and a much nicer API.
|
|
||||||
|
|
||||||
Hence, switch all of libguestfs from YAJL to Jansson:
|
|
||||||
- configure checks, and buildsystem in general
|
|
||||||
- packages pulled in the appliance
|
|
||||||
- actual implementations
|
|
||||||
- contrib scripts
|
|
||||||
- documentation
|
|
||||||
|
|
||||||
This also makes use of the better APIs available (e.g. json_object_get,
|
|
||||||
json_array_foreach, and json_object_foreach). This does not change the
|
|
||||||
API of our OCaml Yajl module.
|
|
||||||
|
|
||||||
(cherry picked from commit bd1c5c9f4dcf38458099db8a0bf4659a07ef055d)
|
|
||||||
---
|
|
||||||
appliance/packagelist.in | 13 ++--
|
|
||||||
builder/Makefile.am | 4 +-
|
|
||||||
builder/yajl-c.c | 66 ++++++++--------
|
|
||||||
contrib/p2v/aux-scripts/do-build.sh | 8 +-
|
|
||||||
contrib/p2v/build-p2v-iso.sh | 3 +-
|
|
||||||
daemon/Makefile.am | 4 +-
|
|
||||||
daemon/ldm.c | 115 ++++++++++++----------------
|
|
||||||
docs/guestfs-building.pod | 2 +-
|
|
||||||
lib/Makefile.am | 4 +-
|
|
||||||
lib/info.c | 113 +++++++++++----------------
|
|
||||||
lib/qemu.c | 64 ++++++----------
|
|
||||||
m4/guestfs-libraries.m4 | 4 +-
|
|
||||||
12 files changed, 169 insertions(+), 231 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
|
|
||||||
index 8ded2588a..f92a6ce95 100644
|
|
||||||
--- a/appliance/packagelist.in
|
|
||||||
+++ b/appliance/packagelist.in
|
|
||||||
@@ -35,6 +35,7 @@ ifelse(REDHAT,1,
|
|
||||||
hivex
|
|
||||||
iproute
|
|
||||||
iputils
|
|
||||||
+ jansson
|
|
||||||
kernel
|
|
||||||
libcap
|
|
||||||
libldm
|
|
||||||
@@ -51,7 +52,6 @@ ifelse(REDHAT,1,
|
|
||||||
systemd dnl for /sbin/reboot and udevd
|
|
||||||
vim-minimal
|
|
||||||
xz
|
|
||||||
- yajl
|
|
||||||
yara
|
|
||||||
zfs-fuse
|
|
||||||
)
|
|
||||||
@@ -82,12 +82,12 @@ dnl iproute has been renamed to iproute2
|
|
||||||
libc-bin
|
|
||||||
libcap2
|
|
||||||
libhivex0
|
|
||||||
+ libjansson4
|
|
||||||
libpcre3
|
|
||||||
libsystemd0
|
|
||||||
libsystemd-id128-0
|
|
||||||
libsystemd-journal0
|
|
||||||
libtirpc1
|
|
||||||
- libyajl2
|
|
||||||
libyara3
|
|
||||||
linux-image
|
|
||||||
dnl syslinux 'suggests' mtools, but in reality it's a hard dependency:
|
|
||||||
@@ -116,6 +116,7 @@ ifelse(ARCHLINUX,1,
|
|
||||||
hivex
|
|
||||||
iproute2
|
|
||||||
iputils
|
|
||||||
+ jansson
|
|
||||||
libcap
|
|
||||||
libtirpc
|
|
||||||
linux
|
|
||||||
@@ -131,7 +132,6 @@ ifelse(ARCHLINUX,1,
|
|
||||||
systemd
|
|
||||||
vim
|
|
||||||
xz
|
|
||||||
- yajl
|
|
||||||
yara
|
|
||||||
)
|
|
||||||
|
|
||||||
@@ -153,9 +153,9 @@ ifelse(SUSE,1,
|
|
||||||
iputils
|
|
||||||
libcap2
|
|
||||||
libhivex0
|
|
||||||
+ libjansson4
|
|
||||||
libselinux1
|
|
||||||
libtirpc3
|
|
||||||
- libyajl2
|
|
||||||
libyara3
|
|
||||||
mkisofs
|
|
||||||
ntfsprogs
|
|
||||||
@@ -177,6 +177,7 @@ ifelse(FRUGALWARE,1,
|
|
||||||
hfsplus
|
|
||||||
iproute2
|
|
||||||
iputils
|
|
||||||
+ jansson
|
|
||||||
kernel
|
|
||||||
libcap
|
|
||||||
libtirpc
|
|
||||||
@@ -188,7 +189,6 @@ ifelse(FRUGALWARE,1,
|
|
||||||
systemd
|
|
||||||
vim
|
|
||||||
xz
|
|
||||||
- yajl
|
|
||||||
xfsprogs-acl
|
|
||||||
xfsprogs-attr
|
|
||||||
gptfdisk
|
|
||||||
@@ -209,9 +209,9 @@ ifelse(MAGEIA,1,
|
|
||||||
iproute2
|
|
||||||
iputils
|
|
||||||
libcap
|
|
||||||
+ libjansson4
|
|
||||||
libldm
|
|
||||||
libtirpc
|
|
||||||
- libyajl
|
|
||||||
dnl syslinux uses mtools without depending on it
|
|
||||||
mtools
|
|
||||||
nilfs-utils
|
|
||||||
@@ -224,7 +224,6 @@ ifelse(MAGEIA,1,
|
|
||||||
systemd /* for /sbin/reboot and udevd */
|
|
||||||
vim-minimal
|
|
||||||
xz
|
|
||||||
- yajl
|
|
||||||
)
|
|
||||||
|
|
||||||
acl
|
|
||||||
diff --git a/builder/Makefile.am b/builder/Makefile.am
|
|
||||||
index e5872bdd9..c7b50778a 100644
|
|
||||||
--- a/builder/Makefile.am
|
|
||||||
+++ b/builder/Makefile.am
|
|
||||||
@@ -157,7 +157,7 @@ virt_builder_CFLAGS = \
|
|
||||||
$(LIBLZMA_CFLAGS) \
|
|
||||||
$(LIBTINFO_CFLAGS) \
|
|
||||||
$(LIBXML2_CFLAGS) \
|
|
||||||
- $(YAJL_CFLAGS)
|
|
||||||
+ $(JANSSON_CFLAGS)
|
|
||||||
|
|
||||||
BOBJECTS = $(SOURCES_ML:.ml=.cmo)
|
|
||||||
XOBJECTS = $(BOBJECTS:.cmo=.cmx)
|
|
||||||
@@ -211,7 +211,7 @@ OCAMLCLIBS = \
|
|
||||||
$(LIBCRYPT_LIBS) \
|
|
||||||
$(LIBLZMA_LIBS) \
|
|
||||||
$(LIBXML2_LIBS) \
|
|
||||||
- $(YAJL_LIBS) \
|
|
||||||
+ $(JANSSON_LIBS) \
|
|
||||||
$(LIBINTL) \
|
|
||||||
-lgnu
|
|
||||||
|
|
||||||
diff --git a/builder/yajl-c.c b/builder/yajl-c.c
|
|
||||||
index 3c2402e42..e53755f55 100644
|
|
||||||
--- a/builder/yajl-c.c
|
|
||||||
+++ b/builder/yajl-c.c
|
|
||||||
@@ -23,24 +23,17 @@
|
|
||||||
#include <caml/memory.h>
|
|
||||||
#include <caml/mlvalues.h>
|
|
||||||
|
|
||||||
-#include <yajl/yajl_tree.h>
|
|
||||||
+#include <jansson.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
-/* GCC can't work out that the YAJL_IS_<foo> test is sufficient to
|
|
||||||
- * ensure that YAJL_GET_<foo> later doesn't return NULL.
|
|
||||||
- */
|
|
||||||
-#if defined(__GNUC__) && __GNUC__ >= 6 /* gcc >= 6 */
|
|
||||||
-#pragma GCC diagnostic ignored "-Wnull-dereference"
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
#define Val_none (Val_int (0))
|
|
||||||
|
|
||||||
value virt_builder_yajl_tree_parse (value stringv);
|
|
||||||
|
|
||||||
static value
|
|
||||||
-convert_yajl_value (yajl_val val, int level)
|
|
||||||
+convert_json_t (json_t *val, int level)
|
|
||||||
{
|
|
||||||
CAMLparam0 ();
|
|
||||||
CAMLlocal4 (rv, lv, v, sv);
|
|
||||||
@@ -48,46 +41,51 @@ convert_yajl_value (yajl_val val, int level)
|
|
||||||
if (level > 20)
|
|
||||||
caml_invalid_argument ("too many levels of object/array nesting");
|
|
||||||
|
|
||||||
- if (YAJL_IS_OBJECT (val)) {
|
|
||||||
- const size_t len = YAJL_GET_OBJECT(val)->len;
|
|
||||||
+ if (json_is_object (val)) {
|
|
||||||
+ const size_t len = json_object_size (val);
|
|
||||||
size_t i;
|
|
||||||
+ const char *key;
|
|
||||||
+ json_t *jvalue;
|
|
||||||
rv = caml_alloc (1, 3);
|
|
||||||
lv = caml_alloc_tuple (len);
|
|
||||||
- for (i = 0; i < len; ++i) {
|
|
||||||
+ i = 0;
|
|
||||||
+ json_object_foreach (val, key, jvalue) {
|
|
||||||
v = caml_alloc_tuple (2);
|
|
||||||
- sv = caml_copy_string (YAJL_GET_OBJECT(val)->keys[i]);
|
|
||||||
+ sv = caml_copy_string (key);
|
|
||||||
Store_field (v, 0, sv);
|
|
||||||
- sv = convert_yajl_value (YAJL_GET_OBJECT(val)->values[i], level + 1);
|
|
||||||
+ sv = convert_json_t (jvalue, level + 1);
|
|
||||||
Store_field (v, 1, sv);
|
|
||||||
Store_field (lv, i, v);
|
|
||||||
+ ++i;
|
|
||||||
}
|
|
||||||
Store_field (rv, 0, lv);
|
|
||||||
- } else if (YAJL_IS_ARRAY (val)) {
|
|
||||||
- const size_t len = YAJL_GET_ARRAY(val)->len;
|
|
||||||
+ } else if (json_is_array (val)) {
|
|
||||||
+ const size_t len = json_array_size (val);
|
|
||||||
size_t i;
|
|
||||||
+ json_t *jvalue;
|
|
||||||
rv = caml_alloc (1, 4);
|
|
||||||
lv = caml_alloc_tuple (len);
|
|
||||||
- for (i = 0; i < len; ++i) {
|
|
||||||
- v = convert_yajl_value (YAJL_GET_ARRAY(val)->values[i], level + 1);
|
|
||||||
+ json_array_foreach (val, i, jvalue) {
|
|
||||||
+ v = convert_json_t (jvalue, level + 1);
|
|
||||||
Store_field (lv, i, v);
|
|
||||||
}
|
|
||||||
Store_field (rv, 0, lv);
|
|
||||||
- } else if (YAJL_IS_STRING (val)) {
|
|
||||||
+ } else if (json_is_string (val)) {
|
|
||||||
rv = caml_alloc (1, 0);
|
|
||||||
- v = caml_copy_string (YAJL_GET_STRING(val));
|
|
||||||
+ v = caml_copy_string (json_string_value (val));
|
|
||||||
Store_field (rv, 0, v);
|
|
||||||
- } else if (YAJL_IS_DOUBLE (val)) {
|
|
||||||
+ } else if (json_is_real (val)) {
|
|
||||||
rv = caml_alloc (1, 2);
|
|
||||||
- v = caml_copy_double (YAJL_GET_DOUBLE(val));
|
|
||||||
+ v = caml_copy_double (json_real_value (val));
|
|
||||||
Store_field (rv, 0, v);
|
|
||||||
- } else if (YAJL_IS_INTEGER (val)) {
|
|
||||||
+ } else if (json_is_integer (val)) {
|
|
||||||
rv = caml_alloc (1, 1);
|
|
||||||
- v = caml_copy_int64 (YAJL_GET_INTEGER(val));
|
|
||||||
+ v = caml_copy_int64 (json_integer_value (val));
|
|
||||||
Store_field (rv, 0, v);
|
|
||||||
- } else if (YAJL_IS_TRUE (val)) {
|
|
||||||
+ } else if (json_is_true (val)) {
|
|
||||||
rv = caml_alloc (1, 5);
|
|
||||||
Store_field (rv, 0, Val_true);
|
|
||||||
- } else if (YAJL_IS_FALSE (val)) {
|
|
||||||
+ } else if (json_is_false (val)) {
|
|
||||||
rv = caml_alloc (1, 5);
|
|
||||||
Store_field (rv, 0, Val_false);
|
|
||||||
} else
|
|
||||||
@@ -101,21 +99,21 @@ virt_builder_yajl_tree_parse (value stringv)
|
|
||||||
{
|
|
||||||
CAMLparam1 (stringv);
|
|
||||||
CAMLlocal1 (rv);
|
|
||||||
- yajl_val tree;
|
|
||||||
- char error_buf[256];
|
|
||||||
+ json_t *tree;
|
|
||||||
+ json_error_t err;
|
|
||||||
|
|
||||||
- tree = yajl_tree_parse (String_val (stringv), error_buf, sizeof error_buf);
|
|
||||||
+ tree = json_loads (String_val (stringv), JSON_DECODE_ANY, &err);
|
|
||||||
if (tree == NULL) {
|
|
||||||
- char buf[256 + sizeof error_buf];
|
|
||||||
- if (strlen (error_buf) > 0)
|
|
||||||
- snprintf (buf, sizeof buf, "JSON parse error: %s", error_buf);
|
|
||||||
+ char buf[256 + JSON_ERROR_TEXT_LENGTH];
|
|
||||||
+ if (strlen (err.text) > 0)
|
|
||||||
+ snprintf (buf, sizeof buf, "JSON parse error: %s", err.text);
|
|
||||||
else
|
|
||||||
snprintf (buf, sizeof buf, "unknown JSON parse error");
|
|
||||||
caml_invalid_argument (buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
- rv = convert_yajl_value (tree, 1);
|
|
||||||
- yajl_tree_free (tree);
|
|
||||||
+ rv = convert_json_t (tree, 1);
|
|
||||||
+ json_decref (tree);
|
|
||||||
|
|
||||||
CAMLreturn (rv);
|
|
||||||
}
|
|
||||||
diff --git a/contrib/p2v/aux-scripts/do-build.sh b/contrib/p2v/aux-scripts/do-build.sh
|
|
||||||
index 5edb53d0e..dd6424bb4 100644
|
|
||||||
--- a/contrib/p2v/aux-scripts/do-build.sh
|
|
||||||
+++ b/contrib/p2v/aux-scripts/do-build.sh
|
|
||||||
@@ -53,8 +53,8 @@ case $osversion in
|
|
||||||
# This just forces configure to ignore these missing dependencies.
|
|
||||||
export LIBTINFO_CFLAGS=-D_GNU_SOURCE
|
|
||||||
export LIBTINFO_LIBS=-lncurses
|
|
||||||
- export YAJL_CFLAGS=-D_GNU_SOURCE
|
|
||||||
- export YAJL_LIBS=-lyajl
|
|
||||||
+ export JANSSON_CFLAGS=-D_GNU_SOURCE
|
|
||||||
+ export JANSSON_LIBS=-ljansson
|
|
||||||
# Remove some unsupported flags that the configure script hard codes.
|
|
||||||
sed -i -e 's/-fno-strict-overflow//' configure
|
|
||||||
sed -i -e 's/-Wno-strict-overflow//' configure
|
|
||||||
@@ -66,8 +66,8 @@ case $osversion in
|
|
||||||
# This just forces configure to ignore these missing dependencies.
|
|
||||||
export LIBTINFO_CFLAGS=-D_GNU_SOURCE
|
|
||||||
export LIBTINFO_LIBS=-lncurses
|
|
||||||
- export YAJL_CFLAGS=-D_GNU_SOURCE
|
|
||||||
- export YAJL_LIBS=-lyajl
|
|
||||||
+ export JANSSON_CFLAGS=-D_GNU_SOURCE
|
|
||||||
+ export JANSSON_LIBS=-ljansson
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
diff --git a/contrib/p2v/build-p2v-iso.sh b/contrib/p2v/build-p2v-iso.sh
|
|
||||||
index c80a1b134..ae25cebc8 100755
|
|
||||||
--- a/contrib/p2v/build-p2v-iso.sh
|
|
||||||
+++ b/contrib/p2v/build-p2v-iso.sh
|
|
||||||
@@ -86,7 +86,6 @@ done
|
|
||||||
# Various hacks for different versions of RHEL.
|
|
||||||
if=virtio
|
|
||||||
netdev=virtio-net-pci
|
|
||||||
-pkgs="$pkgs,yajl-devel"
|
|
||||||
declare -a epel
|
|
||||||
case $osversion in
|
|
||||||
rhel-5.*|centos-5.*)
|
|
||||||
@@ -105,10 +104,12 @@ case $osversion in
|
|
||||||
rhel-6.*|centos-6.*)
|
|
||||||
epel[0]="--run-command"
|
|
||||||
epel[1]="yum install -y --nogpgcheck https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm"
|
|
||||||
+ pkgs="$pkgs,jansson-devel"
|
|
||||||
;;
|
|
||||||
rhel-7.*|centos-7.*)
|
|
||||||
epel[0]="--run-command"
|
|
||||||
epel[1]="yum install -y --nogpgcheck https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm"
|
|
||||||
+ pkgs="$pkgs,jansson-devel"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
|
||||||
index 6240f517d..d9ed5625e 100644
|
|
||||||
--- a/daemon/Makefile.am
|
|
||||||
+++ b/daemon/Makefile.am
|
|
||||||
@@ -218,7 +218,7 @@ guestfsd_LDADD = \
|
|
||||||
camldaemon.o \
|
|
||||||
$(ACL_LIBS) \
|
|
||||||
$(CAP_LIBS) \
|
|
||||||
- $(YAJL_LIBS) \
|
|
||||||
+ $(JANSSON_LIBS) \
|
|
||||||
$(SELINUX_LIBS) \
|
|
||||||
$(AUGEAS_LIBS) \
|
|
||||||
$(HIVEX_LIBS) \
|
|
||||||
@@ -256,7 +256,7 @@ guestfsd_CFLAGS = \
|
|
||||||
$(AUGEAS_CFLAGS) \
|
|
||||||
$(HIVEX_CFLAGS) \
|
|
||||||
$(SD_JOURNAL_CFLAGS) \
|
|
||||||
- $(YAJL_CFLAGS) \
|
|
||||||
+ $(JANSSON_CFLAGS) \
|
|
||||||
$(PCRE_CFLAGS)
|
|
||||||
|
|
||||||
# Parts of the daemon are written in OCaml. These are linked into a
|
|
||||||
diff --git a/daemon/ldm.c b/daemon/ldm.c
|
|
||||||
index 2f4d2aef3..be4fb9701 100644
|
|
||||||
--- a/daemon/ldm.c
|
|
||||||
+++ b/daemon/ldm.c
|
|
||||||
@@ -25,19 +25,12 @@
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
-#include <yajl/yajl_tree.h>
|
|
||||||
+#include <jansson.h>
|
|
||||||
|
|
||||||
#include "daemon.h"
|
|
||||||
#include "actions.h"
|
|
||||||
#include "optgroups.h"
|
|
||||||
|
|
||||||
-/* GCC can't work out that the YAJL_IS_<foo> test is sufficient to
|
|
||||||
- * ensure that YAJL_GET_<foo> later doesn't return NULL.
|
|
||||||
- */
|
|
||||||
-#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 60000 /* gcc >= 6 */
|
|
||||||
-#pragma GCC diagnostic ignored "-Wnull-dereference"
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
int
|
|
||||||
optgroup_ldm_available (void)
|
|
||||||
{
|
|
||||||
@@ -72,44 +65,42 @@ do_ldmtool_remove_all (void)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static yajl_val
|
|
||||||
+static json_t *
|
|
||||||
parse_json (const char *json, const char *func)
|
|
||||||
{
|
|
||||||
- yajl_val tree;
|
|
||||||
- char parse_error[1024];
|
|
||||||
+ json_t *tree;
|
|
||||||
+ json_error_t err;
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
fprintf (stderr, "%s: parsing json: %s\n", func, json);
|
|
||||||
|
|
||||||
- tree = yajl_tree_parse (json, parse_error, sizeof parse_error);
|
|
||||||
+ tree = json_loads (json, 0, &err);
|
|
||||||
if (tree == NULL) {
|
|
||||||
reply_with_error ("parse error: %s",
|
|
||||||
- strlen (parse_error) ? parse_error : "unknown error");
|
|
||||||
+ strlen (err.text) ? err.text : "unknown error");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* Caller should free this by doing 'yajl_tree_free (tree);'. */
|
|
||||||
+ /* Caller should free this by doing 'json_decref (tree);'. */
|
|
||||||
return tree;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TYPE_ERROR ((char **) -1)
|
|
||||||
|
|
||||||
static char **
|
|
||||||
-json_value_to_string_list (yajl_val node)
|
|
||||||
+json_value_to_string_list (json_t *node)
|
|
||||||
{
|
|
||||||
CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (strs);
|
|
||||||
- yajl_val n;
|
|
||||||
- size_t i, len;
|
|
||||||
+ json_t *n;
|
|
||||||
+ size_t i;
|
|
||||||
|
|
||||||
- if (! YAJL_IS_ARRAY (node))
|
|
||||||
+ if (!json_is_array (node))
|
|
||||||
return TYPE_ERROR;
|
|
||||||
|
|
||||||
- len = YAJL_GET_ARRAY (node)->len;
|
|
||||||
- for (i = 0; i < len; ++i) {
|
|
||||||
- n = YAJL_GET_ARRAY (node)->values[i];
|
|
||||||
- if (! YAJL_IS_STRING (n))
|
|
||||||
+ json_array_foreach (node, i, n) {
|
|
||||||
+ if (!json_is_string (n))
|
|
||||||
return TYPE_ERROR;
|
|
||||||
- if (add_string (&strs, YAJL_GET_STRING (n)) == -1)
|
|
||||||
+ if (add_string (&strs, json_string_value (n)) == -1)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (end_stringsbuf (&strs) == -1)
|
|
||||||
@@ -123,14 +114,14 @@ parse_json_get_string_list (const char *json,
|
|
||||||
const char *func, const char *cmd)
|
|
||||||
{
|
|
||||||
char **ret;
|
|
||||||
- yajl_val tree = NULL;
|
|
||||||
+ json_t *tree = NULL;
|
|
||||||
|
|
||||||
tree = parse_json (json, func);
|
|
||||||
if (tree == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret = json_value_to_string_list (tree);
|
|
||||||
- yajl_tree_free (tree);
|
|
||||||
+ json_decref (tree);
|
|
||||||
if (ret == TYPE_ERROR) {
|
|
||||||
reply_with_error ("output of '%s' was not a JSON array of strings", cmd);
|
|
||||||
return NULL;
|
|
||||||
@@ -144,43 +135,40 @@ static char *
|
|
||||||
parse_json_get_object_string (const char *json, const char *key, int flags,
|
|
||||||
const char *func, const char *cmd)
|
|
||||||
{
|
|
||||||
- char *str, *ret;
|
|
||||||
- yajl_val tree = NULL, node;
|
|
||||||
- size_t i, len;
|
|
||||||
+ const char *str;
|
|
||||||
+ char *ret;
|
|
||||||
+ json_t *tree = NULL, *node;
|
|
||||||
|
|
||||||
tree = parse_json (json, func);
|
|
||||||
if (tree == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- if (! YAJL_IS_OBJECT (tree))
|
|
||||||
+ if (!json_is_object (tree))
|
|
||||||
+ goto bad_type;
|
|
||||||
+
|
|
||||||
+ node = json_object_get (tree, key);
|
|
||||||
+ if (node == NULL)
|
|
||||||
goto bad_type;
|
|
||||||
|
|
||||||
- len = YAJL_GET_OBJECT (tree)->len;
|
|
||||||
- for (i = 0; i < len; ++i) {
|
|
||||||
- if (STREQ (YAJL_GET_OBJECT (tree)->keys[i], key)) {
|
|
||||||
- node = YAJL_GET_OBJECT (tree)->values[i];
|
|
||||||
-
|
|
||||||
- if ((flags & GET_STRING_NULL_TO_EMPTY) && YAJL_IS_NULL (node))
|
|
||||||
- ret = strdup ("");
|
|
||||||
- else {
|
|
||||||
- str = YAJL_GET_STRING (node);
|
|
||||||
- if (str == NULL)
|
|
||||||
- goto bad_type;
|
|
||||||
- ret = strdup (str);
|
|
||||||
- }
|
|
||||||
- if (ret == NULL)
|
|
||||||
- reply_with_perror ("strdup");
|
|
||||||
-
|
|
||||||
- yajl_tree_free (tree);
|
|
||||||
-
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
+ if ((flags & GET_STRING_NULL_TO_EMPTY) && json_is_null (node))
|
|
||||||
+ ret = strdup ("");
|
|
||||||
+ else {
|
|
||||||
+ str = json_string_value (node);
|
|
||||||
+ if (str == NULL)
|
|
||||||
+ goto bad_type;
|
|
||||||
+ ret = strndup (str, json_string_length (node));
|
|
||||||
}
|
|
||||||
+ if (ret == NULL)
|
|
||||||
+ reply_with_perror ("strdup");
|
|
||||||
+
|
|
||||||
+ json_decref (tree);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
|
|
||||||
bad_type:
|
|
||||||
reply_with_error ("output of '%s' was not a JSON object "
|
|
||||||
"containing a key '%s' of type string", cmd, key);
|
|
||||||
- yajl_tree_free (tree);
|
|
||||||
+ json_decref (tree);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -189,33 +177,30 @@ parse_json_get_object_string_list (const char *json, const char *key,
|
|
||||||
const char *func, const char *cmd)
|
|
||||||
{
|
|
||||||
char **ret;
|
|
||||||
- yajl_val tree, node;
|
|
||||||
- size_t i, len;
|
|
||||||
+ json_t *tree, *node;
|
|
||||||
|
|
||||||
tree = parse_json (json, func);
|
|
||||||
if (tree == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- if (! YAJL_IS_OBJECT (tree))
|
|
||||||
+ if (!json_is_object (tree))
|
|
||||||
goto bad_type;
|
|
||||||
|
|
||||||
- len = YAJL_GET_OBJECT (tree)->len;
|
|
||||||
- for (i = 0; i < len; ++i) {
|
|
||||||
- if (STREQ (YAJL_GET_OBJECT (tree)->keys[i], key)) {
|
|
||||||
- node = YAJL_GET_OBJECT (tree)->values[i];
|
|
||||||
- ret = json_value_to_string_list (node);
|
|
||||||
- if (ret == TYPE_ERROR)
|
|
||||||
- goto bad_type;
|
|
||||||
- yajl_tree_free (tree);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ node = json_object_get (tree, key);
|
|
||||||
+ if (node == NULL)
|
|
||||||
+ goto bad_type;
|
|
||||||
+
|
|
||||||
+ ret = json_value_to_string_list (node);
|
|
||||||
+ if (ret == TYPE_ERROR)
|
|
||||||
+ goto bad_type;
|
|
||||||
+ json_decref (tree);
|
|
||||||
+ return ret;
|
|
||||||
|
|
||||||
bad_type:
|
|
||||||
reply_with_error ("output of '%s' was not a JSON object "
|
|
||||||
"containing a key '%s' of type array of strings",
|
|
||||||
cmd, key);
|
|
||||||
- yajl_tree_free (tree);
|
|
||||||
+ json_decref (tree);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/docs/guestfs-building.pod b/docs/guestfs-building.pod
|
|
||||||
index d350b1d73..2029429fd 100644
|
|
||||||
--- a/docs/guestfs-building.pod
|
|
||||||
+++ b/docs/guestfs-building.pod
|
|
||||||
@@ -172,7 +172,7 @@ I<Required>.
|
|
||||||
|
|
||||||
I<Required>.
|
|
||||||
|
|
||||||
-=item yajl E<ge> 2.0.4
|
|
||||||
+=item Jansson
|
|
||||||
|
|
||||||
I<Required>.
|
|
||||||
|
|
||||||
diff --git a/lib/Makefile.am b/lib/Makefile.am
|
|
||||||
index 91c4e0a2e..d075174d9 100644
|
|
||||||
--- a/lib/Makefile.am
|
|
||||||
+++ b/lib/Makefile.am
|
|
||||||
@@ -141,7 +141,7 @@ libguestfs_la_CFLAGS = \
|
|
||||||
$(PCRE_CFLAGS) \
|
|
||||||
$(LIBVIRT_CFLAGS) \
|
|
||||||
$(LIBXML2_CFLAGS) \
|
|
||||||
- $(YAJL_CFLAGS)
|
|
||||||
+ $(JANSSON_CFLAGS)
|
|
||||||
|
|
||||||
libguestfs_la_LIBADD = \
|
|
||||||
../common/errnostring/liberrnostring.la \
|
|
||||||
@@ -152,7 +152,7 @@ libguestfs_la_LIBADD = \
|
|
||||||
$(PCRE_LIBS) \
|
|
||||||
$(LIBVIRT_LIBS) $(LIBXML2_LIBS) \
|
|
||||||
$(SELINUX_LIBS) \
|
|
||||||
- $(YAJL_LIBS) \
|
|
||||||
+ $(JANSSON_LIBS) \
|
|
||||||
../gnulib/lib/libgnu.la \
|
|
||||||
$(GETADDRINFO_LIB) \
|
|
||||||
$(HOSTENT_LIB) \
|
|
||||||
diff --git a/lib/info.c b/lib/info.c
|
|
||||||
index 93fadcd39..2eadc1c11 100644
|
|
||||||
--- a/lib/info.c
|
|
||||||
+++ b/lib/info.c
|
|
||||||
@@ -37,53 +37,46 @@
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-#include <yajl/yajl_tree.h>
|
|
||||||
+#include <jansson.h>
|
|
||||||
|
|
||||||
#include "guestfs.h"
|
|
||||||
#include "guestfs-internal.h"
|
|
||||||
#include "guestfs-internal-actions.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_ATTRIBUTE_CLEANUP
|
|
||||||
-#define CLEANUP_YAJL_TREE_FREE __attribute__((cleanup(cleanup_yajl_tree_free)))
|
|
||||||
+#define CLEANUP_JSON_T_DECREF __attribute__((cleanup(cleanup_json_t_decref)))
|
|
||||||
|
|
||||||
static void
|
|
||||||
-cleanup_yajl_tree_free (void *ptr)
|
|
||||||
+cleanup_json_t_decref (void *ptr)
|
|
||||||
{
|
|
||||||
- yajl_tree_free (* (yajl_val *) ptr);
|
|
||||||
+ json_decref (* (json_t **) ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
-#define CLEANUP_YAJL_TREE_FREE
|
|
||||||
+#define CLEANUP_JSON_T_DECREF
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-static yajl_val get_json_output (guestfs_h *g, const char *filename);
|
|
||||||
+static json_t *get_json_output (guestfs_h *g, const char *filename);
|
|
||||||
static void set_child_rlimits (struct command *);
|
|
||||||
|
|
||||||
char *
|
|
||||||
guestfs_impl_disk_format (guestfs_h *g, const char *filename)
|
|
||||||
{
|
|
||||||
- size_t i, len;
|
|
||||||
- CLEANUP_YAJL_TREE_FREE yajl_val tree = get_json_output (g, filename);
|
|
||||||
+ CLEANUP_JSON_T_DECREF json_t *tree = get_json_output (g, filename);
|
|
||||||
+ json_t *node;
|
|
||||||
|
|
||||||
if (tree == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
- if (! YAJL_IS_OBJECT (tree))
|
|
||||||
+ if (!json_is_object (tree))
|
|
||||||
goto bad_type;
|
|
||||||
|
|
||||||
- len = YAJL_GET_OBJECT(tree)->len;
|
|
||||||
- for (i = 0; i < len; ++i) {
|
|
||||||
- if (STREQ (YAJL_GET_OBJECT(tree)->keys[i], "format")) {
|
|
||||||
- const char *str;
|
|
||||||
- yajl_val node = YAJL_GET_OBJECT(tree)->values[i];
|
|
||||||
- if (YAJL_IS_NULL (node))
|
|
||||||
- goto bad_type;
|
|
||||||
- str = YAJL_GET_STRING (node);
|
|
||||||
- if (str == NULL)
|
|
||||||
- goto bad_type;
|
|
||||||
- return safe_strdup (g, str); /* caller frees */
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ node = json_object_get (tree, "format");
|
|
||||||
+ if (!json_is_string (node))
|
|
||||||
+ goto bad_type;
|
|
||||||
+
|
|
||||||
+ return safe_strndup (g, json_string_value (node),
|
|
||||||
+ json_string_length (node)); /* caller frees */
|
|
||||||
|
|
||||||
bad_type:
|
|
||||||
error (g, _("qemu-img info: JSON output did not contain ‘format’ key"));
|
|
||||||
@@ -93,30 +86,20 @@ guestfs_impl_disk_format (guestfs_h *g, const char *filename)
|
|
||||||
int64_t
|
|
||||||
guestfs_impl_disk_virtual_size (guestfs_h *g, const char *filename)
|
|
||||||
{
|
|
||||||
- size_t i, len;
|
|
||||||
- CLEANUP_YAJL_TREE_FREE yajl_val tree = get_json_output (g, filename);
|
|
||||||
+ CLEANUP_JSON_T_DECREF json_t *tree = get_json_output (g, filename);
|
|
||||||
+ json_t *node;
|
|
||||||
|
|
||||||
if (tree == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
- if (! YAJL_IS_OBJECT (tree))
|
|
||||||
+ if (!json_is_object (tree))
|
|
||||||
goto bad_type;
|
|
||||||
|
|
||||||
- len = YAJL_GET_OBJECT(tree)->len;
|
|
||||||
- for (i = 0; i < len; ++i) {
|
|
||||||
- if (STREQ (YAJL_GET_OBJECT(tree)->keys[i], "virtual-size")) {
|
|
||||||
- yajl_val node = YAJL_GET_OBJECT(tree)->values[i];
|
|
||||||
- if (YAJL_IS_NULL (node))
|
|
||||||
- goto bad_type;
|
|
||||||
- if (! YAJL_IS_NUMBER (node))
|
|
||||||
- goto bad_type;
|
|
||||||
- if (! YAJL_IS_INTEGER (node)) {
|
|
||||||
- error (g, _("qemu-img info: ‘virtual-size’ is not representable as a 64 bit integer"));
|
|
||||||
- return -1;
|
|
||||||
- }
|
|
||||||
- return YAJL_GET_INTEGER (node);
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ node = json_object_get (tree, "virtual-size");
|
|
||||||
+ if (!json_is_integer (node))
|
|
||||||
+ goto bad_type;
|
|
||||||
+
|
|
||||||
+ return json_integer_value (node);
|
|
||||||
|
|
||||||
bad_type:
|
|
||||||
error (g, _("qemu-img info: JSON output did not contain ‘virtual-size’ key"));
|
|
||||||
@@ -126,29 +109,25 @@ guestfs_impl_disk_virtual_size (guestfs_h *g, const char *filename)
|
|
||||||
int
|
|
||||||
guestfs_impl_disk_has_backing_file (guestfs_h *g, const char *filename)
|
|
||||||
{
|
|
||||||
- size_t i, len;
|
|
||||||
- CLEANUP_YAJL_TREE_FREE yajl_val tree = get_json_output (g, filename);
|
|
||||||
+ CLEANUP_JSON_T_DECREF json_t *tree = get_json_output (g, filename);
|
|
||||||
+ json_t *node;
|
|
||||||
|
|
||||||
if (tree == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
- if (! YAJL_IS_OBJECT (tree))
|
|
||||||
+ if (!json_is_object (tree))
|
|
||||||
goto bad_type;
|
|
||||||
|
|
||||||
- len = YAJL_GET_OBJECT(tree)->len;
|
|
||||||
- for (i = 0; i < len; ++i) {
|
|
||||||
- if (STREQ (YAJL_GET_OBJECT(tree)->keys[i], "backing-filename")) {
|
|
||||||
- yajl_val node = YAJL_GET_OBJECT(tree)->values[i];
|
|
||||||
- /* Work on the assumption that if this field is null, it means
|
|
||||||
- * no backing file, rather than being an error.
|
|
||||||
- */
|
|
||||||
- if (YAJL_IS_NULL (node))
|
|
||||||
- return 0;
|
|
||||||
- return 1;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ node = json_object_get (tree, "backing-filename");
|
|
||||||
+ if (node == NULL)
|
|
||||||
+ return 0; /* no backing-filename key means no backing file */
|
|
||||||
|
|
||||||
- return 0; /* no backing-filename key means no backing file */
|
|
||||||
+ /* Work on the assumption that if this field is null, it means
|
|
||||||
+ * no backing file, rather than being an error.
|
|
||||||
+ */
|
|
||||||
+ if (json_is_null (node))
|
|
||||||
+ return 0;
|
|
||||||
+ return 1;
|
|
||||||
|
|
||||||
bad_type:
|
|
||||||
error (g, _("qemu-img info: JSON output was not an object"));
|
|
||||||
@@ -161,12 +140,12 @@ guestfs_impl_disk_has_backing_file (guestfs_h *g, const char *filename)
|
|
||||||
static void parse_json (guestfs_h *g, void *treevp, const char *input, size_t len);
|
|
||||||
#define PARSE_JSON_NO_OUTPUT ((void *) -1)
|
|
||||||
|
|
||||||
-static yajl_val
|
|
||||||
+static json_t *
|
|
||||||
get_json_output (guestfs_h *g, const char *filename)
|
|
||||||
{
|
|
||||||
CLEANUP_CMD_CLOSE struct command *cmd = guestfs_int_new_command (g);
|
|
||||||
int r;
|
|
||||||
- yajl_val tree = NULL;
|
|
||||||
+ json_t *tree = NULL;
|
|
||||||
|
|
||||||
guestfs_int_cmd_add_arg (cmd, "qemu-img");
|
|
||||||
guestfs_int_cmd_add_arg (cmd, "info");
|
|
||||||
@@ -196,16 +175,15 @@ get_json_output (guestfs_h *g, const char *filename)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return tree; /* caller must call yajl_tree_free (tree) */
|
|
||||||
+ return tree; /* caller must call json_decref (tree) */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse the JSON document printed by qemu-img info --output json. */
|
|
||||||
static void
|
|
||||||
parse_json (guestfs_h *g, void *treevp, const char *input, size_t len)
|
|
||||||
{
|
|
||||||
- yajl_val *tree_ret = treevp;
|
|
||||||
- CLEANUP_FREE char *input_copy = NULL;
|
|
||||||
- char parse_error[256];
|
|
||||||
+ json_t **tree_ret = treevp;
|
|
||||||
+ json_error_t err;
|
|
||||||
|
|
||||||
assert (*tree_ret == NULL);
|
|
||||||
|
|
||||||
@@ -218,15 +196,12 @@ parse_json (guestfs_h *g, void *treevp, const char *input, size_t len)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* 'input' is not \0-terminated; we have to make it so. */
|
|
||||||
- input_copy = safe_strndup (g, input, len);
|
|
||||||
-
|
|
||||||
- debug (g, "%s: qemu-img info JSON output:\n%s\n", __func__, input_copy);
|
|
||||||
+ debug (g, "%s: qemu-img info JSON output:\n%.*s\n", __func__, (int) len, input);
|
|
||||||
|
|
||||||
- *tree_ret = yajl_tree_parse (input_copy, parse_error, sizeof parse_error);
|
|
||||||
+ *tree_ret = json_loadb (input, len, 0, &err);
|
|
||||||
if (*tree_ret == NULL) {
|
|
||||||
- if (strlen (parse_error) > 0)
|
|
||||||
- error (g, _("qemu-img info: JSON parse error: %s"), parse_error);
|
|
||||||
+ if (strlen (err.text) > 0)
|
|
||||||
+ error (g, _("qemu-img info: JSON parse error: %s"), err.text);
|
|
||||||
else
|
|
||||||
error (g, _("qemu-img info: unknown JSON parse error"));
|
|
||||||
}
|
|
||||||
diff --git a/lib/qemu.c b/lib/qemu.c
|
|
||||||
index 6159b5a52..a50eca988 100644
|
|
||||||
--- a/lib/qemu.c
|
|
||||||
+++ b/lib/qemu.c
|
|
||||||
@@ -37,7 +37,7 @@
|
|
||||||
|
|
||||||
#include <libxml/uri.h>
|
|
||||||
|
|
||||||
-#include <yajl/yajl_tree.h>
|
|
||||||
+#include <jansson.h>
|
|
||||||
|
|
||||||
#include "full-write.h"
|
|
||||||
#include "ignore-value.h"
|
|
||||||
@@ -57,7 +57,7 @@ struct qemu_data {
|
|
||||||
|
|
||||||
/* The following fields are derived from the fields above. */
|
|
||||||
struct version qemu_version; /* Parsed qemu version number. */
|
|
||||||
- yajl_val qmp_schema_tree; /* qmp_schema parsed into a JSON tree */
|
|
||||||
+ json_t *qmp_schema_tree; /* qmp_schema parsed into a JSON tree */
|
|
||||||
};
|
|
||||||
|
|
||||||
static char *cache_filename (guestfs_h *g, const char *cachedir, const struct stat *, const char *suffix);
|
|
||||||
@@ -73,7 +73,7 @@ static int write_cache_qmp_schema (guestfs_h *g, const struct qemu_data *data, c
|
|
||||||
static int read_cache_qemu_stat (guestfs_h *g, struct qemu_data *data, const char *filename);
|
|
||||||
static int write_cache_qemu_stat (guestfs_h *g, const struct qemu_data *data, const char *filename);
|
|
||||||
static void parse_qemu_version (guestfs_h *g, const char *, struct version *qemu_version);
|
|
||||||
-static void parse_json (guestfs_h *g, const char *, yajl_val *);
|
|
||||||
+static void parse_json (guestfs_h *g, const char *, json_t **);
|
|
||||||
static void read_all (guestfs_h *g, void *retv, const char *buf, size_t len);
|
|
||||||
static int generic_read_cache (guestfs_h *g, const char *filename, char **strp);
|
|
||||||
static int generic_write_cache (guestfs_h *g, const char *filename, const char *str);
|
|
||||||
@@ -405,17 +405,17 @@ parse_qemu_version (guestfs_h *g, const char *qemu_help,
|
|
||||||
* is not possible.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
-parse_json (guestfs_h *g, const char *json, yajl_val *treep)
|
|
||||||
+parse_json (guestfs_h *g, const char *json, json_t **treep)
|
|
||||||
{
|
|
||||||
- char parse_error[256] = "";
|
|
||||||
+ json_error_t err;
|
|
||||||
|
|
||||||
if (!json)
|
|
||||||
return;
|
|
||||||
|
|
||||||
- *treep = yajl_tree_parse (json, parse_error, sizeof parse_error);
|
|
||||||
+ *treep = json_loads (json, 0, &err);
|
|
||||||
if (*treep == NULL) {
|
|
||||||
- if (strlen (parse_error) > 0)
|
|
||||||
- debug (g, "QMP parse error: %s (ignored)", parse_error);
|
|
||||||
+ if (strlen (err.text) > 0)
|
|
||||||
+ debug (g, "QMP parse error: %s (ignored)", err.text);
|
|
||||||
else
|
|
||||||
debug (g, "QMP unknown parse error (ignored)");
|
|
||||||
}
|
|
||||||
@@ -580,17 +580,6 @@ guestfs_int_qemu_supports_device (guestfs_h *g,
|
|
||||||
return strstr (data->qemu_devices, device_name) != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* GCC can't work out that the YAJL_IS_<foo> test is sufficient to
|
|
||||||
- * ensure that YAJL_GET_<foo> later doesn't return NULL.
|
|
||||||
- */
|
|
||||||
-#pragma GCC diagnostic push
|
|
||||||
-#if defined(__GNUC__) && __GNUC__ >= 6 /* gcc >= 6 */
|
|
||||||
-#pragma GCC diagnostic ignored "-Wnull-dereference"
|
|
||||||
-#endif
|
|
||||||
-#if defined(__GNUC__) && GUESTFS_GCC_VERSION >= 40800 /* gcc >= 4.8.0 */
|
|
||||||
-#pragma GCC diagnostic ignored "-Wnonnull"
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
/**
|
|
||||||
* Test if the qemu binary uses mandatory file locking, added in
|
|
||||||
* QEMU >= 2.10 (but sometimes disabled).
|
|
||||||
@@ -599,11 +588,7 @@ int
|
|
||||||
guestfs_int_qemu_mandatory_locking (guestfs_h *g,
|
|
||||||
const struct qemu_data *data)
|
|
||||||
{
|
|
||||||
- const char *return_path[] = { "return", NULL };
|
|
||||||
- const char *meta_type_path[] = { "meta-type", NULL };
|
|
||||||
- const char *members_path[] = { "members", NULL };
|
|
||||||
- const char *name_path[] = { "name", NULL };
|
|
||||||
- yajl_val schema, v, meta_type, members, m, name;
|
|
||||||
+ json_t *schema, *v, *meta_type, *members, *m, *name;
|
|
||||||
size_t i, j;
|
|
||||||
|
|
||||||
/* If there's no QMP schema, fall back to checking the version. */
|
|
||||||
@@ -616,27 +601,24 @@ guestfs_int_qemu_mandatory_locking (guestfs_h *g,
|
|
||||||
* Extract the schema from the wrapper. Note the returned ‘schema’
|
|
||||||
* will be an array.
|
|
||||||
*/
|
|
||||||
- schema = yajl_tree_get (data->qmp_schema_tree, return_path, yajl_t_array);
|
|
||||||
- if (schema == NULL)
|
|
||||||
+ schema = json_object_get (data->qmp_schema_tree, "return");
|
|
||||||
+ if (!json_is_array (schema))
|
|
||||||
goto fallback;
|
|
||||||
- assert (YAJL_IS_ARRAY(schema));
|
|
||||||
|
|
||||||
/* Now look for any member of the array which has:
|
|
||||||
* { "meta-type": "object",
|
|
||||||
* "members": [ ... { "name": "locking", ... } ... ] ... }
|
|
||||||
*/
|
|
||||||
- for (i = 0; i < YAJL_GET_ARRAY(schema)->len; ++i) {
|
|
||||||
- v = YAJL_GET_ARRAY(schema)->values[i];
|
|
||||||
- meta_type = yajl_tree_get (v, meta_type_path, yajl_t_string);
|
|
||||||
- if (meta_type && YAJL_IS_STRING (meta_type) &&
|
|
||||||
- STREQ (YAJL_GET_STRING (meta_type), "object")) {
|
|
||||||
- members = yajl_tree_get (v, members_path, yajl_t_array);
|
|
||||||
- if (members) {
|
|
||||||
- for (j = 0; j < YAJL_GET_ARRAY(members)->len; ++j) {
|
|
||||||
- m = YAJL_GET_ARRAY(members)->values[j];
|
|
||||||
- name = yajl_tree_get (m, name_path, yajl_t_string);
|
|
||||||
- if (name && YAJL_IS_STRING (name) &&
|
|
||||||
- STREQ (YAJL_GET_STRING (name), "locking"))
|
|
||||||
+ json_array_foreach (schema, i, v) {
|
|
||||||
+ meta_type = json_object_get (v, "meta-type");
|
|
||||||
+ if (json_is_string (meta_type) &&
|
|
||||||
+ STREQ (json_string_value (meta_type), "object")) {
|
|
||||||
+ members = json_object_get (v, "members");
|
|
||||||
+ if (json_is_array (members)) {
|
|
||||||
+ json_array_foreach (members, j, m) {
|
|
||||||
+ name = json_object_get (v, "name");
|
|
||||||
+ if (json_is_string (name) &&
|
|
||||||
+ STREQ (json_string_value (name), "locking"))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -646,8 +628,6 @@ guestfs_int_qemu_mandatory_locking (guestfs_h *g,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-#pragma GCC diagnostic pop
|
|
||||||
-
|
|
||||||
/**
|
|
||||||
* Escape a qemu parameter.
|
|
||||||
*
|
|
||||||
@@ -996,7 +976,7 @@ guestfs_int_free_qemu_data (struct qemu_data *data)
|
|
||||||
free (data->qemu_help);
|
|
||||||
free (data->qemu_devices);
|
|
||||||
free (data->qmp_schema);
|
|
||||||
- yajl_tree_free (data->qmp_schema_tree);
|
|
||||||
+ json_decref (data->qmp_schema_tree);
|
|
||||||
free (data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/m4/guestfs-libraries.m4 b/m4/guestfs-libraries.m4
|
|
||||||
index 78a9e792f..2fdbd9669 100644
|
|
||||||
--- a/m4/guestfs-libraries.m4
|
|
||||||
+++ b/m4/guestfs-libraries.m4
|
|
||||||
@@ -299,8 +299,8 @@ LIBS="$LIBS $LIBXML2_LIBS"
|
|
||||||
AC_CHECK_FUNCS([xmlBufferDetach])
|
|
||||||
LIBS="$old_LIBS"
|
|
||||||
|
|
||||||
-dnl Check for yajl JSON library (required).
|
|
||||||
-PKG_CHECK_MODULES([YAJL], [yajl >= 2.0.4])
|
|
||||||
+dnl Check for Jansson JSON library (required).
|
|
||||||
+PKG_CHECK_MODULES([JANSSON], [jansson])
|
|
||||||
|
|
||||||
dnl Check for C++ (optional, we just use this to test the header works).
|
|
||||||
AC_PROG_CXX
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,126 @@
|
|||||||
|
From 6e0dbefde3ddb0711e2b0961ee913084dc5e6a41 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 0762a8341..be054a004 100644
|
||||||
|
--- a/common/mlpcre/pcre-c.c
|
||||||
|
+++ b/common/mlpcre/pcre-c.c
|
||||||
|
@@ -121,6 +121,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,
|
||||||
|
@@ -165,9 +174,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);
|
||||||
|
@@ -205,7 +214,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.25.4
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
From 898e6c1e39deb130566220a11a2eaf2dcb2cb733 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Thu, 29 Mar 2018 20:18:34 +0100
|
|
||||||
Subject: [PATCH] qemu: Fix transcription error in conversion of yajl to
|
|
||||||
jansson.
|
|
||||||
|
|
||||||
This broke qemu mandatory locking detection.
|
|
||||||
|
|
||||||
Fixes commit bd1c5c9f4dcf38458099db8a0bf4659a07ef055d.
|
|
||||||
|
|
||||||
(cherry picked from commit e79286f71738d9385157d9e87211be02645722c3)
|
|
||||||
---
|
|
||||||
lib/qemu.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/lib/qemu.c b/lib/qemu.c
|
|
||||||
index a50eca988..3e7f15946 100644
|
|
||||||
--- a/lib/qemu.c
|
|
||||||
+++ b/lib/qemu.c
|
|
||||||
@@ -616,7 +616,7 @@ guestfs_int_qemu_mandatory_locking (guestfs_h *g,
|
|
||||||
members = json_object_get (v, "members");
|
|
||||||
if (json_is_array (members)) {
|
|
||||||
json_array_foreach (members, j, m) {
|
|
||||||
- name = json_object_get (v, "name");
|
|
||||||
+ name = json_object_get (m, "name");
|
|
||||||
if (json_is_string (name) &&
|
|
||||||
STREQ (json_string_value (name), "locking"))
|
|
||||||
return 1;
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
415
SOURCES/0002-v2v-add-Var_expander.patch
Normal file
415
SOURCES/0002-v2v-add-Var_expander.patch
Normal file
@ -0,0 +1,415 @@
|
|||||||
|
From a98136d6ee36df15a226f853d47bd803a7a25329 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.25.4
|
||||||
|
|
785
SOURCES/0003-v2v-add-o-json-output-mode.patch
Normal file
785
SOURCES/0003-v2v-add-o-json-output-mode.patch
Normal file
@ -0,0 +1,785 @@
|
|||||||
|
From 480c7169c341fc2f86609a13100c42e10f599b83 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.25.4
|
||||||
|
|
@ -1,342 +0,0 @@
|
|||||||
From d330b210b7d62ccd9f73909215251f4ce68cd6c9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
|
||||||
Date: Thu, 22 Feb 2018 11:41:07 +0100
|
|
||||||
Subject: [PATCH] v2v: ovf: Create OVF more aligned with the standard
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
For historical reasons the OVF used in RHV export domain contains some
|
|
||||||
deviations from the OVF standard. The format used in -o rhv has to
|
|
||||||
remain fixed but for -o vdsm and we could produce much nicer OVF. This
|
|
||||||
patch serves as a preparatory step to this.
|
|
||||||
|
|
||||||
The main reason for creating different OVF is that it can be used to
|
|
||||||
create VM by oVirt REST API. The RHV export domain flavor cannot be used
|
|
||||||
that way.
|
|
||||||
|
|
||||||
For now the virt-v2v behavior is unchanged. The modified output will be
|
|
||||||
enabled in some later patch.
|
|
||||||
|
|
||||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
|
||||||
(cherry picked from commit a52ed4b4454396eb13d2cdf5762292bff3104f66)
|
|
||||||
---
|
|
||||||
v2v/create_ovf.ml | 152 ++++++++++++++++++++++++++++++++-------------
|
|
||||||
v2v/create_ovf.mli | 12 +++-
|
|
||||||
v2v/output_rhv.ml | 3 +-
|
|
||||||
v2v/output_vdsm.ml | 3 +-
|
|
||||||
4 files changed, 121 insertions(+), 49 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
|
|
||||||
index e9d569dc1..0ec0a088c 100644
|
|
||||||
--- a/v2v/create_ovf.ml
|
|
||||||
+++ b/v2v/create_ovf.ml
|
|
||||||
@@ -29,6 +29,10 @@ open Types
|
|
||||||
open Utils
|
|
||||||
open DOM
|
|
||||||
|
|
||||||
+type ovf_flavour =
|
|
||||||
+ | OVirt
|
|
||||||
+ | RHVExportStorageDomain
|
|
||||||
+
|
|
||||||
(* We set the creation time to be the same for all dates in
|
|
||||||
* all metadata files. All dates in OVF are UTC.
|
|
||||||
*)
|
|
||||||
@@ -295,7 +299,7 @@ let create_meta_files output_alloc sd_uuid image_uuids targets =
|
|
||||||
|
|
||||||
(* Create the OVF file. *)
|
|
||||||
let rec create_ovf source targets guestcaps inspect
|
|
||||||
- output_alloc sd_uuid image_uuids vol_uuids vm_uuid =
|
|
||||||
+ output_alloc sd_uuid image_uuids vol_uuids vm_uuid ovf_flavour =
|
|
||||||
assert (List.length targets = List.length vol_uuids);
|
|
||||||
|
|
||||||
let memsize_mb = source.s_memory /^ 1024L /^ 1024L in
|
|
||||||
@@ -314,12 +318,26 @@ let rec create_ovf source targets guestcaps inspect
|
|
||||||
] [
|
|
||||||
Comment generated_by;
|
|
||||||
e "References" [] [];
|
|
||||||
- e "Section" ["xsi:type", "ovf:NetworkSection_Type"] [
|
|
||||||
- e "Info" [] [PCData "List of networks"]
|
|
||||||
- ];
|
|
||||||
- e "Section" ["xsi:type", "ovf:DiskSection_Type"] [
|
|
||||||
- e "Info" [] [PCData "List of Virtual Disks"]
|
|
||||||
- ];
|
|
||||||
+ (match ovf_flavour with
|
|
||||||
+ | OVirt ->
|
|
||||||
+ e "NetworkSection" [] [
|
|
||||||
+ e "Info" [] [PCData "List of networks"]
|
|
||||||
+ ]
|
|
||||||
+ | RHVExportStorageDomain ->
|
|
||||||
+ e "Section" ["xsi:type", "ovf:NetworkSection_Type"] [
|
|
||||||
+ e "Info" [] [PCData "List of networks"]
|
|
||||||
+ ]
|
|
||||||
+ );
|
|
||||||
+ (match ovf_flavour with
|
|
||||||
+ | OVirt ->
|
|
||||||
+ e "DiskSection" [] [
|
|
||||||
+ e "Info" [] [PCData "List of Virtual Disks"]
|
|
||||||
+ ]
|
|
||||||
+ | RHVExportStorageDomain ->
|
|
||||||
+ e "Section" ["xsi:type", "ovf:DiskSection_Type"] [
|
|
||||||
+ e "Info" [] [PCData "List of Virtual Disks"]
|
|
||||||
+ ]
|
|
||||||
+ );
|
|
||||||
|
|
||||||
let content_subnodes = ref [
|
|
||||||
e "Name" [] [PCData source.s_name];
|
|
||||||
@@ -352,11 +370,20 @@ let rec create_ovf source targets guestcaps inspect
|
|
||||||
);
|
|
||||||
|
|
||||||
List.push_back content_subnodes (
|
|
||||||
- e "Section" ["ovf:id", vm_uuid; "ovf:required", "false";
|
|
||||||
- "xsi:type", "ovf:OperatingSystemSection_Type"] [
|
|
||||||
+ let osinfo_subnodes = [
|
|
||||||
e "Info" [] [PCData inspect.i_product_name];
|
|
||||||
e "Description" [] [PCData ostype];
|
|
||||||
- ]
|
|
||||||
+ ] in
|
|
||||||
+ (match ovf_flavour with
|
|
||||||
+ | OVirt ->
|
|
||||||
+ e "OperatingSystemSection" ["ovf:id", vm_uuid;
|
|
||||||
+ "ovf:required", "false"]
|
|
||||||
+ osinfo_subnodes
|
|
||||||
+ | RHVExportStorageDomain ->
|
|
||||||
+ e "Section" ["ovf:id", vm_uuid; "ovf:required", "false";
|
|
||||||
+ "xsi:type", "ovf:OperatingSystemSection_Type"]
|
|
||||||
+ osinfo_subnodes
|
|
||||||
+ )
|
|
||||||
);
|
|
||||||
|
|
||||||
let virtual_hardware_section_items = ref [
|
|
||||||
@@ -444,24 +471,34 @@ let rec create_ovf source targets guestcaps inspect
|
|
||||||
);
|
|
||||||
|
|
||||||
List.push_back content_subnodes (
|
|
||||||
- e "Section" ["xsi:type", "ovf:VirtualHardwareSection_Type"]
|
|
||||||
- !virtual_hardware_section_items
|
|
||||||
+ match ovf_flavour with
|
|
||||||
+ | OVirt ->
|
|
||||||
+ e "VirtualHardwareSection" [] !virtual_hardware_section_items
|
|
||||||
+ | RHVExportStorageDomain ->
|
|
||||||
+ e "Section" ["xsi:type", "ovf:VirtualHardwareSection_Type"]
|
|
||||||
+ !virtual_hardware_section_items
|
|
||||||
);
|
|
||||||
|
|
||||||
- e "Content" ["ovf:id", "out"; "xsi:type", "ovf:VirtualSystem_Type"]
|
|
||||||
- !content_subnodes
|
|
||||||
+ (match ovf_flavour with
|
|
||||||
+ | OVirt ->
|
|
||||||
+ e "VirtualSystem" ["ovf:id", "out"] !content_subnodes
|
|
||||||
+ | RHVExportStorageDomain ->
|
|
||||||
+ e "Content" ["ovf:id", "out"; "xsi:type", "ovf:VirtualSystem_Type"]
|
|
||||||
+ !content_subnodes
|
|
||||||
+ )
|
|
||||||
] in
|
|
||||||
|
|
||||||
(* Add disks to the OVF XML. *)
|
|
||||||
- add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf;
|
|
||||||
+ add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids
|
|
||||||
+ ovf_flavour ovf;
|
|
||||||
|
|
||||||
(* Old virt-v2v ignored removable media. XXX *)
|
|
||||||
|
|
||||||
(* Add networks to the OVF XML. *)
|
|
||||||
- add_networks source.s_nics guestcaps ovf;
|
|
||||||
+ add_networks source.s_nics guestcaps ovf_flavour ovf;
|
|
||||||
|
|
||||||
(* Add sound card to the OVF XML. *)
|
|
||||||
- add_sound_card source.s_sound ovf;
|
|
||||||
+ add_sound_card source.s_sound ovf_flavour ovf;
|
|
||||||
|
|
||||||
(* Old virt-v2v didn't really look at the video and display
|
|
||||||
* metadata, instead just adding a single standard display (see
|
|
||||||
@@ -481,21 +518,42 @@ let rec create_ovf source targets guestcaps inspect
|
|
||||||
(* Return the OVF document. *)
|
|
||||||
ovf
|
|
||||||
|
|
||||||
+(* Find appropriate section depending on the OVF flavour being generated.
|
|
||||||
+ *
|
|
||||||
+ * For example normal disk section is in node <DiskSection> whereas in case of
|
|
||||||
+ * RHV export storage domain it is <Section xsi:type="ovf:DiskSection_Type">.
|
|
||||||
+ *)
|
|
||||||
+and get_flavoured_section ovf ovf_flavour ovirt_path rhv_path rhv_path_attr =
|
|
||||||
+ let nodes =
|
|
||||||
+ match ovf_flavour with
|
|
||||||
+ | OVirt ->
|
|
||||||
+ let nodes = path_to_nodes ovf ovirt_path in
|
|
||||||
+ (match nodes with
|
|
||||||
+ | [node] -> node
|
|
||||||
+ | [] | _::_::_ -> assert false)
|
|
||||||
+ | RHVExportStorageDomain ->
|
|
||||||
+ let nodes = path_to_nodes ovf rhv_path in
|
|
||||||
+ try find_node_by_attr nodes rhv_path_attr
|
|
||||||
+ with Not_found -> assert false
|
|
||||||
+ in
|
|
||||||
+ nodes
|
|
||||||
+
|
|
||||||
(* This modifies the OVF DOM, adding a section for each disk. *)
|
|
||||||
-and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
|
|
||||||
+and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids
|
|
||||||
+ ovf_flavour ovf =
|
|
||||||
let references =
|
|
||||||
let nodes = path_to_nodes ovf ["ovf:Envelope"; "References"] in
|
|
||||||
match nodes with
|
|
||||||
| [] | _::_::_ -> assert false
|
|
||||||
| [node] -> node in
|
|
||||||
- let disk_section =
|
|
||||||
- let sections = path_to_nodes ovf ["ovf:Envelope"; "Section"] in
|
|
||||||
- try find_node_by_attr sections ("xsi:type", "ovf:DiskSection_Type")
|
|
||||||
- with Not_found -> assert false in
|
|
||||||
- let virtualhardware_section =
|
|
||||||
- let sections = path_to_nodes ovf ["ovf:Envelope"; "Content"; "Section"] in
|
|
||||||
- try find_node_by_attr sections ("xsi:type", "ovf:VirtualHardwareSection_Type")
|
|
||||||
- with Not_found -> assert false in
|
|
||||||
+ let disk_section = get_flavoured_section ovf ovf_flavour
|
|
||||||
+ ["ovf:Envelope"; "DiskSection"]
|
|
||||||
+ ["ovf:Envelope"; "Section"]
|
|
||||||
+ ("xsi:type", "ovf:DiskSection_Type") in
|
|
||||||
+ let virtualhardware_section = get_flavoured_section ovf ovf_flavour
|
|
||||||
+ ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"]
|
|
||||||
+ ["ovf:Envelope"; "Content"; "Section"]
|
|
||||||
+ ("xsi:type", "ovf:VirtualHardwareSection_Type") in
|
|
||||||
|
|
||||||
(* Iterate over the disks, adding them to the OVF document. *)
|
|
||||||
List.iteri (
|
|
||||||
@@ -509,7 +567,12 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
|
|
||||||
let is_bootable_drive = i == 0 in
|
|
||||||
let boot_order = i+1 in
|
|
||||||
|
|
||||||
- let fileref = sprintf "%s/%s" image_uuid vol_uuid in
|
|
||||||
+ let fileref =
|
|
||||||
+ match ovf_flavour with
|
|
||||||
+ | OVirt ->
|
|
||||||
+ vol_uuid
|
|
||||||
+ | RHVExportStorageDomain ->
|
|
||||||
+ sprintf "%s/%s" image_uuid vol_uuid in
|
|
||||||
|
|
||||||
(* ovf:size and ovf:actual_size fields are integer GBs. If you
|
|
||||||
* use floating point numbers then RHV will fail to parse them.
|
|
||||||
@@ -560,7 +623,10 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
|
|
||||||
(* Add disk to DiskSection. *)
|
|
||||||
let disk =
|
|
||||||
let attrs = ref [
|
|
||||||
- "ovf:diskId", vol_uuid;
|
|
||||||
+ "ovf:diskId",
|
|
||||||
+ (match ovf_flavour with
|
|
||||||
+ | OVirt -> image_uuid
|
|
||||||
+ | RHVExportStorageDomain -> vol_uuid);
|
|
||||||
"ovf:size", Int64.to_string size_gb;
|
|
||||||
"ovf:capacity", Int64.to_string ov.ov_virtual_size;
|
|
||||||
"ovf:fileRef", fileref;
|
|
||||||
@@ -619,15 +685,15 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
|
|
||||||
) (List.combine3 targets image_uuids vol_uuids)
|
|
||||||
|
|
||||||
(* This modifies the OVF DOM, adding a section for each NIC. *)
|
|
||||||
-and add_networks nics guestcaps ovf =
|
|
||||||
- let network_section =
|
|
||||||
- let sections = path_to_nodes ovf ["ovf:Envelope"; "Section"] in
|
|
||||||
- try find_node_by_attr sections ("xsi:type", "ovf:NetworkSection_Type")
|
|
||||||
- with Not_found -> assert false in
|
|
||||||
- let virtualhardware_section =
|
|
||||||
- let sections = path_to_nodes ovf ["ovf:Envelope"; "Content"; "Section"] in
|
|
||||||
- try find_node_by_attr sections ("xsi:type", "ovf:VirtualHardwareSection_Type")
|
|
||||||
- with Not_found -> assert false in
|
|
||||||
+and add_networks nics guestcaps ovf_flavour ovf =
|
|
||||||
+ let network_section = get_flavoured_section ovf ovf_flavour
|
|
||||||
+ ["ovf:Envelope"; "NetworkSection"]
|
|
||||||
+ ["ovf:Envelope"; "Section"]
|
|
||||||
+ ("xsi:type", "ovf:NetworkSection_Type") in
|
|
||||||
+ let virtualhardware_section = get_flavoured_section ovf ovf_flavour
|
|
||||||
+ ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"]
|
|
||||||
+ ["ovf:Envelope"; "Content"; "Section"]
|
|
||||||
+ ("xsi:type", "ovf:VirtualHardwareSection_Type") in
|
|
||||||
|
|
||||||
(* Iterate over the NICs, adding them to the OVF document. *)
|
|
||||||
List.iteri (
|
|
||||||
@@ -675,7 +741,7 @@ and add_networks nics guestcaps ovf =
|
|
||||||
) nics
|
|
||||||
|
|
||||||
(* This modifies the OVF DOM, adding a sound card, if oVirt can emulate it. *)
|
|
||||||
-and add_sound_card sound ovf =
|
|
||||||
+and add_sound_card sound ovf_flavour ovf =
|
|
||||||
let device =
|
|
||||||
match sound with
|
|
||||||
| None -> None
|
|
||||||
@@ -688,12 +754,10 @@ and add_sound_card sound ovf =
|
|
||||||
|
|
||||||
match device with
|
|
||||||
| Some device ->
|
|
||||||
- let virtualhardware_section =
|
|
||||||
- let sections =
|
|
||||||
- path_to_nodes ovf ["ovf:Envelope"; "Content"; "Section"] in
|
|
||||||
- try find_node_by_attr sections
|
|
||||||
- ("xsi:type", "ovf:VirtualHardwareSection_Type")
|
|
||||||
- with Not_found -> assert false in
|
|
||||||
+ let virtualhardware_section = get_flavoured_section ovf ovf_flavour
|
|
||||||
+ ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"]
|
|
||||||
+ ["ovf:Envelope"; "Content"; "Section"]
|
|
||||||
+ ("xsi:type", "ovf:VirtualHardwareSection_Type") in
|
|
||||||
|
|
||||||
let item =
|
|
||||||
e "Item" [] [
|
|
||||||
diff --git a/v2v/create_ovf.mli b/v2v/create_ovf.mli
|
|
||||||
index 07e8af6a0..8a8c7dd12 100644
|
|
||||||
--- a/v2v/create_ovf.mli
|
|
||||||
+++ b/v2v/create_ovf.mli
|
|
||||||
@@ -16,16 +16,22 @@
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*)
|
|
||||||
|
|
||||||
+type ovf_flavour =
|
|
||||||
+ | OVirt
|
|
||||||
+ | RHVExportStorageDomain
|
|
||||||
+
|
|
||||||
(** Create OVF and related files for RHV.
|
|
||||||
|
|
||||||
- The format is described in
|
|
||||||
- http://www.ovirt.org/images/8/86/Ovirt_ovf_format.odt
|
|
||||||
+ The format for RHV export storage domain is described in:
|
|
||||||
+ http://resources.ovirt.org/old-site-files/Ovirt_ovf_format.odt
|
|
||||||
+
|
|
||||||
+ The format understood by oVirt has no known documentation.
|
|
||||||
|
|
||||||
OVF isn't a real standard, so it's likely that if we ever had to
|
|
||||||
create OVF for another target management system then we would need
|
|
||||||
to heavily modify or even duplicate this code. *)
|
|
||||||
|
|
||||||
-val create_ovf : Types.source -> Types.target list -> Types.guestcaps -> Types.inspect -> Types.output_allocation -> string -> string list -> string list -> string -> DOM.doc
|
|
||||||
+val create_ovf : Types.source -> Types.target list -> Types.guestcaps -> Types.inspect -> Types.output_allocation -> string -> string list -> string list -> string -> ovf_flavour -> DOM.doc
|
|
||||||
(** Create the OVF file.
|
|
||||||
|
|
||||||
Actually a {!DOM} document is created, not a file. It can be written
|
|
||||||
diff --git a/v2v/output_rhv.ml b/v2v/output_rhv.ml
|
|
||||||
index 0b732e4cf..5260ab030 100644
|
|
||||||
--- a/v2v/output_rhv.ml
|
|
||||||
+++ b/v2v/output_rhv.ml
|
|
||||||
@@ -275,7 +275,8 @@ object
|
|
||||||
|
|
||||||
(* Create the metadata. *)
|
|
||||||
let ovf = Create_ovf.create_ovf source targets guestcaps inspect
|
|
||||||
- output_alloc esd_uuid image_uuids vol_uuids vm_uuid in
|
|
||||||
+ output_alloc esd_uuid image_uuids vol_uuids vm_uuid
|
|
||||||
+ Create_ovf.RHVExportStorageDomain in
|
|
||||||
|
|
||||||
(* Write it to the metadata file. *)
|
|
||||||
let dir = esd_mp // esd_uuid // "master" // "vms" // vm_uuid in
|
|
||||||
diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml
|
|
||||||
index c5e904ba1..ce286d327 100644
|
|
||||||
--- a/v2v/output_vdsm.ml
|
|
||||||
+++ b/v2v/output_vdsm.ml
|
|
||||||
@@ -175,7 +175,8 @@ object
|
|
||||||
output_alloc dd_uuid
|
|
||||||
vdsm_options.image_uuids
|
|
||||||
vdsm_options.vol_uuids
|
|
||||||
- vdsm_options.vm_uuid in
|
|
||||||
+ vdsm_options.vm_uuid
|
|
||||||
+ Create_ovf.RHVExportStorageDomain in
|
|
||||||
|
|
||||||
(* Write it to the metadata file. *)
|
|
||||||
let file = vdsm_options.ovf_output // vdsm_options.vm_uuid ^ ".ovf" in
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
From 31af609ecc65424bb3671c6873005f31fd1b80d4 Mon Sep 17 00:00:00 2001
|
From e7ff090884f5e32585e9683d35b72bca01e0a836 Mon Sep 17 00:00:00 2001
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
From: Pino Toscano <ptoscano@redhat.com>
|
||||||
Date: Mon, 11 Feb 2019 19:28:00 +0100
|
Date: Mon, 11 Feb 2019 19:28:00 +0100
|
||||||
Subject: [PATCH] inspect: fix icon of RHEL
|
Subject: [PATCH] inspect: fix icon of RHEL
|
||||||
@ -15,10 +15,10 @@ Thanks to Ray Strode for the hints.
|
|||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/lib/inspect-icon.c b/lib/inspect-icon.c
|
diff --git a/lib/inspect-icon.c b/lib/inspect-icon.c
|
||||||
index 0edd3d1b0..443dc6dd3 100644
|
index 623591aa6..19f3f87af 100644
|
||||||
--- a/lib/inspect-icon.c
|
--- a/lib/inspect-icon.c
|
||||||
+++ b/lib/inspect-icon.c
|
+++ b/lib/inspect-icon.c
|
||||||
@@ -301,7 +301,7 @@ icon_rhel (guestfs_h *g, int major, size_t *size_r)
|
@@ -317,7 +317,7 @@ icon_rhel (guestfs_h *g, int major, size_t *size_r)
|
||||||
if (major < 7)
|
if (major < 7)
|
||||||
shadowman = "/usr/share/pixmaps/redhat/shadowman-transparent.png";
|
shadowman = "/usr/share/pixmaps/redhat/shadowman-transparent.png";
|
||||||
else
|
else
|
||||||
@ -28,5 +28,5 @@ index 0edd3d1b0..443dc6dd3 100644
|
|||||||
return get_png (g, shadowman, size_r, 102400);
|
return get_png (g, shadowman, size_r, 102400);
|
||||||
}
|
}
|
||||||
--
|
--
|
||||||
2.21.0
|
2.25.4
|
||||||
|
|
@ -1,213 +0,0 @@
|
|||||||
From 14cfe80643a7df4ddf412aebdf39543344c1cf6e Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
|
||||||
Date: Thu, 22 Feb 2018 11:41:08 +0100
|
|
||||||
Subject: [PATCH] v2v: vdsm: add --vdsm-fixed-ovf option
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Add option for -o vdsm that enables output of the modified OVF. oVirt
|
|
||||||
engine should already be able to consume the OVF, but let's not take any
|
|
||||||
chances and enable it only by command line argument. It can be made
|
|
||||||
default later when it receives proper testing.
|
|
||||||
|
|
||||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
|
||||||
(cherry picked from commit 285014b290507865fd2020e44ea453af0262b624)
|
|
||||||
---
|
|
||||||
v2v/cmdline.ml | 10 ++++++++++
|
|
||||||
v2v/create_ovf.ml | 7 +++++++
|
|
||||||
v2v/create_ovf.mli | 9 +++++++++
|
|
||||||
v2v/output_vdsm.ml | 9 +++++++--
|
|
||||||
v2v/output_vdsm.mli | 1 +
|
|
||||||
v2v/test-v2v-o-vdsm-options.sh | 3 ++-
|
|
||||||
v2v/virt-v2v.pod | 20 ++++++++++++++++++++
|
|
||||||
7 files changed, 56 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
|
|
||||||
index d88d0a579..75909ee77 100644
|
|
||||||
--- a/v2v/cmdline.ml
|
|
||||||
+++ b/v2v/cmdline.ml
|
|
||||||
@@ -79,6 +79,11 @@ let parse_cmdline () =
|
|
||||||
let vdsm_compat = ref "0.10" in
|
|
||||||
let set_vdsm_compat s = vdsm_compat := s in
|
|
||||||
|
|
||||||
+ let vdsm_ovf_flavour = ref Create_ovf.RHVExportStorageDomain in
|
|
||||||
+ let ovf_flavours_str = String.concat "|" Create_ovf.ovf_flavours in
|
|
||||||
+ let set_vdsm_ovf_flavour arg =
|
|
||||||
+ vdsm_ovf_flavour := Create_ovf.ovf_flavour_of_string arg in
|
|
||||||
+
|
|
||||||
let set_string_option_once optname optref arg =
|
|
||||||
match !optref with
|
|
||||||
| Some _ ->
|
|
||||||
@@ -251,6 +256,8 @@ let parse_cmdline () =
|
|
||||||
s_"Output VM UUID";
|
|
||||||
[ L"vdsm-ovf-output" ], Getopt.String ("-", set_string_option_once "--vdsm-ovf-output" vdsm_ovf_output),
|
|
||||||
s_"Output OVF file";
|
|
||||||
+ [ L"vdsm-ovf-flavour" ], Getopt.Symbol (ovf_flavours_str, Create_ovf.ovf_flavours, set_vdsm_ovf_flavour),
|
|
||||||
+ s_"Set the type of generated OVF (default rhvexp)";
|
|
||||||
[ L"vmtype" ], Getopt.String ("-", vmtype_warning),
|
|
||||||
s_"Ignored for backwards compatibility";
|
|
||||||
] in
|
|
||||||
@@ -327,6 +334,7 @@ read the man page virt-v2v(1).
|
|
||||||
let vdsm_vol_uuids = List.rev !vdsm_vol_uuids in
|
|
||||||
let vdsm_vm_uuid = !vdsm_vm_uuid in
|
|
||||||
let vdsm_ovf_output = Option.default "." !vdsm_ovf_output in
|
|
||||||
+ let vdsm_ovf_flavour = !vdsm_ovf_flavour in
|
|
||||||
|
|
||||||
(* No arguments and machine-readable mode? Print out some facts
|
|
||||||
* about what this binary supports.
|
|
||||||
@@ -343,6 +351,7 @@ read the man page virt-v2v(1).
|
|
||||||
List.iter (printf "input:%s\n") (Modules_list.input_modules ());
|
|
||||||
List.iter (printf "output:%s\n") (Modules_list.output_modules ());
|
|
||||||
List.iter (printf "convert:%s\n") (Modules_list.convert_modules ());
|
|
||||||
+ List.iter (printf "ovf:%s\n") Create_ovf.ovf_flavours;
|
|
||||||
exit 0
|
|
||||||
);
|
|
||||||
|
|
||||||
@@ -542,6 +551,7 @@ read the man page virt-v2v(1).
|
|
||||||
vm_uuid = vdsm_vm_uuid;
|
|
||||||
ovf_output = vdsm_ovf_output;
|
|
||||||
compat = vdsm_compat;
|
|
||||||
+ ovf_flavour = vdsm_ovf_flavour;
|
|
||||||
} in
|
|
||||||
Output_vdsm.output_vdsm os vdsm_options output_alloc,
|
|
||||||
output_format, output_alloc in
|
|
||||||
diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
|
|
||||||
index 0ec0a088c..d0735afce 100644
|
|
||||||
--- a/v2v/create_ovf.ml
|
|
||||||
+++ b/v2v/create_ovf.ml
|
|
||||||
@@ -33,6 +33,13 @@ type ovf_flavour =
|
|
||||||
| OVirt
|
|
||||||
| RHVExportStorageDomain
|
|
||||||
|
|
||||||
+let ovf_flavours = ["ovirt"; "rhvexp"]
|
|
||||||
+
|
|
||||||
+let ovf_flavour_of_string = function
|
|
||||||
+ | "ovirt" -> OVirt
|
|
||||||
+ | "rhvexp" -> RHVExportStorageDomain
|
|
||||||
+ | flav -> invalid_arg flav
|
|
||||||
+
|
|
||||||
(* We set the creation time to be the same for all dates in
|
|
||||||
* all metadata files. All dates in OVF are UTC.
|
|
||||||
*)
|
|
||||||
diff --git a/v2v/create_ovf.mli b/v2v/create_ovf.mli
|
|
||||||
index 8a8c7dd12..2d80660e3 100644
|
|
||||||
--- a/v2v/create_ovf.mli
|
|
||||||
+++ b/v2v/create_ovf.mli
|
|
||||||
@@ -20,6 +20,15 @@ type ovf_flavour =
|
|
||||||
| OVirt
|
|
||||||
| RHVExportStorageDomain
|
|
||||||
|
|
||||||
+(** The string representation of available OVF flavours. *)
|
|
||||||
+val ovf_flavours : string list
|
|
||||||
+
|
|
||||||
+(** Convert from a string to the corresponding OVF flavour.
|
|
||||||
+
|
|
||||||
+ Throw [Invalid_argument] if the string does not match any
|
|
||||||
+ valid flavour. *)
|
|
||||||
+val ovf_flavour_of_string : string -> ovf_flavour
|
|
||||||
+
|
|
||||||
(** Create OVF and related files for RHV.
|
|
||||||
|
|
||||||
The format for RHV export storage domain is described in:
|
|
||||||
diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml
|
|
||||||
index ce286d327..b76a2e930 100644
|
|
||||||
--- a/v2v/output_vdsm.ml
|
|
||||||
+++ b/v2v/output_vdsm.ml
|
|
||||||
@@ -32,6 +32,7 @@ type vdsm_options = {
|
|
||||||
vm_uuid : string;
|
|
||||||
ovf_output : string;
|
|
||||||
compat : string;
|
|
||||||
+ ovf_flavour : Create_ovf.ovf_flavour;
|
|
||||||
}
|
|
||||||
|
|
||||||
class output_vdsm os vdsm_options output_alloc =
|
|
||||||
@@ -39,7 +40,7 @@ object
|
|
||||||
inherit output
|
|
||||||
|
|
||||||
method as_options =
|
|
||||||
- sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s --vdsm-ovf-output %s%s" os
|
|
||||||
+ sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s --vdsm-ovf-output %s%s%s" os
|
|
||||||
(String.concat ""
|
|
||||||
(List.map (sprintf " --vdsm-image-uuid %s") vdsm_options.image_uuids))
|
|
||||||
(String.concat ""
|
|
||||||
@@ -49,6 +50,10 @@ object
|
|
||||||
(match vdsm_options.compat with
|
|
||||||
| "0.10" -> "" (* currently this is the default, so don't print it *)
|
|
||||||
| s -> sprintf " --vdsm-compat=%s" s)
|
|
||||||
+ (match vdsm_options.ovf_flavour with
|
|
||||||
+ | Create_ovf.OVirt -> "--vdsm-ovf-flavour=ovf"
|
|
||||||
+ (* currently this is the default, so don't print it *)
|
|
||||||
+ | Create_ovf.RHVExportStorageDomain -> "")
|
|
||||||
|
|
||||||
method supported_firmware = [ TargetBIOS ]
|
|
||||||
|
|
||||||
@@ -176,7 +181,7 @@ object
|
|
||||||
vdsm_options.image_uuids
|
|
||||||
vdsm_options.vol_uuids
|
|
||||||
vdsm_options.vm_uuid
|
|
||||||
- Create_ovf.RHVExportStorageDomain in
|
|
||||||
+ vdsm_options.ovf_flavour in
|
|
||||||
|
|
||||||
(* Write it to the metadata file. *)
|
|
||||||
let file = vdsm_options.ovf_output // vdsm_options.vm_uuid ^ ".ovf" in
|
|
||||||
diff --git a/v2v/output_vdsm.mli b/v2v/output_vdsm.mli
|
|
||||||
index 401a71ec4..6ed684638 100644
|
|
||||||
--- a/v2v/output_vdsm.mli
|
|
||||||
+++ b/v2v/output_vdsm.mli
|
|
||||||
@@ -24,6 +24,7 @@ type vdsm_options = {
|
|
||||||
vm_uuid : string; (* --vdsm-vm-uuid *)
|
|
||||||
ovf_output : string; (* --vdsm-ovf-output *)
|
|
||||||
compat : string; (* --vdsm-compat=0.10|1.1 *)
|
|
||||||
+ ovf_flavour : Create_ovf.ovf_flavour;
|
|
||||||
}
|
|
||||||
(** Miscellaneous extra command line parameters used by VDSM. *)
|
|
||||||
|
|
||||||
diff --git a/v2v/test-v2v-o-vdsm-options.sh b/v2v/test-v2v-o-vdsm-options.sh
|
|
||||||
index 753efc4e7..4ad5d4aad 100755
|
|
||||||
--- a/v2v/test-v2v-o-vdsm-options.sh
|
|
||||||
+++ b/v2v/test-v2v-o-vdsm-options.sh
|
|
||||||
@@ -55,7 +55,8 @@ $VG virt-v2v --debug-gc \
|
|
||||||
--vdsm-vol-uuid VOL \
|
|
||||||
--vdsm-vm-uuid VM \
|
|
||||||
--vdsm-ovf-output $d/12345678-1234-1234-1234-123456789abc/master/vms/VM \
|
|
||||||
- --vdsm-compat=1.1
|
|
||||||
+ --vdsm-compat=1.1 \
|
|
||||||
+ --vdsm-ovf-flavour=ovirt
|
|
||||||
|
|
||||||
# Test the OVF metadata was created.
|
|
||||||
test -f $d/12345678-1234-1234-1234-123456789abc/master/vms/VM/VM.ovf
|
|
||||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
|
||||||
index cced114f3..0ea5fa97f 100644
|
|
||||||
--- a/v2v/virt-v2v.pod
|
|
||||||
+++ b/v2v/virt-v2v.pod
|
|
||||||
@@ -759,6 +759,26 @@ hex digit can be C<0-9> or C<a-f>), conforming to S<OSF DCE 1.1>.
|
|
||||||
|
|
||||||
These options can only be used with I<-o vdsm>.
|
|
||||||
|
|
||||||
+=item B<--vdsm-ovf-flavour> flavour
|
|
||||||
+
|
|
||||||
+This option controls the format of the OVF generated at the end of conversion.
|
|
||||||
+Currently there are two possible flavours:
|
|
||||||
+
|
|
||||||
+=over 4
|
|
||||||
+
|
|
||||||
+=item rhevexp
|
|
||||||
+
|
|
||||||
+The OVF format used in RHV export storage domain.
|
|
||||||
+
|
|
||||||
+=item ovirt
|
|
||||||
+
|
|
||||||
+The OVF format understood by oVirt REST API.
|
|
||||||
+
|
|
||||||
+=back
|
|
||||||
+
|
|
||||||
+For backward compatibility the default is I<rhevexp>, but this may change in
|
|
||||||
+the future.
|
|
||||||
+
|
|
||||||
=item B<-v>
|
|
||||||
|
|
||||||
=item B<--verbose>
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,124 +0,0 @@
|
|||||||
From 00ed208050cdb2178ac58878cb126504ebc7b311 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Thu, 22 Feb 2018 14:22:12 +0000
|
|
||||||
Subject: [PATCH] v2v: OVF: Code formatting.
|
|
||||||
|
|
||||||
Updates commit a52ed4b4454396eb13d2cdf5762292bff3104f66
|
|
||||||
("v2v: ovf: Create OVF more aligned with the standard") with some
|
|
||||||
small code refactoring and formatting.
|
|
||||||
|
|
||||||
(cherry picked from commit 9e83f3a2ccef4e91b0b3275b712df8b16e233cff)
|
|
||||||
---
|
|
||||||
v2v/create_ovf.ml | 73 ++++++++++++++++++++++++++---------------------
|
|
||||||
1 file changed, 41 insertions(+), 32 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
|
|
||||||
index d0735afce..0e07afea8 100644
|
|
||||||
--- a/v2v/create_ovf.ml
|
|
||||||
+++ b/v2v/create_ovf.ml
|
|
||||||
@@ -530,20 +530,16 @@ let rec create_ovf source targets guestcaps inspect
|
|
||||||
* For example normal disk section is in node <DiskSection> whereas in case of
|
|
||||||
* RHV export storage domain it is <Section xsi:type="ovf:DiskSection_Type">.
|
|
||||||
*)
|
|
||||||
-and get_flavoured_section ovf ovf_flavour ovirt_path rhv_path rhv_path_attr =
|
|
||||||
- let nodes =
|
|
||||||
- match ovf_flavour with
|
|
||||||
- | OVirt ->
|
|
||||||
- let nodes = path_to_nodes ovf ovirt_path in
|
|
||||||
- (match nodes with
|
|
||||||
+and get_flavoured_section ovf ovirt_path rhv_path rhv_path_attr = function
|
|
||||||
+ | OVirt ->
|
|
||||||
+ let nodes = path_to_nodes ovf ovirt_path in
|
|
||||||
+ (match nodes with
|
|
||||||
| [node] -> node
|
|
||||||
| [] | _::_::_ -> assert false)
|
|
||||||
- | RHVExportStorageDomain ->
|
|
||||||
- let nodes = path_to_nodes ovf rhv_path in
|
|
||||||
- try find_node_by_attr nodes rhv_path_attr
|
|
||||||
- with Not_found -> assert false
|
|
||||||
- in
|
|
||||||
- nodes
|
|
||||||
+ | RHVExportStorageDomain ->
|
|
||||||
+ let nodes = path_to_nodes ovf rhv_path in
|
|
||||||
+ try find_node_by_attr nodes rhv_path_attr
|
|
||||||
+ with Not_found -> assert false
|
|
||||||
|
|
||||||
(* This modifies the OVF DOM, adding a section for each disk. *)
|
|
||||||
and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids
|
|
||||||
@@ -553,14 +549,19 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids
|
|
||||||
match nodes with
|
|
||||||
| [] | _::_::_ -> assert false
|
|
||||||
| [node] -> node in
|
|
||||||
- let disk_section = get_flavoured_section ovf ovf_flavour
|
|
||||||
- ["ovf:Envelope"; "DiskSection"]
|
|
||||||
- ["ovf:Envelope"; "Section"]
|
|
||||||
- ("xsi:type", "ovf:DiskSection_Type") in
|
|
||||||
- let virtualhardware_section = get_flavoured_section ovf ovf_flavour
|
|
||||||
- ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"]
|
|
||||||
- ["ovf:Envelope"; "Content"; "Section"]
|
|
||||||
- ("xsi:type", "ovf:VirtualHardwareSection_Type") in
|
|
||||||
+ let disk_section =
|
|
||||||
+ get_flavoured_section ovf
|
|
||||||
+ ["ovf:Envelope"; "DiskSection"]
|
|
||||||
+ ["ovf:Envelope"; "Section"]
|
|
||||||
+ ("xsi:type", "ovf:DiskSection_Type")
|
|
||||||
+ ovf_flavour in
|
|
||||||
+ let virtualhardware_section =
|
|
||||||
+ get_flavoured_section ovf
|
|
||||||
+ ["ovf:Envelope"; "VirtualSystem";
|
|
||||||
+ "VirtualHardwareSection"]
|
|
||||||
+ ["ovf:Envelope"; "Content"; "Section"]
|
|
||||||
+ ("xsi:type", "ovf:VirtualHardwareSection_Type")
|
|
||||||
+ ovf_flavour in
|
|
||||||
|
|
||||||
(* Iterate over the disks, adding them to the OVF document. *)
|
|
||||||
List.iteri (
|
|
||||||
@@ -693,14 +694,19 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids
|
|
||||||
|
|
||||||
(* This modifies the OVF DOM, adding a section for each NIC. *)
|
|
||||||
and add_networks nics guestcaps ovf_flavour ovf =
|
|
||||||
- let network_section = get_flavoured_section ovf ovf_flavour
|
|
||||||
- ["ovf:Envelope"; "NetworkSection"]
|
|
||||||
- ["ovf:Envelope"; "Section"]
|
|
||||||
- ("xsi:type", "ovf:NetworkSection_Type") in
|
|
||||||
- let virtualhardware_section = get_flavoured_section ovf ovf_flavour
|
|
||||||
- ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"]
|
|
||||||
- ["ovf:Envelope"; "Content"; "Section"]
|
|
||||||
- ("xsi:type", "ovf:VirtualHardwareSection_Type") in
|
|
||||||
+ let network_section =
|
|
||||||
+ get_flavoured_section ovf
|
|
||||||
+ ["ovf:Envelope"; "NetworkSection"]
|
|
||||||
+ ["ovf:Envelope"; "Section"]
|
|
||||||
+ ("xsi:type", "ovf:NetworkSection_Type")
|
|
||||||
+ ovf_flavour in
|
|
||||||
+ let virtualhardware_section =
|
|
||||||
+ get_flavoured_section ovf
|
|
||||||
+ ["ovf:Envelope"; "VirtualSystem";
|
|
||||||
+ "VirtualHardwareSection"]
|
|
||||||
+ ["ovf:Envelope"; "Content"; "Section"]
|
|
||||||
+ ("xsi:type", "ovf:VirtualHardwareSection_Type")
|
|
||||||
+ ovf_flavour in
|
|
||||||
|
|
||||||
(* Iterate over the NICs, adding them to the OVF document. *)
|
|
||||||
List.iteri (
|
|
||||||
@@ -761,10 +767,13 @@ and add_sound_card sound ovf_flavour ovf =
|
|
||||||
|
|
||||||
match device with
|
|
||||||
| Some device ->
|
|
||||||
- let virtualhardware_section = get_flavoured_section ovf ovf_flavour
|
|
||||||
- ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"]
|
|
||||||
- ["ovf:Envelope"; "Content"; "Section"]
|
|
||||||
- ("xsi:type", "ovf:VirtualHardwareSection_Type") in
|
|
||||||
+ let virtualhardware_section =
|
|
||||||
+ get_flavoured_section ovf
|
|
||||||
+ ["ovf:Envelope"; "VirtualSystem";
|
|
||||||
+ "VirtualHardwareSection"]
|
|
||||||
+ ["ovf:Envelope"; "Content"; "Section"]
|
|
||||||
+ ("xsi:type", "ovf:VirtualHardwareSection_Type")
|
|
||||||
+ ovf_flavour in
|
|
||||||
|
|
||||||
let item =
|
|
||||||
e "Item" [] [
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
From df8794643644c742b7cfced948eee4519b38a643 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.25.4
|
||||||
|
|
@ -1,127 +0,0 @@
|
|||||||
From 83b5f589231da2ab6d04680f42c37dc6058cbe6e Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Tue, 20 Feb 2018 15:21:48 +0000
|
|
||||||
Subject: [PATCH] v2v: DOM: Add doc_to_string function.
|
|
||||||
|
|
||||||
Convert a document to an in-memory string.
|
|
||||||
|
|
||||||
(cherry picked from commit 802c8635cc2537a7d4b7af8981c670e2fdbb2675)
|
|
||||||
---
|
|
||||||
v2v/DOM.ml | 61 +++++++++++++++++++++++++++++++++--------------------
|
|
||||||
v2v/DOM.mli | 3 +++
|
|
||||||
2 files changed, 41 insertions(+), 23 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/DOM.ml b/v2v/DOM.ml
|
|
||||||
index 7f66e0920..8b106224b 100644
|
|
||||||
--- a/v2v/DOM.ml
|
|
||||||
+++ b/v2v/DOM.ml
|
|
||||||
@@ -46,43 +46,48 @@ let e name attrs children =
|
|
||||||
* we will be writing, ie. libvirt XML and OVF metadata, where
|
|
||||||
* whitespace is generally not significant, but readability is useful.
|
|
||||||
*)
|
|
||||||
-let rec node_to_chan ?(indent = 0) chan = function
|
|
||||||
- | PCData str -> output_string chan (xml_quote_pcdata str)
|
|
||||||
+let rec node_to_buf ?(indent = 0) buf = function
|
|
||||||
+ | PCData str ->
|
|
||||||
+ Buffer.add_string buf (xml_quote_pcdata str)
|
|
||||||
| Comment str ->
|
|
||||||
- output_spaces chan indent;
|
|
||||||
- fprintf chan "<!-- %s -->" (xml_quote_pcdata str)
|
|
||||||
- | Element e -> element_to_chan ~indent chan e
|
|
||||||
-and element_to_chan ?(indent = 0) chan
|
|
||||||
+ buffer_add_spaces buf indent;
|
|
||||||
+ bprintf buf "<!-- %s -->" (xml_quote_pcdata str)
|
|
||||||
+ | Element e ->
|
|
||||||
+ element_to_buf ~indent buf e
|
|
||||||
+and element_to_buf ?(indent = 0) buf
|
|
||||||
{ e_name = name; e_attrs = attrs; e_children = children } =
|
|
||||||
- output_spaces chan indent;
|
|
||||||
- fprintf chan "<%s" name;
|
|
||||||
- List.iter (fun (n, v) -> fprintf chan " %s='%s'" n (xml_quote_attr v)) attrs;
|
|
||||||
+ buffer_add_spaces buf indent;
|
|
||||||
+ bprintf buf "<%s" name;
|
|
||||||
+ List.iter (fun (n, v) -> bprintf buf " %s='%s'" n (xml_quote_attr v)) attrs;
|
|
||||||
if children <> [] then (
|
|
||||||
- output_string chan ">";
|
|
||||||
+ Buffer.add_string buf ">";
|
|
||||||
let last_child_was_element = ref false in
|
|
||||||
List.iter (
|
|
||||||
function
|
|
||||||
| Element _ as child ->
|
|
||||||
last_child_was_element := true;
|
|
||||||
- output_char chan '\n';
|
|
||||||
- node_to_chan ~indent:(indent+2) chan child;
|
|
||||||
+ Buffer.add_char buf '\n';
|
|
||||||
+ node_to_buf ~indent:(indent+2) buf child;
|
|
||||||
| PCData _ as child ->
|
|
||||||
last_child_was_element := false;
|
|
||||||
- node_to_chan ~indent:(indent+2) chan child;
|
|
||||||
+ node_to_buf ~indent:(indent+2) buf child;
|
|
||||||
| Comment _ as child ->
|
|
||||||
last_child_was_element := true;
|
|
||||||
- output_char chan '\n';
|
|
||||||
- node_to_chan ~indent:(indent+2) chan child;
|
|
||||||
+ Buffer.add_char buf '\n';
|
|
||||||
+ node_to_buf ~indent:(indent+2) buf child;
|
|
||||||
) children;
|
|
||||||
if !last_child_was_element then (
|
|
||||||
- output_char chan '\n';
|
|
||||||
- output_spaces chan indent
|
|
||||||
+ Buffer.add_char buf '\n';
|
|
||||||
+ buffer_add_spaces buf indent
|
|
||||||
);
|
|
||||||
- fprintf chan "</%s>" name
|
|
||||||
+ bprintf buf "</%s>" name
|
|
||||||
) else (
|
|
||||||
- output_string chan "/>"
|
|
||||||
+ Buffer.add_string buf "/>"
|
|
||||||
)
|
|
||||||
|
|
||||||
+and buffer_add_spaces buf n =
|
|
||||||
+ Buffer.add_string buf (String.spaces n)
|
|
||||||
+
|
|
||||||
(* Quote XML <element attr='...'> content. Note you must use single
|
|
||||||
* quotes around the attribute.
|
|
||||||
*)
|
|
||||||
@@ -99,10 +104,20 @@ and xml_quote_pcdata str =
|
|
||||||
let str = String.replace str ">" ">" in
|
|
||||||
str
|
|
||||||
|
|
||||||
-let doc_to_chan chan (Doc doc) =
|
|
||||||
- fprintf chan "<?xml version='1.0' encoding='utf-8'?>\n";
|
|
||||||
- element_to_chan chan doc;
|
|
||||||
- fprintf chan "\n"
|
|
||||||
+let doc_to_buf buf (Doc doc) =
|
|
||||||
+ bprintf buf "<?xml version='1.0' encoding='utf-8'?>\n";
|
|
||||||
+ element_to_buf buf doc;
|
|
||||||
+ bprintf buf "\n"
|
|
||||||
+
|
|
||||||
+let doc_to_string doc =
|
|
||||||
+ let buf = Buffer.create 4096 in
|
|
||||||
+ doc_to_buf buf doc;
|
|
||||||
+ Buffer.contents buf
|
|
||||||
+
|
|
||||||
+let doc_to_chan chan doc =
|
|
||||||
+ let buf = Buffer.create 4096 in
|
|
||||||
+ doc_to_buf buf doc;
|
|
||||||
+ Buffer.output_buffer chan buf
|
|
||||||
|
|
||||||
let path_to_nodes (Doc doc) path =
|
|
||||||
match path with
|
|
||||||
diff --git a/v2v/DOM.mli b/v2v/DOM.mli
|
|
||||||
index 1aa89b7e7..99223c389 100644
|
|
||||||
--- a/v2v/DOM.mli
|
|
||||||
+++ b/v2v/DOM.mli
|
|
||||||
@@ -60,6 +60,9 @@ v}
|
|
||||||
v}
|
|
||||||
*)
|
|
||||||
|
|
||||||
+val doc_to_string : doc -> string
|
|
||||||
+(** Convert a document to a string representation. *)
|
|
||||||
+
|
|
||||||
val doc_to_chan : out_channel -> doc -> unit
|
|
||||||
(** Write the XML document to an output channel. *)
|
|
||||||
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
From 6ea20c9a03cb9ecadd60a1197499a4eaa4593416 Mon Sep 17 00:00:00 2001
|
From de267e07b9b26d2f89470d4305d7259edb24663b Mon Sep 17 00:00:00 2001
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
From: Pino Toscano <ptoscano@redhat.com>
|
||||||
Date: Fri, 12 Apr 2019 16:19:43 +0200
|
Date: Fri, 12 Apr 2019 16:19:43 +0200
|
||||||
Subject: [PATCH] v2v: update documentation on nbdkit (RHBZ#1605242)
|
Subject: [PATCH] v2v: update documentation on nbdkit (RHBZ#1605242)
|
||||||
@ -8,14 +8,14 @@ version instead of recommending to build nbdkit from sources.
|
|||||||
|
|
||||||
(cherry picked from commit 0704d8eb0bcc8139886eb4291f75a3ca49a91e58)
|
(cherry picked from commit 0704d8eb0bcc8139886eb4291f75a3ca49a91e58)
|
||||||
---
|
---
|
||||||
v2v/virt-v2v.pod | 28 ++--------------------------
|
v2v/virt-v2v-input-vmware.pod | 28 ++--------------------------
|
||||||
1 file changed, 2 insertions(+), 26 deletions(-)
|
1 file changed, 2 insertions(+), 26 deletions(-)
|
||||||
|
|
||||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
diff --git a/v2v/virt-v2v-input-vmware.pod b/v2v/virt-v2v-input-vmware.pod
|
||||||
index f4d200e3d..74536a2a6 100644
|
index 2b6dbaeec..b3ebda182 100644
|
||||||
--- a/v2v/virt-v2v.pod
|
--- a/v2v/virt-v2v-input-vmware.pod
|
||||||
+++ b/v2v/virt-v2v.pod
|
+++ b/v2v/virt-v2v-input-vmware.pod
|
||||||
@@ -1657,32 +1657,8 @@ library is permitted by the license.
|
@@ -197,32 +197,8 @@ library is permitted by the license.
|
||||||
|
|
||||||
=item 2.
|
=item 2.
|
||||||
|
|
||||||
@ -51,5 +51,5 @@ index f4d200e3d..74536a2a6 100644
|
|||||||
=item 3.
|
=item 3.
|
||||||
|
|
||||||
--
|
--
|
||||||
2.21.0
|
2.25.4
|
||||||
|
|
@ -1,138 +0,0 @@
|
|||||||
From ae2d0a507af53563d0b70d28654c9c60a857fd10 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Thu, 22 Feb 2018 11:43:33 +0000
|
|
||||||
Subject: [PATCH] v2v: Add -op (output password file) option.
|
|
||||||
|
|
||||||
Currently unused, in a future commit this will allow you to pass in a
|
|
||||||
password to be used when connecting to the target hypervisor.
|
|
||||||
|
|
||||||
(cherry picked from commit a4e181137a38f5767dd1bf05dc482959cb7283be)
|
|
||||||
---
|
|
||||||
v2v/cmdline.ml | 18 ++++++++++++++++++
|
|
||||||
v2v/test-v2v-docs.sh | 2 +-
|
|
||||||
v2v/virt-v2v.pod | 7 +++++++
|
|
||||||
3 files changed, 26 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
|
|
||||||
index 75909ee77..2a067741e 100644
|
|
||||||
--- a/v2v/cmdline.ml
|
|
||||||
+++ b/v2v/cmdline.ml
|
|
||||||
@@ -62,6 +62,7 @@ let parse_cmdline () =
|
|
||||||
let output_conn = ref None in
|
|
||||||
let output_format = ref None in
|
|
||||||
let output_name = ref None in
|
|
||||||
+ let output_password = ref None in
|
|
||||||
let output_storage = ref None in
|
|
||||||
let password_file = ref None in
|
|
||||||
let vddk_config = ref None in
|
|
||||||
@@ -219,6 +220,8 @@ let parse_cmdline () =
|
|
||||||
s_"Set output format";
|
|
||||||
[ M"on" ], Getopt.String ("name", set_string_option_once "-on" output_name),
|
|
||||||
s_"Rename guest when converting";
|
|
||||||
+ [ M"op" ], Getopt.String ("filename", set_string_option_once "-op" output_password),
|
|
||||||
+ s_"Use password from file to connect to output hypervisor";
|
|
||||||
[ M"os" ], Getopt.String ("storage", set_string_option_once "-os" output_storage),
|
|
||||||
s_"Set output storage location";
|
|
||||||
[ L"password-file" ], Getopt.String ("file", set_string_option_once "--password-file" password_file),
|
|
||||||
@@ -314,6 +317,7 @@ read the man page virt-v2v(1).
|
|
||||||
let output_format = !output_format in
|
|
||||||
let output_mode = !output_mode in
|
|
||||||
let output_name = !output_name in
|
|
||||||
+ let output_password = !output_password in
|
|
||||||
let output_storage = !output_storage in
|
|
||||||
let password_file = !password_file in
|
|
||||||
let print_source = !print_source in
|
|
||||||
@@ -461,6 +465,8 @@ read the man page virt-v2v(1).
|
|
||||||
| `Glance ->
|
|
||||||
if output_conn <> None then
|
|
||||||
error_option_cannot_be_used_in_output_mode "glance" "-oc";
|
|
||||||
+ if output_password <> None then
|
|
||||||
+ error_option_cannot_be_used_in_output_mode "glance" "-op";
|
|
||||||
if output_storage <> None then
|
|
||||||
error_option_cannot_be_used_in_output_mode "glance" "-os";
|
|
||||||
if qemu_boot then
|
|
||||||
@@ -472,6 +478,8 @@ read the man page virt-v2v(1).
|
|
||||||
|
|
||||||
| `Not_set
|
|
||||||
| `Libvirt ->
|
|
||||||
+ if output_password <> None then
|
|
||||||
+ error_option_cannot_be_used_in_output_mode "libvirt" "-op";
|
|
||||||
let output_storage = Option.default "default" output_storage in
|
|
||||||
if qemu_boot then
|
|
||||||
error_option_cannot_be_used_in_output_mode "libvirt" "--qemu-boot";
|
|
||||||
@@ -481,6 +489,8 @@ read the man page virt-v2v(1).
|
|
||||||
output_format, output_alloc
|
|
||||||
|
|
||||||
| `Local ->
|
|
||||||
+ if output_password <> None then
|
|
||||||
+ error_option_cannot_be_used_in_output_mode "local" "-op";
|
|
||||||
let os =
|
|
||||||
match output_storage with
|
|
||||||
| None ->
|
|
||||||
@@ -500,6 +510,8 @@ read the man page virt-v2v(1).
|
|
||||||
error_option_cannot_be_used_in_output_mode "null" "-oc";
|
|
||||||
if output_format <> None then
|
|
||||||
error_option_cannot_be_used_in_output_mode "null" "-of";
|
|
||||||
+ if output_password <> None then
|
|
||||||
+ error_option_cannot_be_used_in_output_mode "null" "-op";
|
|
||||||
if output_storage <> None then
|
|
||||||
error_option_cannot_be_used_in_output_mode "null" "-os";
|
|
||||||
if qemu_boot then
|
|
||||||
@@ -509,6 +521,8 @@ read the man page virt-v2v(1).
|
|
||||||
Some "raw", Sparse
|
|
||||||
|
|
||||||
| `QEmu ->
|
|
||||||
+ if output_password <> None then
|
|
||||||
+ error_option_cannot_be_used_in_output_mode "qemu" "-op";
|
|
||||||
let os =
|
|
||||||
match output_storage with
|
|
||||||
| None ->
|
|
||||||
@@ -520,6 +534,8 @@ read the man page virt-v2v(1).
|
|
||||||
output_format, output_alloc
|
|
||||||
|
|
||||||
| `RHV ->
|
|
||||||
+ if output_password <> None then
|
|
||||||
+ error_option_cannot_be_used_in_output_mode "rhv" "-op";
|
|
||||||
let os =
|
|
||||||
match output_storage with
|
|
||||||
| None ->
|
|
||||||
@@ -531,6 +547,8 @@ read the man page virt-v2v(1).
|
|
||||||
output_format, output_alloc
|
|
||||||
|
|
||||||
| `VDSM ->
|
|
||||||
+ if output_password <> None then
|
|
||||||
+ error_option_cannot_be_used_in_output_mode "vdsm" "-op";
|
|
||||||
let os =
|
|
||||||
match output_storage with
|
|
||||||
| None ->
|
|
||||||
diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh
|
|
||||||
index 5d034c465..0e3bd916a 100755
|
|
||||||
--- a/v2v/test-v2v-docs.sh
|
|
||||||
+++ b/v2v/test-v2v-docs.sh
|
|
||||||
@@ -22,4 +22,4 @@ $TEST_FUNCTIONS
|
|
||||||
skip_if_skipped
|
|
||||||
|
|
||||||
$top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \
|
|
||||||
- --ignore=--debug-overlay,--ic,--if,--it,--no-trim,--oa,--oc,--of,--on,--os,--vmtype
|
|
||||||
+ --ignore=--debug-overlay,--ic,--if,--it,--no-trim,--oa,--oc,--of,--on,--op,--os,--vmtype
|
|
||||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
|
||||||
index 0ea5fa97f..00ba45555 100644
|
|
||||||
--- a/v2v/virt-v2v.pod
|
|
||||||
+++ b/v2v/virt-v2v.pod
|
|
||||||
@@ -569,6 +569,13 @@ If not specified, then the input format is used.
|
|
||||||
Rename the guest when converting it. If this option is not used then
|
|
||||||
the output name is the same as the input name.
|
|
||||||
|
|
||||||
+=item B<-op> file
|
|
||||||
+
|
|
||||||
+Supply a file containing a password to be used when connecting to the
|
|
||||||
+target hypervisor. Note the file should contain the whole password,
|
|
||||||
+B<without any trailing newline>, and for security the file should have
|
|
||||||
+mode C<0600> so that others cannot read it.
|
|
||||||
+
|
|
||||||
=item B<-os> storage
|
|
||||||
|
|
||||||
The location of the storage for the converted guest.
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
From 51367a1f2d4a5c54564a6bcaf8c193de643d3ee4 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.25.4
|
||||||
|
|
@ -1,35 +0,0 @@
|
|||||||
From 311d8dff12b8079b7eb9d6d2d917a9c6883928a4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Thu, 22 Mar 2018 10:28:36 +0000
|
|
||||||
Subject: [PATCH] v2v: cmdline: Move definition to before its only use.
|
|
||||||
|
|
||||||
(cherry picked from commit 3167ce1f91667de4c4fe1885bb33c06ee6fa38c5)
|
|
||||||
---
|
|
||||||
v2v/cmdline.ml | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
|
|
||||||
index 2a067741e..a83fcbae0 100644
|
|
||||||
--- a/v2v/cmdline.ml
|
|
||||||
+++ b/v2v/cmdline.ml
|
|
||||||
@@ -81,7 +81,6 @@ let parse_cmdline () =
|
|
||||||
let set_vdsm_compat s = vdsm_compat := s in
|
|
||||||
|
|
||||||
let vdsm_ovf_flavour = ref Create_ovf.RHVExportStorageDomain in
|
|
||||||
- let ovf_flavours_str = String.concat "|" Create_ovf.ovf_flavours in
|
|
||||||
let set_vdsm_ovf_flavour arg =
|
|
||||||
vdsm_ovf_flavour := Create_ovf.ovf_flavour_of_string arg in
|
|
||||||
|
|
||||||
@@ -183,7 +182,8 @@ let parse_cmdline () =
|
|
||||||
let i_options =
|
|
||||||
String.concat "|" (Modules_list.input_modules ())
|
|
||||||
and o_options =
|
|
||||||
- String.concat "|" (Modules_list.output_modules ()) in
|
|
||||||
+ String.concat "|" (Modules_list.output_modules ())
|
|
||||||
+ and ovf_flavours_str = String.concat "|" Create_ovf.ovf_flavours in
|
|
||||||
|
|
||||||
let argspec = [
|
|
||||||
[ S 'b'; L"bridge" ], Getopt.String ("in:out", add_bridge),
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From 6239ce21ea4d47914aa149cee724e998c287d26c 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.25.4
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,61 @@
|
|||||||
|
From 10afd834b5e1787cb2b22fce96de30baf37b5b2b 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.25.4
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
From c7942097bff8cbbfbee34e1750223c308f32f8a4 Mon Sep 17 00:00:00 2001
|
From 54b63460b7602ac5c68d6e58ab60e7f85877cefc Mon Sep 17 00:00:00 2001
|
||||||
From: Martin Kletzander <mkletzan@redhat.com>
|
From: Martin Kletzander <mkletzan@redhat.com>
|
||||||
Date: Mon, 27 May 2019 13:30:05 +0200
|
Date: Mon, 27 May 2019 13:30:05 +0200
|
||||||
Subject: [PATCH] Use proper label for nbdkit sockets
|
Subject: [PATCH] Use proper label for nbdkit sockets
|
||||||
@ -33,10 +33,10 @@ Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
|||||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml
|
diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml
|
||||||
index 0b3ed7af9..5e8e60bd2 100644
|
index 97c7cb532..567233d58 100644
|
||||||
--- a/v2v/input_libvirt_vddk.ml
|
--- a/v2v/input_libvirt_vddk.ml
|
||||||
+++ b/v2v/input_libvirt_vddk.ml
|
+++ b/v2v/input_libvirt_vddk.ml
|
||||||
@@ -292,7 +292,7 @@ object
|
@@ -290,7 +290,7 @@ object
|
||||||
add_arg "--newstyle"; (* use newstyle NBD protocol *)
|
add_arg "--newstyle"; (* use newstyle NBD protocol *)
|
||||||
add_arg "--exportname"; add_arg "/";
|
add_arg "--exportname"; add_arg "/";
|
||||||
if have_selinux then ( (* label the socket so qemu can open it *)
|
if have_selinux then ( (* label the socket so qemu can open it *)
|
||||||
@ -46,10 +46,10 @@ index 0b3ed7af9..5e8e60bd2 100644
|
|||||||
|
|
||||||
(* Name of the plugin. Everything following is a plugin parameter. *)
|
(* Name of the plugin. Everything following is a plugin parameter. *)
|
||||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||||
index 79a2fc8fd..fc33e5033 100644
|
index 77c39107e..c2a5c72c7 100644
|
||||||
--- a/v2v/output_rhv_upload.ml
|
--- a/v2v/output_rhv_upload.ml
|
||||||
+++ b/v2v/output_rhv_upload.ml
|
+++ b/v2v/output_rhv_upload.ml
|
||||||
@@ -230,7 +230,7 @@ See also \"OUTPUT TO RHV\" in the virt-v2v(1) manual.")
|
@@ -217,7 +217,7 @@ See also the virt-v2v-output-rhv(1) manual.")
|
||||||
let args =
|
let args =
|
||||||
(* label the socket so qemu can open it *)
|
(* label the socket so qemu can open it *)
|
||||||
if have_selinux then
|
if have_selinux then
|
||||||
@ -59,5 +59,5 @@ index 79a2fc8fd..fc33e5033 100644
|
|||||||
args in
|
args in
|
||||||
|
|
||||||
--
|
--
|
||||||
2.21.0
|
2.25.4
|
||||||
|
|
@ -1,247 +0,0 @@
|
|||||||
From 1b4c00a3ec7c0618e8557e1e71d5782527a94828 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Wed, 4 Apr 2018 18:18:32 +0200
|
|
||||||
Subject: [PATCH] v2v: OVF: write ovirt:id attribute for the OS in OVirt
|
|
||||||
flavour
|
|
||||||
|
|
||||||
When writing the OVF in OVirt flavour, add a ovirt:id attribute to the
|
|
||||||
OperatingSystemSection tag: this attribute represents the numeric value
|
|
||||||
of the ostype ID, which is ignored by oVirt when parsing OVFs in API
|
|
||||||
mode.
|
|
||||||
|
|
||||||
(cherry picked from commit 593a19cc86cfa8f24c66518c8ba21222550b066a)
|
|
||||||
---
|
|
||||||
v2v/create_ovf.ml | 202 +++++++++++++++++++++++++++++++++++++++++++++-
|
|
||||||
1 file changed, 201 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
|
|
||||||
index 0e07afea8..730ab64b4 100644
|
|
||||||
--- a/v2v/create_ovf.ml
|
|
||||||
+++ b/v2v/create_ovf.ml
|
|
||||||
@@ -242,6 +242,203 @@ and get_ostype = function
|
|
||||||
typ distro major minor arch product;
|
|
||||||
"Unassigned"
|
|
||||||
|
|
||||||
+(* Determine the ovirt:id attribute from libguestfs inspection.
|
|
||||||
+ * See ovirt-engine sources, file:
|
|
||||||
+ * packaging/conf/osinfo-defaults.properties
|
|
||||||
+ * and also:
|
|
||||||
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1219857#c9
|
|
||||||
+ *)
|
|
||||||
+and get_ovirt_osid = function
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 3;
|
|
||||||
+ i_arch = "i386" } ->
|
|
||||||
+ 9
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 3;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 15
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 4;
|
|
||||||
+ i_arch = "i386" } ->
|
|
||||||
+ 8
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 4;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 14
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 5;
|
|
||||||
+ i_arch = "i386" } ->
|
|
||||||
+ 7
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 5;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 13
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 6;
|
|
||||||
+ i_arch = "i386" } ->
|
|
||||||
+ 18
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 6;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 19
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 6;
|
|
||||||
+ i_minor_version = min; i_arch = ("ppc64"|"ppc64le") } when min >= 9 ->
|
|
||||||
+ 1007
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 6;
|
|
||||||
+ i_arch = ("ppc64"|"ppc64le") } ->
|
|
||||||
+ 1003
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 7;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 24
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 7;
|
|
||||||
+ i_arch = ("ppc64"|"ppc64le") } ->
|
|
||||||
+ 1006
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = ("rhel"|"centos"); i_major_version = 7;
|
|
||||||
+ i_arch = "s390x" } ->
|
|
||||||
+ 2003
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = "sles"; i_major_version = maj;
|
|
||||||
+ i_arch = "x86_64" } when maj >= 11 ->
|
|
||||||
+ 1193
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = "sles"; i_major_version = maj;
|
|
||||||
+ i_arch = ("ppc64"|"ppc64le") } when maj >= 11 ->
|
|
||||||
+ 1004
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = "sles"; i_major_version = maj;
|
|
||||||
+ i_arch = "s390x" } when maj >= 12 ->
|
|
||||||
+ 2004
|
|
||||||
+
|
|
||||||
+ (* Only Debian 7 is available, so use it for any 7+ version. *)
|
|
||||||
+ | { i_type = "linux"; i_distro = "debian"; i_major_version = v }
|
|
||||||
+ when v >= 7 ->
|
|
||||||
+ 1300
|
|
||||||
+
|
|
||||||
+ (* Only Ubuntu 12.04 to 14.04 are available, so use them starting
|
|
||||||
+ * from 12.04, and 14.04 for anything after it.
|
|
||||||
+ *)
|
|
||||||
+ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = v;
|
|
||||||
+ i_arch = ("ppc64"|"ppc64le") } when v >= 14 ->
|
|
||||||
+ 1005
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = v;
|
|
||||||
+ i_arch = "s390x" } when v >= 16 ->
|
|
||||||
+ 2005
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = v }
|
|
||||||
+ when v >= 14 ->
|
|
||||||
+ 1256
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = 12;
|
|
||||||
+ i_minor_version = 4 } ->
|
|
||||||
+ 1252
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = 12;
|
|
||||||
+ i_minor_version = 10 } ->
|
|
||||||
+ 1253
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = 13;
|
|
||||||
+ i_minor_version = 4 } ->
|
|
||||||
+ 1254
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_distro = "ubuntu"; i_major_version = 13;
|
|
||||||
+ i_minor_version = 10 } ->
|
|
||||||
+ 1255
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_arch = ("ppc64"|"ppc64le") } ->
|
|
||||||
+ 1002
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux"; i_arch = "s390x" } ->
|
|
||||||
+ 2002
|
|
||||||
+
|
|
||||||
+ | { i_type = "linux" } ->
|
|
||||||
+ 5
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 1 } ->
|
|
||||||
+ 1 (* no architecture differentiation of XP on RHV *)
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2;
|
|
||||||
+ i_product_name = product } when String.find product "XP" >= 0 ->
|
|
||||||
+ 1 (* no architecture differentiation of XP on RHV *)
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2;
|
|
||||||
+ i_arch = "i386" } ->
|
|
||||||
+ 3
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 10
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 0;
|
|
||||||
+ i_arch = "i386" } ->
|
|
||||||
+ 4
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 0;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 16
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1;
|
|
||||||
+ i_arch = "i386" } ->
|
|
||||||
+ 11
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1;
|
|
||||||
+ i_arch = "x86_64"; i_product_variant = "Client" } ->
|
|
||||||
+ 12
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 17
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2;
|
|
||||||
+ i_arch = "i386" } ->
|
|
||||||
+ 20
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2;
|
|
||||||
+ i_arch = "x86_64"; i_product_variant = "Client" } ->
|
|
||||||
+ 21
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 23
|
|
||||||
+
|
|
||||||
+ (* Treat Windows 8.1 client like Windows 8. See:
|
|
||||||
+ * https://bugzilla.redhat.com/show_bug.cgi?id=1309580#c4
|
|
||||||
+ *)
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3;
|
|
||||||
+ i_arch = "i386"; i_product_variant = "Client" } ->
|
|
||||||
+ 20
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3;
|
|
||||||
+ i_arch = "x86_64"; i_product_variant = "Client" } ->
|
|
||||||
+ 21
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 23
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0;
|
|
||||||
+ i_arch = "i386" } ->
|
|
||||||
+ 26
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0;
|
|
||||||
+ i_arch = "x86_64"; i_product_variant = "Client" } ->
|
|
||||||
+ 27
|
|
||||||
+
|
|
||||||
+ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0;
|
|
||||||
+ i_arch = "x86_64" } ->
|
|
||||||
+ 29
|
|
||||||
+
|
|
||||||
+ | { i_type = typ; i_distro = distro;
|
|
||||||
+ i_major_version = major; i_minor_version = minor; i_arch = arch;
|
|
||||||
+ i_product_name = product } ->
|
|
||||||
+ warning (f_"unknown guest operating system: %s %s %d.%d %s (%s)")
|
|
||||||
+ typ distro major minor arch product;
|
|
||||||
+ 0
|
|
||||||
+
|
|
||||||
(* Set the <Origin/> element based on the source hypervisor.
|
|
||||||
* https://bugzilla.redhat.com/show_bug.cgi?id=1342398#c6
|
|
||||||
* https://gerrit.ovirt.org/#/c/59147/
|
|
||||||
@@ -321,6 +518,7 @@ let rec create_ovf source targets guestcaps inspect
|
|
||||||
"xmlns:vssd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData";
|
|
||||||
"xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance";
|
|
||||||
"xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1/";
|
|
||||||
+ "xmlns:ovirt", "http://www.ovirt.org/ovf";
|
|
||||||
"ovf:version", "0.9"
|
|
||||||
] [
|
|
||||||
Comment generated_by;
|
|
||||||
@@ -383,8 +581,10 @@ let rec create_ovf source targets guestcaps inspect
|
|
||||||
] in
|
|
||||||
(match ovf_flavour with
|
|
||||||
| OVirt ->
|
|
||||||
+ let ovirt_osid = get_ovirt_osid inspect in
|
|
||||||
e "OperatingSystemSection" ["ovf:id", vm_uuid;
|
|
||||||
- "ovf:required", "false"]
|
|
||||||
+ "ovf:required", "false";
|
|
||||||
+ "ovirt:id", string_of_int ovirt_osid]
|
|
||||||
osinfo_subnodes
|
|
||||||
| RHVExportStorageDomain ->
|
|
||||||
e "Section" ["ovf:id", vm_uuid; "ovf:required", "false";
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
From b96a2119b20f204661fa2165aea3c6c2b84e23de Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Thu, 5 Apr 2018 10:28:17 +0200
|
|
||||||
Subject: [PATCH] v2v: OVF: fix ovf:id for VirtualSystem in OVirt flavour
|
|
||||||
|
|
||||||
When writing the OVF in OVirt flavour, write the actual UUID of the
|
|
||||||
VM as ovf:id attribute for <VirtualSystem>, instead of a dummy value.
|
|
||||||
|
|
||||||
Suggested by Arik Hadas in
|
|
||||||
https://www.redhat.com/archives/libguestfs/2018-April/msg00005.html
|
|
||||||
|
|
||||||
(cherry picked from commit 9dce43931a19510be1b6d21ce67d14a4136ce241)
|
|
||||||
---
|
|
||||||
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 730ab64b4..b1ab8df3f 100644
|
|
||||||
--- a/v2v/create_ovf.ml
|
|
||||||
+++ b/v2v/create_ovf.ml
|
|
||||||
@@ -688,7 +688,7 @@ let rec create_ovf source targets guestcaps inspect
|
|
||||||
|
|
||||||
(match ovf_flavour with
|
|
||||||
| OVirt ->
|
|
||||||
- e "VirtualSystem" ["ovf:id", "out"] !content_subnodes
|
|
||||||
+ e "VirtualSystem" ["ovf:id", vm_uuid] !content_subnodes
|
|
||||||
| RHVExportStorageDomain ->
|
|
||||||
e "Content" ["ovf:id", "out"; "xsi:type", "ovf:VirtualSystem_Type"]
|
|
||||||
!content_subnodes
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From 042554182bcc782527dc74e035e2efaf6eb38aa4 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.25.4
|
||||||
|
|
@ -0,0 +1,96 @@
|
|||||||
|
From 692a752cf3e552790ada8cc07f937036adaa8bf0 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.25.4
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,34 @@
|
|||||||
|
From 61e503d193706c38d58147a2d308faf01948550c 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.25.4
|
||||||
|
|
@ -1,28 +0,0 @@
|
|||||||
From 2648e807faaa94c080c33b8a0d70c078339c59f8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Fri, 20 Apr 2018 13:00:56 +0200
|
|
||||||
Subject: [PATCH] v2v: refer to the right embed script in EXTRA_DIST
|
|
||||||
|
|
||||||
Fixes commit cc04573927cca97de60d544d37467e67c25867a7.
|
|
||||||
|
|
||||||
(cherry picked from commit cf49fe100338aeac281c7cbcdfe743177ceb0606)
|
|
||||||
---
|
|
||||||
v2v/Makefile.am | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
|
|
||||||
index 694a64573..3a0c80f44 100644
|
|
||||||
--- a/v2v/Makefile.am
|
|
||||||
+++ b/v2v/Makefile.am
|
|
||||||
@@ -31,7 +31,7 @@ EXTRA_DIST = \
|
|
||||||
$(SOURCES_MLI) $(SOURCES_ML) $(SOURCES_C) \
|
|
||||||
copy_to_local.ml \
|
|
||||||
copy_to_local.mli \
|
|
||||||
- embed-code.sh \
|
|
||||||
+ embed.sh \
|
|
||||||
rhv-upload-createvm.py \
|
|
||||||
rhv-upload-plugin.py \
|
|
||||||
rhv-upload-precheck.py \
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
|||||||
|
From 0dd5c55c62f4e239c7be75852cf8a667be833cf1 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.25.4
|
||||||
|
|
@ -1,84 +0,0 @@
|
|||||||
From 2e9cc6b2307668f330d11384bba63b70160d3e42 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Fri, 20 Apr 2018 11:48:47 +0100
|
|
||||||
Subject: [PATCH] =?UTF-8?q?v2v:=20-o=20rhv-upload:=20Don't=20require=20?=
|
|
||||||
=?UTF-8?q?=E2=80=98-of=20raw=E2=80=99=20parameter.?=
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Because we checked the limitation of raw+sparse during command line
|
|
||||||
processing, it had the effect of forcing you to use ‘-of raw’ even if
|
|
||||||
the input was already in raw format. Move the checking to the output
|
|
||||||
mode to avoid this.
|
|
||||||
|
|
||||||
Fixes commit cc04573927cca97de60d544d37467e67c25867a7.
|
|
||||||
|
|
||||||
(cherry picked from commit b3769afaece360b8a2095e3d8a7a934d351c3ade)
|
|
||||||
---
|
|
||||||
v2v/cmdline.ml | 5 -----
|
|
||||||
v2v/output_rhv_upload.ml | 18 +++++++++++++++++-
|
|
||||||
2 files changed, 17 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
|
|
||||||
index 9b1348c37..97d4f4377 100644
|
|
||||||
--- a/v2v/cmdline.ml
|
|
||||||
+++ b/v2v/cmdline.ml
|
|
||||||
@@ -586,11 +586,6 @@ read the man page virt-v2v(1).
|
|
||||||
| None ->
|
|
||||||
error (f_"-o rhv-upload: use ‘-oc’ to point to the oVirt or RHV server REST API URL, which is usually https://servername/ovirt-engine/api")
|
|
||||||
| Some oc -> oc in
|
|
||||||
- (* Output format / sparse must currently be raw+sparse. We can
|
|
||||||
- * change this in future. See TODO file for details. XXX
|
|
||||||
- *)
|
|
||||||
- if output_alloc <> Sparse || output_format <> Some "raw" then
|
|
||||||
- error (f_"-o rhv-upload: currently you must use ‘-of raw’ and you cannot use ‘-oa preallocated’ with this output mode. These restrictions will be loosened in a future version.");
|
|
||||||
(* In theory we could make the password optional in future. *)
|
|
||||||
let output_password =
|
|
||||||
match output_password with
|
|
||||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
|
||||||
index 129461242..dc0d96d53 100644
|
|
||||||
--- a/v2v/output_rhv_upload.ml
|
|
||||||
+++ b/v2v/output_rhv_upload.ml
|
|
||||||
@@ -169,6 +169,19 @@ See also \"OUTPUT TO RHV\" in the virt-v2v(1) manual.")
|
|
||||||
error (f_"nbdkit was compiled without SELinux support. You will have to recompile nbdkit with libselinux-devel installed, or else set SELinux to Permissive mode while doing the conversion.")
|
|
||||||
in
|
|
||||||
|
|
||||||
+ (* Output format/sparse must be raw/sparse. We may be able to
|
|
||||||
+ * lift this limitation in future, but it requires changes on the
|
|
||||||
+ * RHV side. See TODO file for details. XXX
|
|
||||||
+ *)
|
|
||||||
+ let error_current_limitation required_param =
|
|
||||||
+ error (f_"rhv-upload: currently you must use ‘%s’. This restriction will be loosened in a future version.") required_param
|
|
||||||
+ in
|
|
||||||
+
|
|
||||||
+ let error_unless_output_alloc_sparse () =
|
|
||||||
+ if output_alloc <> Sparse then
|
|
||||||
+ error_current_limitation "-oa sparse"
|
|
||||||
+ in
|
|
||||||
+
|
|
||||||
(* JSON parameters which are invariant between disks. *)
|
|
||||||
let json_params = [
|
|
||||||
"verbose", JSON.Bool (verbose ());
|
|
||||||
@@ -220,6 +233,7 @@ object
|
|
||||||
error_unless_python_binary_on_path ();
|
|
||||||
error_unless_nbdkit_working ();
|
|
||||||
error_unless_nbdkit_python3_working ();
|
|
||||||
+ error_unless_output_alloc_sparse ();
|
|
||||||
if have_selinux then
|
|
||||||
error_unless_nbdkit_compiled_with_selinux ()
|
|
||||||
|
|
||||||
@@ -260,7 +274,9 @@ object
|
|
||||||
|
|
||||||
let disk_format =
|
|
||||||
match t.target_format with
|
|
||||||
- | ("raw" | "qcow2") as fmt -> fmt
|
|
||||||
+ | "raw" as fmt -> fmt
|
|
||||||
+ | "qcow2" ->
|
|
||||||
+ error_current_limitation "-of raw"
|
|
||||||
| _ ->
|
|
||||||
error (f_"rhv-upload: -of %s: Only output format ‘raw’ or ‘qcow2’ is supported. If the input is in a different format then force one of these output formats by adding either ‘-of raw’ or ‘-of qcow2’ on the command line.")
|
|
||||||
t.target_format in
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,514 @@
|
|||||||
|
From 1b29702cefae8a66c83bc84dd15e7b858af3ab47 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.25.4
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
From 1ddbe89dbc3877e6135e13413f97ee30a12c8e72 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
|
||||||
Date: Sun, 22 Apr 2018 22:57:55 +0200
|
|
||||||
Subject: [PATCH] v2v: -o rhv-upload: install RHV tools (RHBZ#1561828).
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
|
||||||
(cherry picked from commit f3f00d3f9c6464aa31e3091bdee1191ef15512c6)
|
|
||||||
---
|
|
||||||
v2v/output_rhv_upload.ml | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
|
||||||
index dc0d96d53..0152b8d5a 100644
|
|
||||||
--- a/v2v/output_rhv_upload.ml
|
|
||||||
+++ b/v2v/output_rhv_upload.ml
|
|
||||||
@@ -247,6 +247,9 @@ object
|
|
||||||
|
|
||||||
method supported_firmware = [ TargetBIOS ]
|
|
||||||
|
|
||||||
+ (* rhev-apt.exe will be installed (if available). *)
|
|
||||||
+ method install_rhev_apt = true
|
|
||||||
+
|
|
||||||
method prepare_targets source targets =
|
|
||||||
let output_name = source.s_name in
|
|
||||||
let json_params =
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
77
SOURCES/0016-OCaml-tools-fix-3999-3339-typo.patch
Normal file
77
SOURCES/0016-OCaml-tools-fix-3999-3339-typo.patch
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
From 1d4e167ebcf75771957f3ba109354a8217e78004 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.25.4
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
From c2570c81e8c3dffadbcfa5c857a38ae858745f9e Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Tue, 1 May 2018 11:30:11 +0100
|
|
||||||
Subject: [PATCH] v2v: Map Windows Server 2012 R2 x86-64 to ovirt ID 25.
|
|
||||||
|
|
||||||
Thanks: Michal Skrivanek
|
|
||||||
|
|
||||||
Fixes commit 593a19cc86cfa8f24c66518c8ba21222550b066a.
|
|
||||||
|
|
||||||
(cherry picked from commit c6e89299299f1f620437ac3d05a1f0f12de0f208)
|
|
||||||
---
|
|
||||||
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 b1ab8df3f..b3beb1eba 100644
|
|
||||||
--- a/v2v/create_ovf.ml
|
|
||||||
+++ b/v2v/create_ovf.ml
|
|
||||||
@@ -418,7 +418,7 @@ and get_ovirt_osid = function
|
|
||||||
|
|
||||||
| { i_type = "windows"; i_major_version = 6; i_minor_version = 3;
|
|
||||||
i_arch = "x86_64" } ->
|
|
||||||
- 23
|
|
||||||
+ 25
|
|
||||||
|
|
||||||
| { i_type = "windows"; i_major_version = 10; i_minor_version = 0;
|
|
||||||
i_arch = "i386" } ->
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
|||||||
From b31fcaf9879b9f4fe36a19e439895a867a1fbc72 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Tue, 22 May 2018 17:24:18 +0200
|
|
||||||
Subject: [PATCH] v2v: fix build rules for output_rhv_upload_*_source.ml files
|
|
||||||
|
|
||||||
Use the $(srcdir) variable where needed, to make sure it builds also
|
|
||||||
with srcdir != builddir.
|
|
||||||
|
|
||||||
Furthermore, make sure that the OCaml dependencies calculation depend on
|
|
||||||
the generated output_rhv_upload_*_source.ml files, otherwise there will
|
|
||||||
be incomplete OCaml rules for them in the generated .depend.
|
|
||||||
|
|
||||||
Fixes commit cc04573927cca97de60d544d37467e67c25867a7.
|
|
||||||
|
|
||||||
(cherry picked from commit a4e3b7c0598370d8d068b21909da95b6031eb688)
|
|
||||||
---
|
|
||||||
v2v/Makefile.am | 14 +++++++-------
|
|
||||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
|
|
||||||
index 3a0c80f44..7de050b06 100644
|
|
||||||
--- a/v2v/Makefile.am
|
|
||||||
+++ b/v2v/Makefile.am
|
|
||||||
@@ -143,12 +143,12 @@ SOURCES_C = \
|
|
||||||
|
|
||||||
# These files are generated and contain rhv-upload-*.py embedded as an
|
|
||||||
# OCaml string.
|
|
||||||
-output_rhv_upload_createvm_source.ml: rhv-upload-createvm.py
|
|
||||||
- ./embed.sh code $^ $@
|
|
||||||
-output_rhv_upload_plugin_source.ml: rhv-upload-plugin.py
|
|
||||||
- ./embed.sh code $^ $@
|
|
||||||
-output_rhv_upload_precheck_source.ml: rhv-upload-precheck.py
|
|
||||||
- ./embed.sh code $^ $@
|
|
||||||
+output_rhv_upload_createvm_source.ml: $(srcdir)/rhv-upload-createvm.py
|
|
||||||
+ $(srcdir)/embed.sh code $^ $@
|
|
||||||
+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 $^ $@
|
|
||||||
|
|
||||||
if HAVE_OCAML
|
|
||||||
|
|
||||||
@@ -575,7 +575,7 @@ v2v_unit_tests_LINK = \
|
|
||||||
$(v2v_unit_tests_THEOBJECTS) -o $@
|
|
||||||
|
|
||||||
# Dependencies.
|
|
||||||
-.depend: $(srcdir)/*.mli $(srcdir)/*.ml
|
|
||||||
+.depend: $(srcdir)/*.mli $(srcdir)/*.ml output_rhv_upload_createvm_source.ml output_rhv_upload_plugin_source.ml output_rhv_upload_precheck_source.ml
|
|
||||||
$(top_builddir)/ocaml-dep.sh $^
|
|
||||||
-include .depend
|
|
||||||
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From 18007f645332e6a7c039a6bdb690e0a55f9cd1c7 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.25.4
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
From bd2afb6e11b107aa7f158136ff6d4fb24732b2bf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Tue, 29 May 2018 06:49:23 +0200
|
|
||||||
Subject: [PATCH] v2v: fix "rhevexp" typo in documentation
|
|
||||||
|
|
||||||
Spotted by Ming Xie.
|
|
||||||
|
|
||||||
(cherry picked from commit c021ac5e64053052a392762aaff9c8ed73fc2082)
|
|
||||||
---
|
|
||||||
v2v/virt-v2v.pod | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
|
||||||
index 2d2f8cfd3..f012ea533 100644
|
|
||||||
--- a/v2v/virt-v2v.pod
|
|
||||||
+++ b/v2v/virt-v2v.pod
|
|
||||||
@@ -728,7 +728,7 @@ Currently there are two possible flavours:
|
|
||||||
|
|
||||||
=over 4
|
|
||||||
|
|
||||||
-=item rhevexp
|
|
||||||
+=item rhvexp
|
|
||||||
|
|
||||||
The OVF format used in RHV export storage domain.
|
|
||||||
|
|
||||||
@@ -738,7 +738,7 @@ The OVF format understood by oVirt REST API.
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
-For backward compatibility the default is I<rhevexp>, but this may change in
|
|
||||||
+For backward compatibility the default is I<rhvexp>, but this may change in
|
|
||||||
the future.
|
|
||||||
|
|
||||||
=item B<-op> file
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
From 06e5cfb90bc63f1d6c56821f0745c6fa8d3f8259 Mon Sep 17 00:00:00 2001
|
From d74842f209b5461692a2d283d622157862bdc230 Mon Sep 17 00:00:00 2001
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||||
Date: Thu, 25 Jul 2019 14:52:42 +0100
|
Date: Thu, 25 Jul 2019 14:52:42 +0100
|
||||||
Subject: [PATCH] v2v: -i vmx: Use scp -T option if available to unbreak scp
|
Subject: [PATCH] v2v: -i vmx: Use scp -T option if available to unbreak scp
|
||||||
@ -18,7 +18,7 @@ Thanks: Ming Xie, Jakub Jelen.
|
|||||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml
|
diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml
|
||||||
index f79e89139..695266313 100644
|
index b169b2537..e3469308d 100644
|
||||||
--- a/v2v/input_vmx.ml
|
--- a/v2v/input_vmx.ml
|
||||||
+++ b/v2v/input_vmx.ml
|
+++ b/v2v/input_vmx.ml
|
||||||
@@ -61,6 +61,11 @@ let server_of_uri { Xml.uri_server } =
|
@@ -61,6 +61,11 @@ let server_of_uri { Xml.uri_server } =
|
||||||
@ -45,5 +45,5 @@ index f79e89139..695266313 100644
|
|||||||
| None -> ""
|
| None -> ""
|
||||||
| Some port -> sprintf " -P %d" port)
|
| Some port -> sprintf " -P %d" port)
|
||||||
--
|
--
|
||||||
2.21.0
|
2.25.4
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
From 4b94dac532dc17cde462479bf90ab2631006b80b 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.25.4
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
From 973810a232b2f2a33425d28287e0ec77c483279a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Tue, 29 May 2018 07:04:50 +0200
|
|
||||||
Subject: [PATCH] v2v: add and use Create_ovf.ovf_flavour_to_string
|
|
||||||
|
|
||||||
Add an helper to convert an OVF flavour to string, and use it in
|
|
||||||
-o vdsm to print the actual value of the vdsm-ovf-flavour option.
|
|
||||||
|
|
||||||
Thanks to Ming Xie.
|
|
||||||
|
|
||||||
(cherry picked from commit c0da02f90d9b52413c24dd9dae61662ad033cc16)
|
|
||||||
---
|
|
||||||
v2v/create_ovf.ml | 4 ++++
|
|
||||||
v2v/create_ovf.mli | 3 +++
|
|
||||||
v2v/output_vdsm.ml | 5 +++--
|
|
||||||
3 files changed, 10 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
|
|
||||||
index b3beb1eba..9e0c772fd 100644
|
|
||||||
--- a/v2v/create_ovf.ml
|
|
||||||
+++ b/v2v/create_ovf.ml
|
|
||||||
@@ -40,6 +40,10 @@ let ovf_flavour_of_string = function
|
|
||||||
| "rhvexp" -> RHVExportStorageDomain
|
|
||||||
| flav -> invalid_arg flav
|
|
||||||
|
|
||||||
+let ovf_flavour_to_string = function
|
|
||||||
+ | OVirt -> "ovirt"
|
|
||||||
+ | RHVExportStorageDomain -> "rhvexp"
|
|
||||||
+
|
|
||||||
(* We set the creation time to be the same for all dates in
|
|
||||||
* all metadata files. All dates in OVF are UTC.
|
|
||||||
*)
|
|
||||||
diff --git a/v2v/create_ovf.mli b/v2v/create_ovf.mli
|
|
||||||
index 2d80660e3..8200b76f9 100644
|
|
||||||
--- a/v2v/create_ovf.mli
|
|
||||||
+++ b/v2v/create_ovf.mli
|
|
||||||
@@ -29,6 +29,9 @@ val ovf_flavours : string list
|
|
||||||
valid flavour. *)
|
|
||||||
val ovf_flavour_of_string : string -> ovf_flavour
|
|
||||||
|
|
||||||
+(** Convert an OVF flavour to its string representation. *)
|
|
||||||
+val ovf_flavour_to_string : ovf_flavour -> string
|
|
||||||
+
|
|
||||||
(** Create OVF and related files for RHV.
|
|
||||||
|
|
||||||
The format for RHV export storage domain is described in:
|
|
||||||
diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml
|
|
||||||
index 92b3fd122..9a1b748bc 100644
|
|
||||||
--- a/v2v/output_vdsm.ml
|
|
||||||
+++ b/v2v/output_vdsm.ml
|
|
||||||
@@ -118,9 +118,10 @@ object
|
|
||||||
| "0.10" -> "" (* currently this is the default, so don't print it *)
|
|
||||||
| s -> sprintf " -oo vdsm-compat=%s" s)
|
|
||||||
(match vdsm_options.ovf_flavour with
|
|
||||||
- | Create_ovf.OVirt -> "-oo vdsm-ovf-flavour=ovf"
|
|
||||||
(* currently this is the default, so don't print it *)
|
|
||||||
- | Create_ovf.RHVExportStorageDomain -> "")
|
|
||||||
+ | Create_ovf.RHVExportStorageDomain -> ""
|
|
||||||
+ | flav -> sprintf "-oo vdsm-ovf-flavour=%s"
|
|
||||||
+ (Create_ovf.ovf_flavour_to_string flav))
|
|
||||||
|
|
||||||
method supported_firmware = [ TargetBIOS ]
|
|
||||||
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
From 2eeada3ec57760f57d5da473f32b359c6b55c616 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.25.4
|
||||||
|
|
@ -1,42 +0,0 @@
|
|||||||
From e61cbd740b84eb78a1ffc52223e4f1cc3202c978 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Tue, 5 Jun 2018 19:09:43 +0100
|
|
||||||
Subject: [PATCH] v2v: -o rhv-upload: Set inactivity timeout (RHBZ#1586198).
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
This increases the inactivity timeout for transfers from the default
|
|
||||||
(60 seconds in oVirt < 4.2.3, 600 seconds in >= 4.2.3), up to 1 hour,
|
|
||||||
so that we should never hit it for ordinary transfers.
|
|
||||||
|
|
||||||
Note this requires oVirt >= 4.2.3. The corresponding oVirt fix was
|
|
||||||
https://bugzilla.redhat.com/1563278
|
|
||||||
|
|
||||||
I also replaced the deprecated ‘image’ parameter with ‘disk’.
|
|
||||||
|
|
||||||
Thanks: Nir Soffer, Daniel Erez.
|
|
||||||
(cherry picked from commit f25404c65f8e078a3ca5bd5a1ab91343edd22506)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 5 ++---
|
|
||||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index 791c9e7d2..b4557b83c 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -123,9 +123,8 @@ def open(readonly):
|
|
||||||
# Create a new image transfer.
|
|
||||||
transfer = transfers_service.add(
|
|
||||||
types.ImageTransfer(
|
|
||||||
- image = types.Image(
|
|
||||||
- id = disk.id
|
|
||||||
- )
|
|
||||||
+ disk = types.Disk(id = disk.id),
|
|
||||||
+ inactivity_timeout = 3600,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
debug("transfer.id = %r" % transfer.id)
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
|||||||
From 24aef5baa9725e26efd37fa78b83f98629d77eba Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Wed, 21 Feb 2018 17:33:28 +0100
|
|
||||||
Subject: [PATCH] New API: inspect_get_osinfo
|
|
||||||
|
|
||||||
Try to guess the possible osinfo-db short ID for the specified OS.
|
|
||||||
|
|
||||||
Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1544842
|
|
||||||
|
|
||||||
(cherry picked from commit 286b88891c2288fb7f64c9538296599ece04bcb1)
|
|
||||||
---
|
|
||||||
generator/actions_inspection.ml | 14 ++++++
|
|
||||||
lib/Makefile.am | 1 +
|
|
||||||
lib/inspect-osinfo.c | 75 +++++++++++++++++++++++++++++++++
|
|
||||||
3 files changed, 90 insertions(+)
|
|
||||||
create mode 100644 lib/inspect-osinfo.c
|
|
||||||
|
|
||||||
diff --git a/generator/actions_inspection.ml b/generator/actions_inspection.ml
|
|
||||||
index 0ac282435..ff5083114 100644
|
|
||||||
--- a/generator/actions_inspection.ml
|
|
||||||
+++ b/generator/actions_inspection.ml
|
|
||||||
@@ -770,4 +770,18 @@ advice before using trademarks in applications.
|
|
||||||
|
|
||||||
=back" };
|
|
||||||
|
|
||||||
+ { defaults with
|
|
||||||
+ name = "inspect_get_osinfo"; added = (1, 39, 1);
|
|
||||||
+ style = RString (RPlainString, "id"), [String (Mountable, "root")], [];
|
|
||||||
+ shortdesc = "get a possible osinfo short ID corresponding to this operating system";
|
|
||||||
+ longdesc = "\
|
|
||||||
+This function returns a possible short ID for libosinfo corresponding
|
|
||||||
+to the guest.
|
|
||||||
+
|
|
||||||
+I<Note:> The returned ID is only a guess by libguestfs, and nothing
|
|
||||||
+ensures that it actually exists in osinfo-db.
|
|
||||||
+
|
|
||||||
+If no ID could not be determined, then the string C<unknown> is
|
|
||||||
+returned." };
|
|
||||||
+
|
|
||||||
]
|
|
||||||
diff --git a/lib/Makefile.am b/lib/Makefile.am
|
|
||||||
index d075174d9..742b182cc 100644
|
|
||||||
--- a/lib/Makefile.am
|
|
||||||
+++ b/lib/Makefile.am
|
|
||||||
@@ -95,6 +95,7 @@ libguestfs_la_SOURCES = \
|
|
||||||
info.c \
|
|
||||||
inspect-apps.c \
|
|
||||||
inspect-icon.c \
|
|
||||||
+ inspect-osinfo.c \
|
|
||||||
journal.c \
|
|
||||||
launch.c \
|
|
||||||
launch-direct.c \
|
|
||||||
diff --git a/lib/inspect-osinfo.c b/lib/inspect-osinfo.c
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..816d317f1
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/lib/inspect-osinfo.c
|
|
||||||
@@ -0,0 +1,75 @@
|
|
||||||
+/* libguestfs
|
|
||||||
+ * Copyright (C) 2018 Red Hat Inc.
|
|
||||||
+ *
|
|
||||||
+ * This library is free software; you can redistribute it and/or
|
|
||||||
+ * modify it under the terms of the GNU Lesser General Public
|
|
||||||
+ * License as published by the Free Software Foundation; either
|
|
||||||
+ * version 2 of the License, or (at your option) any later version.
|
|
||||||
+ *
|
|
||||||
+ * This library 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
|
|
||||||
+ * Lesser General Public License for more details.
|
|
||||||
+ *
|
|
||||||
+ * You should have received a copy of the GNU Lesser General Public
|
|
||||||
+ * License along with this library; if not, write to the Free Software
|
|
||||||
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+#include <config.h>
|
|
||||||
+
|
|
||||||
+#include "guestfs.h"
|
|
||||||
+#include "guestfs-internal.h"
|
|
||||||
+#include "guestfs-internal-actions.h"
|
|
||||||
+
|
|
||||||
+char *
|
|
||||||
+guestfs_impl_inspect_get_osinfo (guestfs_h *g, const char *root)
|
|
||||||
+{
|
|
||||||
+ CLEANUP_FREE char *type = NULL;
|
|
||||||
+ CLEANUP_FREE char *distro = NULL;
|
|
||||||
+ int major, minor;
|
|
||||||
+
|
|
||||||
+ type = guestfs_inspect_get_type (g, root);
|
|
||||||
+ if (!type)
|
|
||||||
+ return NULL;
|
|
||||||
+ distro = guestfs_inspect_get_distro (g, root);
|
|
||||||
+ if (!distro)
|
|
||||||
+ return NULL;
|
|
||||||
+ major = guestfs_inspect_get_major_version (g, root);
|
|
||||||
+ minor = guestfs_inspect_get_minor_version (g, root);
|
|
||||||
+
|
|
||||||
+ if (STREQ (type, "linux")) {
|
|
||||||
+ if (STREQ (distro, "centos")) {
|
|
||||||
+ if (major >= 7)
|
|
||||||
+ return safe_asprintf (g, "%s%d.0", distro, major);
|
|
||||||
+ else if (major == 6)
|
|
||||||
+ return safe_asprintf (g, "%s%d.%d", distro, major, minor);
|
|
||||||
+ }
|
|
||||||
+ else if (STREQ (distro, "debian")) {
|
|
||||||
+ if (major >= 4)
|
|
||||||
+ return safe_asprintf (g, "%s%d", distro, major);
|
|
||||||
+ }
|
|
||||||
+ else if (STREQ (distro, "fedora") || STREQ (distro, "mageia"))
|
|
||||||
+ return safe_asprintf (g, "%s%d", distro, major);
|
|
||||||
+ else if (STREQ (distro, "sles")) {
|
|
||||||
+ if (minor == 0)
|
|
||||||
+ return safe_asprintf (g, "%s%d", distro, major);
|
|
||||||
+ else
|
|
||||||
+ return safe_asprintf (g, "%s%dsp%d", distro, major, minor);
|
|
||||||
+ }
|
|
||||||
+ else if (STREQ (distro, "ubuntu"))
|
|
||||||
+ return safe_asprintf (g, "%s%d.%02d", distro, major, minor);
|
|
||||||
+
|
|
||||||
+ if (major > 0 || minor > 0)
|
|
||||||
+ return safe_asprintf (g, "%s%d.%d", distro, major, minor);
|
|
||||||
+ }
|
|
||||||
+ else if (STREQ (type, "freebsd") || STREQ (type, "netbsd") || STREQ (type, "openbsd"))
|
|
||||||
+ return safe_asprintf (g, "%s%d.%d", distro, major, minor);
|
|
||||||
+ else if (STREQ (type, "dos")) {
|
|
||||||
+ if (STREQ (distro, "msdos"))
|
|
||||||
+ return safe_strdup (g, "msdos6.22");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* No ID could be guessed, return "unknown". */
|
|
||||||
+ return safe_strdup (g, "unknown");
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
From 41f3e803050b46fd79d8c2e728fc0425da05878c 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.25.4
|
||||||
|
|
@ -1,99 +0,0 @@
|
|||||||
From ee00f39eea1c97c5fcb9948b30586c9c106356d7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Wed, 21 Feb 2018 17:37:30 +0100
|
|
||||||
Subject: [PATCH] inspector: show the per-OS osinfo guess (RHBZ#1544842)
|
|
||||||
|
|
||||||
Output also the osinfo guess for each OS in the generated XML output;
|
|
||||||
adapt the RNG schema, and the test data to it.
|
|
||||||
|
|
||||||
(cherry picked from commit 2f8ec91fc1f3e81c8fb81d45849bc7462ee13642)
|
|
||||||
---
|
|
||||||
inspector/expected-coreos.img.xml | 1 +
|
|
||||||
inspector/expected-debian.img.xml | 1 +
|
|
||||||
inspector/expected-fedora.img.xml | 1 +
|
|
||||||
inspector/expected-ubuntu.img.xml | 1 +
|
|
||||||
inspector/inspector.c | 7 +++++++
|
|
||||||
inspector/virt-inspector.rng | 1 +
|
|
||||||
6 files changed, 12 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/inspector/expected-coreos.img.xml b/inspector/expected-coreos.img.xml
|
|
||||||
index e4a5d1134..0cdfba6e6 100644
|
|
||||||
--- a/inspector/expected-coreos.img.xml
|
|
||||||
+++ b/inspector/expected-coreos.img.xml
|
|
||||||
@@ -8,6 +8,7 @@
|
|
||||||
<major_version>899</major_version>
|
|
||||||
<minor_version>13</minor_version>
|
|
||||||
<hostname>coreos.invalid</hostname>
|
|
||||||
+ <osinfo>coreos899.13</osinfo>
|
|
||||||
<mountpoints>
|
|
||||||
<mountpoint dev="/dev/sda5">/</mountpoint>
|
|
||||||
<mountpoint dev="/dev/sda3">/usr</mountpoint>
|
|
||||||
diff --git a/inspector/expected-debian.img.xml b/inspector/expected-debian.img.xml
|
|
||||||
index 37ecfa049..6583dc262 100644
|
|
||||||
--- a/inspector/expected-debian.img.xml
|
|
||||||
+++ b/inspector/expected-debian.img.xml
|
|
||||||
@@ -11,6 +11,7 @@
|
|
||||||
<package_format>deb</package_format>
|
|
||||||
<package_management>apt</package_management>
|
|
||||||
<hostname>debian.invalid</hostname>
|
|
||||||
+ <osinfo>debian5</osinfo>
|
|
||||||
<mountpoints>
|
|
||||||
<mountpoint dev="/dev/debian/root">/</mountpoint>
|
|
||||||
<mountpoint dev="/dev/debian/usr">/usr</mountpoint>
|
|
||||||
diff --git a/inspector/expected-fedora.img.xml b/inspector/expected-fedora.img.xml
|
|
||||||
index 8d40e8cb7..df6060a73 100644
|
|
||||||
--- a/inspector/expected-fedora.img.xml
|
|
||||||
+++ b/inspector/expected-fedora.img.xml
|
|
||||||
@@ -11,6 +11,7 @@
|
|
||||||
<package_format>rpm</package_format>
|
|
||||||
<package_management>yum</package_management>
|
|
||||||
<hostname>fedora.invalid</hostname>
|
|
||||||
+ <osinfo>fedora14</osinfo>
|
|
||||||
<mountpoints>
|
|
||||||
<mountpoint dev="/dev/VG/Root">/</mountpoint>
|
|
||||||
<mountpoint dev="/dev/sda1">/boot</mountpoint>
|
|
||||||
diff --git a/inspector/expected-ubuntu.img.xml b/inspector/expected-ubuntu.img.xml
|
|
||||||
index c19c14cd5..4ebcd76d6 100644
|
|
||||||
--- a/inspector/expected-ubuntu.img.xml
|
|
||||||
+++ b/inspector/expected-ubuntu.img.xml
|
|
||||||
@@ -11,6 +11,7 @@
|
|
||||||
<package_format>deb</package_format>
|
|
||||||
<package_management>apt</package_management>
|
|
||||||
<hostname>ubuntu.invalid</hostname>
|
|
||||||
+ <osinfo>ubuntu10.10</osinfo>
|
|
||||||
<mountpoints>
|
|
||||||
<mountpoint dev="/dev/sda2">/</mountpoint>
|
|
||||||
<mountpoint dev="/dev/sda1">/boot</mountpoint>
|
|
||||||
diff --git a/inspector/inspector.c b/inspector/inspector.c
|
|
||||||
index d608b1b63..5075a8f04 100644
|
|
||||||
--- a/inspector/inspector.c
|
|
||||||
+++ b/inspector/inspector.c
|
|
||||||
@@ -443,6 +443,13 @@ output_root (xmlTextWriterPtr xo, char *root)
|
|
||||||
BAD_CAST str));
|
|
||||||
free (str);
|
|
||||||
|
|
||||||
+ str = guestfs_inspect_get_osinfo (g, root);
|
|
||||||
+ if (!str) exit (EXIT_FAILURE);
|
|
||||||
+ if (STRNEQ (str, "unknown"))
|
|
||||||
+ XMLERROR (-1,
|
|
||||||
+ xmlTextWriterWriteElement (xo, BAD_CAST "osinfo", BAD_CAST str));
|
|
||||||
+ free (str);
|
|
||||||
+
|
|
||||||
output_mountpoints (xo, root);
|
|
||||||
|
|
||||||
output_filesystems (xo, root);
|
|
||||||
diff --git a/inspector/virt-inspector.rng b/inspector/virt-inspector.rng
|
|
||||||
index 314785202..1e3a58af8 100644
|
|
||||||
--- a/inspector/virt-inspector.rng
|
|
||||||
+++ b/inspector/virt-inspector.rng
|
|
||||||
@@ -38,6 +38,7 @@
|
|
||||||
<optional><ref name="ospackageformat"/></optional>
|
|
||||||
<optional><ref name="ospackagemanagement"/></optional>
|
|
||||||
<optional><element name="hostname"><text/></element></optional>
|
|
||||||
+ <optional><element name="osinfo"><text/></element></optional>
|
|
||||||
|
|
||||||
<ref name="mountpoints"/>
|
|
||||||
<ref name="filesystems"/>
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
|||||||
|
From b37ca67f769749b7b3b5d51e171b7cccfa3b5fd2 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.25.4
|
||||||
|
|
@ -1,90 +0,0 @@
|
|||||||
From 5917bdc15f3b2e0c96ba5a9860cd36f968a28ec2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nir Soffer <nirsof@gmail.com>
|
|
||||||
Date: Thu, 14 Jun 2018 21:16:01 +0300
|
|
||||||
Subject: [PATCH] v2v: -o rhv-upload: Optimize http request sending
|
|
||||||
|
|
||||||
When sending request with small or no payload, it is simpler and
|
|
||||||
possibly more efficient to use the high level HTTPSConnection.request(),
|
|
||||||
instead of the lower level APIs.
|
|
||||||
|
|
||||||
The only reason to use the lower level APIs is to avoid copying the
|
|
||||||
payload, or on python 2, to use a bigger buffer size when streaming a
|
|
||||||
file-like object.
|
|
||||||
|
|
||||||
(cherry picked from commit 77a412c0a1cd0e303a072fc5088c8f3bfed36583)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 35 ++++++++++++++++-------------------
|
|
||||||
1 file changed, 16 insertions(+), 19 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index b4557b83c..9ad354b84 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -237,12 +237,12 @@ def pread(h, count, offset):
|
|
||||||
transfer = h['transfer']
|
|
||||||
transfer_service = h['transfer_service']
|
|
||||||
|
|
||||||
- http.putrequest("GET", h['path'])
|
|
||||||
+ headers = {"Range", "bytes=%d-%d" % (offset, offset+count-1)}
|
|
||||||
# Authorization is only needed for old imageio.
|
|
||||||
if h['needs_auth']:
|
|
||||||
- http.putheader("Authorization", transfer.signed_ticket)
|
|
||||||
- http.putheader("Range", "bytes=%d-%d" % (offset, offset+count-1))
|
|
||||||
- http.endheaders()
|
|
||||||
+ headers["Authorization"] = transfer.signed_ticket
|
|
||||||
+
|
|
||||||
+ http.request("GET", h['path'], headers=headers)
|
|
||||||
|
|
||||||
r = http.getresponse()
|
|
||||||
# 206 = HTTP Partial Content.
|
|
||||||
@@ -297,11 +297,10 @@ def zero(h, count, offset, may_trim):
|
|
||||||
'size': count,
|
|
||||||
'flush': False}).encode()
|
|
||||||
|
|
||||||
- http.putrequest("PATCH", h['path'])
|
|
||||||
- http.putheader("Content-Type", "application/json")
|
|
||||||
- http.putheader("Content-Length", len(buf))
|
|
||||||
- http.endheaders()
|
|
||||||
- http.send(buf)
|
|
||||||
+ headers = {"Content-Type": "application/json",
|
|
||||||
+ "Content-Length": str(len(buf))}
|
|
||||||
+
|
|
||||||
+ http.request("PATCH", h['path'], body=buf, headers=headers)
|
|
||||||
|
|
||||||
r = http.getresponse()
|
|
||||||
if r.status != 200:
|
|
||||||
@@ -349,11 +348,10 @@ def trim(h, count, offset):
|
|
||||||
'size': count,
|
|
||||||
'flush': False}).encode()
|
|
||||||
|
|
||||||
- http.putrequest("PATCH", h['path'])
|
|
||||||
- http.putheader("Content-Type", "application/json")
|
|
||||||
- http.putheader("Content-Length", len(buf))
|
|
||||||
- http.endheaders()
|
|
||||||
- http.send(buf)
|
|
||||||
+ headers = {"Content-Type": "application/json",
|
|
||||||
+ "Content-Length": str(len(buf))}
|
|
||||||
+
|
|
||||||
+ http.request("PATCH", h['path'], body=buf, headers=headers)
|
|
||||||
|
|
||||||
r = http.getresponse()
|
|
||||||
if r.status != 200:
|
|
||||||
@@ -370,11 +368,10 @@ def flush(h):
|
|
||||||
# Construct the JSON request for flushing.
|
|
||||||
buf = json.dumps({'op': "flush"}).encode()
|
|
||||||
|
|
||||||
- http.putrequest("PATCH", h['path'])
|
|
||||||
- http.putheader("Content-Type", "application/json")
|
|
||||||
- http.putheader("Content-Length", len(buf))
|
|
||||||
- http.endheaders()
|
|
||||||
- http.send(buf)
|
|
||||||
+ headers = {"Content-Type": "application/json",
|
|
||||||
+ "Content-Length": str(len(buf))}
|
|
||||||
+
|
|
||||||
+ http.request("PATCH", h['path'], body=buf, headers=headers)
|
|
||||||
|
|
||||||
r = http.getresponse()
|
|
||||||
if r.status != 200:
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,264 @@
|
|||||||
|
From ae560843517da393492418bb61c3dee43e64af2c 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.25.4
|
||||||
|
|
@ -1,153 +0,0 @@
|
|||||||
From c2ed35e2bc17bcacf333626b21cd6796d4d8d6cf Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Tue, 5 Jun 2018 13:27:43 +0100
|
|
||||||
Subject: [PATCH] v2v: -o rhv-upload: Log full imageio response on failure.
|
|
||||||
|
|
||||||
Thanks: Nir Soffer
|
|
||||||
(cherry picked from commit 831a75cd11c5a87e40fccdadcb62353f6a4d5a72)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 69 ++++++++++++++++++++++++----------------
|
|
||||||
1 file changed, 42 insertions(+), 27 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index 9ad354b84..7c5084efd 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -227,6 +227,32 @@ def can_flush(h):
|
|
||||||
def get_size(h):
|
|
||||||
return params['disk_size']
|
|
||||||
|
|
||||||
+# Any unexpected HTTP response status from the server will end up
|
|
||||||
+# calling this function which logs the full error, pauses the
|
|
||||||
+# transfer, sets the failed state, and raises a RuntimeError
|
|
||||||
+# exception.
|
|
||||||
+def request_failed(h, r, msg):
|
|
||||||
+ # Setting the failed flag in the handle causes the disk to be
|
|
||||||
+ # cleaned up on close.
|
|
||||||
+ h['failed'] = True
|
|
||||||
+ h['transfer_service'].pause()
|
|
||||||
+
|
|
||||||
+ status = r.status
|
|
||||||
+ reason = r.reason
|
|
||||||
+ try:
|
|
||||||
+ body = r.read()
|
|
||||||
+ except EnvironmentError as e:
|
|
||||||
+ body = "(Unable to read response body: %s)" % e
|
|
||||||
+
|
|
||||||
+ # Log the full error if we're verbose.
|
|
||||||
+ debug("unexpected response from imageio server:")
|
|
||||||
+ debug(msg)
|
|
||||||
+ debug("%d: %s" % (status, reason))
|
|
||||||
+ debug(body)
|
|
||||||
+
|
|
||||||
+ # Only a short error is included in the exception.
|
|
||||||
+ raise RuntimeError("%s: %d %s: %r", msg, status, reason, body[:200])
|
|
||||||
+
|
|
||||||
# For documentation see:
|
|
||||||
# https://github.com/oVirt/ovirt-imageio/blob/master/docs/random-io.md
|
|
||||||
# For examples of working code to read/write from the server, see:
|
|
||||||
@@ -247,16 +273,14 @@ def pread(h, count, offset):
|
|
||||||
r = http.getresponse()
|
|
||||||
# 206 = HTTP Partial Content.
|
|
||||||
if r.status != 206:
|
|
||||||
- h['transfer_service'].pause()
|
|
||||||
- h['failed'] = True
|
|
||||||
- raise RuntimeError("could not read sector (%d, %d): %d: %s" %
|
|
||||||
- (offset, count, r.status, r.reason))
|
|
||||||
+ request_failed(h, r,
|
|
||||||
+ "could not read sector offset %d size %d" %
|
|
||||||
+ (offset, count))
|
|
||||||
return r.read()
|
|
||||||
|
|
||||||
def pwrite(h, buf, offset):
|
|
||||||
http = h['http']
|
|
||||||
transfer = h['transfer']
|
|
||||||
- transfer_service = h['transfer_service']
|
|
||||||
|
|
||||||
count = len(buf)
|
|
||||||
h['highestwrite'] = max(h['highestwrite'], offset+count)
|
|
||||||
@@ -274,15 +298,13 @@ def pwrite(h, buf, offset):
|
|
||||||
|
|
||||||
r = http.getresponse()
|
|
||||||
if r.status != 200:
|
|
||||||
- transfer_service.pause()
|
|
||||||
- h['failed'] = True
|
|
||||||
- raise RuntimeError("could not write sector (%d, %d): %d: %s" %
|
|
||||||
- (offset, count, r.status, r.reason))
|
|
||||||
+ request_failed(h, r,
|
|
||||||
+ "could not write sector offset %d size %d" %
|
|
||||||
+ (offset, count))
|
|
||||||
|
|
||||||
def zero(h, count, offset, may_trim):
|
|
||||||
http = h['http']
|
|
||||||
transfer = h['transfer']
|
|
||||||
- transfer_service = h['transfer_service']
|
|
||||||
|
|
||||||
# Unlike the trim and flush calls, there is no 'can_zero' method
|
|
||||||
# so nbdkit could call this even if the server doesn't support
|
|
||||||
@@ -304,10 +326,9 @@ def zero(h, count, offset, may_trim):
|
|
||||||
|
|
||||||
r = http.getresponse()
|
|
||||||
if r.status != 200:
|
|
||||||
- transfer_service.pause()
|
|
||||||
- h['failed'] = True
|
|
||||||
- raise RuntimeError("could not zero sector (%d, %d): %d: %s" %
|
|
||||||
- (offset, count, r.status, r.reason))
|
|
||||||
+ request_failed(h, r,
|
|
||||||
+ "could not zero sector offset %d size %d" %
|
|
||||||
+ (offset, count))
|
|
||||||
|
|
||||||
def emulate_zero(h, count, offset):
|
|
||||||
# qemu-img convert starts by trying to zero/trim the whole device.
|
|
||||||
@@ -332,15 +353,13 @@ def emulate_zero(h, count, offset):
|
|
||||||
|
|
||||||
r = http.getresponse()
|
|
||||||
if r.status != 200:
|
|
||||||
- transfer_service.pause()
|
|
||||||
- h['failed'] = True
|
|
||||||
- raise RuntimeError("could not write zeroes (%d, %d): %d: %s" %
|
|
||||||
- (offset, count, r.status, r.reason))
|
|
||||||
+ request_failed(h, r,
|
|
||||||
+ "could not write zeroes offset %d size %d" %
|
|
||||||
+ (offset, count))
|
|
||||||
|
|
||||||
def trim(h, count, offset):
|
|
||||||
http = h['http']
|
|
||||||
transfer = h['transfer']
|
|
||||||
- transfer_service = h['transfer_service']
|
|
||||||
|
|
||||||
# Construct the JSON request for trimming.
|
|
||||||
buf = json.dumps({'op': "trim",
|
|
||||||
@@ -355,15 +374,13 @@ def trim(h, count, offset):
|
|
||||||
|
|
||||||
r = http.getresponse()
|
|
||||||
if r.status != 200:
|
|
||||||
- transfer_service.pause()
|
|
||||||
- h['failed'] = True
|
|
||||||
- raise RuntimeError("could not trim sector (%d, %d): %d: %s" %
|
|
||||||
- (offset, count, r.status, r.reason))
|
|
||||||
+ request_failed(h, r,
|
|
||||||
+ "could not trim sector offset %d size %d" %
|
|
||||||
+ (offset, count))
|
|
||||||
|
|
||||||
def flush(h):
|
|
||||||
http = h['http']
|
|
||||||
transfer = h['transfer']
|
|
||||||
- transfer_service = h['transfer_service']
|
|
||||||
|
|
||||||
# Construct the JSON request for flushing.
|
|
||||||
buf = json.dumps({'op': "flush"}).encode()
|
|
||||||
@@ -375,9 +392,7 @@ def flush(h):
|
|
||||||
|
|
||||||
r = http.getresponse()
|
|
||||||
if r.status != 200:
|
|
||||||
- transfer_service.pause()
|
|
||||||
- h['failed'] = True
|
|
||||||
- raise RuntimeError("could not flush: %d: %s" % (r.status, r.reason))
|
|
||||||
+ request_failed(h, r, "could not flush")
|
|
||||||
|
|
||||||
def delete_disk_on_failure(h):
|
|
||||||
disk_service = h['disk_service']
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
|||||||
|
From f0f00c5f0ea1a726dd2c8501bcc269211f30e2a8 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.25.4
|
||||||
|
|
@ -0,0 +1,169 @@
|
|||||||
|
From ccd327919ca1fed3e10fdd3567ede0dc8cd5d0c3 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.25.4
|
||||||
|
|
@ -1,112 +0,0 @@
|
|||||||
From 6cd873ff9a6ba6fed0534a253148b4daf48f0190 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nir Soffer <nirsof@gmail.com>
|
|
||||||
Date: Mon, 25 Jun 2018 19:22:13 +0300
|
|
||||||
Subject: [PATCH] v2v: rvh-upload-plugin: Always read the response
|
|
||||||
|
|
||||||
Python manual warns[1]:
|
|
||||||
|
|
||||||
Note that you must have read the whole response before you can send
|
|
||||||
a new request to the server.
|
|
||||||
|
|
||||||
The reason for this warning is exposed only when the server is using
|
|
||||||
keep alive connections. When the response is not read, sending a new
|
|
||||||
request will fail with:
|
|
||||||
|
|
||||||
httplib.ResponseNotReady
|
|
||||||
|
|
||||||
Even if Content-Length was 0 or the request has no content. The failure
|
|
||||||
looks like this when using --verbose:
|
|
||||||
|
|
||||||
nbdkit: python[1]: debug: zero count=33554432 offset=0 may_trim=1 fua=0
|
|
||||||
nbdkit: python[1]: debug: zero count=33554432 offset=33554432 may_trim=1 fua=0
|
|
||||||
nbdkit: python[1]: error: /home/nsoffer/src/libguestfs/tmp/rhvupload.Au2B5I/rhv-upload-plugin.py: zero: error: Request-sent
|
|
||||||
nbdkit: python[1]: debug: sending error reply: Input/output error
|
|
||||||
qemu-img: error writing zeroes at offset 0: Input/output error
|
|
||||||
|
|
||||||
Change all requests to read the whole response.
|
|
||||||
|
|
||||||
Tested with imageio patch supporting keep alive connections:
|
|
||||||
https://gerrit.ovirt.org/#/c/92296/
|
|
||||||
|
|
||||||
[1] https://docs.python.org/3.8/library/http.client.html#http.client.HTTPConnection.getresponse
|
|
||||||
|
|
||||||
(cherry picked from commit f4e0a8342dbeb2c779c76e1807a37b24a0c96feb)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 15 ++++++++++++++-
|
|
||||||
1 file changed, 14 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index 7c5084efd..2eec375f7 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -197,11 +197,13 @@ def get_options(h):
|
|
||||||
http.endheaders()
|
|
||||||
|
|
||||||
r = http.getresponse()
|
|
||||||
+ data = r.read()
|
|
||||||
+
|
|
||||||
if r.status == 200:
|
|
||||||
# New imageio never needs authentication.
|
|
||||||
h['needs_auth'] = False
|
|
||||||
|
|
||||||
- j = json.loads(r.read())
|
|
||||||
+ j = json.loads(data)
|
|
||||||
h['can_zero'] = "zero" in j['features']
|
|
||||||
h['can_trim'] = "trim" in j['features']
|
|
||||||
h['can_flush'] = "flush" in j['features']
|
|
||||||
@@ -276,6 +278,7 @@ def pread(h, count, offset):
|
|
||||||
request_failed(h, r,
|
|
||||||
"could not read sector offset %d size %d" %
|
|
||||||
(offset, count))
|
|
||||||
+
|
|
||||||
return r.read()
|
|
||||||
|
|
||||||
def pwrite(h, buf, offset):
|
|
||||||
@@ -302,6 +305,8 @@ def pwrite(h, buf, offset):
|
|
||||||
"could not write sector offset %d size %d" %
|
|
||||||
(offset, count))
|
|
||||||
|
|
||||||
+ r.read()
|
|
||||||
+
|
|
||||||
def zero(h, count, offset, may_trim):
|
|
||||||
http = h['http']
|
|
||||||
transfer = h['transfer']
|
|
||||||
@@ -330,6 +335,8 @@ def zero(h, count, offset, may_trim):
|
|
||||||
"could not zero sector offset %d size %d" %
|
|
||||||
(offset, count))
|
|
||||||
|
|
||||||
+ r.read()
|
|
||||||
+
|
|
||||||
def emulate_zero(h, count, offset):
|
|
||||||
# qemu-img convert starts by trying to zero/trim the whole device.
|
|
||||||
# Since we've just created a new disk it's safe to ignore these
|
|
||||||
@@ -357,6 +364,8 @@ def emulate_zero(h, count, offset):
|
|
||||||
"could not write zeroes offset %d size %d" %
|
|
||||||
(offset, count))
|
|
||||||
|
|
||||||
+ r.read()
|
|
||||||
+
|
|
||||||
def trim(h, count, offset):
|
|
||||||
http = h['http']
|
|
||||||
transfer = h['transfer']
|
|
||||||
@@ -378,6 +387,8 @@ def trim(h, count, offset):
|
|
||||||
"could not trim sector offset %d size %d" %
|
|
||||||
(offset, count))
|
|
||||||
|
|
||||||
+ r.read()
|
|
||||||
+
|
|
||||||
def flush(h):
|
|
||||||
http = h['http']
|
|
||||||
transfer = h['transfer']
|
|
||||||
@@ -394,6 +405,8 @@ def flush(h):
|
|
||||||
if r.status != 200:
|
|
||||||
request_failed(h, r, "could not flush")
|
|
||||||
|
|
||||||
+ r.read()
|
|
||||||
+
|
|
||||||
def delete_disk_on_failure(h):
|
|
||||||
disk_service = h['disk_service']
|
|
||||||
disk_service.remove()
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From 5883b1efc1c54742bed7f56f4b1522061321c8f9 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.25.4
|
||||||
|
|
@ -1,35 +0,0 @@
|
|||||||
From 47fd85a883892e2070a2287cc9411896645ab3bf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nir Soffer <nirsof@gmail.com>
|
|
||||||
Date: Mon, 25 Jun 2018 20:56:52 +0300
|
|
||||||
Subject: [PATCH] v2v: rhv-upload-plugin: Fix name error
|
|
||||||
|
|
||||||
"http" and "transfer" variables were missing in emulate_zero, so the
|
|
||||||
code would fail with NameError. This can happen only when communicating
|
|
||||||
with old imageio versions not supporting the "zero" feature.
|
|
||||||
|
|
||||||
Testing with qemu-img 2.12 show that we never send emulated zero request
|
|
||||||
because of the highestwrite mechanism, but it can break with older
|
|
||||||
qemu-img-rhev used on RHEL.
|
|
||||||
|
|
||||||
(cherry picked from commit 0ae61ce99c351f9cda598016fb55ccc50313df67)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index 2eec375f7..10887c031 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -338,6 +338,9 @@ def zero(h, count, offset, may_trim):
|
|
||||||
r.read()
|
|
||||||
|
|
||||||
def emulate_zero(h, count, offset):
|
|
||||||
+ http = h['http']
|
|
||||||
+ transfer = h['transfer']
|
|
||||||
+
|
|
||||||
# qemu-img convert starts by trying to zero/trim the whole device.
|
|
||||||
# Since we've just created a new disk it's safe to ignore these
|
|
||||||
# requests as long as they are smaller than the highest write seen.
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
76
SOURCES/0027-v2v-add-output-disk_copied-hook.patch
Normal file
76
SOURCES/0027-v2v-add-output-disk_copied-hook.patch
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
From 7baca2397e3e494fa727e63e9a2d34b81b78c298 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.25.4
|
||||||
|
|
@ -1,52 +0,0 @@
|
|||||||
From 6e683fa651864a04a1c4e2a326d84cfc9330d706 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nir Soffer <nirsof@gmail.com>
|
|
||||||
Date: Tue, 26 Jun 2018 01:43:01 +0300
|
|
||||||
Subject: [PATCH] v2v: rhv-upload-plugin: Remove unused variables
|
|
||||||
|
|
||||||
Remove some instances of "transfer" and "transfer_service" that are not
|
|
||||||
used in current code.
|
|
||||||
|
|
||||||
(cherry picked from commit 32ab53cecd78ee5c140f17e5792710698627d265)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 4 ----
|
|
||||||
1 file changed, 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index 10887c031..5c036c46a 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -263,7 +263,6 @@ def request_failed(h, r, msg):
|
|
||||||
def pread(h, count, offset):
|
|
||||||
http = h['http']
|
|
||||||
transfer = h['transfer']
|
|
||||||
- transfer_service = h['transfer_service']
|
|
||||||
|
|
||||||
headers = {"Range", "bytes=%d-%d" % (offset, offset+count-1)}
|
|
||||||
# Authorization is only needed for old imageio.
|
|
||||||
@@ -309,7 +308,6 @@ def pwrite(h, buf, offset):
|
|
||||||
|
|
||||||
def zero(h, count, offset, may_trim):
|
|
||||||
http = h['http']
|
|
||||||
- transfer = h['transfer']
|
|
||||||
|
|
||||||
# Unlike the trim and flush calls, there is no 'can_zero' method
|
|
||||||
# so nbdkit could call this even if the server doesn't support
|
|
||||||
@@ -371,7 +369,6 @@ def emulate_zero(h, count, offset):
|
|
||||||
|
|
||||||
def trim(h, count, offset):
|
|
||||||
http = h['http']
|
|
||||||
- transfer = h['transfer']
|
|
||||||
|
|
||||||
# Construct the JSON request for trimming.
|
|
||||||
buf = json.dumps({'op': "trim",
|
|
||||||
@@ -394,7 +391,6 @@ def trim(h, count, offset):
|
|
||||||
|
|
||||||
def flush(h):
|
|
||||||
http = h['http']
|
|
||||||
- transfer = h['transfer']
|
|
||||||
|
|
||||||
# Construct the JSON request for flushing.
|
|
||||||
buf = json.dumps({'op': "flush"}).encode()
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
|||||||
From 1d2058c08b9eff607127d199b574273100e9ba55 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Tue, 19 Jun 2018 18:02:21 +0100
|
|
||||||
Subject: [PATCH] v2v: -o rhv-upload: Always fetch server options when opening
|
|
||||||
the connection.
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Previously we lazily requested the server options in the can_*
|
|
||||||
callbacks. The can_* callbacks are always called by nbdkit straight
|
|
||||||
after open, so this just adds complexity for no benefit. This change
|
|
||||||
simply makes the code always fetch the server options during the open
|
|
||||||
callback.
|
|
||||||
|
|
||||||
This is — functionally at least — mostly just refactoring. However I
|
|
||||||
also added a useful debug message so we can see what features the
|
|
||||||
imageio server is offering.
|
|
||||||
|
|
||||||
(cherry picked from commit a1e1f6ec887c2a7973612d2edf7066fd3194ba0b)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 63 +++++++++++++++++++---------------------
|
|
||||||
1 file changed, 30 insertions(+), 33 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index 5c036c46a..f215eaecf 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -165,34 +165,13 @@ def open(readonly):
|
|
||||||
context = context
|
|
||||||
)
|
|
||||||
|
|
||||||
- # Save everything we need to make requests in the handle.
|
|
||||||
- return {
|
|
||||||
- 'can_flush': False,
|
|
||||||
- 'can_trim': False,
|
|
||||||
- 'can_zero': False,
|
|
||||||
- 'connection': connection,
|
|
||||||
- 'disk': disk,
|
|
||||||
- 'disk_service': disk_service,
|
|
||||||
- 'failed': False,
|
|
||||||
- 'got_options': False,
|
|
||||||
- 'highestwrite': 0,
|
|
||||||
- 'http': http,
|
|
||||||
- 'needs_auth': not params['rhv_direct'],
|
|
||||||
- 'path': destination_url.path,
|
|
||||||
- 'transfer': transfer,
|
|
||||||
- 'transfer_service': transfer_service,
|
|
||||||
- }
|
|
||||||
+ # The first request is to fetch the features of the server.
|
|
||||||
+ needs_auth = not params['rhv_direct']
|
|
||||||
+ can_flush = False
|
|
||||||
+ can_trim = False
|
|
||||||
+ can_zero = False
|
|
||||||
|
|
||||||
-# Can we issue zero, trim or flush requests?
|
|
||||||
-def get_options(h):
|
|
||||||
- if h['got_options']:
|
|
||||||
- return
|
|
||||||
- h['got_options'] = True
|
|
||||||
-
|
|
||||||
- http = h['http']
|
|
||||||
- transfer = h['transfer']
|
|
||||||
-
|
|
||||||
- http.putrequest("OPTIONS", h['path'])
|
|
||||||
+ http.putrequest("OPTIONS", destination_url.path)
|
|
||||||
http.putheader("Authorization", transfer.signed_ticket)
|
|
||||||
http.endheaders()
|
|
||||||
|
|
||||||
@@ -201,12 +180,12 @@ def get_options(h):
|
|
||||||
|
|
||||||
if r.status == 200:
|
|
||||||
# New imageio never needs authentication.
|
|
||||||
- h['needs_auth'] = False
|
|
||||||
+ needs_auth = False
|
|
||||||
|
|
||||||
j = json.loads(data)
|
|
||||||
- h['can_zero'] = "zero" in j['features']
|
|
||||||
- h['can_trim'] = "trim" in j['features']
|
|
||||||
- h['can_flush'] = "flush" in j['features']
|
|
||||||
+ can_flush = "flush" in j['features']
|
|
||||||
+ can_trim = "trim" in j['features']
|
|
||||||
+ can_zero = "zero" in j['features']
|
|
||||||
|
|
||||||
# Old imageio servers returned either 405 Method Not Allowed or
|
|
||||||
# 204 No Content (with an empty body). If we see that we leave
|
|
||||||
@@ -218,12 +197,30 @@ def get_options(h):
|
|
||||||
raise RuntimeError("could not use OPTIONS request: %d: %s" %
|
|
||||||
(r.status, r.reason))
|
|
||||||
|
|
||||||
+ debug("imageio features: flush=%r trim=%r zero=%r" %
|
|
||||||
+ (can_flush, can_trim, can_zero))
|
|
||||||
+
|
|
||||||
+ # Save everything we need to make requests in the handle.
|
|
||||||
+ return {
|
|
||||||
+ 'can_flush': can_flush,
|
|
||||||
+ 'can_trim': can_trim,
|
|
||||||
+ 'can_zero': can_zero,
|
|
||||||
+ 'connection': connection,
|
|
||||||
+ 'disk': disk,
|
|
||||||
+ 'disk_service': disk_service,
|
|
||||||
+ 'failed': False,
|
|
||||||
+ 'highestwrite': 0,
|
|
||||||
+ 'http': http,
|
|
||||||
+ 'needs_auth': needs_auth,
|
|
||||||
+ 'path': destination_url.path,
|
|
||||||
+ 'transfer': transfer,
|
|
||||||
+ 'transfer_service': transfer_service,
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
def can_trim(h):
|
|
||||||
- get_options(h)
|
|
||||||
return h['can_trim']
|
|
||||||
|
|
||||||
def can_flush(h):
|
|
||||||
- get_options(h)
|
|
||||||
return h['can_flush']
|
|
||||||
|
|
||||||
def get_size(h):
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,84 @@
|
|||||||
|
From 9ae4cc6feaf66cf34b9cdf0cf2c251ed7ef61259 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.25.4
|
||||||
|
|
@ -1,141 +0,0 @@
|
|||||||
From db7e06935bfd20e02110549371a5174e68a45cf0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Mon, 18 Jun 2018 15:34:37 +0100
|
|
||||||
Subject: [PATCH] v2v: -o rhv-upload: Use Unix domain socket to access imageio
|
|
||||||
(RHBZ#1588088).
|
|
||||||
|
|
||||||
In the case where virt-v2v runs on the same server as the imageio
|
|
||||||
daemon that we are talking to, it may be possible to optimize access
|
|
||||||
using a Unix domain socket.
|
|
||||||
|
|
||||||
This is only an optimization. If it fails or if we're not running on
|
|
||||||
the same server it will fall back to the usual HTTPS over TCP
|
|
||||||
connection.
|
|
||||||
|
|
||||||
Thanks: Nir Soffer, Daniel Erez.
|
|
||||||
(cherry picked from commit b7a2e6270d53200d2df471c36a1fb2b46db8bbac)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 61 ++++++++++++++++++++++++++++++++++++++--
|
|
||||||
1 file changed, 58 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index f215eaecf..8805e3552 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -19,11 +19,12 @@
|
|
||||||
import builtins
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
+import socket
|
|
||||||
import ssl
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
-from http.client import HTTPSConnection
|
|
||||||
+from http.client import HTTPSConnection, HTTPConnection
|
|
||||||
from urllib.parse import urlparse
|
|
||||||
|
|
||||||
import ovirtsdk4 as sdk
|
|
||||||
@@ -56,6 +57,28 @@ def debug(s):
|
|
||||||
print(s, file=sys.stderr)
|
|
||||||
sys.stderr.flush()
|
|
||||||
|
|
||||||
+def find_host(connection):
|
|
||||||
+ """Return the current host object or None."""
|
|
||||||
+ try:
|
|
||||||
+ with builtins.open("/etc/vdsm/vdsm.id") as f:
|
|
||||||
+ vdsm_id = f.readline().strip()
|
|
||||||
+ except Exception as e:
|
|
||||||
+ return None
|
|
||||||
+ debug("hw_id = %r" % vdsm_id)
|
|
||||||
+
|
|
||||||
+ hosts_service = connection.system_service().hosts_service()
|
|
||||||
+ hosts = hosts_service.list(
|
|
||||||
+ search="hw_id=%s" % vdsm_id,
|
|
||||||
+ case_sensitive=False,
|
|
||||||
+ )
|
|
||||||
+ if len(hosts) == 0:
|
|
||||||
+ return None
|
|
||||||
+
|
|
||||||
+ host = hosts[0]
|
|
||||||
+ debug("host.id = %r" % host.id)
|
|
||||||
+
|
|
||||||
+ return types.Host(id = host.id)
|
|
||||||
+
|
|
||||||
def open(readonly):
|
|
||||||
# Parse out the username from the output_conn URL.
|
|
||||||
parsed = urlparse(params['output_conn'])
|
|
||||||
@@ -121,9 +144,11 @@ def open(readonly):
|
|
||||||
transfers_service = system_service.image_transfers_service()
|
|
||||||
|
|
||||||
# Create a new image transfer.
|
|
||||||
+ host = find_host(connection)
|
|
||||||
transfer = transfers_service.add(
|
|
||||||
types.ImageTransfer(
|
|
||||||
disk = types.Disk(id = disk.id),
|
|
||||||
+ host = host,
|
|
||||||
inactivity_timeout = 3600,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
@@ -170,6 +195,7 @@ def open(readonly):
|
|
||||||
can_flush = False
|
|
||||||
can_trim = False
|
|
||||||
can_zero = False
|
|
||||||
+ unix_socket = None
|
|
||||||
|
|
||||||
http.putrequest("OPTIONS", destination_url.path)
|
|
||||||
http.putheader("Authorization", transfer.signed_ticket)
|
|
||||||
@@ -186,6 +212,7 @@ def open(readonly):
|
|
||||||
can_flush = "flush" in j['features']
|
|
||||||
can_trim = "trim" in j['features']
|
|
||||||
can_zero = "zero" in j['features']
|
|
||||||
+ unix_socket = j.get('unix_socket')
|
|
||||||
|
|
||||||
# Old imageio servers returned either 405 Method Not Allowed or
|
|
||||||
# 204 No Content (with an empty body). If we see that we leave
|
|
||||||
@@ -197,8 +224,17 @@ def open(readonly):
|
|
||||||
raise RuntimeError("could not use OPTIONS request: %d: %s" %
|
|
||||||
(r.status, r.reason))
|
|
||||||
|
|
||||||
- debug("imageio features: flush=%r trim=%r zero=%r" %
|
|
||||||
- (can_flush, can_trim, can_zero))
|
|
||||||
+ debug("imageio features: flush=%r trim=%r zero=%r unix_socket=%r" %
|
|
||||||
+ (can_flush, can_trim, can_zero, unix_socket))
|
|
||||||
+
|
|
||||||
+ # If we are connected to imageio on the local host and the
|
|
||||||
+ # transfer features a unix_socket then we can reconnect to that.
|
|
||||||
+ if host is not None and unix_socket is not None:
|
|
||||||
+ try:
|
|
||||||
+ http = UnixHTTPConnection(unix_socket)
|
|
||||||
+ debug("optimizing connection using unix socket %r" % unix_socket)
|
|
||||||
+ except:
|
|
||||||
+ pass
|
|
||||||
|
|
||||||
# Save everything we need to make requests in the handle.
|
|
||||||
return {
|
|
||||||
@@ -463,3 +499,22 @@ def close(h):
|
|
||||||
raise
|
|
||||||
|
|
||||||
connection.close()
|
|
||||||
+
|
|
||||||
+# Modify http.client.HTTPConnection to work over a Unix domain socket.
|
|
||||||
+# Derived from uhttplib written by Erik van Zijst under an MIT license.
|
|
||||||
+# (https://pypi.org/project/uhttplib/)
|
|
||||||
+# Ported to Python 3 by Irit Goihman.
|
|
||||||
+
|
|
||||||
+class UnsupportedError(Exception):
|
|
||||||
+ pass
|
|
||||||
+
|
|
||||||
+class UnixHTTPConnection(HTTPConnection):
|
|
||||||
+ def __init__(self, path, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
|
|
||||||
+ self.path = path
|
|
||||||
+ HTTPConnection.__init__(self, "localhost", timeout=timeout)
|
|
||||||
+
|
|
||||||
+ def connect(self):
|
|
||||||
+ self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
||||||
+ if self.timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
|
|
||||||
+ self.sock.settimeout(timeout)
|
|
||||||
+ self.sock.connect(self.path)
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
201
SOURCES/0029-v2v-o-rhv-upload-add-oo-rhv-disk-uuid-option.patch
Normal file
201
SOURCES/0029-v2v-o-rhv-upload-add-oo-rhv-disk-uuid-option.patch
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
From 9d7503382f33a7721378ec586ea718c63a0ec3b6 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.25.4
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
From da504873e18fc1414d670f318c10d5fb512e05dd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Fri, 29 Jun 2018 12:58:33 +0200
|
|
||||||
Subject: [PATCH] v2v: improve -os documentation for rhv-upload
|
|
||||||
|
|
||||||
Thanks to: Ming Xie
|
|
||||||
|
|
||||||
(cherry picked from commit 8d33ff8ba415180dee8f1f91f3b4d16d72ec094e)
|
|
||||||
---
|
|
||||||
v2v/virt-v2v.pod | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
|
||||||
index f012ea533..893e47fb9 100644
|
|
||||||
--- a/v2v/virt-v2v.pod
|
|
||||||
+++ b/v2v/virt-v2v.pod
|
|
||||||
@@ -758,6 +758,9 @@ For I<-o libvirt>, this is a libvirt directory pool
|
|
||||||
For 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.
|
|
||||||
+
|
|
||||||
For I<-o rhv>, this can be an NFS path of the Export Storage Domain
|
|
||||||
of the form C<E<lt>hostE<gt>:E<lt>pathE<gt>>, eg:
|
|
||||||
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
|||||||
|
From 5ad1e7c160f5fe0d499d8d25116cb0e1692f1e93 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.25.4
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
From 1b409cee748cfb60cc87f8bfa80370048d8dd014 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.25.4
|
||||||
|
|
@ -1,69 +0,0 @@
|
|||||||
From a3e99c84e1aed2fc275be00292f86414c8d4432a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nir Soffer <nirsof@gmail.com>
|
|
||||||
Date: Fri, 29 Jun 2018 17:41:10 +0300
|
|
||||||
Subject: [PATCH] v2v: rhv-upload-plugin: Remove unneeded auth
|
|
||||||
|
|
||||||
Old imageio proxy was using Authorization header for GET and PUT
|
|
||||||
requests. Remove unneeded authorization when sending OPTIONS request.
|
|
||||||
|
|
||||||
Remove unneeded duplicated comments about authorization for old
|
|
||||||
imageio, and replace them with a comment when we set needs_auth.
|
|
||||||
|
|
||||||
(cherry picked from commit d5f36bacf9bb6d4d244184551792989906f60896)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 12 +++++-------
|
|
||||||
1 file changed, 5 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index 8805e3552..f404bd758 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -191,16 +191,17 @@ def open(readonly):
|
|
||||||
)
|
|
||||||
|
|
||||||
# The first request is to fetch the features of the server.
|
|
||||||
+
|
|
||||||
+ # Authentication was needed only for GET and PUT requests when
|
|
||||||
+ # communicating with old imageio-proxy.
|
|
||||||
needs_auth = not params['rhv_direct']
|
|
||||||
+
|
|
||||||
can_flush = False
|
|
||||||
can_trim = False
|
|
||||||
can_zero = False
|
|
||||||
unix_socket = None
|
|
||||||
|
|
||||||
- http.putrequest("OPTIONS", destination_url.path)
|
|
||||||
- http.putheader("Authorization", transfer.signed_ticket)
|
|
||||||
- http.endheaders()
|
|
||||||
-
|
|
||||||
+ http.request("OPTIONS", destination_url.path)
|
|
||||||
r = http.getresponse()
|
|
||||||
data = r.read()
|
|
||||||
|
|
||||||
@@ -298,7 +299,6 @@ def pread(h, count, offset):
|
|
||||||
transfer = h['transfer']
|
|
||||||
|
|
||||||
headers = {"Range", "bytes=%d-%d" % (offset, offset+count-1)}
|
|
||||||
- # Authorization is only needed for old imageio.
|
|
||||||
if h['needs_auth']:
|
|
||||||
headers["Authorization"] = transfer.signed_ticket
|
|
||||||
|
|
||||||
@@ -321,7 +321,6 @@ def pwrite(h, buf, offset):
|
|
||||||
h['highestwrite'] = max(h['highestwrite'], offset+count)
|
|
||||||
|
|
||||||
http.putrequest("PUT", h['path'] + "?flush=n")
|
|
||||||
- # Authorization is only needed for old imageio.
|
|
||||||
if h['needs_auth']:
|
|
||||||
http.putheader("Authorization", transfer.signed_ticket)
|
|
||||||
# The oVirt server only uses the first part of the range, and the
|
|
||||||
@@ -378,7 +377,6 @@ def emulate_zero(h, count, offset):
|
|
||||||
# After that we must emulate them with writes.
|
|
||||||
if offset+count < h['highestwrite']:
|
|
||||||
http.putrequest("PUT", h['path'])
|
|
||||||
- # Authorization is only needed for old imageio.
|
|
||||||
if h['needs_auth']:
|
|
||||||
http.putheader("Authorization", transfer.signed_ticket)
|
|
||||||
http.putheader("Content-Range",
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
|||||||
From 8aaf7d89ef8b686840d3683fb27c4746624088a5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nir Soffer <nirsof@gmail.com>
|
|
||||||
Date: Sat, 30 Jun 2018 01:21:50 +0300
|
|
||||||
Subject: [PATCH] v2v: rhv-upload-plugin: Improve error handling
|
|
||||||
|
|
||||||
When optimizing the connection using unix socket, we handle these cases:
|
|
||||||
|
|
||||||
- The local host is not an oVirt host (no /etc/vdsm/vdsm.id).
|
|
||||||
- The local host is an oVirt host, but is not registered with engine.
|
|
||||||
- Creating UnixHTTPConnection() fails. Unlikely and probably a bug in
|
|
||||||
the plugin, but we can recover by using the https connection.
|
|
||||||
|
|
||||||
The current code handle these cases silently, making it harder to
|
|
||||||
understand why the unix socket optimization did no happen. Add debug
|
|
||||||
message to make this clear.
|
|
||||||
|
|
||||||
Also comment in the error handler why we take this path instead of
|
|
||||||
failing the operation.
|
|
||||||
|
|
||||||
(cherry picked from commit f5442d2f044b398efc992fb4d56c8d3096c781e6)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 12 ++++++++++--
|
|
||||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index f404bd758..8e4052048 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -63,7 +63,10 @@ def find_host(connection):
|
|
||||||
with builtins.open("/etc/vdsm/vdsm.id") as f:
|
|
||||||
vdsm_id = f.readline().strip()
|
|
||||||
except Exception as e:
|
|
||||||
+ # This is most likely not an oVirt host.
|
|
||||||
+ debug("cannot read /etc/vdsm/vdsm.id, using any host: %s" % e)
|
|
||||||
return None
|
|
||||||
+
|
|
||||||
debug("hw_id = %r" % vdsm_id)
|
|
||||||
|
|
||||||
hosts_service = connection.system_service().hosts_service()
|
|
||||||
@@ -72,6 +75,8 @@ def find_host(connection):
|
|
||||||
case_sensitive=False,
|
|
||||||
)
|
|
||||||
if len(hosts) == 0:
|
|
||||||
+ # This oVirt host is not registered with engine.
|
|
||||||
+ debug("cannot find host with hw_id=%r, using any host" % vdsm_id)
|
|
||||||
return None
|
|
||||||
|
|
||||||
host = hosts[0]
|
|
||||||
@@ -233,9 +238,12 @@ def open(readonly):
|
|
||||||
if host is not None and unix_socket is not None:
|
|
||||||
try:
|
|
||||||
http = UnixHTTPConnection(unix_socket)
|
|
||||||
+ except Exception as e:
|
|
||||||
+ # Very unlikely failure, but we can recover by using the https
|
|
||||||
+ # connection.
|
|
||||||
+ debug("cannot create unix socket connection, using https: %s" % e)
|
|
||||||
+ else:
|
|
||||||
debug("optimizing connection using unix socket %r" % unix_socket)
|
|
||||||
- except:
|
|
||||||
- pass
|
|
||||||
|
|
||||||
# Save everything we need to make requests in the handle.
|
|
||||||
return {
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
|||||||
|
From bb09f8b1ab0fc3bda654e7d564d5010f9f24f660 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.25.4
|
||||||
|
|
@ -0,0 +1,423 @@
|
|||||||
|
From 70e2215cd1f660dbad5a336bb611ad1b9cf1e60d 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.25.4
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
From 7b5ec5a6478276cec587c7d6a64b9a1ab26447b2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Nir Soffer <nirsof@gmail.com>
|
|
||||||
Date: Sat, 30 Jun 2018 01:39:03 +0300
|
|
||||||
Subject: [PATCH] v2v: rhv-upload-plugin: Optimize only direct upload
|
|
||||||
|
|
||||||
The optimization to start the transfer on the local host makes sense
|
|
||||||
only when using the rhv-direct=true option. When using a proxy, let the
|
|
||||||
engine choose a host.
|
|
||||||
|
|
||||||
(cherry picked from commit 891b5a0ec0f320acec0f06b64159eaf3dfbbfeaf)
|
|
||||||
---
|
|
||||||
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 8e4052048..da309e288 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -148,8 +148,8 @@ def open(readonly):
|
|
||||||
# Get a reference to the transfer service.
|
|
||||||
transfers_service = system_service.image_transfers_service()
|
|
||||||
|
|
||||||
- # Create a new image transfer.
|
|
||||||
- host = find_host(connection)
|
|
||||||
+ # Create a new image transfer, using the local host is possible.
|
|
||||||
+ host = find_host(connection) if params['rhv_direct'] else None
|
|
||||||
transfer = transfers_service.add(
|
|
||||||
types.ImageTransfer(
|
|
||||||
disk = types.Disk(id = disk.id),
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
87
SOURCES/0034-New-API-luks_uuid.patch
Normal file
87
SOURCES/0034-New-API-luks_uuid.patch
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
From bcd376966fedca02a52ad61405e84de931a89899 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.25.4
|
||||||
|
|
@ -1,61 +0,0 @@
|
|||||||
From e1401de974b6ac6d3e6e94e774f24a9b74f806f2 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Erez <derez@redhat.com>
|
|
||||||
Date: Thu, 5 Jul 2018 20:23:35 +0300
|
|
||||||
Subject: [PATCH] v2v: rhv plugin - find suitable host (RHBZ#1596810)
|
|
||||||
(RHBZ#1596851)
|
|
||||||
|
|
||||||
For direct upload, a suitable host must be in status 'Up'
|
|
||||||
and belong to the same datacenter as the created disk.
|
|
||||||
Added these criteria to the host search query.
|
|
||||||
|
|
||||||
(cherry picked from commit 4ed1bc5a79a77ad3a620b339f9ac2ecc8df6fd03)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-plugin.py | 28 ++++++++++++++++++++++++----
|
|
||||||
1 file changed, 24 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
|
||||||
index da309e288..931fcfaa2 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -69,14 +69,34 @@ def find_host(connection):
|
|
||||||
|
|
||||||
debug("hw_id = %r" % vdsm_id)
|
|
||||||
|
|
||||||
- hosts_service = connection.system_service().hosts_service()
|
|
||||||
+ system_service = connection.system_service()
|
|
||||||
+ storage_name = params['output_storage']
|
|
||||||
+ data_centers = system_service.data_centers_service().list(
|
|
||||||
+ search='storage=%s' % storage_name,
|
|
||||||
+ case_sensitive=False,
|
|
||||||
+ )
|
|
||||||
+ if len(data_centers) == 0:
|
|
||||||
+ # The storage domain is not attached to a datacenter
|
|
||||||
+ # (shouldn't happen, would fail on disk creation).
|
|
||||||
+ debug("storange domain (%s) is not attached to a DC" % storage_name)
|
|
||||||
+ return None
|
|
||||||
+
|
|
||||||
+ datacenter = data_centers[0]
|
|
||||||
+ debug("datacenter = %s" % datacenter.name)
|
|
||||||
+
|
|
||||||
+ hosts_service = system_service.hosts_service()
|
|
||||||
hosts = hosts_service.list(
|
|
||||||
- search="hw_id=%s" % vdsm_id,
|
|
||||||
+ search="hw_id=%s and datacenter=%s and status=Up" % (vdsm_id, datacenter.name),
|
|
||||||
case_sensitive=False,
|
|
||||||
)
|
|
||||||
if len(hosts) == 0:
|
|
||||||
- # This oVirt host is not registered with engine.
|
|
||||||
- debug("cannot find host with hw_id=%r, using any host" % vdsm_id)
|
|
||||||
+ # Couldn't find a host that's fulfilling the following criteria:
|
|
||||||
+ # - 'hw_id' equals to 'vdsm_id'
|
|
||||||
+ # - Its status is 'Up'
|
|
||||||
+ # - Belongs to the storage domain's datacenter
|
|
||||||
+ debug("cannot find a running host with hw_id=%r, " \
|
|
||||||
+ "that belongs to datacenter '%s', " \
|
|
||||||
+ "using any host" % (vdsm_id, datacenter.name))
|
|
||||||
return None
|
|
||||||
|
|
||||||
host = hosts[0]
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
From 7f12a3ddad2b735dc6d06b7b3ef67aacc57defe2 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.25.4
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
From 77604b91ec01ddd7961e69b70727b8e8c6e4c50b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Fri, 13 Jul 2018 13:24:07 +0200
|
|
||||||
Subject: [PATCH] v2v: change QXL ResourceType in OVirt flavour (RHBZ#1598715)
|
|
||||||
|
|
||||||
Due to a conflict with the IDs of the OVF standard, and the existing
|
|
||||||
implementation in ovirt-engine, the ID of QXL devices changed to a
|
|
||||||
different value.
|
|
||||||
|
|
||||||
As a consequence, change the ResourceType of QXL devices, but only in
|
|
||||||
OVirt flavour to avoid breaking vdsm mode.
|
|
||||||
|
|
||||||
See: https://bugzilla.redhat.com/show_bug.cgi?id=1598715#c5
|
|
||||||
(cherry picked from commit aa9e18f6d1fd503822dfd2124b92a2c67704c4c1)
|
|
||||||
---
|
|
||||||
v2v/create_ovf.ml | 6 +++++-
|
|
||||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
|
|
||||||
index 9e0c772fd..5db239d66 100644
|
|
||||||
--- a/v2v/create_ovf.ml
|
|
||||||
+++ b/v2v/create_ovf.ml
|
|
||||||
@@ -643,10 +643,14 @@ let rec create_ovf source targets guestcaps inspect
|
|
||||||
* See RHBZ#1213701 and RHBZ#1211231 for the reasoning
|
|
||||||
* behind that.
|
|
||||||
*)
|
|
||||||
+ let qxl_resourcetype =
|
|
||||||
+ match ovf_flavour with
|
|
||||||
+ | OVirt -> 32768 (* RHBZ#1598715 *)
|
|
||||||
+ | RHVExportStorageDomain -> 20 in
|
|
||||||
e "Item" [] [
|
|
||||||
e "rasd:Caption" [] [PCData "Graphical Controller"];
|
|
||||||
e "rasd:InstanceId" [] [PCData (uuidgen ())];
|
|
||||||
- e "rasd:ResourceType" [] [PCData "20"];
|
|
||||||
+ e "rasd:ResourceType" [] [PCData (string_of_int qxl_resourcetype)];
|
|
||||||
e "Type" [] [PCData "video"];
|
|
||||||
e "rasd:VirtualQuantity" [] [PCData "1"];
|
|
||||||
e "rasd:Device" [] [PCData "qxl"];
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
|||||||
|
From d2ca3f2f9bd9f26cacef2cf2a38e8ac18484d8e4 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.25.4
|
||||||
|
|
@ -1,40 +0,0 @@
|
|||||||
From bb6b81861e72535f57bdc8e9a3457807f21ad28c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Tue, 17 Jul 2018 17:12:38 +0200
|
|
||||||
Subject: [PATCH] v2v: -o rhv-upload: check for ovirtsdk4 (RHBZ#1601943)
|
|
||||||
|
|
||||||
Check earlier whether the ovirtsdk4 Python can be imported correctly,
|
|
||||||
to avoid errors later on during the migration.
|
|
||||||
---
|
|
||||||
v2v/output_rhv_upload.ml | 8 ++++++++
|
|
||||||
1 file changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
|
||||||
index 0152b8d5a..63fa2411a 100644
|
|
||||||
--- a/v2v/output_rhv_upload.ml
|
|
||||||
+++ b/v2v/output_rhv_upload.ml
|
|
||||||
@@ -126,6 +126,13 @@ class output_rhv_upload output_alloc output_conn
|
|
||||||
python3
|
|
||||||
in
|
|
||||||
|
|
||||||
+ (* Check that the 'ovirtsdk4' Python module is available. *)
|
|
||||||
+ let error_unless_ovirtsdk4_module_available () =
|
|
||||||
+ let res = run_command [ python3; "-c"; "import ovirtsdk4" ] in
|
|
||||||
+ if res <> 0 then
|
|
||||||
+ error (f_"the Python module ‘ovirtsdk4’ could not be loaded, is it installed? See previous messages for problems.")
|
|
||||||
+ in
|
|
||||||
+
|
|
||||||
(* Check that nbdkit is available and new enough. *)
|
|
||||||
let error_unless_nbdkit_working () =
|
|
||||||
if 0 <> Sys.command "nbdkit --version >/dev/null" then
|
|
||||||
@@ -231,6 +238,7 @@ object
|
|
||||||
|
|
||||||
method precheck () =
|
|
||||||
error_unless_python_binary_on_path ();
|
|
||||||
+ error_unless_ovirtsdk4_module_available ();
|
|
||||||
error_unless_nbdkit_working ();
|
|
||||||
error_unless_nbdkit_python3_working ();
|
|
||||||
error_unless_output_alloc_sparse ();
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
181
SOURCES/0037-options-Allow-multiple-key-parameters.patch
Normal file
181
SOURCES/0037-options-Allow-multiple-key-parameters.patch
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
From d3c6f71eed46df3f9ec376359433d9c4b9830860 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 | 37 +++++++++++++++++++++++++--------
|
||||||
|
common/options/keys.c | 45 +++++++++++++++++++++++++++++++---------
|
||||||
|
common/options/options.h | 6 ++++--
|
||||||
|
3 files changed, 67 insertions(+), 21 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.25.4
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
From c0f9ab66655ec5ca3f065357d6797d0061f04fe0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Erez <derez@redhat.com>
|
|
||||||
Date: Tue, 24 Jul 2018 19:16:10 +0300
|
|
||||||
Subject: [PATCH] v2v: rhv plugin - fix DC search string
|
|
||||||
|
|
||||||
Search for DC by 'storage.name=' to make it explicit.
|
|
||||||
I.e. "storage=" uses regex, so similar names can be
|
|
||||||
found in the search query. For example, searching for
|
|
||||||
a domain named FCSD, will find FCSD1 as well.
|
|
||||||
---
|
|
||||||
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 931fcfaa2..8274f1ee1 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -72,7 +72,7 @@ def find_host(connection):
|
|
||||||
system_service = connection.system_service()
|
|
||||||
storage_name = params['output_storage']
|
|
||||||
data_centers = system_service.data_centers_service().list(
|
|
||||||
- search='storage=%s' % storage_name,
|
|
||||||
+ search='storage.name=%s' % storage_name,
|
|
||||||
case_sensitive=False,
|
|
||||||
)
|
|
||||||
if len(data_centers) == 0:
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
437
SOURCES/0038-options-rename-key.device-as-key.id.patch
Normal file
437
SOURCES/0038-options-rename-key.device-as-key.id.patch
Normal file
@ -0,0 +1,437 @@
|
|||||||
|
From 3afce3e84c79d7fbca4d6eeb76f237090c5528c9 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.25.4
|
||||||
|
|
@ -1,35 +0,0 @@
|
|||||||
From bc2ba2f47ba8a1f88ea6f3c14addd60e84423adf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Erez <derez@redhat.com>
|
|
||||||
Date: Wed, 25 Jul 2018 11:24:33 +0300
|
|
||||||
Subject: [PATCH] v2v: rhv plugin - case-sensitive search queries
|
|
||||||
|
|
||||||
Changed both search queries to case-sensitive (to ensure an exact match).
|
|
||||||
---
|
|
||||||
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 8274f1ee1..4fad27fb8 100644
|
|
||||||
--- a/v2v/rhv-upload-plugin.py
|
|
||||||
+++ b/v2v/rhv-upload-plugin.py
|
|
||||||
@@ -73,7 +73,7 @@ def find_host(connection):
|
|
||||||
storage_name = params['output_storage']
|
|
||||||
data_centers = system_service.data_centers_service().list(
|
|
||||||
search='storage.name=%s' % storage_name,
|
|
||||||
- case_sensitive=False,
|
|
||||||
+ case_sensitive=True,
|
|
||||||
)
|
|
||||||
if len(data_centers) == 0:
|
|
||||||
# The storage domain is not attached to a datacenter
|
|
||||||
@@ -87,7 +87,7 @@ def find_host(connection):
|
|
||||||
hosts_service = system_service.hosts_service()
|
|
||||||
hosts = hosts_service.list(
|
|
||||||
search="hw_id=%s and datacenter=%s and status=Up" % (vdsm_id, datacenter.name),
|
|
||||||
- case_sensitive=False,
|
|
||||||
+ case_sensitive=True,
|
|
||||||
)
|
|
||||||
if len(hosts) == 0:
|
|
||||||
# Couldn't find a host that's fulfilling the following criteria:
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
313
SOURCES/0039-options-allow-a-UUID-as-identifier-for-key.patch
Normal file
313
SOURCES/0039-options-allow-a-UUID-as-identifier-for-key.patch
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
From abb0a1dcc6e15130c334713d0716e223e5fc494d 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.25.4
|
||||||
|
|
@ -1,44 +0,0 @@
|
|||||||
From 21cf4aaafb6088168d2f5c679477644c19116f3d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Fri, 20 Apr 2018 15:27:04 +0200
|
|
||||||
Subject: [PATCH] uefi: remove last references to kraxel's old edk2 builds
|
|
||||||
|
|
||||||
Commit 889386f8c6088e57fd68f2bb6bf85f69ecfc6f6c removed most of them
|
|
||||||
already, so remove the last ones, and the supporting code.
|
|
||||||
---
|
|
||||||
generator/UEFI.ml | 6 ------
|
|
||||||
v2v/utils.ml | 1 -
|
|
||||||
2 files changed, 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/generator/UEFI.ml b/generator/UEFI.ml
|
|
||||||
index daa78bdc9..bca3fa1ae 100644
|
|
||||||
--- a/generator/UEFI.ml
|
|
||||||
+++ b/generator/UEFI.ml
|
|
||||||
@@ -30,12 +30,6 @@ open Docstrings
|
|
||||||
|
|
||||||
(* Order is significant *within architectures only*. *)
|
|
||||||
let firmware = [
|
|
||||||
- "i386",
|
|
||||||
- "/usr/share/edk2.git/ovmf-ia32/OVMF_CODE-pure-efi.fd",
|
|
||||||
- None,
|
|
||||||
- "/usr/share/edk2.git/ovmf-ia32/OVMF_VARS-pure-efi.fd",
|
|
||||||
- [];
|
|
||||||
-
|
|
||||||
"x86_64",
|
|
||||||
"/usr/share/OVMF/OVMF_CODE.fd",
|
|
||||||
None,
|
|
||||||
diff --git a/v2v/utils.ml b/v2v/utils.ml
|
|
||||||
index e880001eb..67e2028f3 100644
|
|
||||||
--- a/v2v/utils.ml
|
|
||||||
+++ b/v2v/utils.ml
|
|
||||||
@@ -64,7 +64,6 @@ let find_uefi_firmware guest_arch =
|
|
||||||
let files =
|
|
||||||
(* The lists of firmware are actually defined in common/utils/uefi.c. *)
|
|
||||||
match guest_arch with
|
|
||||||
- | "i386" | "i486" | "i586" | "i686" -> Uefi.uefi_i386_firmware
|
|
||||||
| "x86_64" -> Uefi.uefi_x86_64_firmware
|
|
||||||
| "aarch64" -> Uefi.uefi_aarch64_firmware
|
|
||||||
| arch ->
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,82 @@
|
|||||||
|
From 34b2da989021994389b6392fca06590424b7c975 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.25.4
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
From bb804081e9b5fc959b14d2e254d320cf5a658441 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Thu, 9 Aug 2018 15:01:37 +0200
|
|
||||||
Subject: [PATCH] v2v: parse_libvirt_xml: handle srN CDROM devices
|
|
||||||
(RHBZ#1612785)
|
|
||||||
|
|
||||||
This device naming is mostly written by virt-p2v, so get the slot from
|
|
||||||
it directly without using the drive_index "decoding" function.
|
|
||||||
|
|
||||||
(cherry picked from commit c9abaa3e96e7209595f0982c1f2f97e37f3369a6)
|
|
||||||
---
|
|
||||||
v2v/parse_libvirt_xml.ml | 10 ++++++++++
|
|
||||||
1 file changed, 10 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/v2v/parse_libvirt_xml.ml b/v2v/parse_libvirt_xml.ml
|
|
||||||
index 03a201e77..44723014c 100644
|
|
||||||
--- a/v2v/parse_libvirt_xml.ml
|
|
||||||
+++ b/v2v/parse_libvirt_xml.ml
|
|
||||||
@@ -379,6 +379,16 @@ let parse_libvirt_xml ?conn xml =
|
|
||||||
let target_dev = xpath_string "target/@dev" in
|
|
||||||
match target_dev with
|
|
||||||
| None -> None
|
|
||||||
+ | Some dev when String.is_prefix dev "sr" ->
|
|
||||||
+ (* "srN" devices are found mostly in the physical XML written by
|
|
||||||
+ * virt-p2v.
|
|
||||||
+ *)
|
|
||||||
+ let name = String.sub dev 2 (String.length dev - 2) in
|
|
||||||
+ (try Some (int_of_string name)
|
|
||||||
+ with Failure _ ->
|
|
||||||
+ warning (f_"could not parse device name ‘%s’ from the source libvirt XML") dev;
|
|
||||||
+ None
|
|
||||||
+ )
|
|
||||||
| Some dev ->
|
|
||||||
let rec loop = function
|
|
||||||
| [] ->
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From 3dc8b808bdc992fb72372ece84b45644bef2c206 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.25.4
|
||||||
|
|
@ -1,43 +0,0 @@
|
|||||||
From 6f116349a2a02739e64a39ab2aeb23706fac188b Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Tue, 14 Aug 2018 12:50:07 +0100
|
|
||||||
Subject: [PATCH] v2v: -o rhv-upload: Fix error message disk numbering
|
|
||||||
(RHBZ#1615885).
|
|
||||||
|
|
||||||
The output method used the s_disk_id field assuming it was a unique,
|
|
||||||
monotonically increasing number counting from 0. However this is not
|
|
||||||
the case, the input method simply has to set s_disk_id to be unique
|
|
||||||
for each disk.
|
|
||||||
|
|
||||||
Fixes commit cc04573927cca97de60d544d37467e67c25867a7.
|
|
||||||
|
|
||||||
Thanks: Xiaodai Wang
|
|
||||||
(cherry picked from commit 90c9c12258fbb9a89d16f798725d16fe5bb3504c)
|
|
||||||
---
|
|
||||||
v2v/output_rhv_upload.ml | 6 +++---
|
|
||||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
|
||||||
index 63fa2411a..7dbd98a0d 100644
|
|
||||||
--- a/v2v/output_rhv_upload.ml
|
|
||||||
+++ b/v2v/output_rhv_upload.ml
|
|
||||||
@@ -383,13 +383,13 @@ If the messages above are not sufficient to diagnose the problem then add the
|
|
||||||
*)
|
|
||||||
let nr_disks = List.length targets in
|
|
||||||
let image_uuids =
|
|
||||||
- List.map (
|
|
||||||
- fun t ->
|
|
||||||
+ 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")
|
|
||||||
- (id+1) nr_disks;
|
|
||||||
+ (i+1) nr_disks;
|
|
||||||
let diskid = read_whole_file diskid_file in
|
|
||||||
diskid
|
|
||||||
) targets in
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
From a4433085bf38719bd22a7cfe507c503885c839f2 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.25.4
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
From 739ac1bc0f37c4bceb2e2eeed00f9320605aa641 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Tue, 7 Aug 2018 09:06:46 +0100
|
|
||||||
Subject: [PATCH] v2v: -o rhv-upload: Properly replace SD_UUID in OVF
|
|
||||||
(RHBZ#1612653).
|
|
||||||
|
|
||||||
The @SD_UUID@ pattern was not being replaced correctly.
|
|
||||||
|
|
||||||
Thanks: Daniel Erez.
|
|
||||||
(cherry picked from commit 389e165519c33b5234db50ea26dcb267321ee152)
|
|
||||||
---
|
|
||||||
v2v/rhv-upload-createvm.py | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/rhv-upload-createvm.py b/v2v/rhv-upload-createvm.py
|
|
||||||
index a34627ec8..1d0e8c95d 100644
|
|
||||||
--- a/v2v/rhv-upload-createvm.py
|
|
||||||
+++ b/v2v/rhv-upload-createvm.py
|
|
||||||
@@ -70,7 +70,7 @@ sds_service = system_service.storage_domains_service()
|
|
||||||
sd = sds_service.list(search=("name=%s" % params['output_storage']))[0]
|
|
||||||
sd_uuid = sd.id
|
|
||||||
|
|
||||||
-ovf.replace("@SD_UUID@", sd_uuid)
|
|
||||||
+ovf = ovf.replace("@SD_UUID@", sd_uuid)
|
|
||||||
|
|
||||||
vms_service = system_service.vms_service()
|
|
||||||
vm = vms_service.add(
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
|||||||
From 8be6817e95dbdf826a6065751b4a3a000c78071c Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Tue, 28 Aug 2018 12:59:06 +0100
|
|
||||||
Subject: [PATCH] ppc64le: Don't use -cpu parameter under any circumstances
|
|
||||||
(RHBZ#1605071).
|
|
||||||
|
|
||||||
(cherry picked from commit 56318f0b5ffc287fed71cc7cdd2007dff2b8fb17)
|
|
||||||
---
|
|
||||||
lib/appliance-cpu.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/lib/appliance-cpu.c b/lib/appliance-cpu.c
|
|
||||||
index a6c1b0faf..fa1bae3f9 100644
|
|
||||||
--- a/lib/appliance-cpu.c
|
|
||||||
+++ b/lib/appliance-cpu.c
|
|
||||||
@@ -76,6 +76,9 @@ guestfs_int_get_cpu_model (int kvm)
|
|
||||||
return "host";
|
|
||||||
else
|
|
||||||
return "cortex-a57";
|
|
||||||
+#elif defined(__powerpc64__)
|
|
||||||
+ /* 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
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
|||||||
|
From d02694e659ebe1ecad29f8461d87eda6a1f8faa2 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.25.4
|
||||||
|
|
49
SOURCES/0044-rhv-upload-Check-status-more-frequently.patch
Normal file
49
SOURCES/0044-rhv-upload-Check-status-more-frequently.patch
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
From 200a365f20d5d8a3ddfe713e9bbe938206e43e9a 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.25.4
|
||||||
|
|
@ -1,108 +0,0 @@
|
|||||||
From 81a9e4f428e9a2305a2ea8c576dadde60fa5a381 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Thu, 20 Sep 2018 12:42:59 +0100
|
|
||||||
Subject: [PATCH] tools: Link OCaml programs with -runtime-variant _pic if
|
|
||||||
available.
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
OCaml has a small runtime which is statically linked into the virt
|
|
||||||
tools (providing things like GC and primitives). Since OCaml 4.03 it
|
|
||||||
has been possible to select variants of this runtime, one of which is
|
|
||||||
compiled with -fPIC, using ‘ocamlopt -runtime-variant _pic’.
|
|
||||||
|
|
||||||
This has performance implications on i686, but is relatively free on
|
|
||||||
other architectures. Since it (in theory) adds to the security of the
|
|
||||||
final binary this commit enables it whenever it is available.
|
|
||||||
|
|
||||||
(cherry picked from commit 09abb9c990f6e07b3577088522b8ad9fb439a80e)
|
|
||||||
---
|
|
||||||
.gitignore | 1 +
|
|
||||||
configure.ac | 2 ++
|
|
||||||
m4/guestfs-ocaml.m4 | 18 ++++++++++++++++++
|
|
||||||
ocaml-link.sh => ocaml-link.sh.in | 8 +++++++-
|
|
||||||
4 files changed, 28 insertions(+), 1 deletion(-)
|
|
||||||
rename ocaml-link.sh => ocaml-link.sh.in (88%)
|
|
||||||
|
|
||||||
diff --git a/.gitignore b/.gitignore
|
|
||||||
index af80e36d1..89b8baa17 100644
|
|
||||||
--- a/.gitignore
|
|
||||||
+++ b/.gitignore
|
|
||||||
@@ -410,6 +410,7 @@ Makefile.in
|
|
||||||
/make-fs/virt-make-fs.1
|
|
||||||
/missing
|
|
||||||
/ocaml-dep.sh
|
|
||||||
+/ocaml-link.sh
|
|
||||||
/ocaml/bindtests.bc
|
|
||||||
/ocaml/bindtests.opt
|
|
||||||
/ocaml/bindtests.ml
|
|
||||||
diff --git a/configure.ac b/configure.ac
|
|
||||||
index 4da3bd021..6c38406bb 100644
|
|
||||||
--- a/configure.ac
|
|
||||||
+++ b/configure.ac
|
|
||||||
@@ -198,6 +198,8 @@ AC_CONFIG_FILES([installcheck.sh],
|
|
||||||
[chmod +x,-w installcheck.sh])
|
|
||||||
AC_CONFIG_FILES([ocaml-dep.sh],
|
|
||||||
[chmod +x,-w ocaml-dep.sh])
|
|
||||||
+AC_CONFIG_FILES([ocaml-link.sh],
|
|
||||||
+ [chmod +x,-w ocaml-link.sh])
|
|
||||||
AC_CONFIG_FILES([p2v/virt-p2v-make-disk],
|
|
||||||
[chmod +x,-w p2v/virt-p2v-make-disk])
|
|
||||||
AC_CONFIG_FILES([p2v/virt-p2v-make-kickstart],
|
|
||||||
diff --git a/m4/guestfs-ocaml.m4 b/m4/guestfs-ocaml.m4
|
|
||||||
index e08f40a02..fea11a334 100644
|
|
||||||
--- a/m4/guestfs-ocaml.m4
|
|
||||||
+++ b/m4/guestfs-ocaml.m4
|
|
||||||
@@ -59,6 +59,24 @@ AM_CONDITIONAL([HAVE_OCAMLOPT],
|
|
||||||
AM_CONDITIONAL([HAVE_OCAMLDOC],
|
|
||||||
[test "x$OCAMLDOC" != "xno"])
|
|
||||||
|
|
||||||
+dnl Check if ocamlc/ocamlopt -runtime-variant _pic works. It was
|
|
||||||
+dnl added in OCaml >= 4.03, but in theory might be disabled by
|
|
||||||
+dnl downstream distros.
|
|
||||||
+OCAML_RUNTIME_VARIANT_PIC_OPTION=""
|
|
||||||
+if test "x$OCAMLC" != "xno"; then
|
|
||||||
+ AC_MSG_CHECKING([if OCaml ‘-runtime-variant _pic’ works])
|
|
||||||
+ rm -f conftest.ml contest
|
|
||||||
+ echo 'print_endline "hello world"' > conftest.ml
|
|
||||||
+ if $OCAMLC conftest.ml -runtime-variant _pic -o conftest >&5 2>&5 ; then
|
|
||||||
+ AC_MSG_RESULT([yes])
|
|
||||||
+ OCAML_RUNTIME_VARIANT_PIC_OPTION="-runtime-variant _pic"
|
|
||||||
+ else
|
|
||||||
+ AC_MSG_RESULT([no])
|
|
||||||
+ fi
|
|
||||||
+ rm -f conftest.ml contest
|
|
||||||
+fi
|
|
||||||
+AC_SUBST([OCAML_RUNTIME_VARIANT_PIC_OPTION])
|
|
||||||
+
|
|
||||||
dnl Check if ocamldep has options -all and -one-line (not present in RHEL 6).
|
|
||||||
AC_MSG_CHECKING([if ocamldep has the ‘-all’ option])
|
|
||||||
if ocamldep -all >&AS_MESSAGE_LOG_FD 2>&1; then
|
|
||||||
diff --git a/ocaml-link.sh b/ocaml-link.sh.in
|
|
||||||
similarity index 88%
|
|
||||||
rename from ocaml-link.sh
|
|
||||||
rename to ocaml-link.sh.in
|
|
||||||
index 855637534..fbcc07951 100755
|
|
||||||
--- a/ocaml-link.sh
|
|
||||||
+++ b/ocaml-link.sh.in
|
|
||||||
@@ -1,4 +1,6 @@
|
|
||||||
#!/bin/bash -
|
|
||||||
+# Script used to link OCaml programs.
|
|
||||||
+# @configure_input@
|
|
||||||
# (C) Copyright 2015-2018 Red Hat Inc.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
@@ -41,4 +43,8 @@ while true ; do
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
-exec "$@" -linkpkg -cclib "${cclib}"
|
|
||||||
+# NB -cclib must come last.
|
|
||||||
+exec "$@" \
|
|
||||||
+ @OCAML_RUNTIME_VARIANT_PIC_OPTION@ \
|
|
||||||
+ -linkpkg \
|
|
||||||
+ -cclib "${cclib}"
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From 7fd1c3be6bb744a93eff6ae1a9cfcdd9280cf247 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.25.4
|
||||||
|
|
@ -1,328 +0,0 @@
|
|||||||
From 7423e43ec2cd27d52650a1caeb7c0576350e0a78 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Thu, 20 Sep 2018 12:59:44 +0100
|
|
||||||
Subject: [PATCH] tools: Ensure CFLAGS and LDFLAGS are passed to all OCaml
|
|
||||||
binaries (RHBZ#1624130).
|
|
||||||
|
|
||||||
After this commit, all annocheck errors are fixed except for:
|
|
||||||
|
|
||||||
Hardened: virt-get-kernel: MAYB: Gaps were detected in the annobin coverage. Run with -v to list.
|
|
||||||
|
|
||||||
After discussion with the annocheck maintainers this gap in coverage
|
|
||||||
(which corresponds to the OCaml runtime) seems to be caused either by
|
|
||||||
the runtime not being linked with the right flags, or might be a bug
|
|
||||||
in annocheck itself. In any case it's not something that can be
|
|
||||||
resolved within the scope of libguestfs.
|
|
||||||
|
|
||||||
(cherry picked from commit 34c23403c51a4d59d826c8045e06f9aabc2ceb16)
|
|
||||||
---
|
|
||||||
builder/Makefile.am | 2 +-
|
|
||||||
common/mlaugeas/Makefile.am | 2 +-
|
|
||||||
common/mlgettext/Makefile.am | 2 +-
|
|
||||||
common/mlpcre/Makefile.am | 2 +-
|
|
||||||
common/mlprogress/Makefile.am | 2 +-
|
|
||||||
common/mlstdutils/Makefile.am | 2 +-
|
|
||||||
common/mltools/Makefile.am | 2 +-
|
|
||||||
common/mlutils/Makefile.am | 2 +-
|
|
||||||
common/mlvisit/Makefile.am | 2 +-
|
|
||||||
common/mlxml/Makefile.am | 2 +-
|
|
||||||
customize/Makefile.am | 2 +-
|
|
||||||
daemon/Makefile.am | 2 +-
|
|
||||||
dib/Makefile.am | 2 +-
|
|
||||||
generator/Makefile.am | 2 +-
|
|
||||||
get-kernel/Makefile.am | 2 +-
|
|
||||||
ocaml-link.sh.in | 2 +-
|
|
||||||
ocaml/Makefile.am | 2 +-
|
|
||||||
resize/Makefile.am | 2 +-
|
|
||||||
sparsify/Makefile.am | 2 +-
|
|
||||||
sysprep/Makefile.am | 2 +-
|
|
||||||
v2v/Makefile.am | 2 +-
|
|
||||||
v2v/test-harness/Makefile.am | 2 +-
|
|
||||||
22 files changed, 22 insertions(+), 22 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/builder/Makefile.am b/builder/Makefile.am
|
|
||||||
index c7b50778a..a30a229b2 100644
|
|
||||||
--- a/builder/Makefile.am
|
|
||||||
+++ b/builder/Makefile.am
|
|
||||||
@@ -215,7 +215,7 @@ OCAMLCLIBS = \
|
|
||||||
$(LIBINTL) \
|
|
||||||
-lgnu
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/common/mlaugeas/Makefile.am b/common/mlaugeas/Makefile.am
|
|
||||||
index 8aa15b80e..2c1a6e0fd 100644
|
|
||||||
--- a/common/mlaugeas/Makefile.am
|
|
||||||
+++ b/common/mlaugeas/Makefile.am
|
|
||||||
@@ -61,7 +61,7 @@ BOBJECTS = $(SOURCES_ML:.ml=.cmo)
|
|
||||||
XOBJECTS = $(BOBJECTS:.cmo=.cmx)
|
|
||||||
|
|
||||||
OCAMLPACKAGES =
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/common/mlgettext/Makefile.am b/common/mlgettext/Makefile.am
|
|
||||||
index cdcea33ec..b918f90c3 100644
|
|
||||||
--- a/common/mlgettext/Makefile.am
|
|
||||||
+++ b/common/mlgettext/Makefile.am
|
|
||||||
@@ -60,7 +60,7 @@ if HAVE_OCAML_PKG_GETTEXT
|
|
||||||
OCAMLPACKAGES += -package gettext-stub
|
|
||||||
endif
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/common/mlpcre/Makefile.am b/common/mlpcre/Makefile.am
|
|
||||||
index f9699f592..6f04256da 100644
|
|
||||||
--- a/common/mlpcre/Makefile.am
|
|
||||||
+++ b/common/mlpcre/Makefile.am
|
|
||||||
@@ -70,7 +70,7 @@ OCAMLPACKAGES = \
|
|
||||||
-I $(builddir)
|
|
||||||
OCAMLPACKAGES_TESTS = $(MLPCRE_CMA)
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/common/mlprogress/Makefile.am b/common/mlprogress/Makefile.am
|
|
||||||
index be88ef2de..af006d228 100644
|
|
||||||
--- a/common/mlprogress/Makefile.am
|
|
||||||
+++ b/common/mlprogress/Makefile.am
|
|
||||||
@@ -76,7 +76,7 @@ OCAMLPACKAGES = \
|
|
||||||
-I $(top_builddir)/ocaml \
|
|
||||||
-I $(builddir)
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/common/mlstdutils/Makefile.am b/common/mlstdutils/Makefile.am
|
|
||||||
index e38230db8..75252eb46 100644
|
|
||||||
--- a/common/mlstdutils/Makefile.am
|
|
||||||
+++ b/common/mlstdutils/Makefile.am
|
|
||||||
@@ -79,7 +79,7 @@ if HAVE_OCAML_PKG_OUNIT
|
|
||||||
OCAMLPACKAGES_TESTS += -package oUnit
|
|
||||||
endif
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/common/mltools/Makefile.am b/common/mltools/Makefile.am
|
|
||||||
index 66b18f5de..b326cf56a 100644
|
|
||||||
--- a/common/mltools/Makefile.am
|
|
||||||
+++ b/common/mltools/Makefile.am
|
|
||||||
@@ -131,7 +131,7 @@ OCAMLCLIBS = \
|
|
||||||
$(LIBINTL) \
|
|
||||||
-lgnu
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/common/mlutils/Makefile.am b/common/mlutils/Makefile.am
|
|
||||||
index 8627e5b10..77feafa56 100644
|
|
||||||
--- a/common/mlutils/Makefile.am
|
|
||||||
+++ b/common/mlutils/Makefile.am
|
|
||||||
@@ -74,7 +74,7 @@ OCAMLPACKAGES = \
|
|
||||||
-I $(top_builddir)/common/mlstdutils \
|
|
||||||
-I $(builddir)
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/common/mlvisit/Makefile.am b/common/mlvisit/Makefile.am
|
|
||||||
index add1fe56e..7230415e7 100644
|
|
||||||
--- a/common/mlvisit/Makefile.am
|
|
||||||
+++ b/common/mlvisit/Makefile.am
|
|
||||||
@@ -80,7 +80,7 @@ OCAMLPACKAGES = \
|
|
||||||
-I $(builddir)
|
|
||||||
OCAMLPACKAGES_TESTS = $(MLVISIT_CMA)
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/common/mlxml/Makefile.am b/common/mlxml/Makefile.am
|
|
||||||
index eab036b82..7f36b743a 100644
|
|
||||||
--- a/common/mlxml/Makefile.am
|
|
||||||
+++ b/common/mlxml/Makefile.am
|
|
||||||
@@ -72,7 +72,7 @@ OCAMLPACKAGES = \
|
|
||||||
-I $(top_builddir)/gnulib/lib/.libs \
|
|
||||||
-I $(builddir)
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/customize/Makefile.am b/customize/Makefile.am
|
|
||||||
index efdd27227..69cf6c13f 100644
|
|
||||||
--- a/customize/Makefile.am
|
|
||||||
+++ b/customize/Makefile.am
|
|
||||||
@@ -173,7 +173,7 @@ OCAMLCLIBS = \
|
|
||||||
$(LIBINTL) \
|
|
||||||
-lgnu
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
virt_customize_DEPENDENCIES = \
|
|
||||||
$(top_srcdir)/ocaml-link.sh \
|
|
||||||
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
|
||||||
index d9ed5625e..dcae1a66c 100644
|
|
||||||
--- a/daemon/Makefile.am
|
|
||||||
+++ b/daemon/Makefile.am
|
|
||||||
@@ -347,7 +347,7 @@ OCAMLPACKAGES = \
|
|
||||||
-I $(top_builddir)/common/mlpcre/.libs \
|
|
||||||
-I $(top_builddir)/gnulib/lib/.libs
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/dib/Makefile.am b/dib/Makefile.am
|
|
||||||
index 316f49903..7c2ab09d6 100644
|
|
||||||
--- a/dib/Makefile.am
|
|
||||||
+++ b/dib/Makefile.am
|
|
||||||
@@ -99,7 +99,7 @@ OCAMLCLIBS = \
|
|
||||||
$(LIBINTL) \
|
|
||||||
-lgnu
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/generator/Makefile.am b/generator/Makefile.am
|
|
||||||
index c2d10966a..056d01346 100644
|
|
||||||
--- a/generator/Makefile.am
|
|
||||||
+++ b/generator/Makefile.am
|
|
||||||
@@ -175,7 +175,7 @@ OCAMLPACKAGES = \
|
|
||||||
-I . \
|
|
||||||
-I $(top_srcdir)/common/mlstdutils \
|
|
||||||
-I $(top_builddir)/common/mlstdutils
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
noinst_PROGRAM = generator
|
|
||||||
|
|
||||||
diff --git a/get-kernel/Makefile.am b/get-kernel/Makefile.am
|
|
||||||
index 81dfb48b4..75379e21f 100644
|
|
||||||
--- a/get-kernel/Makefile.am
|
|
||||||
+++ b/get-kernel/Makefile.am
|
|
||||||
@@ -82,7 +82,7 @@ OCAMLCLIBS = \
|
|
||||||
$(LIBINTL) \
|
|
||||||
-lgnu
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/ocaml-link.sh.in b/ocaml-link.sh.in
|
|
||||||
index fbcc07951..6819c641e 100755
|
|
||||||
--- a/ocaml-link.sh.in
|
|
||||||
+++ b/ocaml-link.sh.in
|
|
||||||
@@ -47,4 +47,4 @@ done
|
|
||||||
exec "$@" \
|
|
||||||
@OCAML_RUNTIME_VARIANT_PIC_OPTION@ \
|
|
||||||
-linkpkg \
|
|
||||||
- -cclib "${cclib}"
|
|
||||||
+ -cclib "@LDFLAGS@ $cclib"
|
|
||||||
diff --git a/ocaml/Makefile.am b/ocaml/Makefile.am
|
|
||||||
index b0f2900f2..752fc109c 100644
|
|
||||||
--- a/ocaml/Makefile.am
|
|
||||||
+++ b/ocaml/Makefile.am
|
|
||||||
@@ -37,7 +37,7 @@ CLEANFILES += t/*.annot t/*.cmi t/*.cmo t/*.cmx t/*.o t/*.a t/*.so
|
|
||||||
|
|
||||||
if HAVE_OCAML
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
noinst_DATA = mlguestfs.cma META
|
|
||||||
if HAVE_OCAMLOPT
|
|
||||||
diff --git a/resize/Makefile.am b/resize/Makefile.am
|
|
||||||
index 847fb313a..7a4367023 100644
|
|
||||||
--- a/resize/Makefile.am
|
|
||||||
+++ b/resize/Makefile.am
|
|
||||||
@@ -80,7 +80,7 @@ OCAMLCLIBS = \
|
|
||||||
$(LIBINTL) \
|
|
||||||
-lgnu
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/sparsify/Makefile.am b/sparsify/Makefile.am
|
|
||||||
index 2ab357a68..2dce5e582 100644
|
|
||||||
--- a/sparsify/Makefile.am
|
|
||||||
+++ b/sparsify/Makefile.am
|
|
||||||
@@ -88,7 +88,7 @@ OCAMLCLIBS = \
|
|
||||||
$(LIBINTL) \
|
|
||||||
-lgnu
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/sysprep/Makefile.am b/sysprep/Makefile.am
|
|
||||||
index 0cc9da80a..6ed4ac713 100644
|
|
||||||
--- a/sysprep/Makefile.am
|
|
||||||
+++ b/sysprep/Makefile.am
|
|
||||||
@@ -136,7 +136,7 @@ OCAMLCLIBS = \
|
|
||||||
$(LIBINTL) \
|
|
||||||
-lgnu
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
|
|
||||||
index 7de050b06..7a1ac329e 100644
|
|
||||||
--- a/v2v/Makefile.am
|
|
||||||
+++ b/v2v/Makefile.am
|
|
||||||
@@ -201,7 +201,7 @@ OCAMLCLIBS = \
|
|
||||||
$(LIBINTL) \
|
|
||||||
-lgnu
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
if !HAVE_OCAMLOPT
|
|
||||||
OBJECTS = $(BOBJECTS)
|
|
||||||
diff --git a/v2v/test-harness/Makefile.am b/v2v/test-harness/Makefile.am
|
|
||||||
index d69188969..22c3b8c49 100644
|
|
||||||
--- a/v2v/test-harness/Makefile.am
|
|
||||||
+++ b/v2v/test-harness/Makefile.am
|
|
||||||
@@ -47,7 +47,7 @@ OCAMLPACKAGES = \
|
|
||||||
-I $(top_builddir)/common/mltools \
|
|
||||||
-I $(top_builddir)/v2v
|
|
||||||
|
|
||||||
-OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR)
|
|
||||||
+OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)'
|
|
||||||
|
|
||||||
BOBJECTS = \
|
|
||||||
$(SOURCES_ML:.ml=.cmo) \
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
|||||||
From 57ed1fc4281462e02604b0e740c4ffa31cf93afb Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pino Toscano <ptoscano@redhat.com>
|
|
||||||
Date: Thu, 27 Sep 2018 15:51:01 +0200
|
|
||||||
Subject: [PATCH] ocaml: make sure to pass LDFLAGS to ocamlmklibs linker
|
|
||||||
(RHBZ#1624130)
|
|
||||||
|
|
||||||
Pass the LDFLAGS properly as arguments for the C linker when using
|
|
||||||
ocamlmklibs via the -ldopt option.
|
|
||||||
|
|
||||||
Followup of commit 34c23403c51a4d59d826c8045e06f9aabc2ceb16.
|
|
||||||
|
|
||||||
(cherry picked from commit 4ff573c352973036b722ec0c9bf79be958b83b2c)
|
|
||||||
---
|
|
||||||
ocaml/Makefile.am | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ocaml/Makefile.am b/ocaml/Makefile.am
|
|
||||||
index 752fc109c..4d13eed97 100644
|
|
||||||
--- a/ocaml/Makefile.am
|
|
||||||
+++ b/ocaml/Makefile.am
|
|
||||||
@@ -64,14 +64,14 @@ endif
|
|
||||||
|
|
||||||
stamp-mlguestfs: libguestfsocaml.a $(guestfs_cmm)
|
|
||||||
$(OCAMLMKLIB) -o mlguestfs \
|
|
||||||
+ -ldopt '$(LDFLAGS)' \
|
|
||||||
$(libguestfsocaml_a_OBJECTS) guestfs.cmo \
|
|
||||||
- $(LDFLAGS) \
|
|
||||||
$(LTLIBINTL) \
|
|
||||||
-L../lib/.libs -lguestfs
|
|
||||||
if HAVE_OCAMLOPT
|
|
||||||
$(OCAMLMKLIB) -o mlguestfs \
|
|
||||||
+ -ldopt '$(LDFLAGS)' \
|
|
||||||
$(libguestfsocaml_a_OBJECTS) guestfs.cmx \
|
|
||||||
- $(LDFLAGS) \
|
|
||||||
$(LTLIBINTL) \
|
|
||||||
-L../lib/.libs -lguestfs
|
|
||||||
endif
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
89
SOURCES/0046-rhv-upload-Fix-waiting-for-transfer.patch
Normal file
89
SOURCES/0046-rhv-upload-Fix-waiting-for-transfer.patch
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
From d132157c9e0b6b990cd989662f5499644508de97 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()
|
||||||
|
- if transfer.phase != types.ImageTransferPhase.INITIALIZING:
|
||||||
|
+ 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 time.time() > endt:
|
||||||
|
+
|
||||||
|
+ if transfer.phase != types.ImageTransferPhase.INITIALIZING:
|
||||||
|
+ 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.25.4
|
||||||
|
|
@ -1,323 +0,0 @@
|
|||||||
From 81f35e441d06bff2bf60bff6354d53de137847d9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Tue, 19 Jun 2018 10:44:57 +0100
|
|
||||||
Subject: [PATCH] v2v: Model machine type explicitly.
|
|
||||||
|
|
||||||
QEMU for x86 supports two machine types, "pc" (emulating the ancient
|
|
||||||
Intel i440FX chipset originally used by the Pentium Pro), and "q35"
|
|
||||||
(https://wiki.qemu.org/Features/Q35).
|
|
||||||
|
|
||||||
Currently virt-v2v does not set any machine type, so libvirt or the
|
|
||||||
target hypervisor will choose some default, probably i440fx. The
|
|
||||||
latest advice from the QEMU and libvirt communities is not to rely on
|
|
||||||
the default machine type but to specify what we need explicitly, but
|
|
||||||
it may also be that the libvirt configuration file has been changed to
|
|
||||||
set the default machine type to Q35 (either by the distro or the end
|
|
||||||
user).
|
|
||||||
|
|
||||||
None of this matters for reasonably new guests since they can boot
|
|
||||||
with either chipset. However there are some very old guests (notably
|
|
||||||
Windows XP) which cannot handle Q35.
|
|
||||||
|
|
||||||
This commit changes virt-v2v so it always tries to specify the machine
|
|
||||||
type explicitly (assuming the target supports that, and not all of
|
|
||||||
them do). For x86_64 guests this patch always selects i440fx (pc).
|
|
||||||
In future we hope to get the correct machine type for the guest from
|
|
||||||
libosinfo but this is not available yet.
|
|
||||||
|
|
||||||
For non-x86 architectures we select the "virt" model which will
|
|
||||||
probably only work for AArch64. More work is needed for POWER.
|
|
||||||
|
|
||||||
For secure boot we still have to force the machine type to Q35. In a
|
|
||||||
future version this forcing can be removed since any guest which is
|
|
||||||
using secure boot will be new enough that it'll be using Q35 anyway
|
|
||||||
(on x86).
|
|
||||||
|
|
||||||
(cherry picked from commit 55879b2f2c5b205352f48f999e20efd9b455ea43)
|
|
||||||
---
|
|
||||||
v2v/convert_linux.ml | 7 +++++++
|
|
||||||
v2v/convert_windows.ml | 7 +++++++
|
|
||||||
v2v/create_libvirt_xml.ml | 37 +++++++++++++++++++++++++------------
|
|
||||||
v2v/create_ovf.ml | 2 ++
|
|
||||||
v2v/output_glance.ml | 5 +++++
|
|
||||||
v2v/output_qemu.ml | 30 +++++++++++++++++++-----------
|
|
||||||
v2v/test-v2v-i-ova.xml | 2 +-
|
|
||||||
v2v/types.ml | 8 ++++++++
|
|
||||||
v2v/types.mli | 6 ++++--
|
|
||||||
9 files changed, 78 insertions(+), 26 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
|
|
||||||
index 4a7447fe1..fd6b71ba4 100644
|
|
||||||
--- a/v2v/convert_linux.ml
|
|
||||||
+++ b/v2v/convert_linux.ml
|
|
||||||
@@ -122,6 +122,12 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
|
||||||
|
|
||||||
SELinux_relabel.relabel g;
|
|
||||||
|
|
||||||
+ (* XXX Look up this information in libosinfo in future. *)
|
|
||||||
+ let machine =
|
|
||||||
+ match inspect.i_arch with
|
|
||||||
+ | "i386"|"x86_64" -> I440FX
|
|
||||||
+ | _ -> Virt in
|
|
||||||
+
|
|
||||||
(* Return guest capabilities from the convert () function. *)
|
|
||||||
let guestcaps = {
|
|
||||||
gcaps_block_bus = block_type;
|
|
||||||
@@ -130,6 +136,7 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
|
||||||
gcaps_virtio_rng = kernel.ki_supports_virtio_rng;
|
|
||||||
gcaps_virtio_balloon = kernel.ki_supports_virtio_balloon;
|
|
||||||
gcaps_isa_pvpanic = kernel.ki_supports_isa_pvpanic;
|
|
||||||
+ gcaps_machine = machine;
|
|
||||||
gcaps_arch = Utils.kvm_arch inspect.i_arch;
|
|
||||||
gcaps_acpi = acpi;
|
|
||||||
} in
|
|
||||||
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
|
||||||
index 163319545..1e058136e 100644
|
|
||||||
--- a/v2v/convert_windows.ml
|
|
||||||
+++ b/v2v/convert_windows.ml
|
|
||||||
@@ -212,6 +212,12 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
|
||||||
warning (f_"this guest has Anti-Virus (AV) software and a new virtio block device driver was installed. In some circumstances, AV may prevent new drivers from working (resulting in a 7B boot error). If this happens, try disabling AV before doing the conversion.");
|
|
||||||
);
|
|
||||||
|
|
||||||
+ (* XXX Look up this information in libosinfo in future. *)
|
|
||||||
+ let machine =
|
|
||||||
+ match inspect.i_arch with
|
|
||||||
+ | "i386"|"x86_64" -> I440FX
|
|
||||||
+ | _ -> Virt in
|
|
||||||
+
|
|
||||||
(* Return guest capabilities from the convert () function. *)
|
|
||||||
let guestcaps = {
|
|
||||||
gcaps_block_bus = block_driver;
|
|
||||||
@@ -220,6 +226,7 @@ let convert (g : G.guestfs) inspect source output rcaps =
|
|
||||||
gcaps_virtio_rng = virtio_rng_supported;
|
|
||||||
gcaps_virtio_balloon = virtio_ballon_supported;
|
|
||||||
gcaps_isa_pvpanic = isa_pvpanic_supported;
|
|
||||||
+ gcaps_machine = machine;
|
|
||||||
gcaps_arch = Utils.kvm_arch inspect.i_arch;
|
|
||||||
gcaps_acpi = true;
|
|
||||||
} in
|
|
||||||
diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml
|
|
||||||
index fbe90eeaa..8a34c94b0 100644
|
|
||||||
--- a/v2v/create_libvirt_xml.ml
|
|
||||||
+++ b/v2v/create_libvirt_xml.ml
|
|
||||||
@@ -81,15 +81,17 @@ let create_libvirt_xml ?pool source target_buses guestcaps
|
|
||||||
match target_firmware with
|
|
||||||
| TargetBIOS -> None
|
|
||||||
| TargetUEFI -> Some (find_uefi_firmware guestcaps.gcaps_arch) in
|
|
||||||
- let secure_boot_required =
|
|
||||||
- match uefi_firmware with
|
|
||||||
- | Some { Uefi.flags = flags }
|
|
||||||
- when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags -> true
|
|
||||||
- | _ -> false in
|
|
||||||
- (* Currently these are required by secure boot, but in theory they
|
|
||||||
- * might be independent properties.
|
|
||||||
- *)
|
|
||||||
- let machine_q35 = secure_boot_required in
|
|
||||||
+ let machine, secure_boot_required =
|
|
||||||
+ match guestcaps.gcaps_machine, uefi_firmware with
|
|
||||||
+ | _, Some { Uefi.flags = flags }
|
|
||||||
+ when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags ->
|
|
||||||
+ (* Force machine type to Q35 because PC does not support
|
|
||||||
+ * secure boot. We must remove this when we get the
|
|
||||||
+ * correct machine type from libosinfo in future. XXX
|
|
||||||
+ *)
|
|
||||||
+ Q35, true
|
|
||||||
+ | machine, _ ->
|
|
||||||
+ machine, false in
|
|
||||||
let smm = secure_boot_required in
|
|
||||||
|
|
||||||
(* We have the machine features of the guest when it was on the
|
|
||||||
@@ -140,7 +142,18 @@ let create_libvirt_xml ?pool source target_buses guestcaps
|
|
||||||
|
|
||||||
(* The <os> section subelements. *)
|
|
||||||
let os_section =
|
|
||||||
- let machine = if machine_q35 then [ "machine", "q35" ] else [] in
|
|
||||||
+ let os = ref [] in
|
|
||||||
+
|
|
||||||
+ let machine =
|
|
||||||
+ match machine with
|
|
||||||
+ | I440FX -> "pc"
|
|
||||||
+ | Q35 -> "q35"
|
|
||||||
+ | Virt -> "virt" in
|
|
||||||
+
|
|
||||||
+ List.push_back os
|
|
||||||
+ (e "type" ["arch", guestcaps.gcaps_arch;
|
|
||||||
+ "machine", machine]
|
|
||||||
+ [PCData "hvm"]);
|
|
||||||
|
|
||||||
let loader =
|
|
||||||
match uefi_firmware with
|
|
||||||
@@ -152,8 +165,8 @@ let create_libvirt_xml ?pool source target_buses guestcaps
|
|
||||||
[ PCData code ];
|
|
||||||
e "nvram" ["template", vars_template] [] ] in
|
|
||||||
|
|
||||||
- (e "type" (["arch", guestcaps.gcaps_arch] @ machine) [PCData "hvm"])
|
|
||||||
- :: loader in
|
|
||||||
+ List.push_back_list os loader;
|
|
||||||
+ !os in
|
|
||||||
|
|
||||||
List.push_back_list body [
|
|
||||||
e "os" [] os_section;
|
|
||||||
diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
|
|
||||||
index 5db239d66..01970013e 100644
|
|
||||||
--- a/v2v/create_ovf.ml
|
|
||||||
+++ b/v2v/create_ovf.ml
|
|
||||||
@@ -602,6 +602,8 @@ let rec create_ovf source targets guestcaps inspect
|
|
||||||
source.s_vcpu memsize_mb)]
|
|
||||||
] in
|
|
||||||
|
|
||||||
+ (* XXX How to set machine type for Q35? *)
|
|
||||||
+
|
|
||||||
List.push_back virtual_hardware_section_items (
|
|
||||||
e "Item" [] ([
|
|
||||||
e "rasd:Caption" [] [PCData (sprintf "%d virtual cpu" source.s_vcpu)];
|
|
||||||
diff --git a/v2v/output_glance.ml b/v2v/output_glance.ml
|
|
||||||
index c334def42..96c31da59 100644
|
|
||||||
--- a/v2v/output_glance.ml
|
|
||||||
+++ b/v2v/output_glance.ml
|
|
||||||
@@ -86,6 +86,11 @@ object
|
|
||||||
(match guestcaps.gcaps_video with
|
|
||||||
| QXL -> "qxl"
|
|
||||||
| Cirrus -> "cirrus");
|
|
||||||
+ "hw_machine_type",
|
|
||||||
+ (match guestcaps.gcaps_machine with
|
|
||||||
+ | I440FX -> "pc"
|
|
||||||
+ | Q35 -> "q35"
|
|
||||||
+ | Virt -> "virt");
|
|
||||||
"architecture", guestcaps.gcaps_arch;
|
|
||||||
"hypervisor_type", "kvm";
|
|
||||||
"vm_mode", "hvm";
|
|
||||||
diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml
|
|
||||||
index 952660de2..e23f22e12 100644
|
|
||||||
--- a/v2v/output_qemu.ml
|
|
||||||
+++ b/v2v/output_qemu.ml
|
|
||||||
@@ -56,17 +56,25 @@ object
|
|
||||||
match target_firmware with
|
|
||||||
| TargetBIOS -> None
|
|
||||||
| TargetUEFI -> Some (find_uefi_firmware guestcaps.gcaps_arch) in
|
|
||||||
- let secure_boot_required =
|
|
||||||
- match uefi_firmware with
|
|
||||||
- | Some { Uefi.flags }
|
|
||||||
- when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags -> true
|
|
||||||
- | _ -> false in
|
|
||||||
- (* Currently these are required by secure boot, but in theory they
|
|
||||||
- * might be independent properties.
|
|
||||||
- *)
|
|
||||||
- let machine_q35 = secure_boot_required in
|
|
||||||
+ let machine, secure_boot_required =
|
|
||||||
+ match guestcaps.gcaps_machine, uefi_firmware with
|
|
||||||
+ | _, Some { Uefi.flags }
|
|
||||||
+ when List.mem Uefi.UEFI_FLAG_SECURE_BOOT_REQUIRED flags ->
|
|
||||||
+ (* Force machine type to Q35 because PC does not support
|
|
||||||
+ * secure boot. We must remove this when we get the
|
|
||||||
+ * correct machine type from libosinfo in future. XXX
|
|
||||||
+ *)
|
|
||||||
+ Q35, true
|
|
||||||
+ | machine, _ ->
|
|
||||||
+ machine, false in
|
|
||||||
let smm = secure_boot_required in
|
|
||||||
|
|
||||||
+ let machine =
|
|
||||||
+ match machine with
|
|
||||||
+ | I440FX -> "pc"
|
|
||||||
+ | Q35 -> "q35"
|
|
||||||
+ | Virt -> "virt" in
|
|
||||||
+
|
|
||||||
(* Construct the command line. Note that the [Qemuopts]
|
|
||||||
* module deals with shell and qemu comma quoting.
|
|
||||||
*)
|
|
||||||
@@ -80,8 +88,8 @@ object
|
|
||||||
|
|
||||||
flag "-no-user-config"; flag "-nodefaults";
|
|
||||||
arg "-name" source.s_name;
|
|
||||||
- arg_list "-machine" (if machine_q35 then ["q35"] else [] @
|
|
||||||
- if smm then ["smm=on"] else [] @
|
|
||||||
+ arg_list "-machine" (machine ::
|
|
||||||
+ (if smm then ["smm=on"] else []) @
|
|
||||||
["accel=kvm:tcg"]);
|
|
||||||
|
|
||||||
(match uefi_firmware with
|
|
||||||
diff --git a/v2v/test-v2v-i-ova.xml b/v2v/test-v2v-i-ova.xml
|
|
||||||
index 5a303b80a..b277193a8 100644
|
|
||||||
--- a/v2v/test-v2v-i-ova.xml
|
|
||||||
+++ b/v2v/test-v2v-i-ova.xml
|
|
||||||
@@ -10,7 +10,7 @@
|
|
||||||
<apic/>
|
|
||||||
</features>
|
|
||||||
<os>
|
|
||||||
- <type arch='x86_64'>hvm</type>
|
|
||||||
+ <type arch='x86_64' machine='pc'>hvm</type>
|
|
||||||
</os>
|
|
||||||
<on_poweroff>destroy</on_poweroff>
|
|
||||||
<on_reboot>restart</on_reboot>
|
|
||||||
diff --git a/v2v/types.ml b/v2v/types.ml
|
|
||||||
index bb77e5669..9851386f7 100644
|
|
||||||
--- a/v2v/types.ml
|
|
||||||
+++ b/v2v/types.ml
|
|
||||||
@@ -401,6 +401,7 @@ type guestcaps = {
|
|
||||||
gcaps_virtio_rng : bool;
|
|
||||||
gcaps_virtio_balloon : bool;
|
|
||||||
gcaps_isa_pvpanic : bool;
|
|
||||||
+ gcaps_machine : guestcaps_machine;
|
|
||||||
gcaps_arch : string;
|
|
||||||
gcaps_acpi : bool;
|
|
||||||
}
|
|
||||||
@@ -412,6 +413,7 @@ and requested_guestcaps = {
|
|
||||||
and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
|
|
||||||
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
|
|
||||||
and guestcaps_video_type = QXL | Cirrus
|
|
||||||
+and guestcaps_machine = I440FX | Q35 | Virt
|
|
||||||
|
|
||||||
let string_of_block_type = function
|
|
||||||
| Virtio_blk -> "virtio-blk"
|
|
||||||
@@ -424,17 +426,23 @@ let string_of_net_type = function
|
|
||||||
let string_of_video = function
|
|
||||||
| QXL -> "qxl"
|
|
||||||
| Cirrus -> "cirrus"
|
|
||||||
+let string_of_machine = function
|
|
||||||
+ | I440FX -> "i440fx"
|
|
||||||
+ | Q35 -> "q35"
|
|
||||||
+ | Virt -> "virt"
|
|
||||||
|
|
||||||
let string_of_guestcaps gcaps =
|
|
||||||
sprintf "\
|
|
||||||
gcaps_block_bus = %s
|
|
||||||
gcaps_net_bus = %s
|
|
||||||
gcaps_video = %s
|
|
||||||
+gcaps_machine = %s
|
|
||||||
gcaps_arch = %s
|
|
||||||
gcaps_acpi = %b
|
|
||||||
" (string_of_block_type gcaps.gcaps_block_bus)
|
|
||||||
(string_of_net_type gcaps.gcaps_net_bus)
|
|
||||||
(string_of_video gcaps.gcaps_video)
|
|
||||||
+ (string_of_machine gcaps.gcaps_machine)
|
|
||||||
gcaps.gcaps_arch
|
|
||||||
gcaps.gcaps_acpi
|
|
||||||
|
|
||||||
diff --git a/v2v/types.mli b/v2v/types.mli
|
|
||||||
index f60e5c98f..5e33b1de9 100644
|
|
||||||
--- a/v2v/types.mli
|
|
||||||
+++ b/v2v/types.mli
|
|
||||||
@@ -240,8 +240,9 @@ type guestcaps = {
|
|
||||||
gcaps_virtio_balloon : bool; (** Guest supports virtio balloon. *)
|
|
||||||
gcaps_isa_pvpanic : bool; (** Guest supports ISA pvpanic device. *)
|
|
||||||
|
|
||||||
- gcaps_arch : string; (** Architecture that KVM must emulate. *)
|
|
||||||
- gcaps_acpi : bool; (** True if guest supports acpi. *)
|
|
||||||
+ gcaps_machine : guestcaps_machine; (** Machine model. *)
|
|
||||||
+ gcaps_arch : string; (** Architecture that KVM must emulate. *)
|
|
||||||
+ gcaps_acpi : bool; (** True if guest supports acpi. *)
|
|
||||||
}
|
|
||||||
(** Guest capabilities after conversion. eg. Was virtio found or installed? *)
|
|
||||||
|
|
||||||
@@ -257,6 +258,7 @@ and requested_guestcaps = {
|
|
||||||
and guestcaps_block_type = Virtio_blk | Virtio_SCSI | IDE
|
|
||||||
and guestcaps_net_type = Virtio_net | E1000 | RTL8139
|
|
||||||
and guestcaps_video_type = QXL | Cirrus
|
|
||||||
+and guestcaps_machine = I440FX | Q35 | Virt
|
|
||||||
|
|
||||||
val string_of_guestcaps : guestcaps -> string
|
|
||||||
val string_of_requested_guestcaps : requested_guestcaps -> string
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,84 @@
|
|||||||
|
From 8d39f6bcf21a7c76e29c270b9304c978bbf2e8ba 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.25.4
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
From 49623c945c93b878d13c0539eddf2d625f5aeb3c 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.25.4
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
From 8a4072c4b16e20c6ac55cbf350bfae2d0d1c7a0b Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Mon, 3 Sep 2018 15:24:05 +0100
|
|
||||||
Subject: [PATCH] v2v: windows: Fix rhev-apt command line (RHBZ#1624902).
|
|
||||||
|
|
||||||
See:
|
|
||||||
https://bugzilla.redhat.com/show_bug.cgi?id=1584678#c15
|
|
||||||
|
|
||||||
Fixes commit bcdbe6405c10ecb7374ae47eee6385be17dbd49e. However this
|
|
||||||
bug was copied directly from old virt-v2v which did the same thing
|
|
||||||
(from lib/Sys/VirtConvert/Converter/Windows.pm):
|
|
||||||
|
|
||||||
echo installing rhev-apt >>log.txt
|
|
||||||
"rhev-apt.exe" /S /v /qn >>log.txt
|
|
||||||
|
|
||||||
Thanks: Lev Veyde
|
|
||||||
(cherry picked from commit e12c56176abcc2d970a35f83bffc95f7ad1b2aab)
|
|
||||||
---
|
|
||||||
v2v/convert_windows.ml | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
|
||||||
index 1e058136e..0346ba4fe 100644
|
|
||||||
--- a/v2v/convert_windows.ml
|
|
||||||
+++ b/v2v/convert_windows.ml
|
|
||||||
@@ -347,7 +347,7 @@ echo Wait for PnP to complete
|
|
||||||
@echo off
|
|
||||||
|
|
||||||
echo installing rhev-apt
|
|
||||||
-\"\\rhev-apt.exe\" /S /v /qn
|
|
||||||
+\"\\rhev-apt.exe\" /S /v/qn
|
|
||||||
|
|
||||||
echo starting rhev-apt
|
|
||||||
net start rhev-apt
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
From 03b67600b98e8af2ea199f8643b2993c1effc60f 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.25.4
|
||||||
|
|
@ -1,40 +0,0 @@
|
|||||||
From 4d78c436b15742c25288bcae441a9782ee316fe5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
||||||
Date: Mon, 3 Sep 2018 14:30:21 +0100
|
|
||||||
Subject: [PATCH] v2v: docs: Describe support for SHA-2 certs for Windows 7 /
|
|
||||||
2008 R2 (RHBZ#1624878).
|
|
||||||
|
|
||||||
Thanks: Yan Vugenfirer.
|
|
||||||
(cherry picked from commit 741ef228cd8d17bd1a8a60a2cfa83c3937120ede)
|
|
||||||
---
|
|
||||||
v2v/virt-v2v.pod | 14 ++++++++++++++
|
|
||||||
1 file changed, 14 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
|
||||||
index 893e47fb9..dc443b717 100644
|
|
||||||
--- a/v2v/virt-v2v.pod
|
|
||||||
+++ b/v2v/virt-v2v.pod
|
|
||||||
@@ -1097,6 +1097,20 @@ This can also prevent booting with a 7B error [see previous section]
|
|
||||||
if the guest has group policy containing
|
|
||||||
C<Device Installation Restrictions>.
|
|
||||||
|
|
||||||
+=head2 Support for SHA-2 certificates in Windows 7 and Windows Server 2008 R2
|
|
||||||
+
|
|
||||||
+Later versions of the Windows virtio drivers are signed using SHA-2
|
|
||||||
+certificates (instead of SHA-1). The original shipping Windows 7 and
|
|
||||||
+Windows Server 2008 R2 did not understand SHA-2 certificates and so
|
|
||||||
+the Windows virtio drivers will not install properly.
|
|
||||||
+
|
|
||||||
+To fix this you must apply SHA-2 Code Signing Support from:
|
|
||||||
+L<https://docs.microsoft.com/en-us/security-updates/SecurityAdvisories/2015/3033929>
|
|
||||||
+before converting the guest.
|
|
||||||
+
|
|
||||||
+For further information see:
|
|
||||||
+L<https://bugzilla.redhat.com/show_bug.cgi?id=1624878>
|
|
||||||
+
|
|
||||||
=head1 UEFI
|
|
||||||
|
|
||||||
VMware allows you to present UEFI firmware to guests (instead of the
|
|
||||||
--
|
|
||||||
2.21.0
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user