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:
try:
self.op.candidate_pool_size = int(self.op.candidate_pool_size)
except ValueError, err:
raise errors.OpPrereqError("Invalid candidate_pool_size value: %s" %
str(err))
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
self.cfg.Update(self.cluster)
# 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:
random.shuffle(node_info)
for node in node_info:
if num_candidates >= self.op.candidate_pool_size:
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
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):
"enabled_hypervisors",
"hvparams",
"beparams",
"candidate_pool_size",
]
def ToDict(self):
......
......@@ -255,7 +255,13 @@ class OpSetClusterParams(OpCode):
"""
OP_ID = "OP_CLUSTER_SET_PARAMS"
__slots__ = ["vg_name", "enabled_hypervisors", "hvparams", "beparams"]
__slots__ = [
"vg_name",
"enabled_hypervisors",
"hvparams",
"beparams",
"candidate_pool_size",
]
# 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):
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,
enabled_hypervisors=hvlist,
hvparams=hvparams,
beparams=beparams)
beparams=beparams,
candidate_pool_size=opts.candidate_pool_size)
SubmitOpCode(op)
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"),
],
"[opts...]",
"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