import libguestfs-1.40.2-22.module+el8.3.0+6423+e4cb6418
This commit is contained in:
commit
215d58342a
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-3
|
||||
SOURCES/libguestfs-1.40.2.tar.gz
|
||||
SOURCES/libguestfs.keyring
|
||||
SOURCES/rhsrvany.exe
|
4
.libguestfs.metadata
Normal file
4
.libguestfs.metadata
Normal file
@ -0,0 +1,4 @@
|
||||
ac8722917cc31c36836e241bd7a4beb5f8a8b0c8 SOURCES/RHEV-Application-Provisioning-Tool.exe_4.43-3
|
||||
45755f0f73b503790974484053ff482f32665b13 SOURCES/libguestfs-1.40.2.tar.gz
|
||||
1bbc40f501a7fef9eef2a39b701a71aee2fea7c4 SOURCES/libguestfs.keyring
|
||||
2bd96e478fc004cd323b5bd754c856641877dac6 SOURCES/rhsrvany.exe
|
@ -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.24.1
|
||||
|
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.24.1
|
||||
|
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.24.1
|
||||
|
32
SOURCES/0004-inspect-fix-icon-of-RHEL.patch
Normal file
32
SOURCES/0004-inspect-fix-icon-of-RHEL.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From e7ff090884f5e32585e9683d35b72bca01e0a836 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Mon, 11 Feb 2019 19:28:00 +0100
|
||||
Subject: [PATCH] inspect: fix icon of RHEL
|
||||
|
||||
Use a better icon for RHEL guests, still provided by redhat-logos (or
|
||||
equivalent in downstream distributions), and which fits a better
|
||||
definition of logo for the distribution.
|
||||
|
||||
Thanks to Ray Strode for the hints.
|
||||
|
||||
(cherry picked from commit c648052690a4a07a59c741308e0e8497d6f18057)
|
||||
---
|
||||
lib/inspect-icon.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lib/inspect-icon.c b/lib/inspect-icon.c
|
||||
index 623591aa6..19f3f87af 100644
|
||||
--- a/lib/inspect-icon.c
|
||||
+++ b/lib/inspect-icon.c
|
||||
@@ -317,7 +317,7 @@ icon_rhel (guestfs_h *g, int major, size_t *size_r)
|
||||
if (major < 7)
|
||||
shadowman = "/usr/share/pixmaps/redhat/shadowman-transparent.png";
|
||||
else
|
||||
- shadowman = "/usr/share/pixmaps/fedora-logo-sprite.png";
|
||||
+ shadowman = "/usr/share/icons/hicolor/96x96/apps/system-logo-icon.png";
|
||||
|
||||
return get_png (g, shadowman, size_r, 102400);
|
||||
}
|
||||
--
|
||||
2.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -0,0 +1,55 @@
|
||||
From de267e07b9b26d2f89470d4305d7259edb24663b Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 12 Apr 2019 16:19:43 +0200
|
||||
Subject: [PATCH] v2v: update documentation on nbdkit (RHBZ#1605242)
|
||||
|
||||
nbdkit >= 1.6 ships a VDDK plugin always built, so recommend that
|
||||
version instead of recommending to build nbdkit from sources.
|
||||
|
||||
(cherry picked from commit 0704d8eb0bcc8139886eb4291f75a3ca49a91e58)
|
||||
---
|
||||
v2v/virt-v2v-input-vmware.pod | 28 ++--------------------------
|
||||
1 file changed, 2 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/v2v/virt-v2v-input-vmware.pod b/v2v/virt-v2v-input-vmware.pod
|
||||
index 2b6dbaeec..b3ebda182 100644
|
||||
--- a/v2v/virt-v2v-input-vmware.pod
|
||||
+++ b/v2v/virt-v2v-input-vmware.pod
|
||||
@@ -197,32 +197,8 @@ library is permitted by the license.
|
||||
|
||||
=item 2.
|
||||
|
||||
-You must also compile nbdkit, enabling the VDDK plugin. nbdkit E<ge>
|
||||
-1.1.25 is recommended, but it is usually best to compile from the git
|
||||
-tree.
|
||||
-
|
||||
-=over 4
|
||||
-
|
||||
-=item *
|
||||
-
|
||||
-L<https://github.com/libguestfs/nbdkit>
|
||||
-
|
||||
-=item *
|
||||
-
|
||||
-L<https://github.com/libguestfs/nbdkit/tree/master/plugins/vddk>
|
||||
-
|
||||
-=back
|
||||
-
|
||||
-Compile nbdkit as described in the sources (see link above).
|
||||
-
|
||||
-You do B<not> need to run C<make install> because you can run nbdkit
|
||||
-from its source directory. The source directory has a shell script
|
||||
-called F<nbdkit> which runs the locally built copy of nbdkit and its
|
||||
-plugins. So set C<$PATH> to point to the nbdkit top build directory
|
||||
-(that is, the directory containing the shell script called F<nbdkit>),
|
||||
-eg:
|
||||
-
|
||||
- export PATH=/path/to/nbdkit-1.1.x:$PATH
|
||||
+nbdkit E<ge> 1.6 is recommended, as it ships with the VDDK plugin
|
||||
+enabled unconditionally.
|
||||
|
||||
=item 3.
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
63
SOURCES/0010-Use-proper-label-for-nbdkit-sockets.patch
Normal file
63
SOURCES/0010-Use-proper-label-for-nbdkit-sockets.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From 54b63460b7602ac5c68d6e58ab60e7f85877cefc Mon Sep 17 00:00:00 2001
|
||||
From: Martin Kletzander <mkletzan@redhat.com>
|
||||
Date: Mon, 27 May 2019 13:30:05 +0200
|
||||
Subject: [PATCH] Use proper label for nbdkit sockets
|
||||
|
||||
While svirt_t can be used for sockets it does not always guarantee that it will
|
||||
be accessible from a virtual machine. The VM might be running under svirt_tcg_t
|
||||
context which will need a svirt_tcg_t label on the socket in order to access it.
|
||||
|
||||
There is, however, another label, svirt_socket_t, which is accessible from
|
||||
virt_domain:
|
||||
|
||||
# sesearch -A -s svirt_t -c unix_stream_socket -p connectto
|
||||
...
|
||||
allow virt_domain svirt_socket_t:unix_stream_socket { ... connectto ... };
|
||||
...
|
||||
|
||||
And virt_domain is a type attribute of both svirt_t and svirt_tcg_t:
|
||||
|
||||
# seinfo -x -a virt_domain
|
||||
Type Attributes: 1
|
||||
attribute virt_domain;
|
||||
svirt_t
|
||||
svirt_tcg_t
|
||||
|
||||
Resolves: https://bugzilla.redhat.com/1698437
|
||||
|
||||
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
||||
(cherry picked from commit c2918b8b74506523a723b804d452816a059c5e50)
|
||||
---
|
||||
v2v/input_libvirt_vddk.ml | 2 +-
|
||||
v2v/output_rhv_upload.ml | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml
|
||||
index 97c7cb532..567233d58 100644
|
||||
--- a/v2v/input_libvirt_vddk.ml
|
||||
+++ b/v2v/input_libvirt_vddk.ml
|
||||
@@ -290,7 +290,7 @@ object
|
||||
add_arg "--newstyle"; (* use newstyle NBD protocol *)
|
||||
add_arg "--exportname"; add_arg "/";
|
||||
if have_selinux then ( (* label the socket so qemu can open it *)
|
||||
- add_arg "--selinux-label"; add_arg "system_u:object_r:svirt_t:s0"
|
||||
+ add_arg "--selinux-label"; add_arg "system_u:object_r:svirt_socket_t:s0"
|
||||
);
|
||||
|
||||
(* Name of the plugin. Everything following is a plugin parameter. *)
|
||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||
index 77c39107e..c2a5c72c7 100644
|
||||
--- a/v2v/output_rhv_upload.ml
|
||||
+++ b/v2v/output_rhv_upload.ml
|
||||
@@ -217,7 +217,7 @@ See also the virt-v2v-output-rhv(1) manual.")
|
||||
let args =
|
||||
(* label the socket so qemu can open it *)
|
||||
if have_selinux then
|
||||
- args @ ["--selinux-label"; "system_u:object_r:svirt_t:s0"]
|
||||
+ args @ ["--selinux-label"; "system_u:object_r:svirt_socket_t:s0"]
|
||||
else args in
|
||||
args in
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -0,0 +1,49 @@
|
||||
From d74842f209b5461692a2d283d622157862bdc230 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 25 Jul 2019 14:52:42 +0100
|
||||
Subject: [PATCH] v2v: -i vmx: Use scp -T option if available to unbreak scp
|
||||
(RHBZ#1733168).
|
||||
|
||||
Tested using:
|
||||
|
||||
cd v2v
|
||||
LIBGUESTFS_BACKEND=direct ../run virt-v2v -i vmx -it ssh "ssh://localhost/$PWD/test-v2v-i-vmx-1.vmx" -o null -v -x
|
||||
|
||||
and manually examining the debug output.
|
||||
|
||||
Thanks: Ming Xie, Jakub Jelen.
|
||||
(cherry picked from commit 7692c31494f7b1d37e380eed9eb99c5952940dbf)
|
||||
---
|
||||
v2v/input_vmx.ml | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/input_vmx.ml b/v2v/input_vmx.ml
|
||||
index b169b2537..e3469308d 100644
|
||||
--- a/v2v/input_vmx.ml
|
||||
+++ b/v2v/input_vmx.ml
|
||||
@@ -61,6 +61,11 @@ let server_of_uri { Xml.uri_server } =
|
||||
let path_of_uri { Xml.uri_path } =
|
||||
match uri_path with None -> assert false | Some p -> p
|
||||
|
||||
+let scp_supports_T_option = lazy (
|
||||
+ let cmd = "LANG=C scp -T |& grep \"unknown option\"" in
|
||||
+ shell_command cmd <> 0
|
||||
+)
|
||||
+
|
||||
(* 'scp' a remote file into a temporary local file, returning the path
|
||||
* of the temporary local file.
|
||||
*)
|
||||
@@ -68,8 +73,9 @@ let scp_from_remote_to_temporary uri tmpdir filename =
|
||||
let localfile = tmpdir // filename in
|
||||
|
||||
let cmd =
|
||||
- sprintf "scp%s%s %s%s:%s %s"
|
||||
+ sprintf "scp%s%s%s %s%s:%s %s"
|
||||
(if verbose () then "" else " -q")
|
||||
+ (if Lazy.force scp_supports_T_option then " -T" else "")
|
||||
(match port_of_uri uri with
|
||||
| None -> ""
|
||||
| Some port -> sprintf " -P %d" port)
|
||||
--
|
||||
2.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
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.24.1
|
||||
|
@ -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.24.1
|
||||
|
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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
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.24.1
|
||||
|
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.24.1
|
||||
|
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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
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.24.1
|
||||
|
@ -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.24.1
|
||||
|
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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -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.24.1
|
||||
|
@ -0,0 +1,35 @@
|
||||
From ebc6680ab1030c763a6c4764f6045734c41f0e7f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Thu, 16 Jan 2020 16:05:10 +0100
|
||||
Subject: [PATCH] add versioned directory for guest agent on EL8
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There was no source directory for EL8 guest agent (only EL6 and EL7).
|
||||
|
||||
RHBZ#1791802
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
|
||||
(cherry picked from commit 79dd6a6bbb7e95691be18f54d601318d7d713702
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/windows_virtio.ml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
|
||||
index a6dc29f2c..7be63a316 100644
|
||||
--- a/v2v/windows_virtio.ml
|
||||
+++ b/v2v/windows_virtio.ml
|
||||
@@ -192,6 +192,7 @@ and install_linux_tools g inspect =
|
||||
(match inspect.i_major_version with
|
||||
| 6 -> Some "el6"
|
||||
| 7 -> Some "el7"
|
||||
+ | 8 -> Some "el8"
|
||||
| _ -> None)
|
||||
| "sles" | "suse-based" | "opensuse" -> Some "lp151"
|
||||
| _ -> None in
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,41 @@
|
||||
From 1d0a22aa3f950330b0cf9c5e874642b5a02edf17 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Fri, 8 Feb 2019 11:44:41 +0100
|
||||
Subject: [PATCH] v2v: fix path to source when copying files from guest tools
|
||||
directory
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The debug message was slightly changed too to better match the similar
|
||||
message for ISO case. It refers to the root directory instead of the
|
||||
specific subdirectory inside guest tools.
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
(cherry picked from commit f4bda5571a36da42bdc800c10f2c85cf20bf5c85)
|
||||
---
|
||||
v2v/windows_virtio.ml | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
|
||||
index 7be63a316..70f0bf09d 100644
|
||||
--- a/v2v/windows_virtio.ml
|
||||
+++ b/v2v/windows_virtio.ml
|
||||
@@ -309,10 +309,11 @@ and copy_drivers g inspect driverdir =
|
||||
and copy_from_virtio_win g inspect srcdir destdir filter missing =
|
||||
let ret = ref [] in
|
||||
if is_directory virtio_win then (
|
||||
- let dir = virtio_win // srcdir in
|
||||
- debug "windows: copy_from_virtio_win: guest tools source directory %s" dir;
|
||||
+ debug "windows: copy_from_virtio_win: guest tools source directory %s"
|
||||
+ virtio_win;
|
||||
|
||||
- if not (is_directory srcdir) then missing ()
|
||||
+ let dir = virtio_win // srcdir in
|
||||
+ if not (is_directory dir) then missing ()
|
||||
else (
|
||||
let cmd = sprintf "cd %s && find -L -type f" (quote dir) in
|
||||
let paths = external_command cmd in
|
||||
--
|
||||
2.24.1
|
||||
|
119
SOURCES/0052-v2v-windows-install-QEMU-Guest-Agent-MSI.patch
Normal file
119
SOURCES/0052-v2v-windows-install-QEMU-Guest-Agent-MSI.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From c664b50ab691a85d8a827ba51ea767744da548c3 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Tue, 8 Oct 2019 13:16:38 +0200
|
||||
Subject: [PATCH] v2v: windows: install QEMU Guest Agent MSI
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Use firstboot script to install MSI with QEMU-GA from virtio-win ISO or
|
||||
oVirt/RHV guest tools ISO.
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
(cherry picked from commit 00b4ed312b0ba179e9901b73c099724c3f6606b4)
|
||||
---
|
||||
v2v/convert_windows.ml | 19 +++++++++++++++++++
|
||||
v2v/windows_virtio.ml | 27 +++++++++++++++++++++++++++
|
||||
v2v/windows_virtio.mli | 4 ++++
|
||||
3 files changed, 50 insertions(+)
|
||||
|
||||
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
||||
index 75e609d61..bdb0092c3 100644
|
||||
--- a/v2v/convert_windows.ml
|
||||
+++ b/v2v/convert_windows.ml
|
||||
@@ -293,6 +293,13 @@ let convert (g : G.guestfs) inspect source output rcaps static_ips =
|
||||
if Sys.file_exists tool_path then
|
||||
configure_vmdp tool_path;
|
||||
|
||||
+ (* Install QEMU Guest Agent unconditionally and warn if missing *)
|
||||
+ let qemu_ga_files = Windows_virtio.copy_qemu_ga g inspect in
|
||||
+ if qemu_ga_files <> [] then
|
||||
+ configure_qemu_ga qemu_ga_files
|
||||
+ else
|
||||
+ warning (f_"QEMU Guest Agent MSI not found on tools ISO/directory. You may want to install the guest agent manually after conversion.");
|
||||
+
|
||||
unconfigure_xenpv ();
|
||||
unconfigure_prltools ();
|
||||
unconfigure_vmwaretools ()
|
||||
@@ -418,6 +425,18 @@ popd
|
||||
Firstboot.add_firstboot_script g inspect.i_root
|
||||
"finish vmdp setup" fb_recover_script
|
||||
|
||||
+ and configure_qemu_ga files =
|
||||
+ List.iter (
|
||||
+ fun msi_path ->
|
||||
+ let fb_script = "\
|
||||
+echo Installing qemu-ga from " ^ msi_path ^ "
|
||||
+\"\\" ^ msi_path ^ "\" /qn /forcerestart /l+*vx \"%cd%\\qemu-ga.log\"
|
||||
+" in
|
||||
+ Firstboot.add_firstboot_script g inspect.i_root
|
||||
+ ("install " ^ msi_path) fb_script;
|
||||
+ ) files
|
||||
+
|
||||
+
|
||||
and unconfigure_xenpv () =
|
||||
match xenpv_uninst with
|
||||
| None -> () (* nothing to be uninstalled *)
|
||||
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
|
||||
index 70f0bf09d..ea7e5c02d 100644
|
||||
--- a/v2v/windows_virtio.ml
|
||||
+++ b/v2v/windows_virtio.ml
|
||||
@@ -296,6 +296,13 @@ and copy_drivers g inspect driverdir =
|
||||
(fun () ->
|
||||
error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log."))
|
||||
|
||||
+and copy_qemu_ga g inspect =
|
||||
+ copy_from_virtio_win g inspect "/" "/"
|
||||
+ virtio_iso_path_matches_qemu_ga
|
||||
+ (fun () ->
|
||||
+ error (f_"root directory ‘/’ is missing from the virtio-win directory or ISO.\n\nThis should not happen and may indicate that virtio-win or virt-v2v is broken in some way. Please report this as a bug with a full debug log."))
|
||||
+
|
||||
+
|
||||
(* Copy all files from virtio_win directory/ISO located in [srcdir]
|
||||
* subdirectory and all its subdirectories to the [destdir]. The directory
|
||||
* hierarchy is not preserved, meaning all files will be directly in [destdir].
|
||||
@@ -427,6 +434,26 @@ and virtio_iso_path_matches_guest_os path inspect =
|
||||
|
||||
with Not_found -> false
|
||||
|
||||
+(* Given a path of a file relative to the root of the directory tree
|
||||
+ * with virtio-win drivers, figure out if it's suitable for the
|
||||
+ * specific Windows flavor of the current guest.
|
||||
+ *)
|
||||
+and virtio_iso_path_matches_qemu_ga path inspect =
|
||||
+ let { i_arch = arch } = inspect in
|
||||
+ (* Lowercased path, since the ISO may contain upper or lowercase path
|
||||
+ * elements.
|
||||
+ *)
|
||||
+ let lc_name = String.lowercase_ascii (Filename.basename path) in
|
||||
+ lc_name = "rhev-qga.msi" ||
|
||||
+ match arch, lc_name with
|
||||
+ | ("i386", "qemu-ga-x86.msi")
|
||||
+ | ("i386", "qemu-ga-i386.msi")
|
||||
+ | ("i386", "RHEV-QGA.msi")
|
||||
+ | ("x86_64", "qemu-ga-x64.msi")
|
||||
+ | ("x86_64", "qemu-ga-x86_64.msi")
|
||||
+ | ("x86_64", "RHEV-QGA64.msi") -> true
|
||||
+ | _ -> false
|
||||
+
|
||||
(* The following function is only exported for unit tests. *)
|
||||
module UNIT_TESTS = struct
|
||||
let virtio_iso_path_matches_guest_os = virtio_iso_path_matches_guest_os
|
||||
diff --git a/v2v/windows_virtio.mli b/v2v/windows_virtio.mli
|
||||
index ae3b7e865..731dbd6f0 100644
|
||||
--- a/v2v/windows_virtio.mli
|
||||
+++ b/v2v/windows_virtio.mli
|
||||
@@ -44,6 +44,10 @@ val install_linux_tools : Guestfs.guestfs -> Types.inspect -> unit
|
||||
(** installs QEMU Guest Agent on Linux guest OS from the driver directory or
|
||||
driver ISO. It is not fatal if we fail to install the agent. *)
|
||||
|
||||
+val copy_qemu_ga : Guestfs.guestfs -> Types.inspect -> string list
|
||||
+(** copy MSIs (idealy just one) with QEMU Guest Agent to Windows guest. The
|
||||
+ MSIs are not installed by this function. *)
|
||||
+
|
||||
(**/**)
|
||||
|
||||
(* The following function is only exported for unit tests. *)
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,42 @@
|
||||
From b5e6c21a8241b3040c772f5ecd93a23a1896dc53 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Wed, 5 Feb 2020 14:11:36 +0100
|
||||
Subject: [PATCH] windows: small tweaks of qemu-ga firstboot script
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
- match log file with script name
|
||||
- restart manually only after successfull install, this also helps
|
||||
debugging because we can log the installer return code
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
|
||||
(cherry picked from commit 59f9ff40621240a6eed28c4425d3d69d8b21bc0e
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/convert_windows.ml | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
||||
index bdb0092c3..43c1f85de 100644
|
||||
--- a/v2v/convert_windows.ml
|
||||
+++ b/v2v/convert_windows.ml
|
||||
@@ -430,7 +430,13 @@ popd
|
||||
fun msi_path ->
|
||||
let fb_script = "\
|
||||
echo Installing qemu-ga from " ^ msi_path ^ "
|
||||
-\"\\" ^ msi_path ^ "\" /qn /forcerestart /l+*vx \"%cd%\\qemu-ga.log\"
|
||||
+\"\\" ^ msi_path ^ "\" /norestart /qn /l+*vx \"%~dpn0.log\"
|
||||
+set elvl=!errorlevel!
|
||||
+echo Done installing qemu-ga error_level=!elvl!
|
||||
+if !elvl! == 0 (
|
||||
+ echo Restarting Windows...
|
||||
+ shutdown /r /f /c \"rebooted by firstboot script\"
|
||||
+)
|
||||
" in
|
||||
Firstboot.add_firstboot_script g inspect.i_root
|
||||
("install " ^ msi_path) fb_script;
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,43 @@
|
||||
From 34305aa93b6107c0aa9efcb1197efae3675a4ffe Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Wed, 5 Feb 2020 14:11:35 +0100
|
||||
Subject: [PATCH] windows: fix detection of qemu-ga installer on RHV
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The detection was incorrectly matching only 32-bit installer on all
|
||||
architectures.
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
|
||||
(cherry picked from commit 45acf8d0557bee948c035305a6bafc6c9963a467
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/windows_virtio.ml | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/v2v/windows_virtio.ml b/v2v/windows_virtio.ml
|
||||
index ea7e5c02d..9a7297344 100644
|
||||
--- a/v2v/windows_virtio.ml
|
||||
+++ b/v2v/windows_virtio.ml
|
||||
@@ -444,14 +444,13 @@ and virtio_iso_path_matches_qemu_ga path inspect =
|
||||
* elements.
|
||||
*)
|
||||
let lc_name = String.lowercase_ascii (Filename.basename path) in
|
||||
- lc_name = "rhev-qga.msi" ||
|
||||
match arch, lc_name with
|
||||
| ("i386", "qemu-ga-x86.msi")
|
||||
| ("i386", "qemu-ga-i386.msi")
|
||||
- | ("i386", "RHEV-QGA.msi")
|
||||
+ | ("i386", "rhev-qga.msi")
|
||||
| ("x86_64", "qemu-ga-x64.msi")
|
||||
| ("x86_64", "qemu-ga-x86_64.msi")
|
||||
- | ("x86_64", "RHEV-QGA64.msi") -> true
|
||||
+ | ("x86_64", "rhev-qga64.msi") -> true
|
||||
| _ -> false
|
||||
|
||||
(* The following function is only exported for unit tests. *)
|
||||
--
|
||||
2.24.1
|
||||
|
67
SOURCES/0055-windows-delay-installation-of-qemu-ga-MSI.patch
Normal file
67
SOURCES/0055-windows-delay-installation-of-qemu-ga-MSI.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From 34a8b1a7115aeb95812ae8ee182055de757f3892 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= <tgolembi@redhat.com>
|
||||
Date: Thu, 5 Mar 2020 15:37:13 +0100
|
||||
Subject: [PATCH] windows: delay installation of qemu-ga MSI
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Instead of running firstboot script during early boot schedule a task
|
||||
delayed for 2 minutes.
|
||||
|
||||
During the first boot, after virt-v2v conversion, Windows installs the
|
||||
drivers injected by virt-v2v. When this installation is finished
|
||||
Windows enforces some kind of internal reboot. This unfortunately
|
||||
terminates any running firstboot scripts thus killing the installation
|
||||
of qemu-ga MSI.
|
||||
|
||||
This is just a best-effort mitigation. It can still happen (e.g. with
|
||||
slow disk drives) that the drivers are not yet installed when the
|
||||
delayed installation starts. On the other hand we cannot delay it too
|
||||
much otherwise we risk that the users logs in and will be doing some
|
||||
work when the MSI installation starts. After MSI installation finishes
|
||||
the VM needs to be rebooted which would be annoying if that would happen
|
||||
under users hands. Although this is not a best fix (that may come later
|
||||
as it is more complex, e.g. introducing waiting mechanism), the delay as
|
||||
it is defined works in most cases. And it dramaticaly improves the
|
||||
situations -- originaly I experienced more than 90% failure rate.
|
||||
|
||||
Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com>
|
||||
|
||||
(cherry picked from commit dc66e78fa37db33e3c7358b7f7c7fa809cf62f9d
|
||||
in virt-v2v)
|
||||
---
|
||||
v2v/convert_windows.ml | 17 +++++++----------
|
||||
1 file changed, 7 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
|
||||
index 43c1f85de..088cd33d9 100644
|
||||
--- a/v2v/convert_windows.ml
|
||||
+++ b/v2v/convert_windows.ml
|
||||
@@ -428,16 +428,13 @@ popd
|
||||
and configure_qemu_ga files =
|
||||
List.iter (
|
||||
fun msi_path ->
|
||||
- let fb_script = "\
|
||||
-echo Installing qemu-ga from " ^ msi_path ^ "
|
||||
-\"\\" ^ msi_path ^ "\" /norestart /qn /l+*vx \"%~dpn0.log\"
|
||||
-set elvl=!errorlevel!
|
||||
-echo Done installing qemu-ga error_level=!elvl!
|
||||
-if !elvl! == 0 (
|
||||
- echo Restarting Windows...
|
||||
- shutdown /r /f /c \"rebooted by firstboot script\"
|
||||
-)
|
||||
-" in
|
||||
+ let fb_script = sprintf "\
|
||||
+echo Removing any previously scheduled qemu-ga installation
|
||||
+schtasks.exe /Delete /TN Firstboot-qemu-ga /F
|
||||
+echo Scheduling delayed installation of qemu-ga from %s
|
||||
+powershell.exe -command \"$d = (get-date).AddSeconds(120); schtasks.exe /Create /SC ONCE /ST $d.ToString('HH:mm') /SD $d.ToString('MM/dd/yyyy') /RU SYSTEM /TN Firstboot-qemu-ga /TR \\\"C:\\%s /forcerestart /qn /l+*vx C:\\%s.log\\\"\"
|
||||
+ "
|
||||
+ msi_path msi_path msi_path in
|
||||
Firstboot.add_firstboot_script g inspect.i_root
|
||||
("install " ^ msi_path) fb_script;
|
||||
) files
|
||||
--
|
||||
2.24.1
|
||||
|
38
SOURCES/0056-RHEL-8-Remove-libguestfs-live-RHBZ-798980.patch
Normal file
38
SOURCES/0056-RHEL-8-Remove-libguestfs-live-RHBZ-798980.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From f9ceb4fd65f882c9e6aad6310567ce40d19c4070 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 21 Dec 2012 15:50:11 +0000
|
||||
Subject: [PATCH] RHEL 8: Remove libguestfs live (RHBZ#798980).
|
||||
|
||||
This isn't supported in RHEL 8.
|
||||
---
|
||||
lib/launch-unix.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/lib/launch-unix.c b/lib/launch-unix.c
|
||||
index 4794a7b13..993b83601 100644
|
||||
--- a/lib/launch-unix.c
|
||||
+++ b/lib/launch-unix.c
|
||||
@@ -37,6 +37,12 @@
|
||||
static int
|
||||
launch_unix (guestfs_h *g, void *datav, const char *sockpath)
|
||||
{
|
||||
+ error (g,
|
||||
+ "launch: In RHEL, only the 'libvirt' or 'direct' method is supported.\n"
|
||||
+ "In particular, \"libguestfs live\" is not supported.");
|
||||
+ return -1;
|
||||
+
|
||||
+#if 0
|
||||
int r, daemon_sock = -1;
|
||||
struct sockaddr_un addr;
|
||||
uint32_t size;
|
||||
@@ -106,6 +112,7 @@ launch_unix (guestfs_h *g, void *datav, const char *sockpath)
|
||||
g->conn = NULL;
|
||||
}
|
||||
return -1;
|
||||
+#endif
|
||||
}
|
||||
|
||||
static int
|
||||
--
|
||||
2.24.1
|
||||
|
372
SOURCES/0057-RHEL-8-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch
Normal file
372
SOURCES/0057-RHEL-8-Remove-9p-APIs-from-RHEL-RHBZ-921710.patch
Normal file
@ -0,0 +1,372 @@
|
||||
From 468bfa7cb5db1294310c0193e51bc5a20092f4ce Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 18 Jul 2013 18:31:53 +0100
|
||||
Subject: [PATCH] RHEL 8: Remove 9p APIs from RHEL (RHBZ#921710).
|
||||
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
daemon/9p.c | 224 --------------------------------------
|
||||
daemon/Makefile.am | 1 -
|
||||
docs/C_SOURCE_FILES | 1 -
|
||||
generator/actions_core.ml | 21 ----
|
||||
generator/proc_nr.ml | 2 -
|
||||
gobject/Makefile.inc | 2 -
|
||||
po/POTFILES | 2 -
|
||||
8 files changed, 1 insertion(+), 254 deletions(-)
|
||||
delete mode 100644 daemon/9p.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 0067d7b7b..e9351eadc 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -78,7 +78,7 @@ SUBDIRS += tests/xfs
|
||||
SUBDIRS += tests/charsets
|
||||
SUBDIRS += tests/xml
|
||||
SUBDIRS += tests/mount-local
|
||||
-SUBDIRS += tests/9p
|
||||
+#SUBDIRS += tests/9p
|
||||
SUBDIRS += tests/rsync
|
||||
SUBDIRS += tests/bigdirs
|
||||
SUBDIRS += tests/disk-labels
|
||||
diff --git a/daemon/9p.c b/daemon/9p.c
|
||||
deleted file mode 100644
|
||||
index 55644249d..000000000
|
||||
--- a/daemon/9p.c
|
||||
+++ /dev/null
|
||||
@@ -1,224 +0,0 @@
|
||||
-/* libguestfs - the guestfsd daemon
|
||||
- * Copyright (C) 2011 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.
|
||||
- */
|
||||
-
|
||||
-#include <config.h>
|
||||
-
|
||||
-#include <stdio.h>
|
||||
-#include <stdlib.h>
|
||||
-#include <string.h>
|
||||
-#include <unistd.h>
|
||||
-#include <limits.h>
|
||||
-#include <errno.h>
|
||||
-#include <sys/types.h>
|
||||
-#include <sys/stat.h>
|
||||
-#include <dirent.h>
|
||||
-#include <fcntl.h>
|
||||
-
|
||||
-#include "daemon.h"
|
||||
-#include "actions.h"
|
||||
-
|
||||
-#define BUS_PATH "/sys/bus/virtio/drivers/9pnet_virtio"
|
||||
-
|
||||
-static char *read_whole_file (const char *filename);
|
||||
-
|
||||
-/* https://bugzilla.redhat.com/show_bug.cgi?id=714981#c1 */
|
||||
-char **
|
||||
-do_list_9p (void)
|
||||
-{
|
||||
- CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (r);
|
||||
-
|
||||
- DIR *dir;
|
||||
-
|
||||
- dir = opendir (BUS_PATH);
|
||||
- if (!dir) {
|
||||
- perror ("opendir: " BUS_PATH);
|
||||
- if (errno != ENOENT) {
|
||||
- reply_with_perror ("opendir: " BUS_PATH);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- /* If this directory doesn't exist, it probably means that
|
||||
- * the virtio driver isn't loaded. Don't return an error
|
||||
- * in this case, but return an empty list.
|
||||
- */
|
||||
- if (end_stringsbuf (&r) == -1)
|
||||
- return NULL;
|
||||
-
|
||||
- return take_stringsbuf (&r);
|
||||
- }
|
||||
-
|
||||
- while (1) {
|
||||
- struct dirent *d;
|
||||
-
|
||||
- errno = 0;
|
||||
- d = readdir (dir);
|
||||
- if (d == NULL) break;
|
||||
-
|
||||
- if (STRPREFIX (d->d_name, "virtio")) {
|
||||
- CLEANUP_FREE char *mount_tag_path = NULL;
|
||||
- if (asprintf (&mount_tag_path, BUS_PATH "/%s/mount_tag",
|
||||
- d->d_name) == -1) {
|
||||
- reply_with_perror ("asprintf");
|
||||
- closedir (dir);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- /* A bit unclear, but it looks like the virtio transport allows
|
||||
- * the mount tag length to be unlimited (or up to 65536 bytes).
|
||||
- * See: linux/include/linux/virtio_9p.h
|
||||
- */
|
||||
- CLEANUP_FREE char *mount_tag = read_whole_file (mount_tag_path);
|
||||
- if (mount_tag == 0)
|
||||
- continue;
|
||||
-
|
||||
- if (add_string (&r, mount_tag) == -1) {
|
||||
- closedir (dir);
|
||||
- return NULL;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* Check readdir didn't fail */
|
||||
- if (errno != 0) {
|
||||
- reply_with_perror ("readdir: /sys/block");
|
||||
- closedir (dir);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- /* Close the directory handle */
|
||||
- if (closedir (dir) == -1) {
|
||||
- reply_with_perror ("closedir: /sys/block");
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- /* Sort the tags. */
|
||||
- if (r.size > 0)
|
||||
- sort_strings (r.argv, r.size);
|
||||
-
|
||||
- /* NULL terminate the list */
|
||||
- if (end_stringsbuf (&r) == -1)
|
||||
- return NULL;
|
||||
-
|
||||
- return take_stringsbuf (&r);
|
||||
-}
|
||||
-
|
||||
-/* Read whole file into dynamically allocated array. If there is an
|
||||
- * error, DON'T call reply_with_perror, just return NULL. Returns a
|
||||
- * \0-terminated string.
|
||||
- */
|
||||
-static char *
|
||||
-read_whole_file (const char *filename)
|
||||
-{
|
||||
- char *r = NULL;
|
||||
- size_t alloc = 0, size = 0;
|
||||
- int fd;
|
||||
-
|
||||
- fd = open (filename, O_RDONLY|O_CLOEXEC);
|
||||
- if (fd == -1) {
|
||||
- perror (filename);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- while (1) {
|
||||
- alloc += 256;
|
||||
- char *r2 = realloc (r, alloc);
|
||||
- if (r2 == NULL) {
|
||||
- perror ("realloc");
|
||||
- free (r);
|
||||
- close (fd);
|
||||
- return NULL;
|
||||
- }
|
||||
- r = r2;
|
||||
-
|
||||
- /* The '- 1' in the size calculation ensures there is space below
|
||||
- * to add \0 to the end of the input.
|
||||
- */
|
||||
- ssize_t n = read (fd, r + size, alloc - size - 1);
|
||||
- if (n == -1) {
|
||||
- fprintf (stderr, "read: %s: %m\n", filename);
|
||||
- free (r);
|
||||
- close (fd);
|
||||
- return NULL;
|
||||
- }
|
||||
- if (n == 0)
|
||||
- break;
|
||||
- size += n;
|
||||
- }
|
||||
-
|
||||
- if (close (fd) == -1) {
|
||||
- fprintf (stderr, "close: %s: %m\n", filename);
|
||||
- free (r);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- r[size] = '\0';
|
||||
-
|
||||
- return r;
|
||||
-}
|
||||
-
|
||||
-/* Takes optional arguments, consult optargs_bitmask. */
|
||||
-int
|
||||
-do_mount_9p (const char *mount_tag, const char *mountpoint, const char *options)
|
||||
-{
|
||||
- CLEANUP_FREE char *mp = NULL, *opts = NULL, *err = NULL;
|
||||
- struct stat statbuf;
|
||||
- int r;
|
||||
-
|
||||
- ABS_PATH (mountpoint, 0, return -1);
|
||||
-
|
||||
- mp = sysroot_path (mountpoint);
|
||||
- if (!mp) {
|
||||
- reply_with_perror ("malloc");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- /* Check the mountpoint exists and is a directory. */
|
||||
- if (stat (mp, &statbuf) == -1) {
|
||||
- reply_with_perror ("%s", mountpoint);
|
||||
- return -1;
|
||||
- }
|
||||
- if (!S_ISDIR (statbuf.st_mode)) {
|
||||
- reply_with_perror ("%s: mount point is not a directory", mountpoint);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- /* Add trans=virtio to the options. */
|
||||
- if ((optargs_bitmask & GUESTFS_MOUNT_9P_OPTIONS_BITMASK) &&
|
||||
- STRNEQ (options, "")) {
|
||||
- if (asprintf (&opts, "trans=virtio,%s", options) == -1) {
|
||||
- reply_with_perror ("asprintf");
|
||||
- return -1;
|
||||
- }
|
||||
- }
|
||||
- else {
|
||||
- opts = strdup ("trans=virtio");
|
||||
- if (opts == NULL) {
|
||||
- reply_with_perror ("strdup");
|
||||
- return -1;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- r = command (NULL, &err,
|
||||
- "mount", "-o", opts, "-t", "9p", mount_tag, mp, NULL);
|
||||
- if (r == -1) {
|
||||
- reply_with_error ("%s on %s: %s", mount_tag, mountpoint, err);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
|
||||
index 5d1c222db..a9b40be25 100644
|
||||
--- a/daemon/Makefile.am
|
||||
+++ b/daemon/Makefile.am
|
||||
@@ -76,7 +76,6 @@ guestfsd_SOURCES = \
|
||||
../common/protocol/guestfs_protocol.h \
|
||||
../common/utils/cleanups.h \
|
||||
../common/utils/guestfs-utils.h \
|
||||
- 9p.c \
|
||||
acl.c \
|
||||
actions.h \
|
||||
available.c \
|
||||
diff --git a/docs/C_SOURCE_FILES b/docs/C_SOURCE_FILES
|
||||
index 7f1c60b30..f45e7124d 100644
|
||||
--- a/docs/C_SOURCE_FILES
|
||||
+++ b/docs/C_SOURCE_FILES
|
||||
@@ -71,7 +71,6 @@ common/windows/windows.h
|
||||
customize/crypt-c.c
|
||||
customize/dummy.c
|
||||
customize/perl_edit-c.c
|
||||
-daemon/9p.c
|
||||
daemon/acl.c
|
||||
daemon/actions.h
|
||||
daemon/augeas.c
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index deda483a9..f466600df 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -6167,27 +6167,6 @@ This returns true iff the device exists and contains all zero bytes.
|
||||
|
||||
Note that for large devices this can take a long time to run." };
|
||||
|
||||
- { defaults with
|
||||
- name = "list_9p"; added = (1, 11, 12);
|
||||
- style = RStringList (RPlainString, "mounttags"), [], [];
|
||||
- shortdesc = "list 9p filesystems";
|
||||
- longdesc = "\
|
||||
-List all 9p filesystems attached to the guest. A list of
|
||||
-mount tags is returned." };
|
||||
-
|
||||
- { defaults with
|
||||
- name = "mount_9p"; added = (1, 11, 12);
|
||||
- style = RErr, [String (PlainString, "mounttag"); String (PlainString, "mountpoint")], [OString "options"];
|
||||
- camel_name = "Mount9P";
|
||||
- shortdesc = "mount 9p filesystem";
|
||||
- longdesc = "\
|
||||
-Mount the virtio-9p filesystem with the tag C<mounttag> on the
|
||||
-directory C<mountpoint>.
|
||||
-
|
||||
-If required, C<trans=virtio> will be automatically added to the options.
|
||||
-Any other options required can be passed in the optional C<options>
|
||||
-parameter." };
|
||||
-
|
||||
{ defaults with
|
||||
name = "list_dm_devices"; added = (1, 11, 15);
|
||||
style = RStringList (RDevice, "devices"), [], [];
|
||||
diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
|
||||
index 11a557076..1ef5ba0b7 100644
|
||||
--- a/generator/proc_nr.ml
|
||||
+++ b/generator/proc_nr.ml
|
||||
@@ -295,8 +295,6 @@ let proc_nr = [
|
||||
282, "internal_autosync";
|
||||
283, "is_zero";
|
||||
284, "is_zero_device";
|
||||
-285, "list_9p";
|
||||
-286, "mount_9p";
|
||||
287, "list_dm_devices";
|
||||
288, "ntfsresize";
|
||||
289, "btrfs_filesystem_resize";
|
||||
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
|
||||
index 067f861a9..7afe83c59 100644
|
||||
--- a/gobject/Makefile.inc
|
||||
+++ b/gobject/Makefile.inc
|
||||
@@ -93,7 +93,6 @@ guestfs_gobject_headers= \
|
||||
include/guestfs-gobject/optargs-mksquashfs.h \
|
||||
include/guestfs-gobject/optargs-mkswap.h \
|
||||
include/guestfs-gobject/optargs-mktemp.h \
|
||||
- include/guestfs-gobject/optargs-mount_9p.h \
|
||||
include/guestfs-gobject/optargs-mount_local.h \
|
||||
include/guestfs-gobject/optargs-ntfsclone_out.h \
|
||||
include/guestfs-gobject/optargs-ntfsfix.h \
|
||||
@@ -186,7 +185,6 @@ guestfs_gobject_sources= \
|
||||
src/optargs-mksquashfs.c \
|
||||
src/optargs-mkswap.c \
|
||||
src/optargs-mktemp.c \
|
||||
- src/optargs-mount_9p.c \
|
||||
src/optargs-mount_local.c \
|
||||
src/optargs-ntfsclone_out.c \
|
||||
src/optargs-ntfsfix.c \
|
||||
diff --git a/po/POTFILES b/po/POTFILES
|
||||
index 79f4b8c56..b99333d0d 100644
|
||||
--- a/po/POTFILES
|
||||
+++ b/po/POTFILES
|
||||
@@ -58,7 +58,6 @@ customize/crypt-c.c
|
||||
customize/dummy.c
|
||||
customize/perl_edit-c.c
|
||||
customize/test-password.pl
|
||||
-daemon/9p.c
|
||||
daemon/acl.c
|
||||
daemon/augeas.c
|
||||
daemon/available.c
|
||||
@@ -291,7 +290,6 @@ gobject/src/optargs-mkfs_btrfs.c
|
||||
gobject/src/optargs-mksquashfs.c
|
||||
gobject/src/optargs-mkswap.c
|
||||
gobject/src/optargs-mktemp.c
|
||||
-gobject/src/optargs-mount_9p.c
|
||||
gobject/src/optargs-mount_local.c
|
||||
gobject/src/optargs-ntfsclone_out.c
|
||||
gobject/src/optargs-ntfsfix.c
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,609 @@
|
||||
From d20dddb121c5f367cbec71639a64c4fca6737bf2 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 29 Jul 2013 14:47:56 +0100
|
||||
Subject: [PATCH] RHEL 8: Disable unsupported remote drive protocols
|
||||
(RHBZ#962113).
|
||||
|
||||
This disables support for unsupported remote drive protocols:
|
||||
|
||||
* ftp
|
||||
* ftps
|
||||
* http
|
||||
* https
|
||||
* tftp
|
||||
* gluster
|
||||
* iscsi
|
||||
* sheepdog
|
||||
* ssh
|
||||
|
||||
Note 'nbd' is not disabled, and of course 'file' works.
|
||||
|
||||
We hope to gradually add some of these back over the lifetime of RHEL 8.
|
||||
---
|
||||
docs/guestfs-testing.pod | 20 -----
|
||||
fish/guestfish.pod | 66 ++--------------
|
||||
fish/test-add-uri.sh | 32 --------
|
||||
generator/actions_core.ml | 50 +------------
|
||||
lib/drives.c | 8 ++
|
||||
lib/guestfs.pod | 100 -------------------------
|
||||
tests/disks/test-qemu-drive-libvirt.sh | 28 -------
|
||||
tests/disks/test-qemu-drive.sh | 60 ---------------
|
||||
8 files changed, 16 insertions(+), 348 deletions(-)
|
||||
|
||||
diff --git a/docs/guestfs-testing.pod b/docs/guestfs-testing.pod
|
||||
index f558964bf..8f264ed17 100644
|
||||
--- a/docs/guestfs-testing.pod
|
||||
+++ b/docs/guestfs-testing.pod
|
||||
@@ -109,26 +109,6 @@ image. To exit, type C<exit>.
|
||||
If you get an error, try enabling debugging (add C<-v> to the command
|
||||
line). Also make sure that L<libguestfs-test-tool(1)> succeeds.
|
||||
|
||||
-=head2 Try to open a remote guest image with guestfish.
|
||||
-
|
||||
-You may also have to disable libvirt by setting this:
|
||||
-
|
||||
- export LIBGUESTFS_BACKEND=direct
|
||||
-
|
||||
-If you have a disk image available over HTTP/FTP, try to open it.
|
||||
-
|
||||
- guestfish --ro -i --format=raw -a http://www.example.com/disk.img
|
||||
-
|
||||
-For SSH you will need to make sure that ssh-agent is set up so you
|
||||
-don't need a password to log in to the remote machine. Then a command
|
||||
-similar to this should work:
|
||||
-
|
||||
- guestfish --ro -i --format=raw \
|
||||
- -a ssh://remote.example.com/path/to/disk.img
|
||||
-
|
||||
-If you get an error, try enabling debugging (add C<-v> to the command
|
||||
-line). Also make sure that L<libguestfs-test-tool(1)> succeeds.
|
||||
-
|
||||
=head2 Run virt-alignment-scan on all your guests.
|
||||
|
||||
Run L<virt-alignment-scan(1)> on guests or disk images:
|
||||
diff --git a/fish/guestfish.pod b/fish/guestfish.pod
|
||||
index f1fdf094d..bacb60e0b 100644
|
||||
--- a/fish/guestfish.pod
|
||||
+++ b/fish/guestfish.pod
|
||||
@@ -131,9 +131,9 @@ To list what is available do:
|
||||
|
||||
=head2 Remote drives
|
||||
|
||||
-Access a remote disk using ssh:
|
||||
+Access a remote disk using NBD:
|
||||
|
||||
- guestfish -a ssh://example.com/path/to/disk.img
|
||||
+ guestfish -a nbd://example.com
|
||||
|
||||
=head2 Remote control
|
||||
|
||||
@@ -1145,12 +1145,12 @@ L<guestfs(3)/REMOTE STORAGE>>.
|
||||
On the command line, you can use the I<-a> option to add network
|
||||
block devices using a URI-style format, for example:
|
||||
|
||||
- guestfish -a ssh://root@example.com/disk.img
|
||||
+ guestfish -a nbd://example.com
|
||||
|
||||
URIs I<cannot> be used with the L</add> command. The equivalent
|
||||
command using the API directly is:
|
||||
|
||||
- ><fs> add /disk.img protocol:ssh server:tcp:example.com username:root
|
||||
+ ><fs> add /disk.img protocol:nbd server:tcp:example.com
|
||||
|
||||
The possible I<-a URI> formats are described below.
|
||||
|
||||
@@ -1160,40 +1160,6 @@ The possible I<-a URI> formats are described below.
|
||||
|
||||
Add the local disk image (or device) called F<disk.img>.
|
||||
|
||||
-=head2 B<-a ftp://[user@]example.com[:port]/disk.img>
|
||||
-
|
||||
-=head2 B<-a ftps://[user@]example.com[:port]/disk.img>
|
||||
-
|
||||
-=head2 B<-a http://[user@]example.com[:port]/disk.img>
|
||||
-
|
||||
-=head2 B<-a https://[user@]example.com[:port]/disk.img>
|
||||
-
|
||||
-=head2 B<-a tftp://[user@]example.com[:port]/disk.img>
|
||||
-
|
||||
-Add a disk located on a remote FTP, HTTP or TFTP server.
|
||||
-
|
||||
-The equivalent API command would be:
|
||||
-
|
||||
- ><fs> add /disk.img protocol:(ftp|...) server:tcp:example.com
|
||||
-
|
||||
-=head2 B<-a gluster://example.com[:port]/volname/image>
|
||||
-
|
||||
-Add a disk image located on GlusterFS storage.
|
||||
-
|
||||
-The server is the one running C<glusterd>, and may be C<localhost>.
|
||||
-
|
||||
-The equivalent API command would be:
|
||||
-
|
||||
- ><fs> add volname/image protocol:gluster server:tcp:example.com
|
||||
-
|
||||
-=head2 B<-a iscsi://example.com[:port]/target-iqn-name[/lun]>
|
||||
-
|
||||
-Add a disk located on an iSCSI server.
|
||||
-
|
||||
-The equivalent API command would be:
|
||||
-
|
||||
- ><fs> add target-iqn-name/lun protocol:iscsi server:tcp:example.com
|
||||
-
|
||||
=head2 B<-a nbd://example.com[:port]>
|
||||
|
||||
=head2 B<-a nbd://example.com[:port]/exportname>
|
||||
@@ -1228,35 +1194,13 @@ The equivalent API command would be:
|
||||
|
||||
><fs> add pool/disk protocol:rbd server:tcp:example.com:port
|
||||
|
||||
-=head2 B<-a sheepdog://[example.com[:port]]/volume/image>
|
||||
-
|
||||
-Add a disk image located on a Sheepdog volume.
|
||||
-
|
||||
-The server name is optional. Although libguestfs and Sheepdog
|
||||
-supports multiple servers, only at most one server can be specified
|
||||
-when using this URI syntax.
|
||||
-
|
||||
-The equivalent API command would be:
|
||||
-
|
||||
- ><fs> add volume protocol:sheepdog [server:tcp:example.com]
|
||||
-
|
||||
-=head2 B<-a ssh://[user@]example.com[:port]/disk.img>
|
||||
-
|
||||
-Add a disk image located on a remote server, accessed using the Secure
|
||||
-Shell (ssh) SFTP protocol. SFTP is supported out of the box by all
|
||||
-major SSH servers.
|
||||
-
|
||||
-The equivalent API command would be:
|
||||
-
|
||||
- ><fs> add /disk protocol:ssh server:tcp:example.com [username:user]
|
||||
-
|
||||
Note that the URIs follow the syntax of
|
||||
L<RFC 3986|https://tools.ietf.org/html/rfc3986>: in particular, there
|
||||
are restrictions on the allowed characters for the various components
|
||||
of the URI. Characters such as C<:>, C<@>, and C</> B<must> be
|
||||
percent-encoded:
|
||||
|
||||
- $ guestfish -a ssh://user:pass%40word@example.com/disk.img
|
||||
+ $ guestfish -a rbd://user:pass%40word@example.com[:port]/pool/disk
|
||||
|
||||
In this case, the password is C<pass@word>.
|
||||
|
||||
diff --git a/fish/test-add-uri.sh b/fish/test-add-uri.sh
|
||||
index 756df997b..8f84fd31b 100755
|
||||
--- a/fish/test-add-uri.sh
|
||||
+++ b/fish/test-add-uri.sh
|
||||
@@ -40,14 +40,6 @@ function fail ()
|
||||
$VG guestfish -x -a file://$abs_builddir/test-add-uri.img </dev/null >test-add-uri.out 2>&1
|
||||
grep -sq 'add_drive ".*/test-add-uri.img"' test-add-uri.out || fail
|
||||
|
||||
-# curl
|
||||
-$VG guestfish -x -a ftp://user@example.com/disk.img </dev/null >test-add-uri.out 2>&1
|
||||
-grep -sq 'add_drive "/disk.img" "protocol:ftp" "server:tcp:example.com" "username:user"' test-add-uri.out || fail
|
||||
-
|
||||
-# gluster
|
||||
-$VG guestfish -x -a gluster://example.com/disk </dev/null >test-add-uri.out 2>&1
|
||||
-grep -sq 'add_drive "disk" "protocol:gluster" "server:tcp:example.com"' test-add-uri.out || fail
|
||||
-
|
||||
# NBD
|
||||
$VG guestfish -x -a nbd://example.com </dev/null >test-add-uri.out 2>&1
|
||||
grep -sq 'add_drive "" "protocol:nbd" "server:tcp:example.com"' test-add-uri.out || fail
|
||||
@@ -67,29 +59,5 @@ grep -sq 'add_drive "pool/disk" "protocol:rbd" "server:tcp:example.com:6789"' te
|
||||
$VG guestfish -x -a rbd:///pool/disk </dev/null >test-add-uri.out 2>&1
|
||||
grep -sq 'add_drive "pool/disk" "protocol:rbd"' test-add-uri.out || fail
|
||||
|
||||
-# sheepdog
|
||||
-$VG guestfish -x -a sheepdog:///volume/image </dev/null >test-add-uri.out 2>&1
|
||||
-grep -sq 'add_drive "volume/image" "protocol:sheepdog"' test-add-uri.out || fail
|
||||
-
|
||||
-$VG guestfish -x -a sheepdog://example.com:3000/volume/image </dev/null >test-add-uri.out 2>&1
|
||||
-grep -sq 'add_drive "volume/image" "protocol:sheepdog" "server:tcp:example.com:3000"' test-add-uri.out || fail
|
||||
-
|
||||
-# ssh
|
||||
-$VG guestfish -x -a ssh://example.com/disk.img </dev/null >test-add-uri.out 2>&1
|
||||
-grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com"' test-add-uri.out || fail
|
||||
-
|
||||
-$VG guestfish -x -a ssh://user@example.com/disk.img </dev/null >test-add-uri.out 2>&1
|
||||
-grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com" "username:user"' test-add-uri.out || fail
|
||||
-
|
||||
-$VG guestfish -x -a ssh://user@example.com:2000/disk.img </dev/null >test-add-uri.out 2>&1
|
||||
-grep -sq 'add_drive "/disk.img" "protocol:ssh" "server:tcp:example.com:2000" "username:user"' test-add-uri.out || fail
|
||||
-
|
||||
-# iSCSI
|
||||
-$VG guestfish -x -a iscsi://example.com/iqn.2015-12.com.libguestfs:test1/0 </dev/null >test-add-uri.out 2>&1
|
||||
-grep -sq 'add_drive "iqn.2015-12.com.libguestfs:test1/0" "protocol:iscsi" "server:tcp:example.com"' test-add-uri.out || fail
|
||||
-
|
||||
-$VG guestfish -x -a iscsi://user:password@example.com/iqn.2015-12.com.libguestfs:test2/0 </dev/null >test-add-uri.out 2>&1
|
||||
-grep -sq 'add_drive "iqn.2015-12.com.libguestfs:test2/0" "protocol:iscsi" "server:tcp:example.com" "username:user" "secret:password"' test-add-uri.out || fail
|
||||
-
|
||||
rm test-add-uri.out
|
||||
rm test-add-uri.img
|
||||
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
|
||||
index f466600df..3893d0e8d 100644
|
||||
--- a/generator/actions_core.ml
|
||||
+++ b/generator/actions_core.ml
|
||||
@@ -297,29 +297,6 @@ F<filename> is interpreted as a local file or device.
|
||||
This is the default if the optional protocol parameter
|
||||
is omitted.
|
||||
|
||||
-=item C<protocol = \"ftp\"|\"ftps\"|\"http\"|\"https\"|\"tftp\">
|
||||
-
|
||||
-Connect to a remote FTP, HTTP or TFTP server.
|
||||
-The C<server> parameter must also be supplied - see below.
|
||||
-
|
||||
-See also: L<guestfs(3)/FTP, HTTP AND TFTP>
|
||||
-
|
||||
-=item C<protocol = \"gluster\">
|
||||
-
|
||||
-Connect to the GlusterFS server.
|
||||
-The C<server> parameter must also be supplied - see below.
|
||||
-
|
||||
-See also: L<guestfs(3)/GLUSTER>
|
||||
-
|
||||
-=item C<protocol = \"iscsi\">
|
||||
-
|
||||
-Connect to the iSCSI server.
|
||||
-The C<server> parameter must also be supplied - see below.
|
||||
-The C<username> parameter may be supplied. See below.
|
||||
-The C<secret> parameter may be supplied. See below.
|
||||
-
|
||||
-See also: L<guestfs(3)/ISCSI>.
|
||||
-
|
||||
=item C<protocol = \"nbd\">
|
||||
|
||||
Connect to the Network Block Device server.
|
||||
@@ -336,22 +313,6 @@ The C<secret> parameter may be supplied. See below.
|
||||
|
||||
See also: L<guestfs(3)/CEPH>.
|
||||
|
||||
-=item C<protocol = \"sheepdog\">
|
||||
-
|
||||
-Connect to the Sheepdog server.
|
||||
-The C<server> parameter may also be supplied - see below.
|
||||
-
|
||||
-See also: L<guestfs(3)/SHEEPDOG>.
|
||||
-
|
||||
-=item C<protocol = \"ssh\">
|
||||
-
|
||||
-Connect to the Secure Shell (ssh) server.
|
||||
-
|
||||
-The C<server> parameter must be supplied.
|
||||
-The C<username> parameter may be supplied. See below.
|
||||
-
|
||||
-See also: L<guestfs(3)/SSH>.
|
||||
-
|
||||
=back
|
||||
|
||||
=item C<server>
|
||||
@@ -362,13 +323,8 @@ is a list of server(s).
|
||||
Protocol Number of servers required
|
||||
-------- --------------------------
|
||||
file List must be empty or param not used at all
|
||||
- ftp|ftps|http|https|tftp Exactly one
|
||||
- gluster Exactly one
|
||||
- iscsi Exactly one
|
||||
nbd Exactly one
|
||||
rbd Zero or more
|
||||
- sheepdog Zero or more
|
||||
- ssh Exactly one
|
||||
|
||||
Each list element is a string specifying a server. The string must be
|
||||
in one of the following formats:
|
||||
@@ -384,10 +340,10 @@ for the protocol is used (see F</etc/services>).
|
||||
|
||||
=item C<username>
|
||||
|
||||
-For the C<ftp>, C<ftps>, C<http>, C<https>, C<iscsi>, C<rbd>, C<ssh>
|
||||
-and C<tftp> protocols, this specifies the remote username.
|
||||
+For the C<rbd>
|
||||
+protocol, this specifies the remote username.
|
||||
|
||||
-If not given, then the local username is used for C<ssh>, and no authentication
|
||||
+If not given, then no authentication
|
||||
is attempted for ceph. But note this sometimes may give unexpected results, for
|
||||
example if using the libvirt backend and if the libvirt backend is configured to
|
||||
start the qemu appliance as a special user such as C<qemu.qemu>. If in doubt,
|
||||
diff --git a/lib/drives.c b/lib/drives.c
|
||||
index 82ef30093..3d712c6e4 100644
|
||||
--- a/lib/drives.c
|
||||
+++ b/lib/drives.c
|
||||
@@ -165,6 +165,7 @@ create_drive_non_file (guestfs_h *g,
|
||||
return drv;
|
||||
}
|
||||
|
||||
+#if 0 /* DISABLED IN RHEL 8 */
|
||||
static struct drive *
|
||||
create_drive_curl (guestfs_h *g,
|
||||
const struct drive_create_data *data)
|
||||
@@ -223,6 +224,7 @@ create_drive_gluster (guestfs_h *g,
|
||||
|
||||
return create_drive_non_file (g, data);
|
||||
}
|
||||
+#endif /* DISABLED IN RHEL 8 */
|
||||
|
||||
static int
|
||||
nbd_port (void)
|
||||
@@ -291,6 +293,7 @@ create_drive_rbd (guestfs_h *g,
|
||||
return create_drive_non_file (g, data);
|
||||
}
|
||||
|
||||
+#if 0 /* DISABLED IN RHEL 8 */
|
||||
static struct drive *
|
||||
create_drive_sheepdog (guestfs_h *g,
|
||||
const struct drive_create_data *data)
|
||||
@@ -391,6 +394,7 @@ create_drive_iscsi (guestfs_h *g,
|
||||
|
||||
return create_drive_non_file (g, data);
|
||||
}
|
||||
+#endif /* DISABLED IN RHEL 8 */
|
||||
|
||||
/**
|
||||
* Create the special F</dev/null> drive.
|
||||
@@ -826,6 +830,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
drv = create_drive_file (g, &data);
|
||||
}
|
||||
}
|
||||
+#if 0 /* DISABLED IN RHEL 8 */
|
||||
else if (STREQ (protocol, "ftp")) {
|
||||
data.protocol = drive_protocol_ftp;
|
||||
drv = create_drive_curl (g, &data);
|
||||
@@ -850,6 +855,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
data.protocol = drive_protocol_iscsi;
|
||||
drv = create_drive_iscsi (g, &data);
|
||||
}
|
||||
+#endif /* DISABLED IN RHEL 8 */
|
||||
else if (STREQ (protocol, "nbd")) {
|
||||
data.protocol = drive_protocol_nbd;
|
||||
drv = create_drive_nbd (g, &data);
|
||||
@@ -858,6 +864,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
data.protocol = drive_protocol_rbd;
|
||||
drv = create_drive_rbd (g, &data);
|
||||
}
|
||||
+#if 0 /* DISABLED IN RHEL 8 */
|
||||
else if (STREQ (protocol, "sheepdog")) {
|
||||
data.protocol = drive_protocol_sheepdog;
|
||||
drv = create_drive_sheepdog (g, &data);
|
||||
@@ -870,6 +877,7 @@ guestfs_impl_add_drive_opts (guestfs_h *g, const char *filename,
|
||||
data.protocol = drive_protocol_tftp;
|
||||
drv = create_drive_curl (g, &data);
|
||||
}
|
||||
+#endif /* DISABLED IN RHEL 8 */
|
||||
else {
|
||||
error (g, _("unknown protocol ‘%s’"), protocol);
|
||||
drv = NULL; /*FALLTHROUGH*/
|
||||
diff --git a/lib/guestfs.pod b/lib/guestfs.pod
|
||||
index af944ddb7..58559a6b4 100644
|
||||
--- a/lib/guestfs.pod
|
||||
+++ b/lib/guestfs.pod
|
||||
@@ -714,70 +714,6 @@ servers. The server string is documented in
|
||||
L</guestfs_add_drive_opts>. The C<username> and C<secret> parameters are
|
||||
also optional, and if not given, then no authentication will be used.
|
||||
|
||||
-=head3 FTP, HTTP AND TFTP
|
||||
-
|
||||
-Libguestfs can access remote disks over FTP, FTPS, HTTP, HTTPS
|
||||
-or TFTP protocols.
|
||||
-
|
||||
-To do this, set the optional C<protocol> and C<server> parameters of
|
||||
-L</guestfs_add_drive_opts> like this:
|
||||
-
|
||||
- char **servers = { "www.example.org", NULL };
|
||||
- guestfs_add_drive_opts (g, "/disk.img",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "http",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers,
|
||||
- -1);
|
||||
-
|
||||
-The C<protocol> can be one of C<"ftp">, C<"ftps">, C<"http">,
|
||||
-C<"https"> or C<"tftp">.
|
||||
-
|
||||
-C<servers> (the C<server> parameter) is a list which must have a
|
||||
-single element. The single element is a string defining the web,
|
||||
-FTP or TFTP server. The format of this string is documented in
|
||||
-L</guestfs_add_drive_opts>.
|
||||
-
|
||||
-=head3 GLUSTER
|
||||
-
|
||||
-Libguestfs can access Gluster disks.
|
||||
-
|
||||
-To do this, set the optional C<protocol> and C<server> parameters of
|
||||
-L</guestfs_add_drive_opts> like this:
|
||||
-
|
||||
- char **servers = { "gluster.example.org:24007", NULL };
|
||||
- guestfs_add_drive_opts (g, "volname/image",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "gluster",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers,
|
||||
- -1);
|
||||
-
|
||||
-C<servers> (the C<server> parameter) is a list which must have a
|
||||
-single element. The single element is a string defining the Gluster
|
||||
-server. The format of this string is documented in
|
||||
-L</guestfs_add_drive_opts>.
|
||||
-
|
||||
-Note that gluster usually requires the client process (ie. libguestfs)
|
||||
-to run as B<root> and will give unfathomable errors if it is not
|
||||
-(eg. "No data available").
|
||||
-
|
||||
-=head3 ISCSI
|
||||
-
|
||||
-Libguestfs can access iSCSI disks remotely.
|
||||
-
|
||||
-To do this, set the optional C<protocol> and C<server> parameters like
|
||||
-this:
|
||||
-
|
||||
- char **server = { "iscsi.example.org:3000", NULL };
|
||||
- guestfs_add_drive_opts (g, "target-iqn-name/lun",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "iscsi",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_SERVER, server,
|
||||
- -1);
|
||||
-
|
||||
-The C<server> parameter is a list which must have a single element.
|
||||
-The single element is a string defining the iSCSI server. The format
|
||||
-of this string is documented in L</guestfs_add_drive_opts>.
|
||||
-
|
||||
=head3 NETWORK BLOCK DEVICE
|
||||
|
||||
Libguestfs can access Network Block Device (NBD) disks remotely.
|
||||
@@ -840,42 +776,6 @@ L<https://bugs.launchpad.net/qemu/+bug/1155677>
|
||||
|
||||
=back
|
||||
|
||||
-=head3 SHEEPDOG
|
||||
-
|
||||
-Libguestfs can access Sheepdog disks.
|
||||
-
|
||||
-To do this, set the optional C<protocol> and C<server> parameters of
|
||||
-L</guestfs_add_drive_opts> like this:
|
||||
-
|
||||
- char **servers = { /* optional servers ... */ NULL };
|
||||
- guestfs_add_drive_opts (g, "volume",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "sheepdog",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_SERVER, servers,
|
||||
- -1);
|
||||
-
|
||||
-The optional list of C<servers> may be zero or more server addresses
|
||||
-(C<"hostname:port">). The format of the server strings is documented
|
||||
-in L</guestfs_add_drive_opts>.
|
||||
-
|
||||
-=head3 SSH
|
||||
-
|
||||
-Libguestfs can access disks over a Secure Shell (SSH) connection.
|
||||
-
|
||||
-To do this, set the C<protocol> and C<server> and (optionally)
|
||||
-C<username> parameters of L</guestfs_add_drive_opts> like this:
|
||||
-
|
||||
- char **server = { "remote.example.com", NULL };
|
||||
- guestfs_add_drive_opts (g, "/path/to/disk.img",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "ssh",
|
||||
- GUESTFS_ADD_DRIVE_OPTS_SERVER, server,
|
||||
- GUESTFS_ADD_DRIVE_OPTS_USERNAME, "remoteuser",
|
||||
- -1);
|
||||
-
|
||||
-The format of the server string is documented in
|
||||
-L</guestfs_add_drive_opts>.
|
||||
-
|
||||
=head2 INSPECTION
|
||||
|
||||
Libguestfs has APIs for inspecting an unknown disk image to find out
|
||||
diff --git a/tests/disks/test-qemu-drive-libvirt.sh b/tests/disks/test-qemu-drive-libvirt.sh
|
||||
index e49c69b43..9b1abc4ec 100755
|
||||
--- a/tests/disks/test-qemu-drive-libvirt.sh
|
||||
+++ b/tests/disks/test-qemu-drive-libvirt.sh
|
||||
@@ -64,34 +64,6 @@ check_output
|
||||
grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail ceph2
|
||||
rm "$DEBUG_QEMU_FILE"
|
||||
|
||||
-# Gluster.
|
||||
-
|
||||
-$guestfish -d gluster run ||:
|
||||
-check_output
|
||||
-grep -sq -- '-drive file=gluster://1.2.3.4:1234/volname/image,' "$DEBUG_QEMU_FILE" || fail gluster
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
-
|
||||
-# iSCSI.
|
||||
-
|
||||
-$guestfish -d iscsi run ||:
|
||||
-check_output
|
||||
-grep -sq -- '-drive file=iscsi://1.2.3.4:1234/iqn.2003-01.org.linux-iscsi.fedora' "$DEBUG_QEMU_FILE" || fail iscsi
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
-
|
||||
-# NBD.
|
||||
-
|
||||
-$guestfish -d nbd run ||:
|
||||
-check_output
|
||||
-grep -sq -- '-drive file=nbd:1.2.3.4:1234,' "$DEBUG_QEMU_FILE" || fail nbd
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
-
|
||||
-# Sheepdog.
|
||||
-
|
||||
-$guestfish -d sheepdog run ||:
|
||||
-check_output
|
||||
-grep -sq -- '-drive file=sheepdog:volume,' "$DEBUG_QEMU_FILE" || fail sheepdog
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
-
|
||||
# Local, stored in a pool.
|
||||
|
||||
$guestfish -d pool1 run ||:
|
||||
diff --git a/tests/disks/test-qemu-drive.sh b/tests/disks/test-qemu-drive.sh
|
||||
index 19dd60a2f..583e031bd 100755
|
||||
--- a/tests/disks/test-qemu-drive.sh
|
||||
+++ b/tests/disks/test-qemu-drive.sh
|
||||
@@ -62,45 +62,6 @@ check_output
|
||||
grep -sq -- '-drive file=rbd:abc-def/ghi-jkl:auth_supported=none,' "$DEBUG_QEMU_FILE" || fail
|
||||
rm "$DEBUG_QEMU_FILE"
|
||||
|
||||
-# HTTP.
|
||||
-
|
||||
-guestfish <<EOF ||:
|
||||
- add "/disk.img" "format:raw" "protocol:http" "server:www.example.com"
|
||||
- run
|
||||
-EOF
|
||||
-check_output
|
||||
-grep -sq -- '-drive file=http://www.example.com/disk.img,' "$DEBUG_QEMU_FILE" || fail
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
-
|
||||
-# Gluster.
|
||||
-
|
||||
-guestfish <<EOF ||:
|
||||
- add "volname/image" "format:raw" "protocol:gluster" "server:www.example.com:24007"
|
||||
- run
|
||||
-EOF
|
||||
-check_output
|
||||
-grep -sq -- '-drive file=gluster://www.example.com:24007/volname/image,' "$DEBUG_QEMU_FILE" || fail
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
-
|
||||
-# iSCSI.
|
||||
-
|
||||
-guestfish <<EOF ||:
|
||||
- add "target-iqn-name/lun" "format:raw" "protocol:iscsi" "server:www.example.com:3000"
|
||||
- run
|
||||
-EOF
|
||||
-check_output
|
||||
-grep -sq -- '-drive file=iscsi://www.example.com:3000/target-iqn-name/lun,' "$DEBUG_QEMU_FILE" || fail
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
-
|
||||
-guestfish <<EOF ||:
|
||||
- add "target-iqn-name/lun" "format:raw" "protocol:iscsi" "server:www.example.com:3000" \
|
||||
- "username:user" "secret:pass"
|
||||
- run
|
||||
-EOF
|
||||
-check_output
|
||||
-grep -sq -- '-drive file=iscsi://user%pass@www.example.com:3000/target-iqn-name/lun,' "$DEBUG_QEMU_FILE" || fail
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
-
|
||||
# NBD.
|
||||
|
||||
guestfish <<EOF ||:
|
||||
@@ -118,24 +79,3 @@ EOF
|
||||
check_output
|
||||
grep -sq -- '-drive file=nbd:unix:/socket,' "$DEBUG_QEMU_FILE" || fail
|
||||
rm "$DEBUG_QEMU_FILE"
|
||||
-
|
||||
-# Sheepdog.
|
||||
-
|
||||
-guestfish <<EOF ||:
|
||||
- add "volume" "format:raw" "protocol:sheepdog"
|
||||
- run
|
||||
-EOF
|
||||
-check_output
|
||||
-grep -sq -- '-drive file=sheepdog:volume,' "$DEBUG_QEMU_FILE" || fail
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
-
|
||||
-# SSH.
|
||||
-
|
||||
-guestfish <<EOF ||:
|
||||
- add "/disk.img" "format:raw" "protocol:ssh" "server:example.com" \
|
||||
- "username:rich"
|
||||
- run
|
||||
-EOF
|
||||
-check_output
|
||||
-grep -sq -- '-drive file=ssh://rich@example.com/disk.img,' "$DEBUG_QEMU_FILE" || fail
|
||||
-rm "$DEBUG_QEMU_FILE"
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,72 @@
|
||||
From 6bf62d3c79aab0dd01ad5ab9cfc9a12b119976f6 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 19 Sep 2014 13:38:20 +0100
|
||||
Subject: [PATCH] RHEL 8: Remove User-Mode Linux (RHBZ#1144197).
|
||||
|
||||
This isn't supported in RHEL 8.
|
||||
---
|
||||
lib/launch-uml.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/lib/launch-uml.c b/lib/launch-uml.c
|
||||
index da20c17d9..a5e0e8179 100644
|
||||
--- a/lib/launch-uml.c
|
||||
+++ b/lib/launch-uml.c
|
||||
@@ -44,7 +44,9 @@ struct backend_uml_data {
|
||||
char umid[UML_UMID_LEN+1]; /* umid=<...> unique ID. */
|
||||
};
|
||||
|
||||
+#if 0
|
||||
static void print_vmlinux_command_line (guestfs_h *g, char **argv);
|
||||
+#endif
|
||||
|
||||
/* Run uml_mkcow to create a COW overlay. */
|
||||
static char *
|
||||
@@ -81,6 +83,7 @@ create_cow_overlay_uml (guestfs_h *g, void *datav, struct drive *drv)
|
||||
return make_cow_overlay (g, drv->src.u.path);
|
||||
}
|
||||
|
||||
+#if 0
|
||||
/* Test for features which are not supported by the UML backend.
|
||||
* Possibly some of these should just be warnings, not errors.
|
||||
*/
|
||||
@@ -128,10 +131,17 @@ uml_supported (guestfs_h *g)
|
||||
|
||||
return true;
|
||||
}
|
||||
+#endif
|
||||
|
||||
static int
|
||||
launch_uml (guestfs_h *g, void *datav, const char *arg)
|
||||
{
|
||||
+ error (g,
|
||||
+ "launch: In RHEL, only the 'libvirt' or 'direct' method is supported.\n"
|
||||
+ "In particular, User-Mode Linux (UML) is not supported.");
|
||||
+ return -1;
|
||||
+
|
||||
+#if 0
|
||||
struct backend_uml_data *data = datav;
|
||||
CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (cmdline);
|
||||
int console_sock = -1, daemon_sock = -1;
|
||||
@@ -491,8 +501,10 @@ launch_uml (guestfs_h *g, void *datav, const char *arg)
|
||||
}
|
||||
g->state = CONFIG;
|
||||
return -1;
|
||||
+#endif
|
||||
}
|
||||
|
||||
+#if 0
|
||||
/* This is called from the forked subprocess just before vmlinux runs,
|
||||
* so it can just print the message straight to stderr, where it will
|
||||
* be picked up and funnelled through the usual appliance event API.
|
||||
@@ -522,6 +534,7 @@ print_vmlinux_command_line (guestfs_h *g, char **argv)
|
||||
|
||||
fputc ('\n', stderr);
|
||||
}
|
||||
+#endif
|
||||
|
||||
static int
|
||||
shutdown_uml (guestfs_h *g, void *datav, int check_for_errors)
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,33 @@
|
||||
From 699137c5c84439597757f8c00373ebb53544223b Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Sun, 28 Sep 2014 19:14:43 +0100
|
||||
Subject: [PATCH] RHEL 8: v2v: Select correct qemu binary for -o qemu mode
|
||||
(RHBZ#1147313).
|
||||
|
||||
RHEL 8 does not have qemu-system-x86_64 (etc), and in addition the
|
||||
qemu binary is located in /usr/libexec. Encode the path to this
|
||||
binary directly in the script.
|
||||
|
||||
Note that we don't support people running qemu directly like this.
|
||||
It's just for quick testing of converted VMs, and to help us with
|
||||
support cases.
|
||||
---
|
||||
v2v/output_qemu.ml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/output_qemu.ml b/v2v/output_qemu.ml
|
||||
index 1f6798aaf..8665d7b5c 100644
|
||||
--- a/v2v/output_qemu.ml
|
||||
+++ b/v2v/output_qemu.ml
|
||||
@@ -81,7 +81,7 @@ object
|
||||
* module deals with shell and qemu comma quoting.
|
||||
*)
|
||||
let cmd = Qemuopts.create () in
|
||||
- Qemuopts.set_binary_by_arch cmd (Some guestcaps.gcaps_arch);
|
||||
+ Qemuopts.set_binary cmd "/usr/libexec/qemu-kvm";
|
||||
|
||||
let flag = Qemuopts.flag cmd
|
||||
and arg = Qemuopts.arg cmd
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,105 @@
|
||||
From 839672ac70f58af6ab4a7ff31335efc28b49df57 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 30 Sep 2014 10:50:27 +0100
|
||||
Subject: [PATCH] RHEL 8: v2v: Disable the --qemu-boot option (RHBZ#1147313).
|
||||
|
||||
This cannot work because there is no Gtk or SDL output mode
|
||||
in RHEL 8's qemu-kvm.
|
||||
|
||||
In addition you will have to edit the -display option in the
|
||||
qemu script.
|
||||
---
|
||||
v2v/cmdline.ml | 3 ++-
|
||||
v2v/virt-v2v-output-local.pod | 6 ++----
|
||||
v2v/virt-v2v.pod | 13 -------------
|
||||
3 files changed, 4 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
|
||||
index 686631271..e3578ddcb 100644
|
||||
--- a/v2v/cmdline.ml
|
||||
+++ b/v2v/cmdline.ml
|
||||
@@ -262,7 +262,6 @@ let parse_cmdline () =
|
||||
s_"Estimate size of source and stop";
|
||||
[ L"print-source" ], Getopt.Set print_source,
|
||||
s_"Print source and stop";
|
||||
- [ L"qemu-boot" ], Getopt.Set qemu_boot, s_"Boot in qemu (-o qemu only)";
|
||||
[ L"root" ], Getopt.String ("ask|... ", set_root_choice),
|
||||
s_"How to choose root filesystem";
|
||||
[ L"vddk-config" ], Getopt.String ("filename", set_input_option_compat "vddk-config"),
|
||||
@@ -640,6 +639,8 @@ read the man page virt-v2v(1).
|
||||
| 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 (f_"-o qemu: the --qemu-boot option cannot be used in RHEL");
|
||||
Output_qemu.output_qemu os qemu_boot,
|
||||
output_format, output_alloc
|
||||
|
||||
diff --git a/v2v/virt-v2v-output-local.pod b/v2v/virt-v2v-output-local.pod
|
||||
index 7c397c0a4..09a11a7b0 100644
|
||||
--- a/v2v/virt-v2v-output-local.pod
|
||||
+++ b/v2v/virt-v2v-output-local.pod
|
||||
@@ -9,7 +9,7 @@ or libvirt
|
||||
|
||||
virt-v2v [-i* options] -o local -os DIRECTORY
|
||||
|
||||
- virt-v2v [-i* options] -o qemu -os DIRECTORY [--qemu-boot]
|
||||
+ virt-v2v [-i* options] -o qemu -os DIRECTORY
|
||||
|
||||
virt-v2v [-i* options] -o json -os DIRECTORY
|
||||
[-oo json-disks-pattern=PATTERN]
|
||||
@@ -50,12 +50,10 @@ where C<NAME> is the guest name.
|
||||
|
||||
=item B<-o qemu -os> C<DIRECTORY>
|
||||
|
||||
-=item B<-o qemu -os> C<DIRECTORY> B<--qemu-boot>
|
||||
-
|
||||
This converts the guest to files in C<DIRECTORY>. Unlike I<-o local>
|
||||
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.
|
||||
+run.
|
||||
|
||||
=item B<-o json -os> C<DIRECTORY>
|
||||
|
||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
||||
index 25041d0ec..bd606592b 100644
|
||||
--- a/v2v/virt-v2v.pod
|
||||
+++ b/v2v/virt-v2v.pod
|
||||
@@ -142,11 +142,6 @@ Since F<guest-domain.xml> contains the path(s) to the guest disk
|
||||
image(s) you do not need to specify the name of the disk image on the
|
||||
command line.
|
||||
|
||||
-To convert a local disk image and immediately boot it in local
|
||||
-qemu, do:
|
||||
-
|
||||
- virt-v2v -i disk disk.img -o qemu -os /var/tmp --qemu-boot
|
||||
-
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 4
|
||||
@@ -510,9 +505,6 @@ This is similar to I<-o local>, except that a shell script is written
|
||||
which you can use to boot the guest in qemu. The converted disks and
|
||||
shell script are written to the directory specified by I<-os>.
|
||||
|
||||
-When using this output mode, you can also specify the I<--qemu-boot>
|
||||
-option which boots the guest under qemu immediately.
|
||||
-
|
||||
=item B<-o> B<rhev>
|
||||
|
||||
This is the same as I<-o rhv>.
|
||||
@@ -788,11 +780,6 @@ Print information about the source guest and stop. This option is
|
||||
useful when you are setting up network and bridge maps.
|
||||
See L</Networks and bridges>.
|
||||
|
||||
-=item B<--qemu-boot>
|
||||
-
|
||||
-When using I<-o qemu> only, this boots the guest immediately after
|
||||
-virt-v2v finishes.
|
||||
-
|
||||
=item B<-q>
|
||||
|
||||
=item B<--quiet>
|
||||
--
|
||||
2.24.1
|
||||
|
60
SOURCES/0062-RHEL-8-Disable-alternate-Augeas-lenses.patch
Normal file
60
SOURCES/0062-RHEL-8-Disable-alternate-Augeas-lenses.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From e91337be55a8728125de3457dca8f1a998ad18c5 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Fri, 24 Oct 2014 16:33:50 +0100
|
||||
Subject: [PATCH] RHEL 8: Disable alternate Augeas lenses.
|
||||
|
||||
These are included in the RHEL augeas package, and therefore not
|
||||
required.
|
||||
|
||||
See:
|
||||
https://www.redhat.com/archives/libguestfs/2014-October/msg00220.html
|
||||
---
|
||||
appliance/Makefile.am | 1 -
|
||||
daemon/augeas.c | 5 ++++-
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/appliance/Makefile.am b/appliance/Makefile.am
|
||||
index fc424b1d0..5efc5c036 100644
|
||||
--- a/appliance/Makefile.am
|
||||
+++ b/appliance/Makefile.am
|
||||
@@ -91,7 +91,6 @@ supermin.d/daemon.tar.gz: ../daemon/guestfsd guestfs_shadow.aug
|
||||
rm -rf tmp-d
|
||||
mkdir -p tmp-d$(DAEMON_SUPERMIN_DIR) tmp-d/etc tmp-d/usr/share/guestfs
|
||||
ln ../daemon/guestfsd tmp-d$(DAEMON_SUPERMIN_DIR)/guestfsd
|
||||
- ln $(srcdir)/guestfs_shadow.aug tmp-d/usr/share/guestfs/guestfs_shadow.aug
|
||||
( cd tmp-d && tar zcf - * ) > $@-t
|
||||
rm -r tmp-d
|
||||
mv $@-t $@
|
||||
diff --git a/daemon/augeas.c b/daemon/augeas.c
|
||||
index 453251337..5bbfffa2d 100644
|
||||
--- a/daemon/augeas.c
|
||||
+++ b/daemon/augeas.c
|
||||
@@ -134,7 +134,7 @@ do_aug_init (const char *root, int flags)
|
||||
}
|
||||
|
||||
/* Pass AUG_NO_ERR_CLOSE so we can display detailed errors. */
|
||||
- aug = aug_init (buf, "/usr/share/guestfs/", flags | AUG_NO_ERR_CLOSE);
|
||||
+ aug = aug_init (buf, NULL, flags | AUG_NO_ERR_CLOSE);
|
||||
|
||||
if (!aug) {
|
||||
reply_with_error ("augeas initialization failed");
|
||||
@@ -148,6 +148,8 @@ do_aug_init (const char *root, int flags)
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ /* We already have the needed lenses in RHEL 8 */
|
||||
+#if 0
|
||||
if (!augeas_is_version (1, 2, 1)) {
|
||||
int r = aug_transform (aug, "guestfs_shadow", "/etc/shadow",
|
||||
0 /* = included */);
|
||||
@@ -166,6 +168,7 @@ do_aug_init (const char *root, int flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,34 @@
|
||||
From 2736193735e3e84d81993ac8464c64381119c679 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Fri, 24 Apr 2015 09:45:41 -0400
|
||||
Subject: [PATCH] RHEL 8: Fix list of supported sound cards to match RHEL qemu
|
||||
(RHBZ#1176493).
|
||||
|
||||
---
|
||||
v2v/utils.ml | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/v2v/utils.ml b/v2v/utils.ml
|
||||
index 74b501f81..21e9c9c15 100644
|
||||
--- a/v2v/utils.ml
|
||||
+++ b/v2v/utils.ml
|
||||
@@ -51,13 +51,14 @@ let kvm_arch = function
|
||||
(* Does qemu support the given sound card? *)
|
||||
let qemu_supports_sound_card = function
|
||||
| Types.AC97
|
||||
- | Types.ES1370
|
||||
| Types.ICH6
|
||||
| Types.ICH9
|
||||
| Types.PCSpeaker
|
||||
+ -> true
|
||||
+ | Types.ES1370
|
||||
| Types.SB16
|
||||
| Types.USBAudio
|
||||
- -> true
|
||||
+ -> false
|
||||
|
||||
(* Find the UEFI firmware. *)
|
||||
let find_uefi_firmware guest_arch =
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 9f85ee42bc679642ead93582e3d44e5cf3c30503 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Tue, 7 Jul 2015 09:28:03 -0400
|
||||
Subject: [PATCH] RHEL 8: Reject use of libguestfs-winsupport features except
|
||||
for virt-* tools (RHBZ#1240276).
|
||||
|
||||
---
|
||||
generator/c.ml | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/generator/c.ml b/generator/c.ml
|
||||
index 86f7d89a3..b5bb99f53 100644
|
||||
--- a/generator/c.ml
|
||||
+++ b/generator/c.ml
|
||||
@@ -1832,6 +1832,22 @@ and generate_client_actions actions () =
|
||||
check_args_validity c_name style;
|
||||
trace_call name c_name style;
|
||||
|
||||
+ (* RHEL 8 *)
|
||||
+ if name = "mount" || name = "mount_ro" || name = "mount_options" ||
|
||||
+ name = "mount_vfs" then (
|
||||
+ pr " if (g->program && !STRPREFIX (g->program, \"virt-\")) {\n";
|
||||
+ pr " CLEANUP_FREE char *vfs_type = guestfs_vfs_type (g, mountable);\n";
|
||||
+ pr " if (vfs_type && STREQ (vfs_type, \"ntfs\")) {\n";
|
||||
+ pr " error (g, \"mount: unsupported filesystem type\");\n";
|
||||
+ pr " if (trace_flag)\n";
|
||||
+ pr " guestfs_int_trace (g, \"%%s = %%s (error)\",\n";
|
||||
+ pr " \"%s\", \"-1\");\n" name;
|
||||
+ pr " return %s;\n" (string_of_errcode errcode);
|
||||
+ pr " }\n";
|
||||
+ pr " }\n";
|
||||
+ pr "\n";
|
||||
+ );
|
||||
+
|
||||
(* Calculate the total size of all FileIn arguments to pass
|
||||
* as a progress bar hint.
|
||||
*)
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,93 @@
|
||||
From a08c766a556bc6f258dc498b0a1a3b17f251ed66 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Sun, 30 Aug 2015 03:21:57 -0400
|
||||
Subject: [PATCH] RHEL 8: Fix tests for libguestfs-winsupport.
|
||||
|
||||
It doesn't let us use guestfish for arbitrary Windows edits.
|
||||
---
|
||||
test-data/phony-guests/make-windows-img.sh | 1 +
|
||||
tests/charsets/test-charset-fidelity.c | 2 ++
|
||||
v2v/test-v2v-virtio-win-iso.sh | 8 +++++++-
|
||||
v2v/test-v2v-windows-conversion.sh | 8 +++++++-
|
||||
4 files changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/test-data/phony-guests/make-windows-img.sh b/test-data/phony-guests/make-windows-img.sh
|
||||
index 8676b5ac0..1a88d9fc9 100755
|
||||
--- a/test-data/phony-guests/make-windows-img.sh
|
||||
+++ b/test-data/phony-guests/make-windows-img.sh
|
||||
@@ -37,6 +37,7 @@ fi
|
||||
|
||||
# Create a disk image.
|
||||
guestfish <<EOF
|
||||
+set-program virt-testing
|
||||
sparse windows.img-t 512M
|
||||
run
|
||||
|
||||
diff --git a/tests/charsets/test-charset-fidelity.c b/tests/charsets/test-charset-fidelity.c
|
||||
index 967afbc88..eb0491b13 100644
|
||||
--- a/tests/charsets/test-charset-fidelity.c
|
||||
+++ b/tests/charsets/test-charset-fidelity.c
|
||||
@@ -93,6 +93,8 @@ main (int argc, char *argv[])
|
||||
if (g == NULL)
|
||||
error (EXIT_FAILURE, 0, "failed to create handle");
|
||||
|
||||
+ guestfs_set_program (g, "virt-testing");
|
||||
+
|
||||
if (guestfs_add_drive_scratch (g, 1024*1024*1024, -1) == -1)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
diff --git a/v2v/test-v2v-virtio-win-iso.sh b/v2v/test-v2v-virtio-win-iso.sh
|
||||
index 6e99f0f1d..a8e572c5f 100755
|
||||
--- a/v2v/test-v2v-virtio-win-iso.sh
|
||||
+++ b/v2v/test-v2v-virtio-win-iso.sh
|
||||
@@ -79,6 +79,12 @@ mktest ()
|
||||
:> "$script"
|
||||
:> "$expected"
|
||||
|
||||
+cat >> "$script" <<EOF
|
||||
+ set-program virt-testing
|
||||
+ run
|
||||
+ mount /dev/sda2 /
|
||||
+EOF
|
||||
+
|
||||
firstboot_dir="/Program Files/Guestfs/Firstboot"
|
||||
mktest "is-dir \"$firstboot_dir\"" true
|
||||
mktest "is-file \"$firstboot_dir/firstboot.bat\"" true
|
||||
@@ -91,7 +97,7 @@ for drv in netkvm vioscsi viostor; do
|
||||
done
|
||||
done
|
||||
|
||||
-guestfish --ro -a "$d/windows-sda" -i < "$script" > "$response"
|
||||
+guestfish --ro -a "$d/windows-sda" < "$script" > "$response"
|
||||
diff -u "$expected" "$response"
|
||||
|
||||
rm -r $d
|
||||
diff --git a/v2v/test-v2v-windows-conversion.sh b/v2v/test-v2v-windows-conversion.sh
|
||||
index f1da222a9..ff94fe39b 100755
|
||||
--- a/v2v/test-v2v-windows-conversion.sh
|
||||
+++ b/v2v/test-v2v-windows-conversion.sh
|
||||
@@ -73,6 +73,12 @@ mktest ()
|
||||
:> "$script"
|
||||
:> "$expected"
|
||||
|
||||
+cat >> "$script" <<EOF
|
||||
+ set-program virt-testing
|
||||
+ run
|
||||
+ mount /dev/sda2 /
|
||||
+EOF
|
||||
+
|
||||
firstboot_dir="/Program Files/Guestfs/Firstboot"
|
||||
mktest "is-dir \"$firstboot_dir\"" true
|
||||
mktest "is-file \"$firstboot_dir/firstboot.bat\"" true
|
||||
@@ -85,7 +91,7 @@ for drv in netkvm qxl vioscsi viostor; do
|
||||
done
|
||||
done
|
||||
|
||||
-guestfish --ro -a "$d/windows-sda" -i < "$script" > "$response"
|
||||
+guestfish --ro -a "$d/windows-sda" < "$script" > "$response"
|
||||
diff -u "$expected" "$response"
|
||||
|
||||
# We also update the Registry several times, for firstboot, and (ONLY
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,28 @@
|
||||
From 101d4d7718eb5a53e44de72bc1337c6d3882f314 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 21 Sep 2015 13:12:43 -0400
|
||||
Subject: [PATCH] RHEL 8: tests: Disable daemon tests that require the 'unix'
|
||||
backend.
|
||||
|
||||
---
|
||||
tests/daemon/Makefile.am | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tests/daemon/Makefile.am b/tests/daemon/Makefile.am
|
||||
index 053cad3e1..0d723fee4 100644
|
||||
--- a/tests/daemon/Makefile.am
|
||||
+++ b/tests/daemon/Makefile.am
|
||||
@@ -23,9 +23,7 @@ include $(top_srcdir)/subdir-rules.mk
|
||||
|
||||
check_DATA = captive-daemon.pm
|
||||
|
||||
-TESTS = \
|
||||
- test-daemon-start.pl \
|
||||
- test-btrfs.pl
|
||||
+TESTS =
|
||||
|
||||
TESTS_ENVIRONMENT = $(top_builddir)/run --test
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,286 @@
|
||||
From cff6b6531fe7e2bcb9ae8f022bb38a0cabd218f4 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 14 Jan 2016 11:53:42 -0500
|
||||
Subject: [PATCH] RHEL 8: v2v: Disable the virt-v2v --in-place option.
|
||||
|
||||
This disables the virt-v2v --in-place option which we do not
|
||||
wish to support in RHEL.
|
||||
(See commit d0069559a939e47e5f29973ed9a69a13f0b58301).
|
||||
---
|
||||
v2v/Makefile.am | 2 -
|
||||
v2v/cmdline.ml | 8 +--
|
||||
v2v/test-v2v-docs.sh | 1 +
|
||||
v2v/test-v2v-in-place.sh | 108 ---------------------------------------
|
||||
v2v/virt-v2v.pod | 48 +----------------
|
||||
5 files changed, 7 insertions(+), 160 deletions(-)
|
||||
delete mode 100755 v2v/test-v2v-in-place.sh
|
||||
|
||||
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
|
||||
index 6568c9a6b..affa6f7e9 100644
|
||||
--- a/v2v/Makefile.am
|
||||
+++ b/v2v/Makefile.am
|
||||
@@ -469,7 +469,6 @@ if HAVE_LIBVIRT
|
||||
TESTS += \
|
||||
test-v2v-cdrom.sh \
|
||||
test-v2v-floppy.sh \
|
||||
- test-v2v-in-place.sh \
|
||||
test-v2v-mac.sh \
|
||||
test-v2v-networks-and-bridges.sh \
|
||||
test-v2v-no-copy.sh \
|
||||
@@ -621,7 +620,6 @@ EXTRA_DIST += \
|
||||
test-v2v-i-vmx-3.vmx \
|
||||
test-v2v-i-vmx-4.vmx \
|
||||
test-v2v-i-vmx-5.vmx \
|
||||
- test-v2v-in-place.sh \
|
||||
test-v2v-it-vddk-io-query.sh \
|
||||
test-v2v-machine-readable.sh \
|
||||
test-v2v-mac-expected.xml \
|
||||
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
|
||||
index e3578ddcb..19c5a269b 100644
|
||||
--- a/v2v/cmdline.ml
|
||||
+++ b/v2v/cmdline.ml
|
||||
@@ -230,8 +230,7 @@ let parse_cmdline () =
|
||||
s_"Use password from file to connect to input hypervisor";
|
||||
[ M"it" ], Getopt.String ("transport", set_string_option_once "-it" input_transport),
|
||||
s_"Input transport";
|
||||
- [ L"in-place" ], Getopt.Set in_place,
|
||||
- s_"Only tune the guest in the input VM";
|
||||
+ [ L"in-place" ], Getopt.Set in_place, Getopt.hidden_option_description;
|
||||
[ 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),
|
||||
@@ -369,7 +368,6 @@ read the man page virt-v2v(1).
|
||||
pr "vddk\n";
|
||||
pr "colours-option\n";
|
||||
pr "vdsm-compat-option\n";
|
||||
- pr "in-place\n";
|
||||
pr "io/oo\n";
|
||||
pr "mac-option\n";
|
||||
pr "mac-ip-option\n";
|
||||
@@ -544,6 +542,10 @@ read the man page virt-v2v(1).
|
||||
error (f_"only ‘-it ssh’ can be used here") in
|
||||
Input_vmx.input_vmx input_transport arg in
|
||||
|
||||
+ (* Prevent use of --in-place option in RHEL. *)
|
||||
+ if in_place then
|
||||
+ error (f_"--in-place cannot be used in RHEL");
|
||||
+
|
||||
(* Common error message. *)
|
||||
let error_option_cannot_be_used_in_output_mode mode opt =
|
||||
error (f_"-o %s: %s option cannot be used in this output mode") mode opt
|
||||
diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh
|
||||
index dfb12bb14..2e45705a3 100755
|
||||
--- a/v2v/test-v2v-docs.sh
|
||||
+++ b/v2v/test-v2v-docs.sh
|
||||
@@ -26,6 +26,7 @@ $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \
|
||||
--debug-overlay,\
|
||||
--ic,\
|
||||
--if,\
|
||||
+--in-place,\
|
||||
--io,\
|
||||
--ip,\
|
||||
--it,\
|
||||
diff --git a/v2v/test-v2v-in-place.sh b/v2v/test-v2v-in-place.sh
|
||||
deleted file mode 100755
|
||||
index 6f7d78f39..000000000
|
||||
--- a/v2v/test-v2v-in-place.sh
|
||||
+++ /dev/null
|
||||
@@ -1,108 +0,0 @@
|
||||
-#!/bin/bash -
|
||||
-# libguestfs virt-v2v test script
|
||||
-# Copyright (C) 2014 Red Hat Inc.
|
||||
-# Copyright (C) 2015 Parallels IP Holdings GmbH.
|
||||
-#
|
||||
-# 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 --in-place.
|
||||
-
|
||||
-unset CDPATH
|
||||
-export LANG=C
|
||||
-set -e
|
||||
-
|
||||
-$TEST_FUNCTIONS
|
||||
-skip_if_skipped
|
||||
-skip_if_backend uml
|
||||
-skip_unless_phony_guest windows.img
|
||||
-
|
||||
-img_base="$abs_top_builddir/test-data/phony-guests/windows.img"
|
||||
-
|
||||
-export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools"
|
||||
-export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win"
|
||||
-
|
||||
-d=$PWD/test-v2v-in-place.d
|
||||
-rm -rf $d
|
||||
-mkdir $d
|
||||
-
|
||||
-img="$d/test.qcow2"
|
||||
-rm -f $img
|
||||
-qemu-img create -f qcow2 -b $img_base -o compat=1.1,backing_fmt=raw $img
|
||||
-md5="$(do_md5 $img_base)"
|
||||
-
|
||||
-libvirt_xml="$d/test.xml"
|
||||
-rm -f $libvirt_xml
|
||||
-n=windows-overlay
|
||||
-cat > $libvirt_xml <<EOF
|
||||
-<node>
|
||||
- <domain type='test'>
|
||||
- <name>$n</name>
|
||||
- <memory>1048576</memory>
|
||||
- <os>
|
||||
- <type>hvm</type>
|
||||
- <boot dev='hd'/>
|
||||
- </os>
|
||||
- <devices>
|
||||
- <disk type='file' device='disk'>
|
||||
- <driver name='qemu' type='qcow2'/>
|
||||
- <source file='$img'/>
|
||||
- <target dev='vda' bus='virtio'/>
|
||||
- </disk>
|
||||
- </devices>
|
||||
- </domain>
|
||||
-</node>
|
||||
-EOF
|
||||
-
|
||||
-$VG virt-v2v --debug-gc -i libvirt -ic "test://$libvirt_xml" $n --in-place
|
||||
-
|
||||
-# Test that the drivers have been copied over into the guest
|
||||
-script="$d/test.fish"
|
||||
-expected="$d/expected"
|
||||
-response="$d/response"
|
||||
-
|
||||
-mktest ()
|
||||
-{
|
||||
- local cmd="$1" exp="$2"
|
||||
-
|
||||
- echo "echo '$cmd'" >> "$script"
|
||||
- echo "$cmd" >> "$expected"
|
||||
-
|
||||
- echo "$cmd" >> "$script"
|
||||
- echo "$exp" >> "$expected"
|
||||
-}
|
||||
-
|
||||
-:> "$script"
|
||||
-:> "$expected"
|
||||
-
|
||||
-firstboot_dir="/Program Files/Guestfs/Firstboot"
|
||||
-mktest "is-dir \"$firstboot_dir\"" true
|
||||
-mktest "is-file \"$firstboot_dir/firstboot.bat\"" true
|
||||
-mktest "is-dir \"$firstboot_dir/scripts\"" true
|
||||
-virtio_dir="/Windows/Drivers/VirtIO"
|
||||
-mktest "is-dir \"$virtio_dir\"" true
|
||||
-for drv in netkvm qxl vioscsi viostor; do
|
||||
- for sfx in cat inf sys; do
|
||||
- mktest "is-file \"$virtio_dir/$drv.$sfx\"" true
|
||||
- done
|
||||
-done
|
||||
-
|
||||
-guestfish --ro -a "$img" -i < "$script" > "$response"
|
||||
-diff -u "$expected" "$response"
|
||||
-
|
||||
-# Test the base image remained untouched
|
||||
-test "$md5" = "$(do_md5 $img_base)"
|
||||
-
|
||||
-# Clean up.
|
||||
-rm -r $d
|
||||
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
|
||||
index bd606592b..092d88635 100644
|
||||
--- a/v2v/virt-v2v.pod
|
||||
+++ b/v2v/virt-v2v.pod
|
||||
@@ -8,10 +8,6 @@ virt-v2v - Convert a guest to use KVM
|
||||
[-o mode] [other -o* options]
|
||||
[guest|filename]
|
||||
|
||||
- virt-v2v --in-place
|
||||
- [-i mode] [other -i* options]
|
||||
- [guest|filename]
|
||||
-
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Virt-v2v converts a single guest from a foreign hypervisor to run on
|
||||
@@ -39,9 +35,6 @@ these sides of virt-v2v are documented separately in this manual.
|
||||
|
||||
Virt-v2v normally copies from the input to the output, called "copying
|
||||
mode". In this case the source guest is always left unchanged.
|
||||
-In-place conversion (I<--in-place>) only uses the I<-i*> options and
|
||||
-modifies the source guest in-place. (See L</In-place conversion>
|
||||
-below.)
|
||||
|
||||
=head2 Other virt-v2v topics
|
||||
|
||||
@@ -255,20 +248,6 @@ For I<-i disk> only, this specifies the format of the input disk
|
||||
image. For other input methods you should specify the input
|
||||
format in the metadata.
|
||||
|
||||
-=item B<--in-place>
|
||||
-
|
||||
-Do not create an output virtual machine in the target hypervisor.
|
||||
-Instead, adjust the guest OS in the source VM to run in the input
|
||||
-hypervisor.
|
||||
-
|
||||
-This mode is meant for integration with other toolsets, which take the
|
||||
-responsibility of converting the VM configuration, providing for
|
||||
-rollback in case of errors, transforming the storage, etc.
|
||||
-
|
||||
-See L</In-place conversion> below.
|
||||
-
|
||||
-Conflicts with all I<-o *> options.
|
||||
-
|
||||
=item B<-io> OPTION=VALUE
|
||||
|
||||
Set input option(s) related to the current input mode or transport.
|
||||
@@ -1300,7 +1279,7 @@ Minimum free space: 10 MB
|
||||
=head3 Minimum free space check in the host
|
||||
|
||||
You must have sufficient free space in the host directory used to
|
||||
-store temporary overlays (except in I<--in-place> mode). To find out
|
||||
+store temporary overlays. To find out
|
||||
which directory this is, use:
|
||||
|
||||
$ df -h "`guestfish get-cachedir`"
|
||||
@@ -1403,31 +1382,6 @@ that instead.
|
||||
</devices>
|
||||
</domain>
|
||||
|
||||
-=head2 In-place conversion
|
||||
-
|
||||
-It is also possible to use virt-v2v in scenarios where a foreign VM
|
||||
-has already been imported into a KVM-based hypervisor, but still needs
|
||||
-adjustments in the guest to make it run in the new virtual hardware.
|
||||
-
|
||||
-In that case it is assumed that a third-party tool has created the
|
||||
-target VM in the supported KVM-based hypervisor based on the source VM
|
||||
-configuration and contents, but using virtual devices more appropriate
|
||||
-for KVM (e.g. virtio storage and network, etc.).
|
||||
-
|
||||
-Then, to make the guest OS boot and run in the changed environment,
|
||||
-one can use:
|
||||
-
|
||||
- virt-v2v -ic qemu:///system converted_vm --in-place
|
||||
-
|
||||
-Virt-v2v will analyze the configuration of C<converted_vm> in the
|
||||
-C<qemu:///system> libvirt instance, and apply various fixups to the
|
||||
-guest OS configuration to make it match the VM configuration. This
|
||||
-may include installing virtio drivers, configuring the bootloader, the
|
||||
-mountpoints, the network interfaces, and so on.
|
||||
-
|
||||
-Should an error occur during the operation, virt-v2v exits with an
|
||||
-error code leaving the VM in an undefined state.
|
||||
-
|
||||
=head2 Machine readable output
|
||||
|
||||
The I<--machine-readable> option can be used to make the output more
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,26 @@
|
||||
From 6ae622c541bdc1128a0a8a6d0cfe7cae29186556 Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Thu, 2 Mar 2017 14:21:37 +0100
|
||||
Subject: [PATCH] RHEL 8: v2v: -i disk: force VNC as display (RHBZ#1372671)
|
||||
|
||||
The SDL output mode is not supported in RHEL 8's qemu-kvm.
|
||||
---
|
||||
v2v/input_disk.ml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/input_disk.ml b/v2v/input_disk.ml
|
||||
index 8321a2a8c..6bd9f43f8 100644
|
||||
--- a/v2v/input_disk.ml
|
||||
+++ b/v2v/input_disk.ml
|
||||
@@ -89,7 +89,7 @@ class input_disk input_format disk = object
|
||||
s_features = [ "acpi"; "apic"; "pae" ];
|
||||
s_firmware = UnknownFirmware; (* causes virt-v2v to autodetect *)
|
||||
s_display =
|
||||
- Some { s_display_type = Window; s_keymap = None; s_password = None;
|
||||
+ Some { s_display_type = VNC; s_keymap = None; s_password = None;
|
||||
s_listen = LNoListen; s_port = None };
|
||||
s_video = None;
|
||||
s_sound = None;
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,26 @@
|
||||
From b60599b78bdf31c289767b01c235580534f52f77 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Wed, 8 Mar 2017 11:03:40 +0100
|
||||
Subject: [PATCH] RHEL 8: v2v: do not mention SUSE Xen hosts (RHBZ#1430203)
|
||||
|
||||
They are not supported in RHEL 8.
|
||||
---
|
||||
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 9fd5065f1..c3c20a6b6 100644
|
||||
--- a/v2v/virt-v2v-input-xen.pod
|
||||
+++ b/v2v/virt-v2v-input-xen.pod
|
||||
@@ -10,7 +10,7 @@ virt-v2v-input-xen - Using virt-v2v to convert guests from Xen
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This page documents how to use L<virt-v2v(1)> to convert guests from
|
||||
-RHEL 5 Xen, or SLES and OpenSUSE Xen hosts.
|
||||
+RHEL 5 Xen hosts.
|
||||
|
||||
=head1 INPUT FROM XEN
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,91 @@
|
||||
From a233d0f924d7c052bbd663a8e1d47fe363de120c Mon Sep 17 00:00:00 2001
|
||||
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||||
Date: Mon, 14 May 2018 10:16:58 +0100
|
||||
Subject: [PATCH] RHEL 8: v2v: rhv-upload: Remove restriction on -oa sparse.
|
||||
|
||||
See: https://bugzilla.redhat.com/show_bug.cgi?id=1565681
|
||||
and the v2v-devel private thread "Do we already support migration using FC?"
|
||||
---
|
||||
v2v/output_rhv_upload.ml | 11 +----------
|
||||
v2v/rhv-upload-plugin.py | 4 +---
|
||||
v2v/virt-v2v-output-rhv.pod | 8 +-------
|
||||
3 files changed, 3 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
||||
index e1d06867b..3f078157a 100644
|
||||
--- a/v2v/output_rhv_upload.ml
|
||||
+++ b/v2v/output_rhv_upload.ml
|
||||
@@ -177,19 +177,11 @@ See also the virt-v2v-output-rhv(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
|
||||
- *)
|
||||
+ (* Output format must be raw. *)
|
||||
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 ());
|
||||
@@ -249,7 +241,6 @@ object
|
||||
error_unless_ovirtsdk4_module_available ();
|
||||
error_unless_nbdkit_working ();
|
||||
error_unless_nbdkit_python_plugin_working ();
|
||||
- error_unless_output_alloc_sparse ();
|
||||
(* Python code prechecks. *)
|
||||
let precheck_fn = tmpdir // "v2vprecheck.json" in
|
||||
let fd = Unix.openfile precheck_fn [O_WRONLY; O_CREAT] 0o600 in
|
||||
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
|
||||
index 14d4e37fb..c7f7a5e8b 100644
|
||||
--- a/v2v/rhv-upload-plugin.py
|
||||
+++ b/v2v/rhv-upload-plugin.py
|
||||
@@ -142,10 +142,8 @@ def open(readonly):
|
||||
format = disk_format,
|
||||
initial_size = params['disk_size'],
|
||||
provisioned_size = params['disk_size'],
|
||||
- # XXX Ignores params['output_sparse'].
|
||||
- # Handling this properly will be complex, see:
|
||||
# https://www.redhat.com/archives/libguestfs/2018-March/msg00177.html
|
||||
- sparse = True,
|
||||
+ sparse = params['output_sparse'],
|
||||
storage_domains = [
|
||||
types.StorageDomain(
|
||||
name = params['output_storage'],
|
||||
diff --git a/v2v/virt-v2v-output-rhv.pod b/v2v/virt-v2v-output-rhv.pod
|
||||
index 4520c9184..f6579a48e 100644
|
||||
--- a/v2v/virt-v2v-output-rhv.pod
|
||||
+++ b/v2v/virt-v2v-output-rhv.pod
|
||||
@@ -5,7 +5,7 @@ virt-v2v-output-rhv - Using virt-v2v to convert guests to oVirt or RHV
|
||||
=head1 SYNOPSIS
|
||||
|
||||
virt-v2v [-i* options] -o rhv-upload [-oc ENGINE_URL] -os STORAGE
|
||||
- [-op PASSWORD] [-of raw]
|
||||
+ [-op PASSWORD]
|
||||
[-oo rhv-cafile=FILE]
|
||||
[-oo rhv-cluster=CLUSTER]
|
||||
[-oo rhv-direct]
|
||||
@@ -79,12 +79,6 @@ username is not specified then virt-v2v defaults to using
|
||||
C<admin@internal> which is the typical superuser account for oVirt
|
||||
instances.
|
||||
|
||||
-=item I<-of raw>
|
||||
-
|
||||
-Currently you must use I<-of raw> and you cannot use I<-oa preallocated>.
|
||||
-
|
||||
-These restrictions will be loosened in a future version.
|
||||
-
|
||||
=item I<-op> F<password-file>
|
||||
|
||||
A file containing a password to be used when connecting to the oVirt
|
||||
--
|
||||
2.24.1
|
||||
|
27
SOURCES/0071-RHEL-8-use-platform-python.patch
Normal file
27
SOURCES/0071-RHEL-8-use-platform-python.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From c5212d2acda7eb21923e376f7c7b0d8ce8a108d1 Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Sun, 16 Dec 2018 16:42:46 +0100
|
||||
Subject: [PATCH] RHEL 8: use platform-python
|
||||
|
||||
Use the stable platform-python provided in BaseOS, instead of relying on
|
||||
some arbitrary version installed by the user.
|
||||
---
|
||||
v2v/python_script.ml | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/v2v/python_script.ml b/v2v/python_script.ml
|
||||
index 3159373a1..f2c00c40f 100644
|
||||
--- a/v2v/python_script.ml
|
||||
+++ b/v2v/python_script.ml
|
||||
@@ -24,7 +24,7 @@ open Unix_utils
|
||||
|
||||
open Common_gettext.Gettext
|
||||
|
||||
-let python = "python3" (* Defined by PEP 394 *)
|
||||
+let python = "/usr/libexec/platform-python"
|
||||
|
||||
type script = {
|
||||
tmpdir : string; (* Temporary directory. *)
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,125 @@
|
||||
From b70c61045e659720ee8f7dbd8eff643a877e8e2f Mon Sep 17 00:00:00 2001
|
||||
From: Pino Toscano <ptoscano@redhat.com>
|
||||
Date: Tue, 26 Mar 2019 09:42:25 +0100
|
||||
Subject: [PATCH] RHEL 8: point to KB for supported v2v hypervisors/guests
|
||||
|
||||
---
|
||||
v2v/virt-v2v-support.pod | 102 ++-------------------------------------
|
||||
1 file changed, 4 insertions(+), 98 deletions(-)
|
||||
|
||||
diff --git a/v2v/virt-v2v-support.pod b/v2v/virt-v2v-support.pod
|
||||
index a22506068..4ec1a07c1 100644
|
||||
--- a/v2v/virt-v2v-support.pod
|
||||
+++ b/v2v/virt-v2v-support.pod
|
||||
@@ -8,104 +8,10 @@ systems and guests in virt-v2v
|
||||
This page documents which foreign hypervisors, virtualization
|
||||
management systems and guest types that L<virt-v2v(1)> can support.
|
||||
|
||||
-Note this page applies to upstream virt-v2v from
|
||||
-L<http://libguestfs.org> and in downstream distributions of virt-v2v
|
||||
-sometimes features are intentionally removed, or are present but not
|
||||
-supported.
|
||||
-
|
||||
-=head2 Hypervisors (Input)
|
||||
-
|
||||
-=over 4
|
||||
-
|
||||
-=item VMware ESXi
|
||||
-
|
||||
-Must be managed by VMware vCenter E<ge> 5.0 unless VDDK is available.
|
||||
-
|
||||
-=item OVA exported from VMware
|
||||
-
|
||||
-OVAs from other hypervisors will not work.
|
||||
-
|
||||
-=item VMX from VMware
|
||||
-
|
||||
-VMX files generated by other hypervisors will not work.
|
||||
-
|
||||
-=item RHEL 5 Xen
|
||||
-
|
||||
-=item SUSE Xen
|
||||
-
|
||||
-=item Citrix Xen
|
||||
-
|
||||
-Citrix Xen has not been recently tested.
|
||||
-
|
||||
-=item Hyper-V
|
||||
-
|
||||
-Not recently tested. Requires that you export the disk or use
|
||||
-L<virt-p2v(1)> on Hyper-V.
|
||||
-
|
||||
-=item Direct from disk images
|
||||
-
|
||||
-Only disk images exported from supported hypervisors, and using
|
||||
-container formats supported by qemu.
|
||||
-
|
||||
-=item Physical machines
|
||||
-
|
||||
-Using the L<virt-p2v(1)> tool.
|
||||
-
|
||||
-=back
|
||||
-
|
||||
-=head2 Hypervisors (Output)
|
||||
-
|
||||
-QEMU and KVM only.
|
||||
-
|
||||
-=head2 Virtualization management systems (Output)
|
||||
-
|
||||
-=over 4
|
||||
-
|
||||
-=item OpenStack
|
||||
-
|
||||
-=item Red Hat Virtualization (RHV) 4.1 and up
|
||||
-
|
||||
-=item Local libvirt
|
||||
-
|
||||
-And hence L<virsh(1)>, L<virt-manager(1)>, and similar tools.
|
||||
-
|
||||
-=item Local disk
|
||||
-
|
||||
-=back
|
||||
-
|
||||
-=head2 Guests
|
||||
-
|
||||
-=over 4
|
||||
-
|
||||
-=item Red Hat Enterprise Linux 3, 4, 5, 6, 7
|
||||
-
|
||||
-=item CentOS 3, 4, 5, 6, 7
|
||||
-
|
||||
-=item Scientific Linux 3, 4, 5, 6, 7
|
||||
-
|
||||
-=item Oracle Linux
|
||||
-
|
||||
-=item Fedora
|
||||
-
|
||||
-=item SLES 10 and up
|
||||
-
|
||||
-=item OpenSUSE 10 and up
|
||||
-
|
||||
-=item Debian 6 and up
|
||||
-
|
||||
-=item Ubuntu 10.04, 12.04, 14.04, 16.04, and up
|
||||
-
|
||||
-=item Windows XP to Windows 10 / Windows Server 2016
|
||||
-
|
||||
-We use Windows internal version numbers, see
|
||||
-L<https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions>
|
||||
-
|
||||
-Currently NT 5.2 to NT 6.3 are supported.
|
||||
-
|
||||
-See L</WINDOWS> below for additional notes on converting Windows
|
||||
-guests.
|
||||
-
|
||||
-=back
|
||||
+For more information on supported hypervisors, and guest types in
|
||||
+RHEL, please consult the following Knowledgebase article on these
|
||||
+Red Hat Customer Portal:
|
||||
+L<https://access.redhat.com/articles/1351473>.
|
||||
|
||||
=head2 Guest firmware
|
||||
|
||||
--
|
||||
2.24.1
|
||||
|
38
SOURCES/README-replacement.in
Normal file
38
SOURCES/README-replacement.in
Normal file
@ -0,0 +1,38 @@
|
||||
Libguestfs is a set of tools and a library for accessing and modifying
|
||||
guest disk images. For more information see the home page:
|
||||
|
||||
http://libguestfs.org/
|
||||
|
||||
For discussion, development, patches, etc. please use the mailing
|
||||
list:
|
||||
|
||||
http://www.redhat.com/mailman/listinfo/libguestfs
|
||||
|
||||
This Red Hat Enterprise Linux package comes with a lot of help and
|
||||
examples to get you started.
|
||||
|
||||
The first place to start are the manual pages. Type:
|
||||
|
||||
man guestfs
|
||||
man guestfs-faq
|
||||
man guestfs-release-notes
|
||||
man guestfish
|
||||
man virt-cat # and other virt-* tools
|
||||
|
||||
If you install the libguestfs-devel package, then in the
|
||||
/usr/share/doc/libguestfs-devel/ directory you will also
|
||||
find:
|
||||
|
||||
- BUGS: list of open bugs in this version
|
||||
|
||||
- ChangeLog: the detailed list of changes in this version
|
||||
|
||||
- ROADMAP: the roadmap for future versions
|
||||
|
||||
- TODO: ideas for extending libguestfs
|
||||
|
||||
- *.c: example C programs using the API
|
||||
|
||||
- *.xml: example virt-inspector output
|
||||
|
||||
- *.rng: virt-inspector RelaxNG schema
|
20
SOURCES/brew-overrides.sh
Executable file
20
SOURCES/brew-overrides.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash -
|
||||
|
||||
# This script is used when we build libguestfs from brew, as sometimes
|
||||
# we require packages which are not available in the current version
|
||||
# of RHEL. Normally these updated packages would be released along
|
||||
# with libguestfs in the next RHEL, although unfortunately sometimes
|
||||
# that doesn't happen (eg. RHBZ#1199605).
|
||||
|
||||
set -x
|
||||
|
||||
pkgs="
|
||||
"
|
||||
|
||||
for pkg in $pkgs ; do
|
||||
brew tag-pkg rhel-8.0-temp-override $pkg
|
||||
done
|
||||
|
||||
for pkg in $pkgs ; do
|
||||
brew wait-repo rhel-8.0-build --build=$pkg
|
||||
done
|
55
SOURCES/copy-patches.sh
Executable file
55
SOURCES/copy-patches.sh
Executable file
@ -0,0 +1,55 @@
|
||||
#!/bin/bash -
|
||||
|
||||
set -e
|
||||
|
||||
# Maintainer script to copy patches from the git repo to the current
|
||||
# directory. Use it like this:
|
||||
# ./copy-patches.sh
|
||||
|
||||
rhel_version=8.0
|
||||
|
||||
# Check we're in the right directory.
|
||||
if [ ! -f libguestfs.spec ]; then
|
||||
echo "$0: run this from the directory containing 'libguestfs.spec'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git_checkout=$HOME/d/libguestfs-rhel-$rhel_version
|
||||
if [ ! -d $git_checkout ]; then
|
||||
echo "$0: $git_checkout does not exist"
|
||||
echo "This script is only for use by the maintainer when preparing a"
|
||||
echo "libguestfs release on RHEL."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the base version of libguestfs.
|
||||
version=`grep '^Version:' libguestfs.spec | awk '{print $2}'`
|
||||
tag="v$version"
|
||||
|
||||
# Remove any existing patches.
|
||||
git rm -f [0-9]*.patch ||:
|
||||
rm -f [0-9]*.patch
|
||||
|
||||
# Get the patches.
|
||||
(cd $git_checkout; rm -f [0-9]*.patch; git format-patch -N $tag)
|
||||
mv $git_checkout/[0-9]*.patch .
|
||||
|
||||
# Remove any not to be applied.
|
||||
rm -f *NOT-FOR-RPM*.patch
|
||||
|
||||
# Add the patches.
|
||||
git add [0-9]*.patch
|
||||
|
||||
# Print out the patch lines.
|
||||
echo
|
||||
echo "--- Copy the following text into libguestfs.spec file"
|
||||
echo
|
||||
|
||||
echo "# Patches."
|
||||
for f in [0-9]*.patch; do
|
||||
n=`echo $f | awk -F- '{print $1}'`
|
||||
echo "Patch$n: $f"
|
||||
done
|
||||
|
||||
echo
|
||||
echo "--- End of text"
|
6
SOURCES/guestfish.sh
Normal file
6
SOURCES/guestfish.sh
Normal file
@ -0,0 +1,6 @@
|
||||
# Guestfish colour prompts. See PROMPT in guestfish(1).
|
||||
GUESTFISH_PS1='\[\e[1;32m\]><fs>\[\e[0;31m\] '
|
||||
GUESTFISH_OUTPUT='\e[0m'
|
||||
GUESTFISH_RESTORE="$GUESTFISH_OUTPUT"
|
||||
GUESTFISH_INIT='\e[1;34m'
|
||||
export GUESTFISH_PS1 GUESTFISH_OUTPUT GUESTFISH_RESTORE GUESTFISH_INIT
|
17
SOURCES/libguestfs-1.40.2.tar.gz.sig
Normal file
17
SOURCES/libguestfs-1.40.2.tar.gz.sig
Normal file
@ -0,0 +1,17 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQJFBAABCAAvFiEE93dPsa0HSn6Mh2fqkXOPc+G3aKAFAlxdivwRHHJpY2hAYW5u
|
||||
ZXhpYS5vcmcACgkQkXOPc+G3aKC8SRAAotTR3nvV2lUeABLn8uiv5CjmeEEm++C4
|
||||
754zGkOb7bRSQzcQ12XC0e4WQwcS/fHHSRhT2ABc1VeLn8ehyEEQ3T3NfDpnpaKR
|
||||
NYolsI3l8iae4QI0wo85/Wb/k7pXg1uWFZ9t286d1e/NYudMEZ6hiVXsUNlSu0lR
|
||||
rU5Xr/XGDV01Vlalo1qcVI1p3b3zBFGcNLv5Myc0+Q+RWVYcyrm270VJYmD0OOnh
|
||||
zzRgb1fBW4rVIbYEhmmhNgbL3758Qaef/jsTxU/tH83LOdJUpxWYvLD7ec3DzsHr
|
||||
xcNgDCZxCtn4ObdfxJGzVbWO96nmVPxNnVMeDol+PDsrVkQnpSPMPrU/oth5Xh19
|
||||
+JeP22SSDahCIbO9YlL3AoA3l1gpLq2f9yTz9JIHm4ytBZmQPD8QU2KBQFsz+/ZE
|
||||
Gulc0j/3mzlRyoesuVGb79OWBfSDCHittKVFPXqokzNu0jWZVd7GxfJ2DQqUprJd
|
||||
eK4LDJpInS+Vdohjko8uuC9AfGB68hWbuazjdWLhTNQb3/8EzX5Xu2N88xlWuBQK
|
||||
HRu8NPp601uI6qdjj38VUXGY5BryDIJdvqf5hoRNe/2scf3OomaMpdck59gLT4LB
|
||||
/yaNbfPSRenXQ1IM3mU9Opktvm48cpJQ8B80OEmWenhhjXrHrgplVNkXK7inZ7vu
|
||||
TKia/N90ugY=
|
||||
=kgC8
|
||||
-----END PGP SIGNATURE-----
|
17
SOURCES/yum.conf.in
Normal file
17
SOURCES/yum.conf.in
Normal file
@ -0,0 +1,17 @@
|
||||
[main]
|
||||
cachedir=@PWD@/cachedir
|
||||
debuglevel=1
|
||||
logfile=@PWD@/yum.log
|
||||
retries=20
|
||||
obsoletes=1
|
||||
gpgcheck=0
|
||||
assumeyes=1
|
||||
reposdir=/dev/null
|
||||
modulesdir=@PWD@/modules
|
||||
|
||||
[local]
|
||||
name=local
|
||||
baseurl=file://@PWD@/repo
|
||||
failovermethod=priority
|
||||
enabled=1
|
||||
gpgcheck=0
|
4096
SPECS/libguestfs.spec
Normal file
4096
SPECS/libguestfs.spec
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user