Revision 21232d04 lib/cmdlib.py

b/lib/cmdlib.py
3797 3797
class LUSetNodeParams(LogicalUnit):
3798 3798
  """Modifies the parameters of a node.
3799 3799

  
3800
  @cvar _F2R: a dictionary from tuples of flags (mc, drained, offline)
3801
      to the node role (as _ROLE_*)
3802
  @cvar _R2F: a dictionary from node role to tuples of flags
3803
  @cvar _FLAGS: a list of attribute names corresponding to the flags
3804

  
3800 3805
  """
3801 3806
  HPATH = "node-modify"
3802 3807
  HTYPE = constants.HTYPE_NODE
......
3809 3814
    _PForce,
3810 3815
    ]
3811 3816
  REQ_BGL = False
3817
  (_ROLE_CANDIDATE, _ROLE_DRAINED, _ROLE_OFFLINE, _ROLE_REGULAR) = range(4)
3818
  _F2R = {
3819
    (True, False, False): _ROLE_CANDIDATE,
3820
    (False, True, False): _ROLE_DRAINED,
3821
    (False, False, True): _ROLE_OFFLINE,
3822
    (False, False, False): _ROLE_REGULAR,
3823
    }
3824
  _R2F = dict((v, k) for k, v in _F2R.items())
3825
  _FLAGS = ["master_candidate", "drained", "offline"]
3812 3826

  
3813 3827
  def CheckArguments(self):
3814 3828
    self.op.node_name = _ExpandNodeName(self.cfg, self.op.node_name)
3815 3829
    all_mods = [self.op.offline, self.op.master_candidate, self.op.drained]
3816
    if all_mods.count(None) == 3:
3830
    if all_mods.count(None) == len(all_mods):
3817 3831
      raise errors.OpPrereqError("Please pass at least one modification",
3818 3832
                                 errors.ECODE_INVAL)
3819 3833
    if all_mods.count(True) > 1:
......
3821 3835
                                 " state at the same time",
3822 3836
                                 errors.ECODE_INVAL)
3823 3837

  
3824
    # Boolean value that tells us whether we're offlining or draining the node
3825
    self.offline_or_drain = (self.op.offline == True or
3826
                             self.op.drained == True)
3827
    self.deoffline_or_drain = (self.op.offline == False or
3828
                               self.op.drained == False)
3838
    # Boolean value that tells us whether we might be demoting from MC
3829 3839
    self.might_demote = (self.op.master_candidate == False or
3830
                         self.offline_or_drain)
3840
                         self.op.offline == True or
3841
                         self.op.drained == True)
3831 3842

  
3832 3843
    self.lock_all = self.op.auto_promote and self.might_demote
3833 3844

  
3834

  
3835 3845
  def ExpandNames(self):
3836 3846
    if self.lock_all:
3837 3847
      self.needed_locks = {locking.LEVEL_NODE: locking.ALL_SET}
......
3881 3891
      if mc_remaining < mc_should:
3882 3892
        raise errors.OpPrereqError("Not enough master candidates, please"
3883 3893
                                   " pass auto_promote to allow promotion",
3884
                                   errors.ECODE_INVAL)
3894
                                   errors.ECODE_STATE)
3885 3895

  
3886
    if (self.op.master_candidate == True and
3887
        ((node.offline and not self.op.offline == False) or
3888
         (node.drained and not self.op.drained == False))):
3889
      raise errors.OpPrereqError("Node '%s' is offline or drained, can't set"
3890
                                 " to master_candidate" % node.name,
3891
                                 errors.ECODE_INVAL)
3896
    self.old_flags = old_flags = (node.master_candidate,
3897
                                  node.drained, node.offline)
3898
    assert old_flags in self._F2R, "Un-handled old flags  %s" % str(old_flags)
3899
    self.old_role = self._F2R[old_flags]
3892 3900

  
3893
    # If we're being deofflined/drained, we'll MC ourself if needed
3894
    if (self.deoffline_or_drain and not self.offline_or_drain and not
3895
        self.op.master_candidate == True and not node.master_candidate):
3896
      self.op.master_candidate = _DecideSelfPromotion(self)
3897
      if self.op.master_candidate:
3898
        self.LogInfo("Autopromoting node to master candidate")
3901
    # Check for ineffective changes
3902
    for attr in self._FLAGS:
