Revision 3a5ba66a lib/cmdlib.py

b/lib/cmdlib.py
2123 2123
    if node_name is None:
2124 2124
      raise errors.OpPrereqError("Invalid node name '%s'" % self.op.node_name)
2125 2125
    self.op.node_name = node_name
2126
    if not hasattr(self.op, 'master_candidate'):
2126
    _CheckBooleanOpField(self.op, 'master_candidate')
2127
    _CheckBooleanOpField(self.op, 'offline')
2128
    if self.op.master_candidate is None and self.op.offline is None:
2127 2129
      raise errors.OpPrereqError("Please pass at least one modification")
2128
    self.op.master_candidate = bool(self.op.master_candidate)
2130
    if self.op.offline == True and self.op.master_candidate == True:
2131
      raise errors.OpPrereqError("Can't set the node into offline and"
2132
                                 " master_candidate at the same time")
2129 2133

  
2130 2134
  def ExpandNames(self):
2131 2135
    self.needed_locks = {locking.LEVEL_NODE: self.op.node_name}
......
2139 2143
    env = {
2140 2144
      "OP_TARGET": self.op.node_name,
2141 2145
      "MASTER_CANDIDATE": str(self.op.master_candidate),
2146
      "OFFLINE": str(self.op.offline),
2142 2147
      }
2143 2148
    nl = [self.cfg.GetMasterNode(),
2144 2149
          self.op.node_name]
......
2150 2155
    This only checks the instance list against the existing names.
2151 2156

  
2152 2157
    """
2153
    force = self.force = self.op.force
2158
    node = self.node = self.cfg.GetNodeInfo(self.op.node_name)
2154 2159

  
2155
    if self.op.master_candidate == False:
2160
    if ((self.op.master_candidate == False or self.op.offline == True)
2161
        and node.master_candidate):
2162
      # we will demote the node from master_candidate
2156 2163
      if self.op.node_name == self.cfg.GetMasterNode():
2157 2164
        raise errors.OpPrereqError("The master node has to be a"
2158
                                   " master candidate")
2165
                                   " master candidate and online")
2159 2166
      cp_size = self.cfg.GetClusterInfo().candidate_pool_size
2160 2167
      node_info = self.cfg.GetAllNodesInfo().values()
2161
      num_candidates = len([node for node in node_info
2162
                            if node.master_candidate])
2168
      num_candidates, _ = self.cfg.GetMasterCandidateStats()
2163 2169
      if num_candidates <= cp_size:
2164 2170
        msg = ("Not enough master candidates (desired"
2165 2171
               " %d, new value will be %d)" % (cp_size, num_candidates-1))
2166
        if force:
2172
        if self.op.force:
2167 2173
          self.LogWarning(msg)
2168 2174
        else:
2169 2175
          raise errors.OpPrereqError(msg)
2170 2176

  
2177
    if (self.op.master_candidate == True and node.offline and
2178
        not self.op.offline == False):
2179
      raise errors.OpPrereqError("Can't set an offline node to"
2180
                                 " master_candidate")
2181

  
2171 2182
    return
2172 2183

  
2173 2184
  def Exec(self, feedback_fn):
2174 2185
    """Modifies a node.
2175 2186

  
2176 2187
    """
2177
    node = self.cfg.GetNodeInfo(self.op.node_name)
2188
    node = self.node
2178 2189

  
2179 2190
    result = []
2180 2191

  
2192
    if self.op.offline is not None:
2193
      node.offline = self.op.offline
2194
      result.append(("offline", str(self.op.offline)))
2195
      if self.op.offline == True and node.master_candidate:
2196
        node.master_candidate = False
2197
        result.append(("master_candidate", "auto-demotion due to offline"))
2198

  
2181 2199
    if self.op.master_candidate is not None:
2182 2200
      node.master_candidate = self.op.master_candidate
2183 2201
      result.append(("master_candidate", str(self.op.master_candidate)))

Also available in: Unified diff