commit 1bdcbbab3d096a23946db02a779413458871a638
Author: Iustin Pop <iustin@google.com>
Date:   Sat Jun 12 04:17:20 2010 +0200

    Add OS parameters to cluster and instance objects
    
    The patch also modifies the instance RPC calls to fill the osparameters
    correctly with the cluster defaults, and exports the OS parameters in
    the instance/OS environment.
    
    Signed-off-by: Iustin Pop <iustin@google.com>
    Reviewed-by: Guido Trotter <ultrotter@google.com>

diff --git a/lib/backend.py b/lib/backend.py
index 58c789a..515306b 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -1930,11 +1930,13 @@ def OSFromDisk(name, base_dir=None):
   return payload
 
 
-def OSCoreEnv(inst_os, debug=0):
+def OSCoreEnv(inst_os, os_params, debug=0):
   """Calculate the basic environment for an os script.
 
   @type inst_os: L{objects.OS}
   @param inst_os: operating system for which the environment is being built
+  @type os_params: dict
+  @param os_params: the OS parameters
   @type debug: integer
   @param debug: debug level (0 or 1, for OS Api 10)
   @rtype: dict
@@ -1958,6 +1960,10 @@ def OSCoreEnv(inst_os, debug=0):
       variant = inst_os.supported_variants[0]
     result['OS_VARIANT'] = variant
 
+  # OS params
+  for pname, pvalue in os_params.items():
+    result['OSP_%s' % pname.upper()] = pvalue
+
   return result
 
 
@@ -1976,7 +1982,7 @@ def OSEnvironment(instance, inst_os, debug=0):
       cannot be found
 
   """
-  result = OSCoreEnv(inst_os, debug)
+  result = OSCoreEnv(inst_os, instance.osparams, debug=debug)
 
   result['INSTANCE_NAME'] = instance.name
   result['INSTANCE_OS'] = instance.os
diff --git a/lib/objects.py b/lib/objects.py
index 1e2d1bb..4f9314f 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -657,6 +657,7 @@ class Instance(TaggableObject):
     "hypervisor",
     "hvparams",
     "beparams",
+    "osparams",
     "admin_up",
     "nics",
     "disks",
@@ -812,6 +813,8 @@ class Instance(TaggableObject):
           del self.hvparams[key]
         except KeyError:
           pass
+    if self.osparams is None:
+      self.osparams = {}
 
 
 class OS(ConfigObject):
@@ -869,6 +872,7 @@ class Cluster(TaggableObject):
     "hvparams",
     "os_hvp",
     "beparams",
+    "osparams",
     "nicparams",
     "candidate_pool_size",
     "modify_etc_hosts",
@@ -893,6 +897,10 @@ class Cluster(TaggableObject):
     if self.os_hvp is None:
       self.os_hvp = {}
 
+    # osparams added before 2.2
+    if self.osparams is None:
+      self.osparams = {}
+
     self.beparams = UpgradeGroupedParams(self.beparams,
                                          constants.BEC_DEFAULTS)
     migrate_default_bridge = not self.nicparams
@@ -1043,6 +1051,26 @@ class Cluster(TaggableObject):
     """
     return FillDict(self.nicparams.get(constants.PP_DEFAULT, {}), nicparams)
 
+  def SimpleFillOS(self, os_name, os_params):
+    """Fill an instance's osparams dict with cluster defaults.
+
+    @type os_name: string
+    @param os_name: the OS name to use
+    @type os_params: dict
+    @param os_params: the dict to fill with default values
+    @rtype: dict
+    @return: a copy of the instance's osparams with missing keys filled from
+        the cluster defaults
+
+    """
+    name_only = os_name.split("+", 1)[0]
+    # base OS
+    result = self.osparams.get(name_only, {})
+    # OS with variant
+    result = FillDict(result, self.osparams.get(os_name, {}))
+    # specified params
+    return FillDict(result, os_params)
+
 
 class BlockDevStatus(ConfigObject):
   """Config object representing the status of a block device."""
diff --git a/lib/rpc.py b/lib/rpc.py
index 6b3aa9f..57dd960 100644
--- a/lib/rpc.py
+++ b/lib/rpc.py
@@ -329,7 +329,7 @@ class RpcRunner(object):
     self._cfg = cfg
     self.port = utils.GetDaemonPort(constants.NODED)
 
-  def _InstDict(self, instance, hvp=None, bep=None):
+  def _InstDict(self, instance, hvp=None, bep=None, osp=None):
     """Convert the given instance to a dict.
 
     This is done via the instance's ToDict() method and additionally
@@ -341,6 +341,8 @@ class RpcRunner(object):
     @param hvp: a dictionary with overridden hypervisor parameters
     @type bep: dict or None
     @param bep: a dictionary with overridden backend parameters
+    @type osp: dict or None
+    @param osp: a dictionary with overriden os parameters
     @rtype: dict
     @return: the instance dict, with the hvparams filled with the
         cluster defaults
@@ -354,6 +356,9 @@ class RpcRunner(object):
     idict["beparams"] = cluster.FillBE(instance)
     if bep is not None:
       idict["beparams"].update(bep)
+    idict["osparams"] = cluster.SimpleFillOS(instance.os, instance.osparams)
+    if osp is not None:
+      idict["osparams"].update(osp)
     for nic in idict["nics"]:
       nic['nicparams'] = objects.FillDict(
         cluster.nicparams[constants.PP_DEFAULT],