3903
      if (getattr(self.op, attr) == False and getattr(node, attr) == False):
3904
        self.LogInfo("Ignoring request to unset flag %s, already unset", attr)
3905
        setattr(self.op, attr, None)
3899 3906

  
3900
    return
3907
    # Past this point, any flag change to False means a transition
3908
    # away from the respective state, as only real changes are kept
3909

  
3910
    # If we're being deofflined/drained, we'll MC ourself if needed
3911
    if self.op.drained == False or self.op.offline == False:
3912
      if _DecideSelfPromotion(self):
3913
        self.op.master_candidate = True
3914
        self.LogInfo("Auto-promoting node to master candidate")
3901 3915

  
3902 3916
  def Exec(self, feedback_fn):
3903 3917
    """Modifies a node.
3904 3918

  
3905 3919
    """
3906 3920
    node = self.node
3921
    old_role = self.old_role
3922

  
3923
    assert [getattr(self.op, attr) for attr in self._FLAGS].count(True) <= 1
3924

  
3925
    # compute new flags
3926
    if self.op.master_candidate:
3927
      new_role = self._ROLE_CANDIDATE
3928
    elif self.op.drained:
3929
      new_role = self._ROLE_DRAINED
3930
    elif self.op.offline:
3931
      new_role = self._ROLE_OFFLINE
3932
    elif False in [self.op.master_candidate, self.op.drained, self.op.offline]:
3933
      # False is still in new flags, which means we're un-setting (the
3934
      # only) True flag
3935
      new_role = self._ROLE_REGULAR
3936
    else: # no new flags, nothing, keep old role
3937
      new_role = old_role
3907 3938

  
3908 3939
    result = []
3909
    changed_mc = False
3910

  
3911
    if self.op.offline is not None:
3912
      node.offline = self.op.offline
3913
      result.append(("offline", str(self.op.offline)))
3914
      if self.op.offline == True:
3915
        if node.master_candidate:
3916
          node.master_candidate = False
3917
          changed_mc = True
3918
          result.append(("master_candidate", "auto-demotion due to offline"))
3919
        if node.drained:
3920
          node.drained = False
3921
          result.append(("drained", "clear drained status due to offline"))
3922

  
3923
    if self.op.master_candidate is not None:
3924
      node.master_candidate = self.op.master_candidate
3925
      changed_mc = True
3926
      result.append(("master_candidate", str(self.op.master_candidate)))
3927
      if self.op.master_candidate == False:
3928
        rrc = self.rpc.call_node_demote_from_mc(node.name)
3929
        msg = rrc.fail_msg
3930
        if msg:
3931
          self.LogWarning("Node failed to demote itself: %s" % msg)
3932

  
3933
    if self.op.drained is not None:
3934
      node.drained = self.op.drained
3935
      result.append(("drained", str(self.op.drained)))
3936
      if self.op.drained == True:
3937
        if node.master_candidate:
3938
          node.master_candidate = False
3939
          changed_mc = True
3940
          result.append(("master_candidate", "auto-demotion due to drain"))
3941
          rrc = self.rpc.call_node_demote_from_mc(node.name)
3942
          msg = rrc.fail_msg
3943
          if msg:
3944
            self.LogWarning("Node failed to demote itself: %s" % msg)
3945
        if node.offline:
3946
          node.offline = False
3947
          result.append(("offline", "clear offline status due to drain"))
3940
    changed_mc = [old_role, new_role].count(self._ROLE_CANDIDATE) == 1
3941

  
3942
    # Tell the node to demote itself, if no longer MC and not offline
3943
    if (old_role == self._ROLE_CANDIDATE and
3944
        new_role != self._ROLE_OFFLINE and new_role != old_role):
3945
      msg = self.rpc.call_node_demote_from_mc(node.name).fail_msg
3946
      if msg:
3947
        self.LogWarning("Node failed to demote itself: %s", msg)
3948

  
3949
    new_flags = self._R2F[new_role]
3950
    for of, nf, desc in zip(self.old_flags, new_flags, self._FLAGS):
3951
      if of != nf:
3952
        result.append((desc, str(nf)))
3953
    (node.master_candidate, node.drained, node.offline) = new_flags
3948 3954

  
3949 3955
    # we locked all nodes, we adjust the CP before updating this node
3950 3956
    if self.lock_all:

Also available in: Unified diff