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

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:
.. pyassert::
constants.IPOLICY_ALL_KEYS == set([constants.ISPECS_MIN,
constants.ISPECS_MAX,
constants.IPOLICY_ALL_KEYS == set([constants.ISPECS_MINMAX,
constants.ISPECS_STD,
constants.IPOLICY_DTS,
constants.IPOLICY_VCPU_RATIO,
......@@ -249,24 +248,30 @@ The instance policy specification is a dict with the following fields:
.. |ispec-std| replace:: :pyeval:`constants.ISPECS_STD`
|ispec-min|, |ispec-max|, |ispec-std|
A sub- `dict` with the following fields, which sets the limit and standard
values of the instances:
:pyeval:`constants.ISPEC_MEM_SIZE`
The size in MiB of the memory used
:pyeval:`constants.ISPEC_DISK_SIZE`
The size in MiB of the disk used
:pyeval:`constants.ISPEC_DISK_COUNT`
The numbers of disks used
:pyeval:`constants.ISPEC_CPU_COUNT`
The numbers of cpus used
:pyeval:`constants.ISPEC_NIC_COUNT`
The numbers of nics used
: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
:pyeval:`constants.ISPECS_MINMAX`
A dict with the following two fields:
|ispec-min|, |ispec-max|
A sub- `dict` with the following fields, which sets the limit of the
instances:
:pyeval:`constants.ISPEC_MEM_SIZE`
The size in MiB of the memory used
:pyeval:`constants.ISPEC_DISK_SIZE`
The size in MiB of the disk used
:pyeval:`constants.ISPEC_DISK_COUNT`
The numbers of disks used
:pyeval:`constants.ISPEC_CPU_COUNT`
The numbers of cpus used
:pyeval:`constants.ISPEC_NIC_COUNT`
The numbers of nics used
: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`
A `list` of disk templates allowed for instances using this policy
:pyeval:`constants.IPOLICY_VCPU_RATIO`
......
......@@ -3717,10 +3717,19 @@ def _InitIspecsFromOpts(ipolicy, ispecs_mem_size, ispecs_cpu_count,
utils.ForceDictType(specs, forced_type, allowed_values=allowed_values)
# then transpose
ispecs = {
constants.ISPECS_MIN: {},
constants.ISPECS_MAX: {},
constants.ISPECS_STD: {},
}
for (name, specs) in ispecs_transposed.iteritems():
assert name in constants.ISPECS_PARAMETERS
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,
......
......@@ -476,10 +476,14 @@ def ShowClusterConfig(opts, args):
("Instance policy - limits for instances",
[
(key,
_FormatGroupedParams(result["ipolicy"][key], roman=opts.roman_integers))
for key in constants.IPOLICY_ISPECS
_FormatGroupedParams(result["ipolicy"][constants.ISPECS_MINMAX][key],
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",
utils.CommaJoin(result["ipolicy"][constants.IPOLICY_DTS])),
] +
......
......@@ -813,8 +813,22 @@ def _GetUpdatedParams(old_params, update_dict,
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):
"""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
we should support removal of policy entries
......@@ -826,7 +840,9 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
if key not in constants.IPOLICY_ALL_KEYS:
raise errors.OpPrereqError("Invalid key in new ipolicy: %s" % key,
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,
use_none=use_none,
use_default=use_default)
......@@ -1203,22 +1219,21 @@ def _CheckInstanceState(lu, instance, req_states, msg=None):
" is down")
def _ComputeMinMaxSpec(name, qualifier, ipolicy, value):
def _ComputeMinMaxSpec(name, qualifier, ispecs, value):
"""Computes if value is in the desired range.
@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',
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
@return: None or element not meeting the criteria
@return: None or an error string
"""
if value in [None, constants.VALUE_AUTO]:
return None
max_v = ipolicy[constants.ISPECS_MAX].get(name, value)
min_v = ipolicy[constants.ISPECS_MIN].get(name, value)
max_v = ispecs[constants.ISPECS_MAX].get(name, value)
min_v = ispecs[constants.ISPECS_MIN].get(name, value)
if value > max_v or min_v > value:
if qualifier:
fqn = "%s/%s" % (name, qualifier)
......@@ -1273,8 +1288,9 @@ def _ComputeIPolicySpecViolation(ipolicy, mem_size, cpu_count, disk_count,
ret.append("Disk template %s is not allowed (allowed templates: %s)" %
(disk_template, utils.CommaJoin(allowed_dts)))
minmax = ipolicy[constants.ISPECS_MINMAX]
return ret + filter(None,
(_compute_fn(name, qualifier, ipolicy, value)
(_compute_fn(name, qualifier, minmax, value)
for (name, qualifier, value) in test_settings))
......
......@@ -600,17 +600,17 @@ class ConfigWriter:
except errors.ConfigurationError, err:
result.append("%s has invalid nicparams: %s" % (owner, err))
def _helper_ipolicy(owner, params, check_std):
def _helper_ipolicy(owner, ipolicy, iscluster):
try:
objects.InstancePolicy.CheckParameterSyntax(params, check_std)
objects.InstancePolicy.CheckParameterSyntax(ipolicy, iscluster)
except errors.ConfigurationError, err:
result.append("%s has invalid instance policy: %s" % (owner, err))
def _helper_ispecs(owner, params):
for key, value in params.items():
if key in constants.IPOLICY_ISPECS:
fullkey = "ipolicy/" + key
_helper(owner, fullkey, value, constants.ISPECS_PARAMETER_TYPES)
for key, value in ipolicy.items():
if key == constants.ISPECS_MINMAX:
_helper_ispecs(owner, "ipolicy/" + key, value)
elif key == constants.ISPECS_STD:
_helper(owner, "ipolicy/" + key, value,
constants.ISPECS_PARAMETER_TYPES)
else:
# FIXME: assuming list type
if key in constants.IPOLICY_PARAMETERS:
......@@ -622,6 +622,11 @@ class ConfigWriter:
" expecting %s, got %s" %
(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
_helper("cluster", "beparams", cluster.SimpleFillBE({}),
constants.BES_PARAMETER_TYPES)
......@@ -630,8 +635,7 @@ class ConfigWriter:
_helper_nic("cluster", cluster.SimpleFillNIC({}))
_helper("cluster", "ndparams", cluster.SimpleFillND({}),
constants.NDS_PARAMETER_TYPES)
_helper_ipolicy("cluster", cluster.SimpleFillIPolicy({}), True)
_helper_ispecs("cluster", cluster.SimpleFillIPolicy({}))
_helper_ipolicy("cluster", cluster.ipolicy, True)
# per-instance checks
for instance_name in data.instances:
......@@ -762,7 +766,6 @@ class ConfigWriter:
group_name = "group %s" % nodegroup.name
_helper_ipolicy(group_name, cluster.SimpleFillIPolicy(nodegroup.ipolicy),
False)
_helper_ispecs(group_name, cluster.SimpleFillIPolicy(nodegroup.ipolicy))
if nodegroup.ndparams:
_helper(group_name, "ndparams",
cluster.SimpleFillND(nodegroup.ndparams),
......
......@@ -1139,6 +1139,7 @@ ISPECS_PARAMETER_TYPES = {
ISPECS_PARAMETERS = frozenset(ISPECS_PARAMETER_TYPES.keys())
ISPECS_MINMAX = "minmax"
ISPECS_MIN = "min"
ISPECS_MAX = "max"
ISPECS_STD = "std"
......@@ -1146,10 +1147,9 @@ IPOLICY_DTS = "disk-templates"
IPOLICY_VCPU_RATIO = "vcpu-ratio"
IPOLICY_SPINDLE_RATIO = "spindle-ratio"
IPOLICY_ISPECS = compat.UniqueFrozenset([
ISPECS_MINMAX_KEYS = compat.UniqueFrozenset([
ISPECS_MIN,
ISPECS_MAX,
ISPECS_STD,
])
IPOLICY_PARAMETERS = compat.UniqueFrozenset([
......@@ -1157,9 +1157,8 @@ IPOLICY_PARAMETERS = compat.UniqueFrozenset([
IPOLICY_SPINDLE_RATIO,
])
IPOLICY_ALL_KEYS = (IPOLICY_ISPECS |
IPOLICY_PARAMETERS |
frozenset([IPOLICY_DTS]))
IPOLICY_ALL_KEYS = (IPOLICY_PARAMETERS |
frozenset([ISPECS_MINMAX, ISPECS_STD, IPOLICY_DTS]))
# Node parameter names
ND_OOB_PROGRAM = "oob_program"
......@@ -2182,7 +2181,7 @@ NICC_DEFAULTS = {
# All of the following values are quite arbitrarily - there are no
# "good" defaults, these must be customised per-site
IPOLICY_DEFAULTS = {
ISPECS_MINMAX_DEFAULTS = {
ISPECS_MIN: {
ISPEC_MEM_SIZE: 128,
ISPEC_CPU_COUNT: 1,
......@@ -2199,6 +2198,9 @@ IPOLICY_DEFAULTS = {
ISPEC_NIC_COUNT: MAX_NICS,
ISPEC_SPINDLE_USE: 12,
},
}
IPOLICY_DEFAULTS = {
ISPECS_MINMAX: ISPECS_MINMAX_DEFAULTS,
ISPECS_STD: {
ISPEC_MEM_SIZE: 128,
ISPEC_CPU_COUNT: 1,
......
......@@ -82,16 +82,28 @@ def FillDict(defaults_dict, custom_dict, skip_keys=None):
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.
"""
assert frozenset(default_ipolicy.keys()) == constants.IPOLICY_ALL_KEYS
ret_dict = {}
for key in constants.IPOLICY_ISPECS:
ret_dict[key] = FillDict(default_ipolicy[key],
custom_ipolicy.get(key, {}),
skip_keys=skip_keys)
# Instance specs
new_mm = _FillMinMaxISpecs(default_ipolicy[constants.ISPECS_MINMAX],
custom_ipolicy.get(constants.ISPECS_MINMAX, {}))
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
for key in [constants.IPOLICY_DTS]:
ret_dict[key] = list(custom_ipolicy.get(key, default_ipolicy[key]))
......@@ -186,11 +198,13 @@ def MakeEmptyIPolicy():
"""Create empty IPolicy dictionary.
"""
return dict([
(constants.ISPECS_MIN, {}),
(constants.ISPECS_MAX, {}),
(constants.ISPECS_STD, {}),
])
return {
constants.ISPECS_MINMAX: {
constants.ISPECS_MIN: {},
constants.ISPECS_MAX: {},
},
constants.ISPECS_STD: {},
}
class ConfigObject(outils.ValidatedSlots):
......@@ -912,7 +926,6 @@ class Disk(ConfigObject):
class InstancePolicy(ConfigObject):
"""Config object representing instance policy limits dictionary.
Note that this object is not actually used in the config, it's just
used as a placeholder for a few functions.
......@@ -921,9 +934,21 @@ class InstancePolicy(ConfigObject):
def CheckParameterSyntax(cls, ipolicy, check_std):
""" 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:
InstancePolicy.CheckISpecSyntax(ipolicy, param, check_std)
if constants.ISPECS_MINMAX in ipolicy:
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:
InstancePolicy.CheckDiskTemplates(ipolicy[constants.IPOLICY_DTS])
for key in constants.IPOLICY_PARAMETERS:
......@@ -935,37 +960,47 @@ class InstancePolicy(ConfigObject):
utils.CommaJoin(wrong_keys))
@classmethod
def CheckISpecSyntax(cls, ipolicy, name, check_std):
"""Check the instance policy for validity on a given key.
def CheckISpecSyntax(cls, minmaxspecs, stdspec, name, check_std):
"""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
if ipolicy[min][name] <= ipolicy[std][name] <= ipolicy[max][name].
We check if the instance specs makes sense for a given key, that is
if minmaxspecs[min][name] <= stdspec[name] <= minmaxspec[max][name].
@type ipolicy: dict
@param ipolicy: dictionary with min, max, std specs
@type minmaxspecs: dict
@param minmaxspecs: dictionary with min and max instance spec
@type stdspec: dict
@param stdspec: dictionary with standard instance spec
@type name: string
@param name: what are the limits for
@type check_std: bool
@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:
std_v = ipolicy[constants.ISPECS_STD].get(name, min_v)
std_v = stdspec.get(name, min_v)
std_msg = std_v
else:
std_v = min_v
std_msg = "-"
max_v = ipolicy[constants.ISPECS_MAX].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))
max_v = maxspec.get(name, std_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)
@classmethod
......
......@@ -467,8 +467,9 @@ def _GetClusterIPolicy():
policy = info["Instance policy - limits for instances"]
ret_specs = {}
ret_policy = {}
ispec_keys = constants.ISPECS_MINMAX_KEYS | frozenset([constants.ISPECS_STD])
for (key, val) in policy.items():
if key in constants.IPOLICY_ISPECS:
if key in ispec_keys:
for (par, pval) in val.items():
if par == "memory-size":
par = "mem-size"
......
......@@ -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
it under the terms of the GNU General Public License as published by
......@@ -132,7 +132,8 @@ serializeDiskTemplates = intercalate "," . map diskTemplateToRaw
-- | Generate policy data from a given policy object.
serializeIPolicy :: String -> IPolicy -> String
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
, serializeISpec stdspec
, serializeISpec minspec
......@@ -263,7 +264,8 @@ loadIPolicy [owner, stdspec, minspec, maxspec, dtemplates,
xvcpu_ratio <- tryRead (owner ++ "/vcpu_ratio") vcpu_ratio
xspindle_ratio <- tryRead (owner ++ "/spindle_ratio") spindle_ratio
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 ++ "'"
loadOnePolicy :: (IPolicy, Group.List) -> String
......
......@@ -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
it under the terms of the GNU General Public License as published by
......@@ -280,8 +280,9 @@ instAboveISpec inst ispec
-- | Checks if an instance matches a policy.
instMatchesPolicy :: Instance -> T.IPolicy -> T.OpResult ()
instMatchesPolicy inst ipol = do
instAboveISpec inst (T.iPolicyMinSpec ipol)
instBelowISpec inst (T.iPolicyMaxSpec ipol)
let minmax = T.iPolicyMinMaxISpecs ipol
instAboveISpec inst (T.minMaxISpecsMinSpec minmax)
instBelowISpec inst (T.minMaxISpecsMaxSpec minmax)
if diskTemplate inst `elem` T.iPolicyDiskTemplates ipol
then Ok ()
else Bad T.FailDisk
......
......@@ -443,7 +443,8 @@ main opts args = do
-- Run the tiered allocation
let tspec = fromMaybe (rspecFromISpec (iPolicyMaxSpec ipol))
let minmax = iPolicyMinMaxISpecs ipol
let tspec = fromMaybe (rspecFromISpec (minMaxISpecsMaxSpec minmax))
(optTieredSpec opts)
(treason, trl_nl, _, spec_map) <-
......
......@@ -6,7 +6,7 @@
{-
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
it under the terms of the GNU General Public License as published by
......@@ -69,6 +69,7 @@ module Ganeti.HTools.Types
, opToResult
, EvacMode(..)
, ISpec(..)
, MinMaxISpecs(..)
, IPolicy(..)
, defIPolicy
, rspecFromISpec
......@@ -168,12 +169,12 @@ $(THH.buildObject "ISpec" "iSpec"
-- | The default minimum ispec.
defMinISpec :: ISpec
defMinISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsMinMemorySize
, iSpecCpuCount = C.ipolicyDefaultsMinCpuCount
, iSpecDiskSize = C.ipolicyDefaultsMinDiskSize
, iSpecDiskCount = C.ipolicyDefaultsMinDiskCount
, iSpecNicCount = C.ipolicyDefaultsMinNicCount
, iSpecSpindleUse = C.ipolicyDefaultsMinSpindleUse
defMinISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsMinmaxMinMemorySize
, iSpecCpuCount = C.ipolicyDefaultsMinmaxMinCpuCount
, iSpecDiskSize = C.ipolicyDefaultsMinmaxMinDiskSize
, iSpecDiskCount = C.ipolicyDefaultsMinmaxMinDiskCount
, iSpecNicCount = C.ipolicyDefaultsMinmaxMinNicCount
, iSpecSpindleUse = C.ipolicyDefaultsMinmaxMinSpindleUse
}
-- | The default standard ispec.
......@@ -188,19 +189,31 @@ defStdISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsStdMemorySize
-- | The default max ispec.
defMaxISpec :: ISpec
defMaxISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsMaxMemorySize
, iSpecCpuCount = C.ipolicyDefaultsMaxCpuCount
, iSpecDiskSize = C.ipolicyDefaultsMaxDiskSize
, iSpecDiskCount = C.ipolicyDefaultsMaxDiskCount
, iSpecNicCount = C.ipolicyDefaultsMaxNicCount
, iSpecSpindleUse = C.ipolicyDefaultsMaxSpindleUse
defMaxISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsMinmaxMaxMemorySize
, iSpecCpuCount = C.ipolicyDefaultsMinmaxMaxCpuCount
, iSpecDiskSize = C.ipolicyDefaultsMinmaxMaxDiskSize
, iSpecDiskCount = C.ipolicyDefaultsMinmaxMaxDiskCount
, iSpecNicCount = C.ipolicyDefaultsMinmaxMaxNicCount
, iSpecSpindleUse = C.ipolicyDefaultsMinmaxMaxSpindleUse
}
-- | Minimum and maximum instance specs type.
$(THH.buildObject "MinMaxISpecs" "minMaxISpecs"
[ THH.renameField "MinSpec" $ THH.simpleField "min" [t| ISpec |]
, THH.renameField "MaxSpec" $ THH.simpleField "max" [t| ISpec |]
])
-- | Defult minimum and maximum instance specs.
defMinMaxISpecs :: MinMaxISpecs
defMinMaxISpecs = MinMaxISpecs { minMaxISpecsMinSpec = defMinISpec
, minMaxISpecsMaxSpec = defMaxISpec
}
-- | Instance policy type.
$(THH.buildObject "IPolicy" "iPolicy"
[ THH.renameField "StdSpec" $ THH.simpleField C.ispecsStd [t| ISpec |]
, THH.renameField "MinSpec" $ THH.simpleField C.ispecsMin [t| ISpec |]
, THH.renameField "MaxSpec" $ THH.simpleField C.ispecsMax [t| ISpec |]
[ THH.renameField "MinMaxISpecs" $
THH.simpleField C.ispecsMinmax [t| MinMaxISpecs |]
, THH.renameField "StdSpec" $ THH.simpleField C.ispecsStd [t| ISpec |]
, THH.renameField "DiskTemplates" $
THH.simpleField C.ipolicyDts [t| [DiskTemplate] |]
, THH.renameField "VcpuRatio" $
......@@ -218,9 +231,8 @@ rspecFromISpec ispec = RSpec { rspecCpu = iSpecCpuCount ispec
-- | The default instance policy.
defIPolicy :: IPolicy
defIPolicy = IPolicy { iPolicyStdSpec = defStdISpec
, iPolicyMinSpec = defMinISpec
, iPolicyMaxSpec = defMaxISpec
defIPolicy = IPolicy { iPolicyMinMaxISpecs = defMinMaxISpecs
, iPolicyStdSpec = defStdISpec
-- hardcoding here since Constants.hs exports the
-- string values, not the actual type; and in
-- htools, we are mostly looking at DRBD
......
......@@ -66,6 +66,9 @@ module Ganeti.Objects
, PartialISpecParams(..)
, fillISpecParams
, allISpecParamFields
, FilledMinMaxISpecs(..)
, PartialMinMaxISpecs(..)
, fillMinMaxISpecs
, FilledIPolicy(..)
, PartialIPolicy(..)
, fillIPolicy
......@@ -491,11 +494,25 @@ $(buildParam "ISpec" "ispec"
, simpleField C.ispecSpindleUse [t| Int |]
])
-- | Partial min-max instance specs. These is not built via buildParam since
-- it has a special 2-level inheritance mode.
$(buildObject "PartialMinMaxISpecs" "mmis"
[ renameField "MinSpecP" $ simpleField "min" [t| PartialISpecParams |]
, renameField "MaxSpecP" $ simpleField "max" [t| PartialISpecParams |]
])
-- | Filled min-max instance specs. This is not built via buildParam since
-- it has a special 2-level inheritance mode.
$(buildObject "FilledMinMaxISpecs" "mmis"
[ renameField "MinSpec" $ simpleField "min" [t| FilledISpecParams |]
, renameField "MaxSpec" $ simpleField "max" [t| FilledISpecParams |]
])
-- | Custom partial ipolicy. This is not built via buildParam since it
-- has a special 2-level inheritance mode.
$(buildObject "PartialIPolicy" "ipolicy"
[ renameField "MinSpecP" $ simpleField "min" [t| PartialISpecParams |]
, renameField "MaxSpecP" $ simpleField "max" [t| PartialISpecParams |]
[ optionalField . renameField "MinMaxISpecsP"
$ simpleField C.ispecsMinmax [t| PartialMinMaxISpecs |]
, renameField "StdSpecP" $ simpleField "std" [t| PartialISpecParams |]
, optionalField . renameField "SpindleRatioP"
$ simpleField "spindle-ratio" [t| Double |]
......@@ -508,30 +525,38 @@ $(buildObject "PartialIPolicy" "ipolicy"
-- | Custom filled ipolicy. This is not built via buildParam since it
-- has a special 2-level inheritance mode.
$(buildObject "FilledIPolicy" "ipolicy"
[ renameField "MinSpec" $ simpleField "min" [t| FilledISpecParams |]
, renameField "MaxSpec" $ simpleField "max" [t| FilledISpecParams |]
[ renameField "MinMaxISpecs"
$ simpleField C.ispecsMinmax [t| FilledMinMaxISpecs |]
, renameField "StdSpec" $ simpleField "std" [t| FilledISpecParams |]
, simpleField "spindle-ratio" [t| Double |]
, simpleField "vcpu-ratio" [t| Double |]
, simpleField "disk-templates" [t| [DiskTemplate] |]
])
-- | Custom filler for the min-max instance specs.
fillMinMaxISpecs :: FilledMinMaxISpecs -> Maybe PartialMinMaxISpecs ->
FilledMinMaxISpecs
fillMinMaxISpecs fminmax Nothing