From b1ee56101d3fa30bccd6d79f9ef4232ac64a278d Mon Sep 17 00:00:00 2001
From: Adeodato Simo <dato@google.com>
Date: Thu, 2 Dec 2010 18:23:37 +0000
Subject: [PATCH] Group operations: OpCode and LU for adding a group

Signed-off-by: Adeodato Simo <dato@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 doc/hooks.rst    | 14 +++++++++++
 lib/cmdlib.py    | 62 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/constants.py |  1 +
 lib/mcpu.py      |  1 +
 lib/opcodes.py   |  7 ++++++
 5 files changed, 85 insertions(+)

diff --git a/doc/hooks.rst b/doc/hooks.rst
index 2effa481c..3cfd40498 100644
--- a/doc/hooks.rst
+++ b/doc/hooks.rst
@@ -168,6 +168,20 @@ Relocate secondary instances from a node.
 :post-execution: master node
 
 
+Node group operations
+~~~~~~~~~~~~~~~~~~~~~
+
+OP_ADD_GROUP
+++++++++++++
+
+Adds a node group to the cluster.
+
+:directory: group-add
+:env. vars: GROUP_NAME
+:pre-execution: master node
+:post-execution: master node
+
+
 Instance operations
 ~~~~~~~~~~~~~~~~~~~
 
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 9505e19a2..24142ece9 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -81,6 +81,9 @@ _PIgnoreOfflineNodes = ("ignore_offline_nodes", False, ht.TBool)
 #: a required node name (for single-node LUs)
 _PNodeName = ("node_name", ht.NoDefault, ht.TNonEmptyString)
 
+#: a required node group name (for single-group LUs)
+_PGroupName = ("group_name", ht.NoDefault, ht.TNonEmptyString)
+
 #: the migration type (live/non-live)
 _PMigrationMode = ("mode", None,
                    ht.TOr(ht.TNone, ht.TElemOf(constants.HT_MIGRATION_MODES)))
@@ -10297,6 +10300,65 @@ class LURemoveExport(NoHooksLU):
                   " Domain Name.")
 
 
+class LUAddGroup(LogicalUnit):
+  """Logical unit for creating node groups.
+
+  """
+  HPATH = "group-add"
+  HTYPE = constants.HTYPE_GROUP
+
+  _OP_PARAMS = [
+    _PGroupName,
+    ]
+
+  REQ_BGL = False
+
+  def ExpandNames(self):
+    # We need the new group's UUID here so that we can create and acquire the
+    # corresponding lock. Later, in Exec(), we'll indicate to cfg.AddNodeGroup
+    # that it should not check whether the UUID exists in the configuration.
+    self.group_uuid = self.cfg.GenerateUniqueID(self.proc.GetECId())
+    self.needed_locks = {}
+    self.add_locks[locking.LEVEL_NODEGROUP] = self.group_uuid
+
+  def CheckPrereq(self):
+    """Check prerequisites.
+
+    This checks that the given group name is not an existing node group
+    already.
+
+    """
+    try:
+      existing_uuid = self.cfg.LookupNodeGroup(self.op.group_name)
+    except errors.OpPrereqError:
+      pass
+    else:
+      raise errors.OpPrereqError("Desired group name '%s' already exists as a"
+                                 " node group (UUID: %s)" %
+                                 (self.op.group_name, existing_uuid),
+                                 errors.ECODE_EXISTS)
+
+  def BuildHooksEnv(self):
+    """Build hooks env.
+
+    """
+    env = {
+      "GROUP_NAME": self.op.group_name,
+      }
+    mn = self.cfg.GetMasterNode()
+    return env, [mn], [mn]
+
+  def Exec(self, feedback_fn):
+    """Add the node group to the cluster.
+
+    """
+    group_obj = objects.NodeGroup(name=self.op.group_name, members=[],
+                                  uuid=self.group_uuid)
+
+    self.cfg.AddNodeGroup(group_obj, self.proc.GetECId(), check_uuid=False)
+    del self.remove_locks[locking.LEVEL_NODEGROUP]
+
+
 class LUQueryGroups(NoHooksLU):
   """Logical unit for querying node groups.
 
diff --git a/lib/constants.py b/lib/constants.py
index 083a026ea..7716d8e98 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -294,6 +294,7 @@ HOOKS_VERSION = 2
 # hooks subject type (what object type does the LU deal with)
 HTYPE_CLUSTER = "CLUSTER"
 HTYPE_NODE = "NODE"
+HTYPE_GROUP = "GROUP"
 HTYPE_INSTANCE = "INSTANCE"
 
 HKR_SKIP = 0
diff --git a/lib/mcpu.py b/lib/mcpu.py
index 65e52eeac..436ce28ca 100644
--- a/lib/mcpu.py
+++ b/lib/mcpu.py
@@ -189,6 +189,7 @@ class Processor(object):
     opcodes.OpSetInstanceParams: cmdlib.LUSetInstanceParams,
     opcodes.OpGrowDisk: cmdlib.LUGrowDisk,
     # node group lu
+    opcodes.OpAddGroup: cmdlib.LUAddGroup,
     opcodes.OpQueryGroups: cmdlib.LUQueryGroups,
     # os lu
     opcodes.OpDiagnoseOS: cmdlib.LUDiagnoseOS,
diff --git a/lib/opcodes.py b/lib/opcodes.py
index f061c5ab4..6d0e8aaf0 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -720,6 +720,13 @@ class OpGrowDisk(OpCode):
 
 # Node group opcodes
 
+class OpAddGroup(OpCode):
+  """Add a node group to the cluster."""
+  OP_ID = "OP_GROUP_ADD"
+  OP_DSC_FIELD = "group_name"
+  __slots__ = ["group_name"]
+
+
 class OpQueryGroups(OpCode):
   """Compute the list of node groups."""
   OP_ID = "OP_GROUP_QUERY"
-- 
GitLab