diff --git a/doc/hooks.rst b/doc/hooks.rst index 2effa481c688b886edc88b01ed836ac3f04034c6..3cfd40498c3567edb1060f4fc776d9b38e3536e8 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 9505e19a2b3c6e9e8274468a1130b3bcc888975c..24142ece9f347616931f0bb93e1fd4cac03d4173 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 083a026ea78f1ad4f3e79ca19e469fe420c4c5c6..7716d8e9808a03b1bdfcf6b656f82e30f75d3463 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 65e52eeac034b93ea138fd9126cfafe5b93c1182..436ce28ca09c53bdbab155b086e8d03c201eb6d7 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 f061c5ab4591492e2009335daad03994eea78732..6d0e8aaf0c173151628532ea4bd76f31f0203931 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"