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

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:
: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|
A sub- `dict` with the following fields, which sets the limit of the
......
......@@ -3736,13 +3736,24 @@ def FormatPolicyInfo(custom_ipolicy, eff_ipolicy, iscluster):
if iscluster:
eff_ipolicy = custom_ipolicy
custom_minmax = custom_ipolicy.get(constants.ISPECS_MINMAX, {})
ret = [
(key,
FormatParamsDictInfo(custom_minmax.get(key, {}),
eff_ipolicy[constants.ISPECS_MINMAX][key]))
for key in constants.ISPECS_MINMAX_KEYS
]
minmax_out = []
custom_minmax = custom_ipolicy.get(constants.ISPECS_MINMAX)
if custom_minmax:
for (k, minmax) in enumerate(custom_minmax):
minmax_out.append([
("%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:
stdspecs = custom_ipolicy[constants.ISPECS_STD]
ret.append(
......@@ -3787,8 +3798,8 @@ def PrintIPolicyCommand(buf, ipolicy, isgroup):
_PrintSpecsParameters(buf, stdspecs)
minmax = ipolicy.get("minmax")
if minmax:
minspecs = minmax.get("min")
maxspecs = minmax.get("max")
minspecs = minmax[0].get("min")
maxspecs = minmax[0].get("max")
if minspecs and maxspecs:
buf.write(" %s " % IPOLICY_BOUNDS_SPECS_STR)
buf.write("min:")
......@@ -3892,13 +3903,14 @@ def _InitISpecsFromSplitOpts(ipolicy, ispecs_mem_size, ispecs_cpu_count,
for key, val in specs.items(): # {min: .. ,max: .., std: ..}
assert key in ispecs
ispecs[key][name] = val
ipolicy[constants.ISPECS_MINMAX] = {}
minmax_out = {}
for key in constants.ISPECS_MINMAX_KEYS:
if fill_all:
ipolicy[constants.ISPECS_MINMAX][key] = \
minmax_out[key] = \
objects.FillDict(constants.ISPECS_MINMAX_DEFAULTS[key], ispecs[key])
else:
ipolicy[constants.ISPECS_MINMAX][key] = ispecs[key]
minmax_out[key] = ispecs[key]
ipolicy[constants.ISPECS_MINMAX] = [minmax_out]
if fill_all:
ipolicy[constants.ISPECS_STD] = \
objects.FillDict(constants.IPOLICY_DEFAULTS[constants.ISPECS_STD],
......@@ -3953,7 +3965,7 @@ def _InitISpecsFromFullOpts(ipolicy_out, minmax_ispecs, std_ispecs,
msg = "Invalid key in bounds instance specifications: %s" % key
raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
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:
assert not group_ipolicy # This is not an option for gnt-group
ipolicy_out[constants.ISPECS_STD] = _ParseISpec(std_ispecs, "std", False)
......
......@@ -828,7 +828,8 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
if (not value or value == [constants.VALUE_DEFAULT] or
value == constants.VALUE_DEFAULT):
if group_policy:
del ipolicy[key]
if key in ipolicy:
del ipolicy[key]
else:
raise errors.OpPrereqError("Can't unset ipolicy attribute '%s'"
" on the cluster'" % key,
......@@ -843,8 +844,9 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False):
" '%s': '%s', error: %s" %
(key, value, err), errors.ECODE_INVAL)
elif key == constants.ISPECS_MINMAX:
for k in value.keys():
utils.ForceDictType(value[k], constants.ISPECS_PARAMETER_TYPES)
for minmax in value:
for k in minmax.keys():
utils.ForceDictType(minmax[k], constants.ISPECS_PARAMETER_TYPES)
ipolicy[key] = value
elif key == constants.ISPECS_STD:
if group_policy:
......@@ -1276,10 +1278,15 @@ 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, minmax, value)
for (name, qualifier, value) in test_settings))
min_errs = None
for minmax in ipolicy[constants.ISPECS_MINMAX]:
errs = filter(None,
(_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,
......
......@@ -633,7 +633,8 @@ class ConfigWriter:
result.append("%s has invalid instance policy: %s" % (owner, err))
for key, value in ipolicy.items():
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:
_helper(owner, "ipolicy/" + key, value,
constants.ISPECS_PARAMETER_TYPES)
......
......@@ -2215,7 +2215,7 @@ ISPECS_MINMAX_DEFAULTS = {
},
}
IPOLICY_DEFAULTS = {
ISPECS_MINMAX: ISPECS_MINMAX_DEFAULTS,
ISPECS_MINMAX: [ISPECS_MINMAX_DEFAULTS],
ISPECS_STD: {
ISPEC_MEM_SIZE: 128,
ISPEC_CPU_COUNT: 1,
......
......@@ -959,20 +959,24 @@ class InstancePolicy(ConfigObject):
if check_std:
InstancePolicy._CheckIncompleteSpec(stdspec, constants.ISPECS_STD)
minmaxspecs = ipolicy[constants.ISPECS_MINMAX]
missing = constants.ISPECS_MINMAX_KEYS - frozenset(minmaxspecs.keys())
if missing:
msg = "Missing instance specification: %s" % utils.CommaJoin(missing)
raise errors.ConfigurationError(msg)
for (key, spec) in minmaxspecs.items():
InstancePolicy._CheckIncompleteSpec(spec, key)
spec_std_ok = True
for param in constants.ISPECS_PARAMETERS:
par_std_ok = InstancePolicy._CheckISpecParamSyntax(minmaxspecs, stdspec,
param, check_std)
spec_std_ok = spec_std_ok and par_std_ok
if not spec_std_ok:
if not ipolicy[constants.ISPECS_MINMAX]:
raise errors.ConfigurationError("Empty minmax specifications")
std_is_good = False
for minmaxspecs in ipolicy[constants.ISPECS_MINMAX]:
missing = constants.ISPECS_MINMAX_KEYS - frozenset(minmaxspecs.keys())
if missing:
msg = "Missing instance specification: %s" % utils.CommaJoin(missing)
raise errors.ConfigurationError(msg)
for (key, spec) in minmaxspecs.items():
InstancePolicy._CheckIncompleteSpec(spec, key)
spec_std_ok = True
for param in constants.ISPECS_PARAMETERS:
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")
@classmethod
......
......@@ -198,8 +198,10 @@ support all options. Some common options are:
groups, in the following format (separated by ``|``):
- owner (empty if cluster, group name otherwise)
- standard, min, max instance specs, containing the following values
separated by commas:
- standard, min, max instance specs; min and max instance specs are
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
- cpu count
- disk size
......
......@@ -32,12 +32,14 @@ module Ganeti.HTools.Backend.Text
, loadInst
, loadNode
, loadISpec
, loadMultipleMinMaxISpecs
, loadIPolicy
, serializeInstances
, serializeNode
, serializeNodes
, serializeGroup
, serializeISpec
, serializeMultipleMinMaxISpecs
, serializeIPolicy
, serializeCluster
) where
......@@ -117,6 +119,10 @@ serializeInstances :: Node.List -> Instance.List -> String
serializeInstances nl =
unlines . map (serializeInstance nl) . Container.elems
-- | Separator between ISpecs (in MinMaxISpecs).
iSpecsSeparator :: Char
iSpecsSeparator = ';'
-- | Generate a spec data from a given ISpec object.
serializeISpec :: ISpec -> String
serializeISpec ispec =
......@@ -130,15 +136,20 @@ serializeISpec ispec =
serializeDiskTemplates :: [DiskTemplate] -> String
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.
serializeIPolicy :: String -> IPolicy -> String
serializeIPolicy owner ipol =
let IPolicy minmax stdspec dts vcpu_ratio spindle_ratio = ipol
MinMaxISpecs minspec maxspec = minmax
strings = [ owner
, serializeISpec stdspec
, serializeISpec minspec
, serializeISpec maxspec
, serializeMultipleMinMaxISpecs minmax
, serializeDiskTemplates dts
, show vcpu_ratio
, show spindle_ratio
......@@ -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
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.
loadIPolicy :: [String] -> Result (String, IPolicy)
loadIPolicy [owner, stdspec, minspec, maxspec, dtemplates,
loadIPolicy [owner, stdspec, minmaxspecs, dtemplates,
vcpu_ratio, spindle_ratio] = do
xstdspec <- loadISpec (owner ++ "/stdspec") (commaSplit stdspec)
xminspec <- loadISpec (owner ++ "/minspec") (commaSplit minspec)
xmaxspec <- loadISpec (owner ++ "/maxspec") (commaSplit maxspec)
xminmaxspecs <- loadMultipleMinMaxISpecs owner $
sepSplit iSpecsSeparator minmaxspecs
xdts <- mapM diskTemplateFromRaw $ commaSplit dtemplates
xvcpu_ratio <- tryRead (owner ++ "/vcpu_ratio") vcpu_ratio
xspindle_ratio <- tryRead (owner ++ "/spindle_ratio") spindle_ratio
return (owner,
IPolicy (MinMaxISpecs xminspec xmaxspec) xstdspec
IPolicy xminmaxspecs xstdspec
xdts xvcpu_ratio xspindle_ratio)
loadIPolicy s = fail $ "Invalid ipolicy data: '" ++ show s ++ "'"
......
......@@ -279,12 +279,26 @@ instAboveISpec inst ispec
| vcpus inst < T.iSpecCpuCount ispec = Bad T.FailCPU
| 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.
instMatchesPolicy :: Instance -> T.IPolicy -> T.OpResult ()
instMatchesPolicy inst ipol = do
let minmax = T.iPolicyMinMaxISpecs ipol
instAboveISpec inst (T.minMaxISpecsMinSpec minmax)
instBelowISpec inst (T.minMaxISpecsMaxSpec minmax)
instMatchesSpecs inst $ T.iPolicyMinMaxISpecs ipol
if diskTemplate inst `elem` T.iPolicyDiskTemplates ipol
then Ok ()
else Bad T.FailDisk
......
......@@ -446,9 +446,13 @@ main opts args = do
-- Run the tiered allocation
let minmax = iPolicyMinMaxISpecs ipol
let tspec = fromMaybe (rspecFromISpec (minMaxISpecsMaxSpec minmax))
(optTieredSpec opts)
let minmaxes = iPolicyMinMaxISpecs ipol
-- TODO: Go through all min/max specs pairs
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) <-
runAllocation cdata stop_allocation
......
......@@ -169,12 +169,12 @@ $(THH.buildObject "ISpec" "iSpec"
-- | The default minimum ispec.
defMinISpec :: ISpec
defMinISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsMinmaxMinMemorySize
, iSpecCpuCount = C.ipolicyDefaultsMinmaxMinCpuCount
, iSpecDiskSize = C.ipolicyDefaultsMinmaxMinDiskSize
, iSpecDiskCount = C.ipolicyDefaultsMinmaxMinDiskCount
, iSpecNicCount = C.ipolicyDefaultsMinmaxMinNicCount
, iSpecSpindleUse = C.ipolicyDefaultsMinmaxMinSpindleUse
defMinISpec = ISpec { iSpecMemorySize = C.ispecsMinmaxDefaultsMinMemorySize
, iSpecCpuCount = C.ispecsMinmaxDefaultsMinCpuCount
, iSpecDiskSize = C.ispecsMinmaxDefaultsMinDiskSize
, iSpecDiskCount = C.ispecsMinmaxDefaultsMinDiskCount
, iSpecNicCount = C.ispecsMinmaxDefaultsMinNicCount
, iSpecSpindleUse = C.ispecsMinmaxDefaultsMinSpindleUse
}
-- | The default standard ispec.
......@@ -189,12 +189,12 @@ defStdISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsStdMemorySize
-- | The default max ispec.
defMaxISpec :: ISpec
defMaxISpec = ISpec { iSpecMemorySize = C.ipolicyDefaultsMinmaxMaxMemorySize
, iSpecCpuCount = C.ipolicyDefaultsMinmaxMaxCpuCount
, iSpecDiskSize = C.ipolicyDefaultsMinmaxMaxDiskSize
, iSpecDiskCount = C.ipolicyDefaultsMinmaxMaxDiskCount
, iSpecNicCount = C.ipolicyDefaultsMinmaxMaxNicCount
, iSpecSpindleUse = C.ipolicyDefaultsMinmaxMaxSpindleUse
defMaxISpec = ISpec { iSpecMemorySize = C.ispecsMinmaxDefaultsMaxMemorySize
, iSpecCpuCount = C.ispecsMinmaxDefaultsMaxCpuCount
, iSpecDiskSize = C.ispecsMinmaxDefaultsMaxDiskSize
, iSpecDiskCount = C.ispecsMinmaxDefaultsMaxDiskCount
, iSpecNicCount = C.ispecsMinmaxDefaultsMaxNicCount
, iSpecSpindleUse = C.ispecsMinmaxDefaultsMaxSpindleUse
}
-- | Minimum and maximum instance specs type.
......@@ -204,15 +204,15 @@ $(THH.buildObject "MinMaxISpecs" "minMaxISpecs"
])
-- | Defult minimum and maximum instance specs.
defMinMaxISpecs :: MinMaxISpecs
defMinMaxISpecs = MinMaxISpecs { minMaxISpecsMinSpec = defMinISpec
, minMaxISpecsMaxSpec = defMaxISpec
}
defMinMaxISpecs :: [MinMaxISpecs]
defMinMaxISpecs = [MinMaxISpecs { minMaxISpecsMinSpec = defMinISpec
, minMaxISpecsMaxSpec = defMaxISpec
}]
-- | Instance policy type.
$(THH.buildObject "IPolicy" "iPolicy"
[ 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 "DiskTemplates" $
THH.simpleField C.ipolicyDts [t| [DiskTemplate] |]
......
......@@ -512,7 +512,7 @@ $(buildObject "MinMaxISpecs" "mmis"
-- has a special 2-level inheritance mode.
$(buildObject "PartialIPolicy" "ipolicy"
[ optionalField . renameField "MinMaxISpecsP"
$ simpleField C.ispecsMinmax [t| MinMaxISpecs |]
$ simpleField C.ispecsMinmax [t| [MinMaxISpecs] |]
, optionalField . renameField "StdSpecP"
$ simpleField "std" [t| PartialISpecParams |]
, optionalField . renameField "SpindleRatioP"
......@@ -527,7 +527,7 @@ $(buildObject "PartialIPolicy" "ipolicy"
-- has a special 2-level inheritance mode.
$(buildObject "FilledIPolicy" "ipolicy"
[ renameField "MinMaxISpecs"
$ simpleField C.ispecsMinmax [t| MinMaxISpecs |]
$ simpleField C.ispecsMinmax [t| [MinMaxISpecs] |]
, renameField "StdSpec" $ simpleField "std" [t| FilledISpecParams |]
, simpleField "spindle-ratio" [t| Double |]
, simpleField "vcpu-ratio" [t| Double |]
......
......@@ -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
|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
|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
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
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
|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|
|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
|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 @@
"cpu-count": 1,
"spindle-use": 1
},
"minmax": {
"min": {
"nic-count": 1,
"disk-size": 128,
"disk-count": 1,
"memory-size": 128,
"cpu-count": 1,
"spindle-use": 1
},
"max": {
"nic-count": 8,
"disk-size": 1048576,
"disk-count": 16,
"memory-size": 32768,
"cpu-count": 8,
"spindle-use": 8
}
},
"minmax": [
{
"min": {
"nic-count": 1,
"disk-size": 128,
"disk-count": 1,
"memory-size": 128,
"cpu-count": 1,
"spindle-use": 1
},
"max": {
"nic-count": 8,
"disk-size": 1048576,
"disk-count": 16,
"memory-size": 32768,
"cpu-count": 8,
"spindle-use": 8
}
}
],
"vcpu-ratio": 4.0,
"disk-templates": [
"sharedfile",
......@@ -58,22 +60,26 @@
"disk-count": 1,
"spindle-use": 1
},
"min": {
"nic-count": 1,
"disk-size": 1024,
"memory-size": 128,
"cpu-count": 1,
"disk-count": 1,
"spindle-use": 1
},
"max": {
"nic-count": 8,
"disk-size": 1048576,
"memory-size": 32768,
"cpu-count": 8,
"disk-count": 16,
"spindle-use": 8
},
"minmax": [
{
"min": {
"nic-count": 1,
"disk-size": 1024,
"memory-size": 128,
"cpu-count": 1,
"disk-count": 1,
"spindle-use": 1
},
"max": {
"nic-count": 8,
"disk-size": 1048576,
"memory-size": 32768,
"cpu-count": 8,
"disk-count": 16,
"spindle-use": 8
}
}
],
"vcpu-ratio": 4.0,
"disk-templates": [
"sharedfile",
......
......@@ -16,24 +16,26 @@
"disk-templates": [
"file"
],
"minmax" : {
"max": {
"cpu-count": 2,
"disk-count": 8,
"disk-size": 2048,
"memory-size": 12800,
"nic-count": 8,
"spindle-use": 8
},
"min": {
"cpu-count": 1,
"disk-count": 1,
"disk-size": 1024,
"memory-size": 128,
"nic-count": 1,
"spindle-use": 1
"minmax" : [
{
"max": {
"cpu-count": 2,
"disk-count": 8,
"disk-size": 2048,
"memory-size": 12800,
"nic-count": 8,
"spindle-use": 8
},
"min": {
"cpu-count": 1,
"disk-count": 1,
"disk-size": 1024,
"memory-size": 128,
"nic-count": 1,
"spindle-use": 1
}
}
},
],
"spindle-ratio": 32.0,
"std": {
"cpu-count": 1,
......
......@@ -16,24 +16,26 @@
"disk-templates": [
"file"
],
"minmax": {
"max": {
"cpu-count": 2,
"disk-count": 8,
"disk-size": 2048,
"memory-size": 12800,
"nic-count": 8,
"spindle-use": 8
},
"min": {
"cpu-count": 1,
"disk-count": 1,
"disk-size": 1024,
"memory-size": 128,
"nic-count": 1,
"spindle-use": 1
"minmax": [
{
"max": {
"cpu-count": 2,
"disk-count": 8,
"disk-size": 2048,
"memory-size": 12800,
"nic-count": 8,
"spindle-use": 8
},
"min": {
"cpu-count": 1,
"disk-count": 1,
"disk-size": 1024,
"memory-size": 128,
"nic-count": 1,
"spindle-use": 1
}
}
},
],
"spindle-ratio": 32.0,
"std": {