Commit 4b7735f9 authored by Iustin Pop's avatar Iustin Pop
Browse files

Add cluster candidate pool size parameter

This patch adds a new cluster paramater "candidate_pool_size" which
tracks the desired size of the list of nodes with the master_candidate
flag set.

Reviewed-by: imsnah
parent 8135a2db
......@@ -32,6 +32,7 @@ import re
import platform
import logging
import copy
import random
from ganeti import ssh
from ganeti import utils
......@@ -1186,6 +1187,21 @@ class LUSetClusterParams(LogicalUnit):
_OP_REQP = []
REQ_BGL = False
def CheckParameters(self):
"""Check parameters
if not hasattr(self.op, "candidate_pool_size"):
self.op.candidate_pool_size = None
if self.op.candidate_pool_size is not None:
self.op.candidate_pool_size = int(self.op.candidate_pool_size)
except ValueError, err:
raise errors.OpPrereqError("Invalid candidate_pool_size value: %s" %
if self.op.candidate_pool_size < 1:
raise errors.OpPrereqError("At least one master candidate needed")
def ExpandNames(self):
# FIXME: in the future maybe other cluster params won't require checking on
# all nodes to be modified.
......@@ -1284,8 +1300,35 @@ class LUSetClusterParams(LogicalUnit):
self.cluster.enabled_hypervisors = self.op.enabled_hypervisors
if self.op.beparams:
self.cluster.beparams[constants.BEGR_DEFAULT] = self.new_beparams
if self.op.candidate_pool_size is not None:
self.cluster.candidate_pool_size = self.op.candidate_pool_size
# we want to update nodes after the cluster so that if any errors
# happen, we have recorded and saved the cluster info
if self.op.candidate_pool_size is not None:
node_info = self.cfg.GetAllNodesInfo().values()
num_candidates = len([node for node in node_info
if node.master_candidate])
num_nodes = len(node_info)
if num_candidates < self.op.candidate_pool_size:
for node in node_info:
if num_candidates >= self.op.candidate_pool_size:
if node.master_candidate:
node.master_candidate = True
self.LogInfo("Promoting node %s to master candidate",
num_candidates += 1
elif num_candidates > self.op.candidate_pool_size:
self.LogInfo("Note: more nodes are candidates (%d) than the new value"
" of candidate_pool_size (%d)" %
(num_candidates, self.op.candidate_pool_size))
def _WaitForSync(lu, instance, oneshot=False, unlock=False):
"""Sleep and poll for an instance's disk to sync.
......@@ -2058,6 +2101,7 @@ class LUQueryClusterInfo(NoHooksLU):
"enabled_hypervisors": cluster.enabled_hypervisors,
"hvparams": cluster.hvparams,
"beparams": cluster.beparams,
"candidate_pool_size": cluster.candidate_pool_size,
return result
......@@ -707,6 +707,7 @@ class Cluster(TaggableObject):
def ToDict(self):
......@@ -255,7 +255,13 @@ class OpSetClusterParams(OpCode):
__slots__ = ["vg_name", "enabled_hypervisors", "hvparams", "beparams"]
__slots__ = [
# node opcodes
......@@ -238,6 +238,9 @@ def ShowClusterConfig(opts, args):
ToStdout(" %s: %s", item, val)
ToStdout("Cluster parameters:")
ToStdout(" - candidate pool size: %s", result["candidate_pool_size"])
ToStdout("Default instance parameters:")
for gr_name, gr_dict in result["beparams"].items():
ToStdout(" - %s:", gr_name)
for item, val in gr_dict.iteritems():
......@@ -448,7 +451,7 @@ def SetClusterParams(opts, args):
if not (not opts.lvm_storage or opts.vg_name or
opts.enabled_hypervisors or opts.hvparams or
opts.beparams or opts.candidate_pool_size is not None):
ToStderr("Please give at least one of the parameters.")
return 1
......@@ -471,7 +474,8 @@ def SetClusterParams(opts, args):
op = opcodes.OpSetClusterParams(vg_name=opts.vg_name,
return 0
......@@ -636,6 +640,9 @@ commands = {
keyval_option("-B", "--backend-parameters", dest="beparams",
type="keyval", default={},
help="Backend parameters"),
make_option("-C", "--candidate-pool-size", default=None,
help="Set the candidate pool size",
dest="candidate_pool_size", type="int"),
"Alters the parameters of the cluster"),
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment