commit 4da7909a505dbd96f00d1c7c58c72c1117139999
Author: Adeodato Simo <dato@google.com>
Date:   Thu Dec 9 12:55:17 2010 +0000

    Add modification of node groups (OpCode/LU/CLI)
    
    With this commit, only modification of the "ndparams" attribute is
    supported.
    
    Signed-off-by: Adeodato Simo <dato@google.com>
    Reviewed-by: Guido Trotter <ultrotter@google.com>

diff --git a/lib/client/gnt_group.py b/lib/client/gnt_group.py
index 545f0d2..b427647 100644
--- a/lib/client/gnt_group.py
+++ b/lib/client/gnt_group.py
@@ -105,6 +105,36 @@ def ListGroups(opts, args):
   return 0
 
 
+def SetGroupParams(opts, args):
+  """Modifies a node group's parameters.
+
+  @param opts: the command line options seletect by the user
+  @type args: list
+  @param args: should contain only one element, the node group name
+
+  @rtype: int
+  @return: the desired exit code
+
+  """
+  all_changes = {
+    "ndparams": opts.ndparams,
+  }
+
+  if all_changes.values().count(None) == len(all_changes):
+    ToStderr("Please give at least one of the parameters.")
+    return 1
+
+  op = opcodes.OpSetGroupParams(group_name=args[0], **all_changes)
+  result = SubmitOrSend(op, opts)
+
+  if result:
+    ToStdout("Modified node group %s", args[0])
+    for param, data in result:
+      ToStdout(" - %-5s -> %s", param, data)
+
+  return 0
+
+
 def RemoveGroup(opts, args):
   """Remove a node group from the cluster.
 
@@ -146,6 +176,10 @@ commands = {
     "Lists the node groups in the cluster. The available fields are (see"
     " the man page for details): %s. The default list is (in order): %s." %
     (utils.CommaJoin(_LIST_HEADERS), utils.CommaJoin(_LIST_DEF_FIELDS))),
+  "modify": (
+    SetGroupParams, ARGS_ONE_GROUP,
+    [DRY_RUN_OPT, SUBMIT_OPT, NODE_PARAMS_OPT],
+    "<group_name>", "Alters the parameters of a node group"),
   "remove": (
     RemoveGroup, ARGS_ONE_GROUP, [DRY_RUN_OPT],
     "[--dry-run] <group_name>",
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 95ae88c..112f819 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -10341,6 +10341,66 @@ class LUQueryGroups(NoHooksLU):
     return output
 
 
+class LUSetGroupParams(LogicalUnit):
+  """Modifies the parameters of a node group.
+
+  """
+  HPATH = None
+  HTYPE = None
+
+  _OP_PARAMS = [
+    _PGroupName,
+    ("ndparams", None, ht.TOr(ht.TDict, ht.TNone)),
+    ]
+
+  REQ_BGL = False
+
+  def CheckArguments(self):
+    all_changes = [
+      self.op.ndparams,
+      ]
+
+    if all_changes.count(None) == len(all_changes):
+      raise errors.OpPrereqError("Please pass at least one modification",
+                                 errors.ECODE_INVAL)
+
+  def ExpandNames(self):
+    # This raises errors.OpPrereqError on its own:
+    self.group_uuid = self.cfg.LookupNodeGroup(self.op.group_name)
+
+    self.needed_locks = {
+      locking.LEVEL_NODEGROUP: [self.group_uuid],
+      }
+
+  def CheckPrereq(self):
+    """Check prerequisites.
+
+    """
+    self.group = self.cfg.GetNodeGroup(self.group_uuid)
+
+    if self.group is None:
+      raise errors.OpExecError("Could not retrieve group '%s' (UUID: %s)" %
+                               (self.op.group_name, self.group_uuid))
+
+    if self.op.ndparams:
+      utils.ForceDictType(self.op.ndparams, constants.NDS_PARAMETER_TYPES)
+      self.new_ndparams = self.group.SimpleFillND(self.op.ndparams)
+
+  def Exec(self, feedback_fn):
+    """Modifies the node group.
+
+    """
+    result = []
+
+    if self.op.ndparams:
+      self.group.ndparams = self.new_ndparams
+      result.append(("ndparams", str(self.group.ndparams)))
+
+    self.cfg.Update(self.group, feedback_fn)
+    return result
+
+
+
 class LURemoveGroup(LogicalUnit):
   HPATH = "group-remove"
   HTYPE = constants.HTYPE_GROUP
diff --git a/lib/mcpu.py b/lib/mcpu.py
index 036b4f7..f96046b 100644
--- a/lib/mcpu.py
+++ b/lib/mcpu.py
@@ -191,6 +191,7 @@ class Processor(object):
     # node group lu
     opcodes.OpAddGroup: cmdlib.LUAddGroup,
     opcodes.OpQueryGroups: cmdlib.LUQueryGroups,
+    opcodes.OpSetGroupParams: cmdlib.LUSetGroupParams,
     opcodes.OpRemoveGroup: cmdlib.LURemoveGroup,
     opcodes.OpRenameGroup: cmdlib.LURenameGroup,
     # os lu
diff --git a/lib/opcodes.py b/lib/opcodes.py
index 172e451..74bd750 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -737,6 +737,16 @@ class OpQueryGroups(OpCode):
   __slots__ = ["output_fields", "names"]
 
 
+class OpSetGroupParams(OpCode):
+  """Change the parameters of a node group."""
+  OP_ID = "OP_GROUP_SET_PARAMS"
+  OP_DSC_FIELD = "group_name"
+  __slots__ = [
+    "group_name",
+    "ndparams",
+    ]
+
+
 class OpRemoveGroup(OpCode):
   """Remove a node group from the cluster."""
   OP_ID = "OP_GROUP_REMOVE"
diff --git a/man/gnt-group.rst b/man/gnt-group.rst
index 777b0d2..61be0a7 100644
--- a/man/gnt-group.rst
+++ b/man/gnt-group.rst
@@ -34,6 +34,18 @@ The ``--node-parameters`` option allows you to set default node
 parameters for nodes in the group. Please see **ganeti**(7) for more
 information about supported key=value pairs.
 
+MODIFY
+~~~~~~
+
+| **modify**
+| [--node-parameters=*NDPARAMS*]
+| {*group*}
+
+Modifies some parameters from the node group.
+
+The ``--node-parameters`` option is documented in the **add** command
+above.
+
 REMOVE
 ~~~~~~
 
