|
|
46b2f6 |
From ccd327919ca1fed3e10fdd3567ede0dc8cd5d0c3 Mon Sep 17 00:00:00 2001
|
|
|
46b2f6 |
From: Pino Toscano <ptoscano@redhat.com>
|
|
|
46b2f6 |
Date: Thu, 12 Sep 2019 15:21:26 +0200
|
|
|
46b2f6 |
Subject: [PATCH] v2v: -o rhv-upload: improve lookup of specified resources
|
|
|
46b2f6 |
(RHBZ#1612653)
|
|
|
46b2f6 |
|
|
|
46b2f6 |
Improve the way the precheck script checks for the specified resources:
|
|
|
46b2f6 |
- look directly for a data center with the specified storage domain
|
|
|
46b2f6 |
- get the storage domain object from the storage domains attached to the
|
|
|
46b2f6 |
data center found
|
|
|
46b2f6 |
- similarly, look for the specified cluster among the ones attached to
|
|
|
46b2f6 |
the data center found
|
|
|
46b2f6 |
When everything is found, return the UUID of the storage domain, and of
|
|
|
46b2f6 |
the cluster back to virt-v2v, which will store them.
|
|
|
46b2f6 |
|
|
|
46b2f6 |
Similarly, rework the createvm script to directly get the requested
|
|
|
46b2f6 |
cluster, instead of looking for it once again. Also, since the UUID of
|
|
|
46b2f6 |
the storage domain is available in virt-v2v already, use it directly
|
|
|
46b2f6 |
instead of using a placeholder.
|
|
|
46b2f6 |
|
|
|
46b2f6 |
This should fix a number of issues:
|
|
|
46b2f6 |
- unexisting/unattached storage domains are rejected outright
|
|
|
46b2f6 |
- the cluster is rejected if not part of the same data center of the
|
|
|
46b2f6 |
selected storage domain
|
|
|
46b2f6 |
- renaming the specified storage domain during the data copying will not
|
|
|
46b2f6 |
cause the conversion to fail (which will still use the specified
|
|
|
46b2f6 |
storage domain, no matter the new name)
|
|
|
46b2f6 |
|
|
|
46b2f6 |
Based on the hints by Daniel Erez in RHBZ#1612653.
|
|
|
46b2f6 |
|
|
|
46b2f6 |
(cherry picked from commit c49aa4fe01aac82d4776dd2a3524ce16e6deed06)
|
|
|
46b2f6 |
---
|
|
|
46b2f6 |
v2v/output_rhv_upload.ml | 24 +++++++++++++++++++-----
|
|
|
46b2f6 |
v2v/rhv-upload-createvm.py | 11 ++++-------
|
|
|
46b2f6 |
v2v/rhv-upload-precheck.py | 30 ++++++++++++++++++++++++------
|
|
|
46b2f6 |
3 files changed, 47 insertions(+), 18 deletions(-)
|
|
|
46b2f6 |
|
|
|
46b2f6 |
diff --git a/v2v/output_rhv_upload.ml b/v2v/output_rhv_upload.ml
|
|
|
46b2f6 |
index fd6f2e3e6..19bdfcf05 100644
|
|
|
46b2f6 |
--- a/v2v/output_rhv_upload.ml
|
|
|
46b2f6 |
+++ b/v2v/output_rhv_upload.ml
|
|
|
46b2f6 |
@@ -227,6 +227,11 @@ See also the virt-v2v-output-rhv(1) manual.")
|
|
|
46b2f6 |
object
|
|
|
46b2f6 |
inherit output
|
|
|
46b2f6 |
|
|
|
46b2f6 |
+ (* The storage domain UUID. *)
|
|
|
46b2f6 |
+ val mutable rhv_storagedomain_uuid = None
|
|
|
46b2f6 |
+ (* The cluster UUID. *)
|
|
|
46b2f6 |
+ val mutable rhv_cluster_uuid = None
|
|
|
46b2f6 |
+
|
|
|
46b2f6 |
method precheck () =
|
|
|
46b2f6 |
Python_script.error_unless_python_interpreter_found ();
|
|
|
46b2f6 |
error_unless_ovirtsdk4_module_available ();
|
|
|
46b2f6 |
@@ -242,6 +247,10 @@ object
|
|
|
46b2f6 |
let json = JSON_parser.json_parser_tree_parse_file precheck_fn in
|
|
|
46b2f6 |
debug "precheck output parsed as: %s"
|
|
|
46b2f6 |
(JSON.string_of_doc ~fmt:JSON.Indented ["", json]);
|
|
|
46b2f6 |
+ rhv_storagedomain_uuid <-
|
|
|
46b2f6 |
+ Some (JSON_parser.object_get_string "rhv_storagedomain_uuid" json);
|
|
|
46b2f6 |
+ rhv_cluster_uuid <-
|
|
|
46b2f6 |
+ Some (JSON_parser.object_get_string "rhv_cluster_uuid" json);
|
|
|
46b2f6 |
if have_selinux then
|
|
|
46b2f6 |
error_unless_nbdkit_compiled_with_selinux ()
|
|
|
46b2f6 |
|
|
|
46b2f6 |
@@ -388,11 +397,11 @@ If the messages above are not sufficient to diagnose the problem then add the
|
|
|
46b2f6 |
diskid
|
|
|
46b2f6 |
) targets in
|
|
|
46b2f6 |
|
|
|
46b2f6 |
- (* We don't have the storage domain UUID, but instead we write
|
|
|
46b2f6 |
- * in a magic value which the Python code (which can get it)
|
|
|
46b2f6 |
- * will substitute.
|
|
|
46b2f6 |
- *)
|
|
|
46b2f6 |
- let sd_uuid = "@SD_UUID@" in
|
|
|
46b2f6 |
+ (* The storage domain UUID. *)
|
|
|
46b2f6 |
+ let sd_uuid =
|
|
|
46b2f6 |
+ match rhv_storagedomain_uuid with
|
|
|
46b2f6 |
+ | None -> assert false
|
|
|
46b2f6 |
+ | Some uuid -> uuid in
|
|
|
46b2f6 |
|
|
|
46b2f6 |
(* The volume and VM UUIDs are made up. *)
|
|
|
46b2f6 |
let vol_uuids = List.map (fun _ -> uuidgen ()) targets
|
|
|
46b2f6 |
@@ -406,6 +415,11 @@ If the messages above are not sufficient to diagnose the problem then add the
|
|
|
46b2f6 |
OVirt in
|
|
|
46b2f6 |
let ovf = DOM.doc_to_string ovf in
|
|
|
46b2f6 |
|
|
|
46b2f6 |
+ let json_params =
|
|
|
46b2f6 |
+ match rhv_cluster_uuid with
|
|
|
46b2f6 |
+ | None -> assert false
|
|
|
46b2f6 |
+ | Some uuid -> ("rhv_cluster_uuid", JSON.String uuid) :: json_params in
|
|
|
46b2f6 |
+
|
|
|
46b2f6 |
let ovf_file = tmpdir // "vm.ovf" in
|
|
|
46b2f6 |
with_open_out ovf_file (fun chan -> output_string chan ovf);
|
|
|
46b2f6 |
if Python_script.run_command createvm_script json_params [ovf_file] <> 0
|
|
|
46b2f6 |
diff --git a/v2v/rhv-upload-createvm.py b/v2v/rhv-upload-createvm.py
|
|
|
46b2f6 |
index 1d0e8c95d..ed57a9b20 100644
|
|
|
46b2f6 |
--- a/v2v/rhv-upload-createvm.py
|
|
|
46b2f6 |
+++ b/v2v/rhv-upload-createvm.py
|
|
|
46b2f6 |
@@ -65,17 +65,14 @@ connection = sdk.Connection(
|
|
|
46b2f6 |
|
|
|
46b2f6 |
system_service = connection.system_service()
|
|
|
46b2f6 |
|
|
|
46b2f6 |
-# Get the storage domain UUID and substitute it into the OVF doc.
|
|
|
46b2f6 |
-sds_service = system_service.storage_domains_service()
|
|
|
46b2f6 |
-sd = sds_service.list(search=("name=%s" % params['output_storage']))[0]
|
|
|
46b2f6 |
-sd_uuid = sd.id
|
|
|
46b2f6 |
-
|
|
|
46b2f6 |
-ovf = ovf.replace("@SD_UUID@", sd_uuid)
|
|
|
46b2f6 |
+# Get the cluster.
|
|
|
46b2f6 |
+cluster = system_service.clusters_service().cluster_service(params['rhv_cluster_uuid'])
|
|
|
46b2f6 |
+cluster = cluster.get()
|
|
|
46b2f6 |
|
|
|
46b2f6 |
vms_service = system_service.vms_service()
|
|
|
46b2f6 |
vm = vms_service.add(
|
|
|
46b2f6 |
types.Vm(
|
|
|
46b2f6 |
- cluster=types.Cluster(name = params['rhv_cluster']),
|
|
|
46b2f6 |
+ cluster=cluster,
|
|
|
46b2f6 |
initialization=types.Initialization(
|
|
|
46b2f6 |
configuration = types.Configuration(
|
|
|
46b2f6 |
type = types.ConfigurationType.OVA,
|
|
|
46b2f6 |
diff --git a/v2v/rhv-upload-precheck.py b/v2v/rhv-upload-precheck.py
|
|
|
46b2f6 |
index de8a66c05..725a8dc9e 100644
|
|
|
46b2f6 |
--- a/v2v/rhv-upload-precheck.py
|
|
|
46b2f6 |
+++ b/v2v/rhv-upload-precheck.py
|
|
|
46b2f6 |
@@ -60,18 +60,36 @@ connection = sdk.Connection(
|
|
|
46b2f6 |
|
|
|
46b2f6 |
system_service = connection.system_service()
|
|
|
46b2f6 |
|
|
|
46b2f6 |
-# Check whether the specified cluster exists.
|
|
|
46b2f6 |
-clusters_service = system_service.clusters_service()
|
|
|
46b2f6 |
-clusters = clusters_service.list(
|
|
|
46b2f6 |
- search='name=%s' % params['rhv_cluster'],
|
|
|
46b2f6 |
+# Check whether there is a datacenter for the specified storage.
|
|
|
46b2f6 |
+data_centers = system_service.data_centers_service().list(
|
|
|
46b2f6 |
+ search='storage.name=%s' % params['output_storage'],
|
|
|
46b2f6 |
case_sensitive=True,
|
|
|
46b2f6 |
)
|
|
|
46b2f6 |
+if len(data_centers) == 0:
|
|
|
46b2f6 |
+ # The storage domain is not attached to a datacenter
|
|
|
46b2f6 |
+ # (shouldn't happen, would fail on disk creation).
|
|
|
46b2f6 |
+ raise RuntimeError("The storage domain ‘%s’ is not attached to a DC" %
|
|
|
46b2f6 |
+ (params['output_storage']))
|
|
|
46b2f6 |
+datacenter = data_centers[0]
|
|
|
46b2f6 |
+
|
|
|
46b2f6 |
+# Get the storage domain.
|
|
|
46b2f6 |
+storage_domains = connection.follow_link(datacenter.storage_domains)
|
|
|
46b2f6 |
+storage_domain = [sd for sd in storage_domains if sd.name == params['output_storage']][0]
|
|
|
46b2f6 |
+
|
|
|
46b2f6 |
+# Get the cluster.
|
|
|
46b2f6 |
+clusters = connection.follow_link(datacenter.clusters)
|
|
|
46b2f6 |
+clusters = [cluster for cluster in clusters if cluster.name == params['rhv_cluster']]
|
|
|
46b2f6 |
if len(clusters) == 0:
|
|
|
46b2f6 |
- raise RuntimeError("The cluster ‘%s’ does not exist" %
|
|
|
46b2f6 |
- (params['rhv_cluster']))
|
|
|
46b2f6 |
+ raise RuntimeError("The cluster ‘%s’ is not part of the DC ‘%s’, "
|
|
|
46b2f6 |
+ "where the storage domain ‘%s’ is" %
|
|
|
46b2f6 |
+ (params['rhv_cluster'], datacenter.name,
|
|
|
46b2f6 |
+ params['output_storage']))
|
|
|
46b2f6 |
+cluster = clusters[0]
|
|
|
46b2f6 |
|
|
|
46b2f6 |
# Otherwise everything is OK, print a JSON with the results.
|
|
|
46b2f6 |
results = {
|
|
|
46b2f6 |
+ "rhv_storagedomain_uuid": storage_domain.id,
|
|
|
46b2f6 |
+ "rhv_cluster_uuid": cluster.id,
|
|
|
46b2f6 |
}
|
|
|
46b2f6 |
|
|
|
46b2f6 |
json.dump(results, sys.stdout)
|
|
|
46b2f6 |
--
|
|
|
d60042 |
2.25.4
|
|
|
46b2f6 |
|