From 17463d224f6723c3d6424e3d4c4602ef0618ba4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ren=C3=A9=20Nussbaumer?= <rn@google.com>
Date: Tue, 9 Mar 2010 10:40:43 +0100
Subject: [PATCH] Add support for per-os-hypervisor parameters
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch implements all modifications to support per-os-hypervisor
parameters in the framework.

Signed-off-by: RenΓ© Nussbaumer <rn@google.com>
Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/cmdlib.py       | 31 +++++++++++++++++++++++++++++++
 lib/objects.py      | 20 ++++++++++++++++++--
 lib/opcodes.py      |  1 +
 scripts/gnt-cluster |  1 +
 4 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 99b11b407..da13bd50b 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -2064,6 +2064,25 @@ class LUSetClusterParams(LogicalUnit):
         else:
           self.new_hvparams[hv_name].update(hv_dict)
 
+    # os hypervisor parameters
+    self.new_os_hvp = objects.FillDict(cluster.os_hvp, {})
+    if self.op.os_hvp:
+      if not isinstance(self.op.os_hvp, dict):
+        raise errors.OpPrereqError("Invalid 'os_hvp' parameter on input",
+                                   errors.ECODE_INVAL)
+      for os_name, hvs in self.op.os_hvp.items():
+        if not isinstance(hvs, dict):
+          raise errors.OpPrereqError(("Invalid 'os_hvp' parameter on"
+                                      " input"), errors.ECODE_INVAL)
+        if os_name not in self.new_os_hvp:
+          self.new_os_hvp[os_name] = hvs
+        else:
+          for hv_name, hv_dict in hvs.items():
+            if hv_name not in self.new_os_hvp[os_name]:
+              self.new_os_hvp[os_name][hv_name] = hv_dict
+            else:
+              self.new_os_hvp[os_name][hv_name].update(hv_dict)
+
     if self.op.enabled_hypervisors is not None:
       self.hv_list = self.op.enabled_hypervisors
       if not self.hv_list:
@@ -2106,6 +2125,8 @@ class LUSetClusterParams(LogicalUnit):
                     " state, not changing")
     if self.op.hvparams:
       self.cluster.hvparams = self.new_hvparams
+    if self.op.os_hvp:
+      self.cluster.os_hvp = self.new_os_hvp
     if self.op.enabled_hypervisors is not None:
       self.cluster.enabled_hypervisors = self.op.enabled_hypervisors
     if self.op.beparams:
@@ -3336,6 +3357,15 @@ class LUQueryClusterInfo(NoHooksLU):
 
     """
     cluster = self.cfg.GetClusterInfo()
+    os_hvp = {}
+
+    # Filter just for enabled hypervisors
+    for os_name, hv_dict in cluster.os_hvp.items():
+      os_hvp[os_name] = {}
+      for hv_name, hv_params in hv_dict.items():
+        if hv_name in cluster.enabled_hypervisors:
+          os_hvp[os_name][hv_name] = hv_params
+
     result = {
       "software_version": constants.RELEASE_VERSION,
       "protocol_version": constants.PROTOCOL_VERSION,
@@ -3349,6 +3379,7 @@ class LUQueryClusterInfo(NoHooksLU):
       "enabled_hypervisors": cluster.enabled_hypervisors,
       "hvparams": dict([(hypervisor_name, cluster.hvparams[hypervisor_name])
                         for hypervisor_name in cluster.enabled_hypervisors]),
+      "os_hvp": os_hvp,
       "beparams": cluster.beparams,
       "nicparams": cluster.nicparams,
       "candidate_pool_size": cluster.candidate_pool_size,
diff --git a/lib/objects.py b/lib/objects.py
index 6e81a45ea..91174a06d 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -858,6 +858,7 @@ class Cluster(TaggableObject):
     "file_storage_dir",
     "enabled_hypervisors",
     "hvparams",
+    "os_hvp",
     "beparams",
     "nicparams",
     "candidate_pool_size",
@@ -878,6 +879,10 @@ class Cluster(TaggableObject):
         self.hvparams[hypervisor] = FillDict(
             constants.HVC_DEFAULTS[hypervisor], self.hvparams[hypervisor])
 
+    # TODO: Figure out if it's better to put this into OS than Cluster
+    if self.os_hvp is None:
+      self.os_hvp = {}
+
     self.beparams = UpgradeGroupedParams(self.beparams,
                                          constants.BEC_DEFAULTS)
     migrate_default_bridge = not self.nicparams
@@ -940,8 +945,19 @@ class Cluster(TaggableObject):
       skip_keys = constants.HVC_GLOBALS
     else:
       skip_keys = []
-    return FillDict(self.hvparams.get(instance.hypervisor, {}),
-                    instance.hvparams, skip_keys=skip_keys)
+
+    # We fill the list from least to most important override
+    fill_stack = [
+      self.hvparams.get(instance.hypervisor, {}),
+      self.os_hvp.get(instance.os, {}).get(instance.hypervisor, {}),
+      instance.hvparams,
+      ]
+
+    ret_dict = {}
+    for o_dict in fill_stack:
+      ret_dict = FillDict(ret_dict, o_dict, skip_keys=skip_keys)
+
+    return ret_dict
 
   def FillBE(self, instance):
     """Fill an instance's beparams dict.
diff --git a/lib/opcodes.py b/lib/opcodes.py
index 66698f5fc..0799f8ca4 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -301,6 +301,7 @@ class OpSetClusterParams(OpCode):
     "vg_name",
     "enabled_hypervisors",
     "hvparams",
+    "os_hvp",
     "beparams",
     "nicparams",
     "candidate_pool_size",
diff --git a/scripts/gnt-cluster b/scripts/gnt-cluster
index 2a7281164..4a15d59fe 100755
--- a/scripts/gnt-cluster
+++ b/scripts/gnt-cluster
@@ -527,6 +527,7 @@ def SetClusterParams(opts, args):
   op = opcodes.OpSetClusterParams(vg_name=vg_name,
                                   enabled_hypervisors=hvlist,
                                   hvparams=hvparams,
+                                  os_hvp=None,
                                   beparams=beparams,
                                   nicparams=nicparams,
                                   candidate_pool_size=opts.candidate_pool_size)
-- 
GitLab