From 3a5ba66a752d7f3341d1b76a55bed609114760d8 Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Mon, 8 Dec 2008 11:46:51 +0000 Subject: [PATCH] gnt-node modify: add the offline attribute This patch changes gnt-node modify and the associated opcode/lu to allow modification of the node offline attribute. Setting a node into offline mode automatically demotes it from the master role. Reviewed-by: ultrotter --- lib/cmdlib.py | 36 +++++++++++++++++++++++++++--------- lib/opcodes.py | 1 + scripts/gnt-node | 19 +++++++++++++++---- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 552477f45..0d119b97b 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -2123,9 +2123,13 @@ class LUSetNodeParams(LogicalUnit): if node_name is None: raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name) self.op.node_name = node_name - if not hasattr(self.op, 'master_candidate'): + _CheckBooleanOpField(self.op, 'master_candidate') + _CheckBooleanOpField(self.op, 'offline') + if self.op.master_candidate is None and self.op.offline is None: raise errors.OpPrereqError("Please pass at least one modification") - self.op.master_candidate = bool(self.op.master_candidate) + 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") def ExpandNames(self): self.needed_locks = {locking.LEVEL_NODE: self.op.node_name} @@ -2139,6 +2143,7 @@ class LUSetNodeParams(LogicalUnit): env = { "OP_TARGET": self.op.node_name, "MASTER_CANDIDATE": str(self.op.master_candidate), + "OFFLINE": str(self.op.offline), } nl = [self.cfg.GetMasterNode(), self.op.node_name] @@ -2150,34 +2155,47 @@ class LUSetNodeParams(LogicalUnit): This only checks the instance list against the existing names. """ - force = self.force = self.op.force + node = self.node = self.cfg.GetNodeInfo(self.op.node_name) - if self.op.master_candidate == False: + if ((self.op.master_candidate == False or self.op.offline == 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") + " master candidate and online") cp_size = self.cfg.GetClusterInfo().candidate_pool_size node_info = self.cfg.GetAllNodesInfo().values() - num_candidates = len([node for node in node_info - if node.master_candidate]) + num_candidates, _ = self.cfg.GetMasterCandidateStats() if num_candidates <= cp_size: msg = ("Not enough master candidates (desired" " %d, new value will be %d)" % (cp_size, num_candidates-1)) - if force: + if self.op.force: self.LogWarning(msg) 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") + return def Exec(self, feedback_fn): """Modifies a node. """ - node = self.cfg.GetNodeInfo(self.op.node_name) + node = self.node result = [] + 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.master_candidate is not None: node.master_candidate = self.op.master_candidate result.append(("master_candidate", str(self.op.master_candidate))) diff --git a/lib/opcodes.py b/lib/opcodes.py index 958ee4261..fbce4249b 100644 --- a/lib/opcodes.py +++ b/lib/opcodes.py @@ -326,6 +326,7 @@ class OpSetNodeParams(OpCode): "node_name", "force", "master_candidate", + "offline", ] # instance opcodes diff --git a/scripts/gnt-node b/scripts/gnt-node index cf9677af2..306597696 100755 --- a/scripts/gnt-node +++ b/scripts/gnt-node @@ -379,14 +379,22 @@ def SetNodeParams(opts, args): @return: the desired exit code """ - if opts.master_candidate is None: + if opts.master_candidate is None and opts.offline is None: ToStderr("Please give at least one of the parameters.") return 1 - candidate = opts.master_candidate == 'yes' + if opts.master_candidate is not None: + candidate = opts.master_candidate == 'yes' + else: + candidate = None + if opts.offline is not None: + offline = opts.offline == 'yes' + else: + offline = None op = opcodes.OpSetNodeParams(node_name=args[0], - master_candidate=candidate, - force=opts.force) + master_candidate=candidate, + offline=offline, + force=opts.force) # even if here we process the result, we allow submit only result = SubmitOrSend(op, opts) @@ -444,6 +452,9 @@ commands = { make_option("-C", "--master-candidate", dest="master_candidate", choices=('yes', 'no'), default=None, help="Set the master_candidate flag on the node"), + make_option("-O", "--offline", dest="offline", + choices=('yes', 'no'), default=None, + help="Set the offline flag on the node"), ], "<instance>", "Alters the parameters of an instance"), 'remove': (RemoveNode, ARGS_ONE, [DEBUG_OPT], -- GitLab