ganeti.http: Add constant for DELETE
[ganeti-local] / lib / cmdlib.py
index 3b95fd3..77b087d 100644 (file)
@@ -1622,6 +1622,24 @@ class LURemoveNode(LogicalUnit):
 
     self.rpc.call_node_leave_cluster(node.name)
 
+    # Promote nodes to master candidate as needed
+    cp_size = self.cfg.GetClusterInfo().candidate_pool_size
+    node_info = self.cfg.GetAllNodesInfo().values()
+    num_candidates = len([n for n in node_info
+                          if n.master_candidate])
+    num_nodes = len(node_info)
+    random.shuffle(node_info)
+    for node in node_info:
+      if num_candidates >= cp_size or num_candidates >= num_nodes:
+        break
+      if node.master_candidate:
+        continue
+      node.master_candidate = True
+      self.LogInfo("Promoting node %s to master candidate", node.name)
+      self.cfg.Update(node)
+      self.context.ReaddNode(node)
+      num_candidates += 1
+
 
 class LUQueryNodes(NoHooksLU):
   """Logical unit for querying nodes.
@@ -1950,9 +1968,16 @@ class LUAddNode(LogicalUnit):
         raise errors.OpPrereqError("Node secondary ip not reachable by TCP"
                                    " based ping to noded port")
 
+    cp_size = self.cfg.GetClusterInfo().candidate_pool_size
+    node_info = self.cfg.GetAllNodesInfo().values()
+    num_candidates = len([n for n in node_info
+                          if n.master_candidate])
+    master_candidate = num_candidates < cp_size
+
     self.new_node = objects.Node(name=node,
                                  primary_ip=primary_ip,
-                                 secondary_ip=secondary_ip)
+                                 secondary_ip=secondary_ip,
+                                 master_candidate=master_candidate)
 
   def Exec(self, feedback_fn):
     """Adds the new node to the cluster.
@@ -2017,7 +2042,7 @@ class LUAddNode(LogicalUnit):
     result = self.rpc.call_node_verify(node_verify_list, node_verify_param,
                                        self.cfg.GetClusterName())
     for verifier in node_verify_list:
-      if result.failed or not result[verifier].data:
+      if result[verifier].failed or not result[verifier].data:
         raise errors.OpExecError("Cannot communicate with %s's node daemon"
                                  " for remote verification" % verifier)
       if result[verifier].data['nodelist']:
@@ -2100,6 +2125,9 @@ class LUSetNodeParams(LogicalUnit):
     force = self.force = self.op.force
 
     if self.op.master_candidate == False:
+      if self.op.node_name == self.cfg.GetMasterNode():
+        raise errors.OpPrereqError("The master node has to be a"
+                                   " master candidate")
       cp_size = self.cfg.GetClusterInfo().candidate_pool_size
       node_info = self.cfg.GetAllNodesInfo().values()
       num_candidates = len([node for node in node_info
@@ -2129,7 +2157,8 @@ class LUSetNodeParams(LogicalUnit):
     # this will trigger configuration file update, if needed
     self.cfg.Update(node)
     # this will trigger job queue propagation or cleanup
-    self.context.ReaddNode(node)
+    if self.op.node_name != self.cfg.GetMasterNode():
+      self.context.ReaddNode(node)
 
     return result
 
@@ -5338,9 +5367,15 @@ class LUQueryExports(NoHooksLU):
         that node.
 
     """
-    result = self.rpc.call_export_list(self.nodes)
-    result.Raise()
-    return result.data
+    rpcresult = self.rpc.call_export_list(self.nodes)
+    result = {}
+    for node in rpcresult:
+      if rpcresult[node].failed:
+        result[node] = False
+      else:
+        result[node] = rpcresult[node].data
+
+    return result
 
 
 class LUExportInstance(LogicalUnit):