Commit 41044e04 authored by Bernardo Dal Seno's avatar Bernardo Dal Seno
Browse files

Add multiple min/max specs in instance policy



Now instance policies can contain more than one min/max specs.  This is the
main element of the "Constrained instance sizes" section in the
"Partitioned Ganeti" design doc.

This is a big patch, but changing the type of a configuration item requires
to change all the code that handles it.
Signed-off-by: default avatarBernardo Dal Seno <bdalseno@google.com>
Reviewed-by: default avatarHelga Velroyen <helgav@google.com>
parent b342c9dd
...@@ -251,7 +251,7 @@ The instance policy specification is a dict with the following fields: ...@@ -251,7 +251,7 @@ The instance policy specification is a dict with the following fields:
:pyeval:`constants.ISPECS_MINMAX` :pyeval:`constants.ISPECS_MINMAX`
A dict with the following two fields: A list of dictionaries, each with the following two fields:
|ispec-min|, |ispec-max| |ispec-min|, |ispec-max|
A sub- `dict` with the following fields, which sets the limit of the A sub- `dict` with the following fields, which sets the limit of the
......
...@@ -3736,13 +3736,24 @@ def FormatPolicyInfo(custom_ipolicy, eff_ipolicy, iscluster): ...@@ -3736,13 +3736,24 @@ def FormatPolicyInfo(custom_ipolicy, eff_ipolicy, iscluster):
if iscluster: if iscluster:
eff_ipolicy = custom_ipolicy eff_ipolicy = custom_ipolicy
custom_minmax = custom_ipolicy.get(constants.ISPECS_MINMAX, {}) minmax_out = []
ret = [ custom_minmax = custom_ipolicy.get(constants.ISPECS_MINMAX)
(key, if custom_minmax:
FormatParamsDictInfo(custom_minmax.get(key, {}), for (k, minmax) in enumerate(custom_minmax):
eff_ipolicy[constants.ISPECS_MINMAX][key])) minmax_out.append([
for key in constants.ISPECS_MINMAX_KEYS ("%s/%s" % (key, k),
] FormatParamsDictInfo(minmax[key], minmax[key]))
for key in constants.ISPECS_MINMAX_KEYS
])
else:
for (k, minmax) in enumerate(eff_ipolicy[constants.ISPECS_MINMAX]):
minmax_out.append([
("%s/%s" % (key, k),
FormatParamsDictInfo({}, minmax[key]))
for key in constants.ISPECS_MINMAX_KEYS
])
ret = [("bounds specs", minmax_out)]
if iscluster: if iscluster:
stdspecs = custom_ipolicy[constants.ISPECS_STD] stdspecs = custom_ipolicy[constants.ISPECS_STD]
ret.append( ret.append(
...@@ -3787,8 +3798,8 @@ def PrintIPolicyCommand(buf, ipolicy, isgroup): ...@@ -3787,8 +3798,8 @@ def PrintIPolicyCommand(buf, ipolicy, isgroup):
_PrintSpecsParameters(buf, stdspecs) _PrintSpecsParameters(buf, stdspecs)
minmax = ipolicy.get("minmax") minmax = ipolicy.get("minmax")
if minmax: if minmax:
minspecs = minmax.get("min") minspecs = minmax[0].get("min")
maxspecs = minmax.get("max") maxspecs = minmax[0].get("max")
if minspecs and maxspecs: if minspecs and maxspecs:
buf.write(" %s " % IPOLICY_BOUNDS_SPECS_STR) buf.write(" %s " % IPOLICY_BOUNDS_SPECS_STR)
buf.write("min:") buf.write("min:")
...@@ -3892,13 +3903,14 @@ def _InitISpecsFromSplitOpts(ipolicy, ispecs_mem_size, ispecs_cpu_count, ...@@ -3892,13 +3903,14 @@ def _InitISpecsFromSplitOpts(ipolicy, ispecs_mem_size, ispecs_cpu_count,
for key, val in specs.items(): # {min: .. ,max: .., std: ..} for key, val in specs.items(): # {min: .. ,max: .., std: ..}
assert key in ispecs assert key in ispecs
ispecs[key][name] = val ispecs[key][name] = val
ipolicy[constants.ISPECS_MINMAX] = {} minmax_out = {}
for key in constants.ISPECS_MINMAX_KEYS: for key in constants.ISPECS_MINMAX_KEYS:
if fill_all: if fill_all:
ipolicy[constants.ISPECS_MINMAX][key] = \ minmax_out[key] = \
objects.FillDict(constants.ISPECS_MINMAX_DEFAULTS[key], ispecs[key]) objects.FillDict(constants.ISPECS_MINMAX_DEFAULTS[key], ispecs[key])
else: else:
ipolicy[constants.ISPECS_MINMAX][key] = ispecs[key] minmax_out[key] = ispecs[key]
ipolicy[constants.ISPECS_MINMAX] = [minmax_out]
if fill_all: if fill_all:
ipolicy[constants.ISPECS_STD] = \ ipolicy[constants.ISPECS_STD] = \
objects.FillDict(constants.IPOLICY_DEFAULTS[constants.ISPECS_STD], objects.FillDict(constants.IPOLICY_DEFAULTS[constants.ISPECS_STD],
...@@ -3953,7 +3965,7 @@ def _InitISpecsFromFullOpts(ipolicy_out, minmax_ispecs, std_ispecs, ...@@ -3953,7 +3965,7 @@ def _InitISpecsFromFullOpts(ipolicy_out, minmax_ispecs, std_ispecs,
msg = "Invalid key in bounds instance specifications: %s" % key msg = "Invalid key in bounds instance specifications: %s" % key
raise errors.OpPrereqError(msg, errors.ECODE_INVAL) raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
minmax_out[key] = _ParseISpec(spec, key, True) minmax_out[key] = _ParseISpec(spec, key, True)
ipolicy_out[constants.ISPECS_MINMAX] = minmax_out ipolicy_out[constants.ISPECS_MINMAX] = [minmax_out]
if std_ispecs is not None: if std_ispecs is not None:
assert not group_ipolicy # This is not an option for gnt-group assert not group_ipolicy # This is not an option for gnt-group
ipolicy_out[constants.ISPECS_STD] = _ParseISpec(std_ispecs, "std", False) ipolicy_out[constants.ISPECS_STD] = _ParseISpec(std_ispecs, "std", False)
......
...@@ -828,7 +828,8 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False): ...@@ -828,7 +828,8 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
if (not value or value == [constants.VALUE_DEFAULT] or if (not value or value == [constants.VALUE_DEFAULT] or
value == constants.VALUE_DEFAULT): value == constants.VALUE_DEFAULT):
if group_policy: if group_policy:
del ipolicy[key] if key in ipolicy:
del ipolicy[key]
else: else:
raise errors.OpPrereqError("Can't unset ipolicy attribute '%s'" raise errors.OpPrereqError("Can't unset ipolicy attribute '%s'"
" on the cluster'" % key, " on the cluster'" % key,
...@@ -843,8 +844,9 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False): ...@@ -843,8 +844,9 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
" '%s': '%s', error: %s" % " '%s': '%s', error: %s" %
(key, value, err), errors.ECODE_INVAL) (key, value, err), errors.ECODE_INVAL)
elif key == constants.ISPECS_MINMAX: elif key == constants.ISPECS_MINMAX:
for k in value.keys(): for minmax in value:
utils.ForceDictType(value[k], constants.ISPECS_PARAMETER_TYPES) for k in minmax.keys():
utils.ForceDictType(minmax[k], constants.ISPECS_PARAMETER_TYPES)
ipolicy[key] = value ipolicy[key] = value
elif key == constants.ISPECS_STD: elif key == constants.ISPECS_STD:
if group_policy: if group_policy:
...@@ -1276,10 +1278,15 @@ def _ComputeIPolicySpecViolation(ipolicy, mem_size, cpu_count, disk_count, ...@@ -1276,10 +1278,15 @@ 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] min_errs = None
return ret + filter(None, for minmax in ipolicy[constants.ISPECS_MINMAX]:
(_compute_fn(name, qualifier, minmax, value) errs = filter(None,
for (name, qualifier, value) in test_settings)) (_compute_fn(name, qualifier, minmax, value)
for (name, qualifier, value) in test_settings))
if min_errs is None or len(errs) < len(min_errs):
min_errs = errs
assert min_errs is not None
return ret + min_errs
   
   
def _ComputeIPolicyInstanceViolation(ipolicy, instance, cfg, def _ComputeIPolicyInstanceViolation(ipolicy, instance, cfg,
......
...@@ -633,7 +633,8 @@ class ConfigWriter: ...@@ -633,7 +633,8 @@ class ConfigWriter:
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(): for key, value in ipolicy.items():
if key == constants.ISPECS_MINMAX: if key == constants.ISPECS_MINMAX:
_helper_ispecs(owner, "ipolicy/" + key, value) for k in range(len(value)):
_helper_ispecs(owner, "ipolicy/%s[%s]" % (key, k), value[k])
elif key == constants.ISPECS_STD: elif key == constants.ISPECS_STD:
_helper(owner, "ipolicy/" + key, value, _helper(owner, "ipolicy/" + key, value,
constants.ISPECS_PARAMETER_TYPES) constants.ISPECS_PARAMETER_TYPES)
......
...@@ -2215,7 +2215,7 @@ ISPECS_MINMAX_DEFAULTS = { ...@@ -2215,7 +2215,7 @@ ISPECS_MINMAX_DEFAULTS = {
}, },
} }
IPOLICY_DEFAULTS = { IPOLICY_DEFAULTS = {
ISPECS_MINMAX: ISPECS_MINMAX_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,
......
...@@ -959,20 +959,24 @@ class InstancePolicy(ConfigObject): ...@@ -959,20 +959,24 @@ class InstancePolicy(ConfigObject):
if check_std: if check_std:
InstancePolicy._CheckIncompleteSpec(stdspec, constants.ISPECS_STD) InstancePolicy._CheckIncompleteSpec(stdspec, constants.ISPECS_STD)
minmaxspecs = ipolicy[constants.ISPECS_MINMAX] if not ipolicy[constants.ISPECS_MINMAX]:
missing = constants.ISPECS_MINMAX_KEYS - frozenset(minmaxspecs.keys()) raise errors.ConfigurationError("Empty minmax specifications")
if missing: std_is_good = False
msg = "Missing instance specification: %s" % utils.CommaJoin(missing) for minmaxspecs in ipolicy[constants.ISPECS_MINMAX]:
raise errors.ConfigurationError(msg) missing = constants.ISPECS_MINMAX_KEYS - frozenset(minmaxspecs.keys())
for (key, spec) in minmaxspecs.items(): if missing:
InstancePolicy._CheckIncompleteSpec(spec, key) msg = "Missing instance specification: %s" % utils.CommaJoin(missing)
raise errors.ConfigurationError(msg)
spec_std_ok = True for (key, spec) in minmaxspecs.items():
for param in constants.ISPECS_PARAMETERS: InstancePolicy._CheckIncompleteSpec(spec, key)
par_std_ok = InstancePolicy._CheckISpecParamSyntax(minmaxspecs, stdspec,
param, check_std) spec_std_ok = True
spec_std_ok = spec_std_ok and par_std_ok for param in constants.ISPECS_PARAMETERS:
if not spec_std_ok: par_std_ok = InstancePolicy._CheckISpecParamSyntax(minmaxspecs, stdspec,
param, check_std)
spec_std_ok = spec_std_ok and par_std_ok
std_is_good = std_is_good or spec_std_ok
if not std_is_good:
raise errors.ConfigurationError("Invalid std specifications") raise errors.ConfigurationError("Invalid std specifications")
@classmethod @classmethod
......
...@@ -198,8 +198,10 @@ support all options. Some common options are: ...@@ -198,8 +198,10 @@ support all options. Some common options are:
groups, in the following format (separated by ``|``): groups, in the following format (separated by ``|``):
- owner (empty if cluster, group name otherwise) - owner (empty if cluster, group name otherwise)
- standard, min, max instance specs, containing the following values - standard, min, max instance specs; min and max instance specs are
separated by commas: separated between them by a semicolon, and can be specified multiple
times (min;max;min;max...); each of the specs contains the following
values separated by commas:
- memory size - memory size
- cpu count - cpu count
- disk size - disk size
......
...@@ -32,12 +32,14 @@ module Ganeti.HTools.Backend.Text ...@@ -32,12 +32,14 @@ module Ganeti.HTools.Backend.Text
, loadInst , loadInst
, loadNode , loadNode
, loadISpec , loadISpec
, loadMultipleMinMaxISpecs
, loadIPolicy , loadIPolicy
, serializeInstances , serializeInstances
, serializeNode , serializeNode
, serializeNodes , serializeNodes
, serializeGroup , serializeGroup
, serializeISpec , serializeISpec
, serializeMultipleMinMaxISpecs
, serializeIPolicy , serializeIPolicy
, serializeCluster , serializeCluster
) where ) where
...@@ -117,6 +119,10 @@ serializeInstances :: Node.List -> Instance.List -> String ...@@ -117,6 +119,10 @@ serializeInstances :: Node.List -> Instance.List -> String
serializeInstances nl = serializeInstances nl =
unlines . map (serializeInstance nl) . Container.elems unlines . map (serializeInstance nl) . Container.elems
-- | Separator between ISpecs (in MinMaxISpecs).
iSpecsSeparator :: Char
iSpecsSeparator = ';'
-- | Generate a spec data from a given ISpec object. -- | Generate a spec data from a given ISpec object.
serializeISpec :: ISpec -> String serializeISpec :: ISpec -> String
serializeISpec ispec = serializeISpec ispec =
...@@ -130,15 +136,20 @@ serializeISpec ispec = ...@@ -130,15 +136,20 @@ serializeISpec ispec =
serializeDiskTemplates :: [DiskTemplate] -> String serializeDiskTemplates :: [DiskTemplate] -> String
serializeDiskTemplates = intercalate "," . map diskTemplateToRaw serializeDiskTemplates = intercalate "," . map diskTemplateToRaw
-- | Generate min/max instance specs data.
serializeMultipleMinMaxISpecs :: [MinMaxISpecs] -> String
serializeMultipleMinMaxISpecs minmaxes =
intercalate [iSpecsSeparator] $ foldr serialpair [] minmaxes
where serialpair (MinMaxISpecs minspec maxspec) acc =
serializeISpec minspec : serializeISpec maxspec : acc
-- | 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 minmax stdspec 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 , serializeMultipleMinMaxISpecs minmax
, serializeISpec maxspec
, serializeDiskTemplates dts , serializeDiskTemplates dts
, show vcpu_ratio , show vcpu_ratio
, show spindle_ratio , show spindle_ratio
...@@ -255,18 +266,41 @@ loadISpec owner [mem_s, cpu_c, dsk_s, dsk_c, nic_c, su] = do ...@@ -255,18 +266,41 @@ loadISpec owner [mem_s, cpu_c, dsk_s, dsk_c, nic_c, su] = do
return $ ISpec xmem_s xcpu_c xdsk_s xdsk_c xnic_c xsu return $ ISpec xmem_s xcpu_c xdsk_s xdsk_c xnic_c xsu
loadISpec owner s = fail $ "Invalid ispec data for " ++ owner ++ ": " ++ show s loadISpec owner s = fail $ "Invalid ispec data for " ++ owner ++ ": " ++ show s
-- | Load a single min/max ISpec pair
loadMinMaxISpecs :: String -> String -> String -> Result MinMaxISpecs
loadMinMaxISpecs owner minspec maxspec = do
xminspec <- loadISpec (owner ++ "/minspec") (commaSplit minspec)
xmaxspec <- loadISpec (owner ++ "/maxspec") (commaSplit maxspec)
return $ MinMaxISpecs xminspec xmaxspec
-- | Break a list of ispecs strings into a list of (min/max) ispecs pairs
breakISpecsPairs :: String -> [String] -> Result [(String, String)]
breakISpecsPairs _ [] =
return []
breakISpecsPairs owner (x:y:xs) = do
rest <- breakISpecsPairs owner xs
return $ (x, y) : rest
breakISpecsPairs owner _ =
fail $ "Odd number of min/max specs for " ++ owner
-- | Load a list of min/max ispecs pairs
loadMultipleMinMaxISpecs :: String -> [String] -> Result [MinMaxISpecs]
loadMultipleMinMaxISpecs owner ispecs = do
pairs <- breakISpecsPairs owner ispecs
mapM (uncurry $ loadMinMaxISpecs owner) pairs
-- | Loads an ipolicy from a field list. -- | Loads an ipolicy from a field list.
loadIPolicy :: [String] -> Result (String, IPolicy) loadIPolicy :: [String] -> Result (String, IPolicy)
loadIPolicy [owner, stdspec, minspec, maxspec, dtemplates, loadIPolicy [owner, stdspec, minmaxspecs, dtemplates,
vcpu_ratio, spindle_ratio] = do vcpu_ratio, spindle_ratio] = do
xstdspec <- loadISpec (owner ++ "/stdspec") (commaSplit stdspec) xstdspec <- loadISpec (owner ++ "/stdspec") (commaSplit stdspec)
xminspec <- loadISpec (owner ++ "/minspec") (commaSplit minspec) xminmaxspecs <- loadMultipleMinMaxISpecs owner $
xmaxspec <- loadISpec (owner ++ "/maxspec") (commaSplit maxspec) sepSplit iSpecsSeparator minmaxspecs
xdts <- mapM diskTemplateFromRaw $ commaSplit dtemplates xdts <- mapM diskTemplateFromRaw $ commaSplit 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 (MinMaxISpecs xminspec xmaxspec) xstdspec IPolicy xminmaxspecs xstdspec
xdts xvcpu_ratio xspindle_ratio) xdts xvcpu_ratio xspindle_ratio)
loadIPolicy s = fail $ "Invalid ipolicy data: '" ++ show s ++ "'" loadIPolicy s = fail $ "Invalid ipolicy data: '" ++ show s ++ "'"
......
...@@ -279,12 +279,26 @@ instAboveISpec inst ispec ...@@ -279,12 +279,26 @@ instAboveISpec inst ispec
| vcpus inst < T.iSpecCpuCount ispec = Bad T.FailCPU | vcpus inst < T.iSpecCpuCount ispec = Bad T.FailCPU
| otherwise = Ok () | otherwise = Ok ()
-- | Checks if an instance matches a min/max specs pair
instMatchesMinMaxSpecs :: Instance -> T.MinMaxISpecs -> T.OpResult ()
instMatchesMinMaxSpecs inst minmax = do
instAboveISpec inst (T.minMaxISpecsMinSpec minmax)
instBelowISpec inst (T.minMaxISpecsMaxSpec minmax)
-- | Checks if an instance matches any specs of a policy
instMatchesSpecs :: Instance -> [T.MinMaxISpecs] -> T.OpResult ()
-- Return Ok for no constraints, though this should never happen
instMatchesSpecs _ [] = Ok ()
instMatchesSpecs inst (minmax:minmaxes) =
foldr eithermatch (instMatchesMinMaxSpecs inst minmax) minmaxes
where eithermatch mm (Bad _) = instMatchesMinMaxSpecs inst mm
eithermatch _ y@(Ok ()) = y
-- # See 04f231771
-- | Checks if an instance matches a policy. -- | Checks if an instance matches a policy.
instMatchesPolicy :: Instance -> T.IPolicy -> T.OpResult () instMatchesPolicy :: Instance -> T.IPolicy -> T.OpResult ()
instMatchesPolicy inst ipol = do instMatchesPolicy inst ipol = do
let minmax = T.iPolicyMinMaxISpecs ipol instMatchesSpecs inst $ T.iPolicyMinMaxISpecs ipol
instAboveISpec inst (T.minMaxISpecsMinSpec minmax)
instBelowISpec inst (T.minMaxISpecsMaxSpec minmax)
if diskTemplate inst `elem` T.iPolicyDiskTemplates ipol if diskTemplate inst `elem` T.iPolicyDiskTemplates ipol
then Ok () then Ok ()
else Bad T.FailDisk else Bad T.FailDisk
......
...@@ -446,9 +446,13 @@ main opts args = do ...@@ -446,9 +446,13 @@ main opts args = do
-- Run the tiered allocation -- Run the tiered allocation
let minmax = iPolicyMinMaxISpecs ipol let minmaxes = iPolicyMinMaxISpecs ipol
let tspec = fromMaybe (rspecFromISpec (minMaxISpecsMaxSpec minmax)) -- TODO: Go through all min/max specs pairs
(optTieredSpec opts) tspec <- case minmaxes of
[] -> exitErr "Empty list of specs received from the cluster"
minmax:_ -> return $ fromMaybe
(rspecFromISpec (minMaxISpecsMaxSpec minmax))
(optTieredSpec opts)
(treason, trl_nl, _, spec_map) <- (treason, trl_nl, _, spec_map) <-
runAllocation cdata stop_allocation runAllocation cdata stop_allocation
......
...@@ -169,12 +169,12 @@ $(THH.buildObject "ISpec" "iSpec" ...@@ -169,12 +169,12 @@ $(THH.buildObject "ISpec" "iSpec"
-- | The default minimum ispec. -- | The default minimum ispec.
defMinISpec :: ISpec defMinISpec :: ISpec
defMinISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsMinmaxMinMemorySize defMinISpec = ISpec { iSpecMemorySize = C.ispecsMinmaxDefaultsMinMemorySize
, iSpecCpuCount = C.ipolicyDefaultsMinmaxMinCpuCount , iSpecCpuCount = C.ispecsMinmaxDefaultsMinCpuCount
, iSpecDiskSize = C.ipolicyDefaultsMinmaxMinDiskSize , iSpecDiskSize = C.ispecsMinmaxDefaultsMinDiskSize
, iSpecDiskCount = C.ipolicyDefaultsMinmaxMinDiskCount , iSpecDiskCount = C.ispecsMinmaxDefaultsMinDiskCount
, iSpecNicCount = C.ipolicyDefaultsMinmaxMinNicCount , iSpecNicCount = C.ispecsMinmaxDefaultsMinNicCount
, iSpecSpindleUse = C.ipolicyDefaultsMinmaxMinSpindleUse , iSpecSpindleUse = C.ispecsMinmaxDefaultsMinSpindleUse
} }
-- | The default standard ispec. -- | The default standard ispec.
...@@ -189,12 +189,12 @@ defStdISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsStdMemorySize ...@@ -189,12 +189,12 @@ defStdISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsStdMemorySize
-- | The default max ispec. -- | The default max ispec.
defMaxISpec :: ISpec defMaxISpec :: ISpec
defMaxISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsMinmaxMaxMemorySize defMaxISpec = ISpec { iSpecMemorySize = C.ispecsMinmaxDefaultsMaxMemorySize
, iSpecCpuCount = C.ipolicyDefaultsMinmaxMaxCpuCount , iSpecCpuCount = C.ispecsMinmaxDefaultsMaxCpuCount
, iSpecDiskSize = C.ipolicyDefaultsMinmaxMaxDiskSize , iSpecDiskSize = C.ispecsMinmaxDefaultsMaxDiskSize
, iSpecDiskCount = C.ipolicyDefaultsMinmaxMaxDiskCount , iSpecDiskCount = C.ispecsMinmaxDefaultsMaxDiskCount
, iSpecNicCount = C.ipolicyDefaultsMinmaxMaxNicCount , iSpecNicCount = C.ispecsMinmaxDefaultsMaxNicCount
, iSpecSpindleUse = C.ipolicyDefaultsMinmaxMaxSpindleUse , iSpecSpindleUse = C.ispecsMinmaxDefaultsMaxSpindleUse
} }
-- | Minimum and maximum instance specs type. -- | Minimum and maximum instance specs type.
...@@ -204,15 +204,15 @@ $(THH.buildObject "MinMaxISpecs" "minMaxISpecs" ...@@ -204,15 +204,15 @@ $(THH.buildObject "MinMaxISpecs" "minMaxISpecs"
]) ])
-- | Defult minimum and maximum instance specs. -- | Defult minimum and maximum instance specs.
defMinMaxISpecs :: MinMaxISpecs defMinMaxISpecs :: [MinMaxISpecs]
defMinMaxISpecs = MinMaxISpecs { minMaxISpecsMinSpec = defMinISpec defMinMaxISpecs = [MinMaxISpecs { minMaxISpecsMinSpec = defMinISpec
, minMaxISpecsMaxSpec = defMaxISpec , minMaxISpecsMaxSpec = defMaxISpec
} }]
-- | Instance policy type. -- | Instance policy type.
$(THH.buildObject "IPolicy" "iPolicy" $(THH.buildObject "IPolicy" "iPolicy"
[ THH.renameField "MinMaxISpecs" $ [ THH.renameField "MinMaxISpecs" $
THH.simpleField C.ispecsMinmax [t| MinMaxISpecs |] THH.simpleField C.ispecsMinmax [t| [MinMaxISpecs] |]
, THH.renameField "StdSpec" $ THH.simpleField C.ispecsStd [t| ISpec |] , THH.renameField "StdSpec" $ THH.simpleField C.ispecsStd [t| ISpec |]
, THH.renameField "DiskTemplates" $ , THH.renameField "DiskTemplates" $
THH.simpleField C.ipolicyDts [t| [DiskTemplate] |] THH.simpleField C.ipolicyDts [t| [DiskTemplate] |]
......
...@@ -512,7 +512,7 @@ $(buildObject "MinMaxISpecs" "mmis" ...@@ -512,7 +512,7 @@ $(buildObject "MinMaxISpecs" "mmis"
-- has a special 2-level inheritance mode. -- has a special 2-level inheritance mode.
$(buildObject "PartialIPolicy" "ipolicy" $(buildObject "PartialIPolicy" "ipolicy"
[ optionalField . renameField "MinMaxISpecsP" [ optionalField . renameField "MinMaxISpecsP"
$ simpleField C.ispecsMinmax [t| MinMaxISpecs |] $ simpleField C.ispecsMinmax [t| [MinMaxISpecs] |]
, optionalField . renameField "StdSpecP" , optionalField . renameField "StdSpecP"
$ simpleField "std" [t| PartialISpecParams |] $ simpleField "std" [t| PartialISpecParams |]
, optionalField . renameField "SpindleRatioP" , optionalField . renameField "SpindleRatioP"
...@@ -527,7 +527,7 @@ $(buildObject "PartialIPolicy" "ipolicy" ...@@ -527,7 +527,7 @@ $(buildObject "PartialIPolicy" "ipolicy"
-- has a special 2-level inheritance mode. -- has a special 2-level inheritance mode.
$(buildObject "FilledIPolicy" "ipolicy" $(buildObject "FilledIPolicy" "ipolicy"
[ renameField "MinMaxISpecs" [ renameField "MinMaxISpecs"
$ simpleField C.ispecsMinmax [t| MinMaxISpecs |] $ simpleField C.ispecsMinmax [t| [MinMaxISpecs] |]
, renameField "StdSpec" $ simpleField "std" [t| FilledISpecParams |] , renameField "StdSpec" $ simpleField "std" [t| FilledISpecParams |]
, simpleField "spindle-ratio" [t| Double |] , simpleField "spindle-ratio" [t| Double |]
, simpleField "vcpu-ratio" [t| Double |] , simpleField "vcpu-ratio" [t| Double |]
......
...@@ -11,5 +11,5 @@ new-3|128|1024|1|running|Y|node-01-003||diskless||1 ...@@ -11,5 +11,5 @@ new-3|128|1024|1|running|Y|node-01-003||diskless||1
new-4|128|1024|1|running|Y|node-01-002||diskless||1 new-4|128|1024|1|running|Y|node-01-002||diskless||1
|128,1,1024,1,1,1|128,1,1024,1,1,1|32768,8,1048576,16,8,12|diskless,file,sharedfile,plain,blockdev,drbd,rbd,ext|4.0|32.0 |128,1,1024,1,1,1|128,1,1024,1,1,1;32768,8,1048576,16,8,12|diskless,file,sharedfile,plain,blockdev,drbd,rbd,ext|4.0|32.0
group-01|128,1,1024,1,1,1|128,1,1024,1,1,1|32768,8,1048576,16,8,12|diskless,file,sharedfile,plain,blockdev,drbd,rbd,ext|4.0|32.0 group-01|128,1,1024,1,1,1|128,1,1024,1,1,1;32768,8,1048576,16,8,12|diskless,file,sharedfile,plain,blockdev,drbd,rbd,ext|4.0|32.0
...@@ -6,5 +6,5 @@ node2.example.com|1024|0|896|95367|94343|4|N|fake-uuid-01|1 ...@@ -6,5 +6,5 @@ node2.example.com|1024|0|896|95367|94343|4|N|fake-uuid-01|1
instance1.example.com|128|1024|1|running|Y|node2.example.com||plain| instance1.example.com|128|1024|1|running|Y|node2.example.com||plain|
|128,1,1024,1,1,1|128,1,1024,1,1,1|32768,8,1048576,16,8,1|diskless,file,sharedfile,plain,blockdev,drbd,rbd|4.0|32.0 |128,1,1024,1,1,1|128,1,1024,1,1,1;32768,8,1048576,16,8,1|diskless,file,sharedfile,plain,blockdev,drbd,rbd|4.0|32.0
default|128,1,1024,1,1,1|128,1,1024,1,1,1|32768,8,1048576,16,8,1|diskless,file,sharedfile,plain,blockdev,drbd,rbd|4.0|32.0 default|128,1,1024,1,1,1|128,1,1024,1,1,1;32768,8,1048576,16,8,1|diskless,file,sharedfile,plain,blockdev,drbd,rbd|4.0|32.0
...@@ -3,5 +3,5 @@ group-01|fake-uuid-01|preferred| ...@@ -3,5 +3,5 @@ group-01|fake-uuid-01|preferred|
|128,1,1024,1,1,1|128,1,1024,1,1,1|32768,8,1048576,16,8,12|diskless,file,sharedfile,plain,blockdev,drbd,rbd,ext|4.0|32.0 |128,1,1024,1,1,1|128,1,1024,1,1,1;32768,8,1048576,16,8,12|diskless,file,sharedfile,plain,blockdev,drbd,rbd,ext|4.0|32.0
group-01|128,1,1024,1,1,1|128,1,1024,1,1,1|32768,8,1048576,16,8,12|diskless,file,sharedfile,plain,blockdev,drbd,rbd,ext|4.0|32.0 group-01|128,1,1024,1,1,1|128,1,1024,1,1,1;32768,8,1048576,16,8,12|diskless,file,sharedfile,plain,blockdev,drbd,rbd,ext|4.0|32.0
...@@ -14,24 +14,26 @@ ...@@ -14,24 +14,26 @@
"cpu-count": 1, "cpu-count": 1,
"spindle-use": 1 "spindle-use": 1
}, },
"minmax": { "minmax": [
"min": { {
"nic-count": 1, "min": {
"disk-size": 128, "nic-count": 1,
"disk-count": 1, "disk-size": 128,
"memory-size": 128, "disk-count": 1,
"cpu-count": 1, "memory-size": 128,
"spindle-use": 1 "cpu-count": 1,
}, "spindle-use": 1
"max": { },
"nic-count": 8, "max": {
"disk-size": 1048576, "nic-count": 8,
"disk-count": 16,