From c9d443ea4ab1a6c031306afe95f5e9e92d61d693 Mon Sep 17 00:00:00 2001 From: Iustin Pop Date: Tue, 10 Feb 2009 14:47:01 +0000 Subject: [PATCH] Implement modification of the drained flag This patch adds LU and cli-level support for modification of the node drained flag. It is similar to the offline changes. Reviewed-by: imsnah --- lib/cmdlib.py | 52 +++++++++++++++++++++++++++++++++++++--------------- lib/opcodes.py | 1 + scripts/gnt-node | 11 ++++++++++- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 183cf28..0c042e6 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -2240,11 +2240,13 @@ class LUSetNodeParams(LogicalUnit): self.op.node_name = node_name _CheckBooleanOpField(self.op, 'master_candidate') _CheckBooleanOpField(self.op, 'offline') - if self.op.master_candidate is None and self.op.offline is None: + _CheckBooleanOpField(self.op, 'drained') + all_mods = [self.op.offline, self.op.master_candidate, self.op.drained] + if all_mods.count(None) == 3: raise errors.OpPrereqError("Please pass at least one modification") - if self.op.offline == True and self.op.master_candidate == True: - raise errors.OpPrereqError("Can't set the node into offline and" - " master_candidate at the same time") + if all_mods.count(True) > 1: + raise errors.OpPrereqError("Can't set the node into more than one" + " state at the same time") def ExpandNames(self): self.needed_locks = {locking.LEVEL_NODE: self.op.node_name} @@ -2259,6 +2261,7 @@ class LUSetNodeParams(LogicalUnit): "OP_TARGET": self.op.node_name, "MASTER_CANDIDATE": str(self.op.master_candidate), "OFFLINE": str(self.op.offline), + "DRAINED": str(self.op.drained), } nl = [self.cfg.GetMasterNode(), self.op.node_name] @@ -2272,12 +2275,12 @@ class LUSetNodeParams(LogicalUnit): """ node = self.node = self.cfg.GetNodeInfo(self.op.node_name) - if ((self.op.master_candidate == False or self.op.offline == True) - and node.master_candidate): + if ((self.op.master_candidate == False or self.op.offline == True or + self.op.drained == True) and node.master_candidate): # we will demote the node from master_candidate if self.op.node_name == self.cfg.GetMasterNode(): raise errors.OpPrereqError("The master node has to be a" - " master candidate and online") + " master candidate, online and not drained") cp_size = self.cfg.GetClusterInfo().candidate_pool_size num_candidates, _ = self.cfg.GetMasterCandidateStats() if num_candidates <= cp_size: @@ -2288,10 +2291,11 @@ class LUSetNodeParams(LogicalUnit): else: raise errors.OpPrereqError(msg) - if (self.op.master_candidate == True and node.offline and - not self.op.offline == False): - raise errors.OpPrereqError("Can't set an offline node to" - " master_candidate") + if (self.op.master_candidate == True and + ((node.offline and not self.op.offline == False) or + (node.drained and not self.op.drained == False))): + raise errors.OpPrereqError("Node '%s' is offline or drained, can't set" + " to master_candidate") return @@ -2302,16 +2306,23 @@ class LUSetNodeParams(LogicalUnit): node = self.node result = [] + changed_mc = False if self.op.offline is not None: node.offline = self.op.offline result.append(("offline", str(self.op.offline))) - if self.op.offline == True and node.master_candidate: - node.master_candidate = False - result.append(("master_candidate", "auto-demotion due to offline")) + if self.op.offline == True: + if node.master_candidate: + node.master_candidate = False + changed_mc = True + result.append(("master_candidate", "auto-demotion due to offline")) + if node.drained: + node.drained = False + result.append(("drained", "clear drained status due to offline")) if self.op.master_candidate is not None: node.master_candidate = self.op.master_candidate + changed_mc = True result.append(("master_candidate", str(self.op.master_candidate))) if self.op.master_candidate == False: rrc = self.rpc.call_node_demote_from_mc(node.name) @@ -2319,10 +2330,21 @@ class LUSetNodeParams(LogicalUnit): if msg: self.LogWarning("Node failed to demote itself: %s" % msg) + if self.op.drained is not None: + node.drained = self.op.drained + if self.op.drained == True: + if node.master_candidate: + node.master_candidate = False + changed_mc = True + result.append(("master_candidate", "auto-demotion due to drain")) + if node.offline: + node.offline = False + result.append(("offline", "clear offline status due to drain")) + # this will trigger configuration file update, if needed self.cfg.Update(node) # this will trigger job queue propagation or cleanup - if self.op.node_name != self.cfg.GetMasterNode(): + if changed_mc: self.context.ReaddNode(node) return result diff --git a/lib/opcodes.py b/lib/opcodes.py index dea9d62..ad32783 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -337,6 +337,7 @@ class OpSetNodeParams(OpCode): "force", "master_candidate", "offline", + "drained", ] # instance opcodes diff --git a/scripts/gnt-node b/scripts/gnt-node index 75bc419..4dc73f5 100755 --- a/scripts/gnt-node +++ b/scripts/gnt-node @@ -419,7 +419,7 @@ def SetNodeParams(opts, args): @return: the desired exit code """ - if opts.master_candidate is None and opts.offline is None: + if [opts.master_candidate, opts.drained, opts.offline].count(None) == 3: ToStderr("Please give at least one of the parameters.") return 1 @@ -431,9 +431,15 @@ def SetNodeParams(opts, args): offline = opts.offline == 'yes' else: offline = None + + if opts.drained is not None: + drained = opts.drained == 'yes' + else: + drained = None op = opcodes.OpSetNodeParams(node_name=args[0], master_candidate=candidate, offline=offline, + drained=drained, force=opts.force) # even if here we process the result, we allow submit only @@ -515,6 +521,9 @@ commands = { make_option("-O", "--offline", dest="offline", choices=('yes', 'no'), default=None, help="Set the offline flag on the node"), + make_option("-D", "--drained", dest="drained", + choices=('yes', 'no'), default=None, + help="Set the drained flag on the node"), ], "", "Alters the parameters of an instance"), 'remove': (RemoveNode, ARGS_ONE, [DEBUG_OPT], -- 1.7.10.4