diff --git a/lib/client/gnt_cluster.py b/lib/client/gnt_cluster.py index 1fc0cf8e8a23713170f79f38bed67b0055ef37aa..cbaea0d444e795e2c66ddef2799f8d1b84899025 100644 --- a/lib/client/gnt_cluster.py +++ b/lib/client/gnt_cluster.py @@ -468,6 +468,8 @@ def ShowClusterConfig(opts, args): _PrintGroupedParams(result["ipolicy"][key], roman=opts.roman_integers) ToStdout(" - enabled disk templates: %s", utils.CommaJoin(result["ipolicy"][constants.IPOLICY_DTS])) + for key in constants.IPOLICY_PARAMETERS: + ToStdout(" - %s: %s", key, result["ipolicy"][key]) return 0 diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 46bf7eeca6ab24acbb9d0aa942f16c64246c4643..7e00bf880ea2344e7e874a17ef2ad1786b1840f7 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -740,8 +740,6 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False): use_none=use_none, use_default=use_default) else: - # FIXME: we assume all others are lists; this should be redone - # in a nicer way if not value or value == [constants.VALUE_DEFAULT]: if group_policy: del ipolicy[key] @@ -750,7 +748,18 @@ def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False): " on the cluster'" % key, errors.ECODE_INVAL) else: - ipolicy[key] = list(value) + if key in constants.IPOLICY_PARAMETERS: + # FIXME: we assume all such values are float + try: + ipolicy[key] = float(value) + except (TypeError, ValueError), err: + raise errors.OpPrereqError("Invalid value for attribute" + " '%s': '%s', error: %s" % + (key, value, err), errors.ECODE_INVAL) + else: + # FIXME: we assume all others are lists; this should be redone + # in a nicer way + ipolicy[key] = list(value) try: objects.InstancePolicy.CheckParameterSyntax(ipolicy) except errors.ConfigurationError, err: diff --git a/lib/config.py b/lib/config.py index a4f864d82dc15f4b9611b09854eb86b0fdad1844..abf379d4f225c5593a9be9f700906627e3358caa 100644 --- a/lib/config.py +++ b/lib/config.py @@ -439,10 +439,14 @@ class ConfigWriter: _helper(owner, fullkey, value, constants.ISPECS_PARAMETER_TYPES) else: # FIXME: assuming list type - if not isinstance(value, list): + if key in constants.IPOLICY_PARAMETERS: + exp_type = float + else: + exp_type = list + if not isinstance(value, exp_type): result.append("%s has invalid instance policy: for %s," - " expecting list, got %s" % - (owner, key, type(value))) + " expecting %s, got %s" % + (owner, key, exp_type.__name__, type(value))) # check cluster parameters _helper("cluster", "beparams", cluster.SimpleFillBE({}), diff --git a/lib/constants.py b/lib/constants.py index b2cdfec35a0089ac9eb91f2139741aea0437399b..dcece0b4593ae150a205164f40c36f1167e1e434 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -950,13 +950,21 @@ ISPECS_MIN = "min" ISPECS_MAX = "max" ISPECS_STD = "std" IPOLICY_DTS = "disk_templates" +IPOLICY_VCPU_RATIO = "vcpu_ratio" IPOLICY_ISPECS = frozenset([ ISPECS_MIN, ISPECS_MAX, ISPECS_STD, ]) -IPOLICY_ALL_KEYS = IPOLICY_ISPECS.union([IPOLICY_DTS]) + +IPOLICY_PARAMETERS = frozenset([ + IPOLICY_VCPU_RATIO, + ]) + +IPOLICY_ALL_KEYS = (IPOLICY_ISPECS | + IPOLICY_PARAMETERS | + frozenset([IPOLICY_DTS])) # Node parameter names ND_OOB_PROGRAM = "oob_program" @@ -1907,6 +1915,7 @@ IPOLICY_DEFAULTS = { ISPEC_NIC_COUNT: 1, }, IPOLICY_DTS: DISK_TEMPLATES, + IPOLICY_VCPU_RATIO: 4.0, } MASTER_POOL_SIZE_DEFAULT = 10 diff --git a/lib/objects.py b/lib/objects.py index ff921d619e3aa71302a804d29f2f47032fd6be99..cfd723b818512f5b40c90bc83c5428af3673f11a 100644 --- a/lib/objects.py +++ b/lib/objects.py @@ -105,6 +105,9 @@ def FillIPolicy(default_ipolicy, custom_ipolicy, skip_keys=None): # list items for key in [constants.IPOLICY_DTS]: ret_dict[key] = list(custom_ipolicy.get(key, default_ipolicy[key])) + # other items which we know we can directly copy (immutables) + for key in constants.IPOLICY_PARAMETERS: + ret_dict[key] = custom_ipolicy.get(key, default_ipolicy[key]) return ret_dict @@ -908,6 +911,9 @@ class InstancePolicy(ConfigObject): InstancePolicy.CheckISpecSyntax(ipolicy, param) if constants.IPOLICY_DTS in ipolicy: InstancePolicy.CheckDiskTemplates(ipolicy[constants.IPOLICY_DTS]) + for key in constants.IPOLICY_PARAMETERS: + if key in ipolicy: + InstancePolicy.CheckParameter(key, ipolicy[key]) wrong_keys = frozenset(ipolicy.keys()) - constants.IPOLICY_ALL_KEYS if wrong_keys: raise errors.ConfigurationError("Invalid keys in ipolicy: %s" % @@ -948,6 +954,19 @@ class InstancePolicy(ConfigObject): raise errors.ConfigurationError("Invalid disk template(s) %s" % utils.CommaJoin(wrong)) + @classmethod + def CheckParameter(cls, key, value): + """Checks a parameter. + + Currently we expect all parameters to be float values. + + """ + try: + float(value) + except (TypeError, ValueError), err: + raise errors.ConfigurationError("Invalid value for key" " '%s':" + " '%s', error: %s" % (key, value, err)) + class Instance(TaggableObject): """Config object representing an instance."""