mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone

Blame SOURCES/0034-v2v-o-rhv-upload-improve-lookup-of-specified-resourc.patch

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