+ # Past this point, any flag change to False means a transition
+ # away from the respective state, as only real changes are kept
+
+ # If we're being deofflined/drained, we'll MC ourself if needed
+ if (self.op.drained == False or self.op.offline == False or
+ (self.op.master_capable and not node.master_capable)):
+ if _DecideSelfPromotion(self):
+ self.op.master_candidate = True
+ self.LogInfo("Auto-promoting node to master candidate")
+
+ # If we're no longer master capable, we'll demote ourselves from MC
+ if self.op.master_capable == False and node.master_candidate:
+ self.LogInfo("Demoting from master candidate")
+ self.op.master_candidate = False
+
+ # Compute new role
+ assert [getattr(self.op, attr) for attr in self._FLAGS].count(True) <= 1
+ if self.op.master_candidate:
+ new_role = self._ROLE_CANDIDATE
+ elif self.op.drained:
+ new_role = self._ROLE_DRAINED
+ elif self.op.offline:
+ new_role = self._ROLE_OFFLINE
+ elif False in [self.op.master_candidate, self.op.drained, self.op.offline]:
+ # False is still in new flags, which means we're un-setting (the
+ # only) True flag
+ new_role = self._ROLE_REGULAR
+ else: # no new flags, nothing, keep old role
+ new_role = old_role
+
+ self.new_role = new_role
+
+ if old_role == self._ROLE_OFFLINE and new_role != old_role:
+ # Trying to transition out of offline status
+ result = self.rpc.call_version([node.name])[node.name]
+ if result.fail_msg:
+ raise errors.OpPrereqError("Node %s is being de-offlined but fails"
+ " to report its version: %s" %
+ (node.name, result.fail_msg),
+ errors.ECODE_STATE)
+ else:
+ self.LogWarning("Transitioning node from offline to online state"
+ " without using re-add. Please make sure the node"
+ " is healthy!")
+
+ if self.op.secondary_ip:
+ # Ok even without locking, because this can't be changed by any LU
+ master = self.cfg.GetNodeInfo(self.cfg.GetMasterNode())
+ master_singlehomed = master.secondary_ip == master.primary_ip
+ if master_singlehomed and self.op.secondary_ip:
+ raise errors.OpPrereqError("Cannot change the secondary ip on a single"
+ " homed cluster", errors.ECODE_INVAL)
+
+ if node.offline:
+ if self.affected_instances:
+ raise errors.OpPrereqError("Cannot change secondary ip: offline"
+ " node has instances (%s) configured"
+ " to use it" % self.affected_instances)
+ else:
+ # On online nodes, check that no instances are running, and that
+ # the node has the new ip and we can reach it.
+ for instance in self.affected_instances:
+ _CheckInstanceDown(self, instance, "cannot change secondary ip")
+
+ _CheckNodeHasSecondaryIP(self, node.name, self.op.secondary_ip, True)
+ if master.name != node.name:
+ # check reachability from master secondary ip to new secondary ip
+ if not netutils.TcpPing(self.op.secondary_ip,
+ constants.DEFAULT_NODED_PORT,
+ source=master.secondary_ip):
+ raise errors.OpPrereqError("Node secondary ip not reachable by TCP"
+ " based ping to node daemon port",
+ errors.ECODE_ENVIRON)
+
+ if self.op.ndparams:
+ new_ndparams = _GetUpdatedParams(self.node.ndparams, self.op.ndparams)
+ utils.ForceDictType(new_ndparams, constants.NDS_PARAMETER_TYPES)
+ self.new_ndparams = new_ndparams