From efb8da026075374e806374127046a53dc87cf55d Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Thu, 30 Jul 2009 16:38:14 +0200 Subject: [PATCH] cmdlib: Add opcode to modify storage unit fields Signed-off-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Guido Trotter <ultrotter@google.com> --- lib/cmdlib.py | 73 +++++++++++++++++++++++++++++++++++++++++++----- lib/constants.py | 4 +++ lib/mcpu.py | 1 + lib/opcodes.py | 11 ++++++++ 4 files changed, 82 insertions(+), 7 deletions(-) diff --git a/lib/cmdlib.py b/lib/cmdlib.py index c6101c53e..dd28c89bb 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -735,6 +735,17 @@ def _GetNodeSecondaryInstances(cfg, node_name): return instances +def _GetStorageTypeArgs(cfg, storage_type): + """Returns the arguments for a storage type. + + """ + # Special case for file storage + if storage_type == constants.ST_FILE: + return [cfg.GetFileStorageDir()] + + return [] + + class LUDestroyCluster(NoHooksLU): """Logical unit for destroying the cluster. @@ -2349,12 +2360,6 @@ class LUQueryNodeStorage(NoHooksLU): """Computes the list of nodes and their attributes. """ - # Special case for file storage - if self.op.storage_type == constants.ST_FILE: - st_args = [self.cfg.GetFileStorageDir()] - else: - st_args = [] - # Always get name to sort by if constants.SF_NAME in self.op.output_fields: fields = self.op.output_fields[:] @@ -2368,6 +2373,7 @@ class LUQueryNodeStorage(NoHooksLU): field_idx = dict([(name, idx) for (idx, name) in enumerate(fields)]) name_idx = field_idx[constants.SF_NAME] + st_args = _GetStorageTypeArgs(self.cfg, self.op.storage_type) data = self.rpc.call_storage_list(self.nodes, self.op.storage_type, st_args, self.op.name, fields) @@ -2406,6 +2412,59 @@ class LUQueryNodeStorage(NoHooksLU): return result +class LUModifyNodeStorage(NoHooksLU): + """Logical unit for modifying a storage volume on a node. + + """ + _OP_REQP = ["node_name", "storage_type", "name", "changes"] + REQ_BGL = False + + def CheckArguments(self): + node_name = self.cfg.ExpandNodeName(self.op.node_name) + if node_name is None: + raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name) + + self.op.node_name = node_name + + storage_type = self.op.storage_type + if storage_type not in constants.VALID_STORAGE_FIELDS: + raise errors.OpPrereqError("Unknown storage type: %s" % storage_type) + + def ExpandNames(self): + self.needed_locks = { + locking.LEVEL_NODE: self.op.node_name, + } + + def CheckPrereq(self): + """Check prerequisites. + + """ + storage_type = self.op.storage_type + + try: + modifiable = constants.MODIFIABLE_STORAGE_FIELDS[storage_type] + except KeyError: + raise errors.OpPrereqError("Storage units of type '%s' can not be" + " modified" % storage_type) + + diff = set(self.op.changes.keys()) - modifiable + if diff: + raise errors.OpPrereqError("The following fields can not be modified for" + " storage units of type '%s': %r" % + (storage_type, list(diff))) + + def Exec(self, feedback_fn): + """Computes the list of nodes and their attributes. + + """ + st_args = _GetStorageTypeArgs(self.cfg, self.op.storage_type) + result = self.rpc.call_storage_modify(self.op.node_name, + self.op.storage_type, st_args, + self.op.name, self.op.changes) + result.Raise("Failed to modify storage unit '%s' on %s" % + (self.op.name, self.op.node_name)) + + class LUAddNode(LogicalUnit): """Logical unit for adding node to the cluster. @@ -2773,7 +2832,7 @@ class LUPowercycleNode(NoHooksLU): def ExpandNames(self): """Locking for PowercycleNode. - This is a last-resource option and shouldn't block on other + This is a last-resort option and shouldn't block on other jobs. Therefore, we grab no locks. """ diff --git a/lib/constants.py b/lib/constants.py index 23dacdcc2..09f79171e 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -201,6 +201,10 @@ VALID_STORAGE_FIELDS = { ST_LVM_VG: frozenset([SF_NAME, SF_SIZE]), } +MODIFIABLE_STORAGE_FIELDS = { + ST_LVM_PV: frozenset([SF_ALLOCATABLE]), + } + # disk template types DT_DISKLESS = "diskless" DT_PLAIN = "plain" diff --git a/lib/mcpu.py b/lib/mcpu.py index 55d235fb6..01d6eb3ef 100644 --- a/lib/mcpu.py +++ b/lib/mcpu.py @@ -55,6 +55,7 @@ class Processor(object): opcodes.OpQueryNodes: cmdlib.LUQueryNodes, opcodes.OpQueryNodeVolumes: cmdlib.LUQueryNodeVolumes, opcodes.OpQueryNodeStorage: cmdlib.LUQueryNodeStorage, + opcodes.OpModifyNodeStorage: cmdlib.LUModifyNodeStorage, opcodes.OpRemoveNode: cmdlib.LURemoveNode, opcodes.OpSetNodeParams: cmdlib.LUSetNodeParams, opcodes.OpPowercycleNode: cmdlib.LUPowercycleNode, diff --git a/lib/opcodes.py b/lib/opcodes.py index 2a2a5f8a4..77497fcac 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -339,6 +339,17 @@ class OpQueryNodeStorage(OpCode): ] +class OpModifyNodeStorage(OpCode): + """""" + OP_ID = "OP_NODE_MODIFY_STORAGE" + __slots__ = OpCode.__slots__ + [ + "node_name", + "storage_type", + "name", + "changes", + ] + + class OpSetNodeParams(OpCode): """Change the parameters of a node.""" OP_ID = "OP_NODE_SET_PARAMS" -- GitLab