2020-06-09 20:48:13 +00:00
|
|
|
|
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)
|
|
|
|
|
--
|
2020-08-19 12:07:53 +00:00
|
|
|
|
2.26.2
|
2020-06-09 20:48:13 +00:00
|
|
|
|
|