Commit da5f09ef authored by Bernardo Dal Seno's avatar Bernardo Dal Seno
Browse files

Refactor ispecs in ipolicy structures



Minimum and maximum instance specs are put together into a single element
of the instance policy. This is in preparation for introducing multiple
min/max specs.
Signed-off-by: default avatarBernardo Dal Seno <bdalseno@google.com>
Reviewed-by: default avatarHelga Velroyen <helgav@google.com>
parent 1709435e
...@@ -226,8 +226,7 @@ The instance policy specification is a dict with the following fields: ...@@ -226,8 +226,7 @@ The instance policy specification is a dict with the following fields:
.. pyassert:: .. pyassert::
constants.IPOLICY_ALL_KEYS == set([constants.ISPECS_MIN, constants.IPOLICY_ALL_KEYS == set([constants.ISPECS_MINMAX,
constants.ISPECS_MAX,
constants.ISPECS_STD, constants.ISPECS_STD,
constants.IPOLICY_DTS, constants.IPOLICY_DTS,
constants.IPOLICY_VCPU_RATIO, constants.IPOLICY_VCPU_RATIO,
...@@ -249,24 +248,30 @@ The instance policy specification is a dict with the following fields: ...@@ -249,24 +248,30 @@ The instance policy specification is a dict with the following fields:
.. |ispec-std| replace:: :pyeval:`constants.ISPECS_STD` .. |ispec-std| replace:: :pyeval:`constants.ISPECS_STD`
|ispec-min|, |ispec-max|, |ispec-std| :pyeval:`constants.ISPECS_MINMAX`
A sub- `dict` with the following fields, which sets the limit and standard A dict with the following two fields:
values of the instances:
|ispec-min|, |ispec-max|
:pyeval:`constants.ISPEC_MEM_SIZE` A sub- `dict` with the following fields, which sets the limit of the
The size in MiB of the memory used instances:
:pyeval:`constants.ISPEC_DISK_SIZE`
The size in MiB of the disk used :pyeval:`constants.ISPEC_MEM_SIZE`
:pyeval:`constants.ISPEC_DISK_COUNT` The size in MiB of the memory used
The numbers of disks used :pyeval:`constants.ISPEC_DISK_SIZE`
:pyeval:`constants.ISPEC_CPU_COUNT` The size in MiB of the disk used
The numbers of cpus used :pyeval:`constants.ISPEC_DISK_COUNT`
:pyeval:`constants.ISPEC_NIC_COUNT` The numbers of disks used
The numbers of nics used :pyeval:`constants.ISPEC_CPU_COUNT`
:pyeval:`constants.ISPEC_SPINDLE_USE` The numbers of cpus used
The numbers of virtual disk spindles used by this instance. They are :pyeval:`constants.ISPEC_NIC_COUNT`
not real in the sense of actual HDD spindles, but useful for The numbers of nics used
accounting the spindle usage on the residing node :pyeval:`constants.ISPEC_SPINDLE_USE`
The numbers of virtual disk spindles used by this instance. They
are not real in the sense of actual HDD spindles, but useful for
accounting the spindle usage on the residing node
|ispec-std|
A sub- `dict` with the same fields as |ispec-min| and |ispec-max| above,
which sets the standard values of the instances.
:pyeval:`constants.IPOLICY_DTS` :pyeval:`constants.IPOLICY_DTS`
A `list` of disk templates allowed for instances using this policy A `list` of disk templates allowed for instances using this policy
:pyeval:`constants.IPOLICY_VCPU_RATIO` :pyeval:`constants.IPOLICY_VCPU_RATIO`
......
...@@ -3717,10 +3717,19 @@ def _InitIspecsFromOpts(ipolicy, ispecs_mem_size, ispecs_cpu_count, ...@@ -3717,10 +3717,19 @@ def _InitIspecsFromOpts(ipolicy, ispecs_mem_size, ispecs_cpu_count,
utils.ForceDictType(specs, forced_type, allowed_values=allowed_values) utils.ForceDictType(specs, forced_type, allowed_values=allowed_values)
# then transpose # then transpose
ispecs = {
constants.ISPECS_MIN: {},
constants.ISPECS_MAX: {},
constants.ISPECS_STD: {},
}
for (name, specs) in ispecs_transposed.iteritems(): for (name, specs) in ispecs_transposed.iteritems():
assert name in constants.ISPECS_PARAMETERS assert name in constants.ISPECS_PARAMETERS
for key, val in specs.items(): # {min: .. ,max: .., std: ..} for key, val in specs.items(): # {min: .. ,max: .., std: ..}
ipolicy[key][name] = val assert key in ispecs
ispecs[key][name] = val
for key in constants.ISPECS_MINMAX_KEYS:
ipolicy[constants.ISPECS_MINMAX][key] = ispecs[key]
ipolicy[constants.ISPECS_STD] = ispecs[constants.ISPECS_STD]
def CreateIPolicyFromOpts(ispecs_mem_size=None, def CreateIPolicyFromOpts(ispecs_mem_size=None,
......
...@@ -476,10 +476,14 @@ def ShowClusterConfig(opts, args): ...@@ -476,10 +476,14 @@ def ShowClusterConfig(opts, args):
("Instance policy - limits for instances", ("Instance policy - limits for instances",
[ [
(key, (key,
_FormatGroupedParams(result["ipolicy"][key], roman=opts.roman_integers)) _FormatGroupedParams(result["ipolicy"][constants.ISPECS_MINMAX][key],
for key in constants.IPOLICY_ISPECS roman=opts.roman_integers))
for key in constants.ISPECS_MINMAX_KEYS
] + ] +
[ [
(constants.ISPECS_STD,
_FormatGroupedParams(result["ipolicy"][constants.ISPECS_STD],
roman=opts.roman_integers)),
("enabled disk templates", ("enabled disk templates",
utils.CommaJoin(result["ipolicy"][constants.IPOLICY_DTS])), utils.CommaJoin(result["ipolicy"][constants.IPOLICY_DTS])),
] + ] +
......
...@@ -813,8 +813,22 @@ def _GetUpdatedParams(old_params, update_dict, ...@@ -813,8 +813,22 @@ def _GetUpdatedParams(old_params, update_dict,
return params_copy return params_copy
   
   
def _UpdateMinMaxISpecs(ipolicy, new_minmax, group_policy):
use_none = use_default = group_policy
minmax = ipolicy.setdefault(constants.ISPECS_MINMAX, {})
for (key, value) in new_minmax.items():
if key not in constants.ISPECS_MINMAX_KEYS:
raise errors.OpPrereqError("Invalid key in new ipolicy/%s: %s" %
(constants.ISPECS_MINMAX, key),
errors.ECODE_INVAL)
old_spec = minmax.get(key, {})
minmax[key] = _GetUpdatedParams(old_spec, value, use_none=use_none,
use_default=use_default)
utils.ForceDictType(minmax[key], constants.ISPECS_PARAMETER_TYPES)
def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False): def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
"""Return the new version of a instance policy. """Return the new version of an instance policy.
   
@param group_policy: whether this policy applies to a group and thus @param group_policy: whether this policy applies to a group and thus
we should support removal of policy entries we should support removal of policy entries
...@@ -826,7 +840,9 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False): ...@@ -826,7 +840,9 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
if key not in constants.IPOLICY_ALL_KEYS: if key not in constants.IPOLICY_ALL_KEYS:
raise errors.OpPrereqError("Invalid key in new ipolicy: %s" % key, raise errors.OpPrereqError("Invalid key in new ipolicy: %s" % key,
errors.ECODE_INVAL) errors.ECODE_INVAL)
if key in constants.IPOLICY_ISPECS: if key == constants.ISPECS_MINMAX:
_UpdateMinMaxISpecs(ipolicy, value, group_policy)
elif key == constants.ISPECS_STD:
ipolicy[key] = _GetUpdatedParams(old_ipolicy.get(key, {}), value, ipolicy[key] = _GetUpdatedParams(old_ipolicy.get(key, {}), value,
use_none=use_none, use_none=use_none,
use_default=use_default) use_default=use_default)
...@@ -1203,22 +1219,21 @@ def _CheckInstanceState(lu, instance, req_states, msg=None): ...@@ -1203,22 +1219,21 @@ def _CheckInstanceState(lu, instance, req_states, msg=None):
" is down") " is down")
   
   
def _ComputeMinMaxSpec(name, qualifier, ipolicy, value): def _ComputeMinMaxSpec(name, qualifier, ispecs, value):
"""Computes if value is in the desired range. """Computes if value is in the desired range.
   
@param name: name of the parameter for which we perform the check @param name: name of the parameter for which we perform the check
@param qualifier: a qualifier used in the error message (e.g. 'disk/1', @param qualifier: a qualifier used in the error message (e.g. 'disk/1',
not just 'disk') not just 'disk')
@param ipolicy: dictionary containing min, max and std values @param ispecs: dictionary containing min and max values
@param value: actual value that we want to use @param value: actual value that we want to use
@return: None or element not meeting the criteria @return: None or an error string
   
""" """
if value in [None, constants.VALUE_AUTO]: if value in [None, constants.VALUE_AUTO]:
return None return None
max_v = ipolicy[constants.ISPECS_MAX].get(name, value) max_v = ispecs[constants.ISPECS_MAX].get(name, value)
min_v = ipolicy[constants.ISPECS_MIN].get(name, value) min_v = ispecs[constants.ISPECS_MIN].get(name, value)
if value > max_v or min_v > value: if value > max_v or min_v > value:
if qualifier: if qualifier:
fqn = "%s/%s" % (name, qualifier) fqn = "%s/%s" % (name, qualifier)
...@@ -1273,8 +1288,9 @@ def _ComputeIPolicySpecViolation(ipolicy, mem_size, cpu_count, disk_count, ...@@ -1273,8 +1288,9 @@ def _ComputeIPolicySpecViolation(ipolicy, mem_size, cpu_count, disk_count,
ret.append("Disk template %s is not allowed (allowed templates: %s)" % ret.append("Disk template %s is not allowed (allowed templates: %s)" %
(disk_template, utils.CommaJoin(allowed_dts))) (disk_template, utils.CommaJoin(allowed_dts)))
   
minmax = ipolicy[constants.ISPECS_MINMAX]
return ret + filter(None, return ret + filter(None,
(_compute_fn(name, qualifier, ipolicy, value) (_compute_fn(name, qualifier, minmax, value)
for (name, qualifier, value) in test_settings)) for (name, qualifier, value) in test_settings))
   
   
......
...@@ -600,17 +600,17 @@ class ConfigWriter: ...@@ -600,17 +600,17 @@ class ConfigWriter:
except errors.ConfigurationError, err: except errors.ConfigurationError, err:
result.append("%s has invalid nicparams: %s" % (owner, err)) result.append("%s has invalid nicparams: %s" % (owner, err))
def _helper_ipolicy(owner, params, check_std): def _helper_ipolicy(owner, ipolicy, iscluster):
try: try:
objects.InstancePolicy.CheckParameterSyntax(params, check_std) objects.InstancePolicy.CheckParameterSyntax(ipolicy, iscluster)
except errors.ConfigurationError, err: except errors.ConfigurationError, err:
result.append("%s has invalid instance policy: %s" % (owner, err)) result.append("%s has invalid instance policy: %s" % (owner, err))
for key, value in ipolicy.items():
def _helper_ispecs(owner, params): if key == constants.ISPECS_MINMAX:
for key, value in params.items(): _helper_ispecs(owner, "ipolicy/" + key, value)
if key in constants.IPOLICY_ISPECS: elif key == constants.ISPECS_STD:
fullkey = "ipolicy/" + key _helper(owner, "ipolicy/" + key, value,
_helper(owner, fullkey, value, constants.ISPECS_PARAMETER_TYPES) constants.ISPECS_PARAMETER_TYPES)
else: else:
# FIXME: assuming list type # FIXME: assuming list type
if key in constants.IPOLICY_PARAMETERS: if key in constants.IPOLICY_PARAMETERS:
...@@ -622,6 +622,11 @@ class ConfigWriter: ...@@ -622,6 +622,11 @@ class ConfigWriter:
" expecting %s, got %s" % " expecting %s, got %s" %
(owner, key, exp_type.__name__, type(value))) (owner, key, exp_type.__name__, type(value)))
def _helper_ispecs(owner, parentkey, params):
for (key, value) in params.items():
fullkey = "/".join([parentkey, key])
_helper(owner, fullkey, value, constants.ISPECS_PARAMETER_TYPES)
# check cluster parameters # check cluster parameters
_helper("cluster", "beparams", cluster.SimpleFillBE({}), _helper("cluster", "beparams", cluster.SimpleFillBE({}),
constants.BES_PARAMETER_TYPES) constants.BES_PARAMETER_TYPES)
...@@ -630,8 +635,7 @@ class ConfigWriter: ...@@ -630,8 +635,7 @@ class ConfigWriter:
_helper_nic("cluster", cluster.SimpleFillNIC({})) _helper_nic("cluster", cluster.SimpleFillNIC({}))
_helper("cluster", "ndparams", cluster.SimpleFillND({}), _helper("cluster", "ndparams", cluster.SimpleFillND({}),
constants.NDS_PARAMETER_TYPES) constants.NDS_PARAMETER_TYPES)
_helper_ipolicy("cluster", cluster.SimpleFillIPolicy({}), True) _helper_ipolicy("cluster", cluster.ipolicy, True)
_helper_ispecs("cluster", cluster.SimpleFillIPolicy({}))
# per-instance checks # per-instance checks
for instance_name in data.instances: for instance_name in data.instances:
...@@ -762,7 +766,6 @@ class ConfigWriter: ...@@ -762,7 +766,6 @@ class ConfigWriter:
group_name = "group %s" % nodegroup.name group_name = "group %s" % nodegroup.name
_helper_ipolicy(group_name, cluster.SimpleFillIPolicy(nodegroup.ipolicy), _helper_ipolicy(group_name, cluster.SimpleFillIPolicy(nodegroup.ipolicy),
False) False)
_helper_ispecs(group_name, cluster.SimpleFillIPolicy(nodegroup.ipolicy))
if nodegroup.ndparams: if nodegroup.ndparams:
_helper(group_name, "ndparams", _helper(group_name, "ndparams",
cluster.SimpleFillND(nodegroup.ndparams), cluster.SimpleFillND(nodegroup.ndparams),
......
...@@ -1139,6 +1139,7 @@ ISPECS_PARAMETER_TYPES = { ...@@ -1139,6 +1139,7 @@ ISPECS_PARAMETER_TYPES = {
ISPECS_PARAMETERS = frozenset(ISPECS_PARAMETER_TYPES.keys()) ISPECS_PARAMETERS = frozenset(ISPECS_PARAMETER_TYPES.keys())
ISPECS_MINMAX = "minmax"
ISPECS_MIN = "min" ISPECS_MIN = "min"
ISPECS_MAX = "max" ISPECS_MAX = "max"
ISPECS_STD = "std" ISPECS_STD = "std"
...@@ -1146,10 +1147,9 @@ IPOLICY_DTS = "disk-templates" ...@@ -1146,10 +1147,9 @@ IPOLICY_DTS = "disk-templates"
IPOLICY_VCPU_RATIO = "vcpu-ratio" IPOLICY_VCPU_RATIO = "vcpu-ratio"
IPOLICY_SPINDLE_RATIO = "spindle-ratio" IPOLICY_SPINDLE_RATIO = "spindle-ratio"
IPOLICY_ISPECS = compat.UniqueFrozenset([ ISPECS_MINMAX_KEYS = compat.UniqueFrozenset([
ISPECS_MIN, ISPECS_MIN,
ISPECS_MAX, ISPECS_MAX,
ISPECS_STD,
]) ])
IPOLICY_PARAMETERS = compat.UniqueFrozenset([ IPOLICY_PARAMETERS = compat.UniqueFrozenset([
...@@ -1157,9 +1157,8 @@ IPOLICY_PARAMETERS = compat.UniqueFrozenset([ ...@@ -1157,9 +1157,8 @@ IPOLICY_PARAMETERS = compat.UniqueFrozenset([
IPOLICY_SPINDLE_RATIO, IPOLICY_SPINDLE_RATIO,
]) ])
IPOLICY_ALL_KEYS = (IPOLICY_ISPECS | IPOLICY_ALL_KEYS = (IPOLICY_PARAMETERS |
IPOLICY_PARAMETERS | frozenset([ISPECS_MINMAX, ISPECS_STD, IPOLICY_DTS]))
frozenset([IPOLICY_DTS]))
# Node parameter names # Node parameter names
ND_OOB_PROGRAM = "oob_program" ND_OOB_PROGRAM = "oob_program"
...@@ -2182,7 +2181,7 @@ NICC_DEFAULTS = { ...@@ -2182,7 +2181,7 @@ NICC_DEFAULTS = {
# All of the following values are quite arbitrarily - there are no # All of the following values are quite arbitrarily - there are no
# "good" defaults, these must be customised per-site # "good" defaults, these must be customised per-site
IPOLICY_DEFAULTS = { ISPECS_MINMAX_DEFAULTS = {
ISPECS_MIN: { ISPECS_MIN: {
ISPEC_MEM_SIZE: 128, ISPEC_MEM_SIZE: 128,
ISPEC_CPU_COUNT: 1, ISPEC_CPU_COUNT: 1,
...@@ -2199,6 +2198,9 @@ IPOLICY_DEFAULTS = { ...@@ -2199,6 +2198,9 @@ IPOLICY_DEFAULTS = {
ISPEC_NIC_COUNT: MAX_NICS, ISPEC_NIC_COUNT: MAX_NICS,
ISPEC_SPINDLE_USE: 12, ISPEC_SPINDLE_USE: 12,
}, },
}
IPOLICY_DEFAULTS = {
ISPECS_MINMAX: ISPECS_MINMAX_DEFAULTS,
ISPECS_STD: { ISPECS_STD: {
ISPEC_MEM_SIZE: 128, ISPEC_MEM_SIZE: 128,
ISPEC_CPU_COUNT: 1, ISPEC_CPU_COUNT: 1,
......
...@@ -82,16 +82,28 @@ def FillDict(defaults_dict, custom_dict, skip_keys=None): ...@@ -82,16 +82,28 @@ def FillDict(defaults_dict, custom_dict, skip_keys=None):
return ret_dict return ret_dict
def FillIPolicy(default_ipolicy, custom_ipolicy, skip_keys=None): def _FillMinMaxISpecs(default_specs, custom_specs):
assert frozenset(default_specs.keys()) == constants.ISPECS_MINMAX_KEYS
ret_specs = {}
for key in constants.ISPECS_MINMAX_KEYS:
ret_specs[key] = FillDict(default_specs[key],
custom_specs.get(key, {}))
return ret_specs
def FillIPolicy(default_ipolicy, custom_ipolicy):
"""Fills an instance policy with defaults. """Fills an instance policy with defaults.
""" """
assert frozenset(default_ipolicy.keys()) == constants.IPOLICY_ALL_KEYS assert frozenset(default_ipolicy.keys()) == constants.IPOLICY_ALL_KEYS
ret_dict = {} ret_dict = {}
for key in constants.IPOLICY_ISPECS: # Instance specs
ret_dict[key] = FillDict(default_ipolicy[key], new_mm = _FillMinMaxISpecs(default_ipolicy[constants.ISPECS_MINMAX],
custom_ipolicy.get(key, {}), custom_ipolicy.get(constants.ISPECS_MINMAX, {}))
skip_keys=skip_keys) ret_dict[constants.ISPECS_MINMAX] = new_mm
new_std = FillDict(default_ipolicy[constants.ISPECS_STD],
custom_ipolicy.get(constants.ISPECS_STD, {}))
ret_dict[constants.ISPECS_STD] = new_std
# list items # list items
for key in [constants.IPOLICY_DTS]: for key in [constants.IPOLICY_DTS]:
ret_dict[key] = list(custom_ipolicy.get(key, default_ipolicy[key])) ret_dict[key] = list(custom_ipolicy.get(key, default_ipolicy[key]))
...@@ -186,11 +198,13 @@ def MakeEmptyIPolicy(): ...@@ -186,11 +198,13 @@ def MakeEmptyIPolicy():
"""Create empty IPolicy dictionary. """Create empty IPolicy dictionary.
""" """
return dict([ return {
(constants.ISPECS_MIN, {}), constants.ISPECS_MINMAX: {
(constants.ISPECS_MAX, {}), constants.ISPECS_MIN: {},
(constants.ISPECS_STD, {}), constants.ISPECS_MAX: {},
]) },
constants.ISPECS_STD: {},
}
class ConfigObject(outils.ValidatedSlots): class ConfigObject(outils.ValidatedSlots):
...@@ -912,7 +926,6 @@ class Disk(ConfigObject): ...@@ -912,7 +926,6 @@ class Disk(ConfigObject):
class InstancePolicy(ConfigObject): class InstancePolicy(ConfigObject):
"""Config object representing instance policy limits dictionary. """Config object representing instance policy limits dictionary.
Note that this object is not actually used in the config, it's just Note that this object is not actually used in the config, it's just
used as a placeholder for a few functions. used as a placeholder for a few functions.
...@@ -921,9 +934,21 @@ class InstancePolicy(ConfigObject): ...@@ -921,9 +934,21 @@ class InstancePolicy(ConfigObject):
def CheckParameterSyntax(cls, ipolicy, check_std): def CheckParameterSyntax(cls, ipolicy, check_std):
""" Check the instance policy for validity. """ Check the instance policy for validity.
@type ipolicy: dict
@param ipolicy: dictionary with min/max/std specs and policies
@type check_std: bool
@param check_std: Whether to check std value or just assume compliance
@raise errors.ConfigurationError: when the policy is not legal
""" """
for param in constants.ISPECS_PARAMETERS: if constants.ISPECS_MINMAX in ipolicy:
InstancePolicy.CheckISpecSyntax(ipolicy, param, check_std) if check_std and constants.ISPECS_STD not in ipolicy:
msg = "Missing key in ipolicy: %s" % constants.ISPECS_STD
raise errors.ConfigurationError(msg)
minmaxspecs = ipolicy[constants.ISPECS_MINMAX]
stdspec = ipolicy.get(constants.ISPECS_STD)
for param in constants.ISPECS_PARAMETERS:
InstancePolicy.CheckISpecSyntax(minmaxspecs, stdspec, param, check_std)
if constants.IPOLICY_DTS in ipolicy: if constants.IPOLICY_DTS in ipolicy:
InstancePolicy.CheckDiskTemplates(ipolicy[constants.IPOLICY_DTS]) InstancePolicy.CheckDiskTemplates(ipolicy[constants.IPOLICY_DTS])
for key in constants.IPOLICY_PARAMETERS: for key in constants.IPOLICY_PARAMETERS:
...@@ -935,37 +960,47 @@ class InstancePolicy(ConfigObject): ...@@ -935,37 +960,47 @@ class InstancePolicy(ConfigObject):
utils.CommaJoin(wrong_keys)) utils.CommaJoin(wrong_keys))
@classmethod @classmethod
def CheckISpecSyntax(cls, ipolicy, name, check_std): def CheckISpecSyntax(cls, minmaxspecs, stdspec, name, check_std):
"""Check the instance policy for validity on a given key. """Check the instance policy specs for validity on a given key.
We check if the instance policy makes sense for a given key, that is We check if the instance specs makes sense for a given key, that is
if ipolicy[min][name] <= ipolicy[std][name] <= ipolicy[max][name]. if minmaxspecs[min][name] <= stdspec[name] <= minmaxspec[max][name].
@type ipolicy: dict @type minmaxspecs: dict
@param ipolicy: dictionary with min, max, std specs @param minmaxspecs: dictionary with min and max instance spec
@type stdspec: dict
@param stdspec: dictionary with standard instance spec
@type name: string @type name: string
@param name: what are the limits for @param name: what are the limits for
@type check_std: bool @type check_std: bool
@param check_std: Whether to check std value or just assume compliance @param check_std: Whether to check std value or just assume compliance
@raise errors.ConfigureError: when specs for given name are not valid @raise errors.ConfigurationError: when specs for the given name are not
valid
""" """
min_v = ipolicy[constants.ISPECS_MIN].get(name, 0) missing = constants.ISPECS_MINMAX_KEYS - frozenset(minmaxspecs.keys())
if missing:
msg = "Missing instance specification: %s" % utils.CommaJoin(missing)
raise errors.ConfigurationError(msg)
minspec = minmaxspecs[constants.ISPECS_MIN]
maxspec = minmaxspecs[constants.ISPECS_MAX]
min_v = minspec.get(name, 0)
if check_std: if check_std:
std_v = ipolicy[constants.ISPECS_STD].get(name, min_v) std_v = stdspec.get(name, min_v)
std_msg = std_v std_msg = std_v
else: else:
std_v = min_v std_v = min_v
std_msg = "-" std_msg = "-"
max_v = ipolicy[constants.ISPECS_MAX].get(name, std_v) max_v = maxspec.get(name, std_v)
err = ("Invalid specification of min/max/std values for %s: %s/%s/%s" %
(name,
ipolicy[constants.ISPECS_MIN].get(name, "-"),
ipolicy[constants.ISPECS_MAX].get(name, "-"),
std_msg))
if min_v > std_v or std_v > max_v: if min_v > std_v or std_v > max_v:
err = ("Invalid specification of min/max/std values for %s: %s/%s/%s" %
(name,
minspec.get(name, "-"),
maxspec.get(name, "-"),
std_msg))
raise errors.ConfigurationError(err) raise errors.ConfigurationError(err)
@classmethod @classmethod
......
...@@ -467,8 +467,9 @@ def _GetClusterIPolicy(): ...@@ -467,8 +467,9 @@ def _GetClusterIPolicy():
policy = info["Instance policy - limits for instances"] policy = info["Instance policy - limits for instances"]
ret_specs = {} ret_specs = {}
ret_policy = {} ret_policy = {}
ispec_keys = constants.ISPECS_MINMAX_KEYS | frozenset([constants.ISPECS_STD])
for (key, val) in policy.items(): for (key, val) in policy.items():
if key in constants.IPOLICY_ISPECS: if key in ispec_keys:
for (par, pval) in val.items(): for (par, pval) in val.items():
if par == "memory-size": if par == "memory-size":
par = "mem-size" par = "mem-size"
......
...@@ -7,7 +7,7 @@ files, as produced by @gnt-node@ and @gnt-instance@ @list@ command. ...@@ -7,7 +7,7 @@ files, as produced by @gnt-node@ and @gnt-instance@ @list@ command.
{- {-
Copyright (C) 2009, 2010, 2011, 2012 Google Inc. Copyright (C) 2009, 2010, 2011, 2012, 2013 Google Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -132,7 +132,8 @@ serializeDiskTemplates = intercalate "," . map diskTemplateToRaw ...@@ -132,7 +132,8 @@ serializeDiskTemplates = intercalate "," . map diskTemplateToRaw
-- | Generate policy data from a given policy object. -- | Generate policy data from a given policy object.
serializeIPolicy :: String -> IPolicy -> String serializeIPolicy :: String -> IPolicy -> String
serializeIPolicy owner ipol = serializeIPolicy owner ipol =
let IPolicy stdspec minspec maxspec dts vcpu_ratio spindle_ratio = ipol let IPolicy minmax stdspec dts vcpu_ratio spindle_ratio = ipol
MinMaxISpecs minspec maxspec = minmax
strings = [ owner strings = [ owner
, serializeISpec stdspec , serializeISpec stdspec
, serializeISpec minspec , serializeISpec minspec
...@@ -263,7 +264,8 @@ loadIPolicy [owner, stdspec, minspec, maxspec, dtemplates, ...@@ -263,7 +264,8 @@ loadIPolicy [owner, stdspec, minspec, maxspec, dtemplates,
xvcpu_ratio <- tryRead (owner ++ "/vcpu_ratio") vcpu_ratio xvcpu_ratio <- tryRead (owner ++ "/vcpu_ratio") vcpu_ratio
xspindle_ratio <- tryRead (owner ++ "/spindle_ratio") spindle_ratio xspindle_ratio <- tryRead (owner ++ "/spindle_ratio") spindle_ratio
return (owner, return (owner,
IPolicy xstdspec xminspec xmaxspec xdts xvcpu_ratio xspindle_ratio) IPolicy (MinMaxISpecs xminspec xmaxspec) xstdspec
xdts xvcpu_ratio xspindle_ratio)
loadIPolicy s = fail $ "Invalid ipolicy data: '" ++ show s ++ "'" loadIPolicy s = fail $ "Invalid ipolicy data: '" ++ show s ++ "'"
loadOnePolicy :: (IPolicy, Group.List) -> String loadOnePolicy :: (IPolicy, Group.List) -> String
......
<
...@@ -7,7 +7,7 @@ intelligence is in the "Node" and "Cluster" modules. ...@@ -7,7 +7,7 @@ intelligence is in the "Node" and "Cluster" modules.
{- {-
Copyright (C) 2009, 2010, 2011, 2012 Google Inc. Copyright (C) 2009, 2010, 2011, 2012, 2013 Google Inc.
This program is free software; you can redistribute it and/or modify