mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone

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

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