Revision 0f511c8a
b/lib/cli.py | ||
---|---|---|
3731 | 3731 |
if iscluster: |
3732 | 3732 |
eff_ipolicy = custom_ipolicy |
3733 | 3733 |
|
3734 |
custom_minmax = custom_ipolicy.get(constants.ISPECS_MINMAX) |
|
3734 |
custom_minmax = custom_ipolicy.get(constants.ISPECS_MINMAX, {})
|
|
3735 | 3735 |
ret = [ |
3736 | 3736 |
(key, |
3737 | 3737 |
FormatParamsDictInfo(custom_minmax.get(key, {}), |
b/lib/cmdlib.py | ||
---|---|---|
813 | 813 |
return params_copy |
814 | 814 |
|
815 | 815 |
|
816 |
def _UpdateMinMaxISpecs(ipolicy, new_minmax, group_policy): |
|
817 |
use_none = use_default = group_policy |
|
818 |
minmax = ipolicy.setdefault(constants.ISPECS_MINMAX, {}) |
|
819 |
for (key, value) in new_minmax.items(): |
|
820 |
if key not in constants.ISPECS_MINMAX_KEYS: |
|
821 |
raise errors.OpPrereqError("Invalid key in new ipolicy/%s: %s" % |
|
822 |
(constants.ISPECS_MINMAX, key), |
|
823 |
errors.ECODE_INVAL) |
|
824 |
old_spec = minmax.get(key, {}) |
|
825 |
minmax[key] = _GetUpdatedParams(old_spec, value, use_none=use_none, |
|
826 |
use_default=use_default) |
|
827 |
utils.ForceDictType(minmax[key], constants.ISPECS_PARAMETER_TYPES) |
|
828 |
|
|
829 |
|
|
830 | 816 |
def _GetUpdatedIPolicy(old_ipolicy, new_ipolicy, group_policy=False): |
831 | 817 |
"""Return the new version of an instance policy. |
832 | 818 |
|
... | ... | |
834 | 820 |
we should support removal of policy entries |
835 | 821 |
|
836 | 822 |
""" |
837 |
use_none = use_default = group_policy |
|
838 | 823 |
ipolicy = copy.deepcopy(old_ipolicy) |
839 | 824 |
for key, value in new_ipolicy.items(): |
840 | 825 |
if key not in constants.IPOLICY_ALL_KEYS: |
841 | 826 |
raise errors.OpPrereqError("Invalid key in new ipolicy: %s" % key, |
842 | 827 |
errors.ECODE_INVAL) |
843 |
if key == constants.ISPECS_MINMAX: |
|
844 |
_UpdateMinMaxISpecs(ipolicy, value, group_policy) |
|
845 |
elif key == constants.ISPECS_STD: |
|
846 |
ipolicy[key] = _GetUpdatedParams(old_ipolicy.get(key, {}), value, |
|
847 |
use_none=use_none, |
|
848 |
use_default=use_default) |
|
849 |
utils.ForceDictType(ipolicy[key], constants.ISPECS_PARAMETER_TYPES) |
|
828 |
if (not value or value == [constants.VALUE_DEFAULT] or |
|
829 |
value == constants.VALUE_DEFAULT): |
|
830 |
if group_policy: |
|
831 |
del ipolicy[key] |
|
832 |
else: |
|
833 |
raise errors.OpPrereqError("Can't unset ipolicy attribute '%s'" |
|
834 |
" on the cluster'" % key, |
|
835 |
errors.ECODE_INVAL) |
|
850 | 836 |
else: |
851 |
if (not value or value == [constants.VALUE_DEFAULT] or |
|
852 |
value == constants.VALUE_DEFAULT): |
|
837 |
if key in constants.IPOLICY_PARAMETERS: |
|
838 |
# FIXME: we assume all such values are float |
|
839 |
try: |
|
840 |
ipolicy[key] = float(value) |
|
841 |
except (TypeError, ValueError), err: |
|
842 |
raise errors.OpPrereqError("Invalid value for attribute" |
|
843 |
" '%s': '%s', error: %s" % |
|
844 |
(key, value, err), errors.ECODE_INVAL) |
|
845 |
elif key == constants.ISPECS_MINMAX: |
|
846 |
for k in value.keys(): |
|
847 |
utils.ForceDictType(value[k], constants.ISPECS_PARAMETER_TYPES) |
|
848 |
ipolicy[key] = value |
|
849 |
elif key == constants.ISPECS_STD: |
|
853 | 850 |
if group_policy: |
854 |
del ipolicy[key]
|
|
855 |
else:
|
|
856 |
raise errors.OpPrereqError("Can't unset ipolicy attribute '%s'"
|
|
857 |
" on the cluster'" % key,
|
|
858 |
errors.ECODE_INVAL)
|
|
851 |
msg = "%s cannot appear in group instance specs" % key
|
|
852 |
raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
|
|
853 |
ipolicy[key] = _GetUpdatedParams(old_ipolicy.get(key, {}), value,
|
|
854 |
use_none=False, use_default=False)
|
|
855 |
utils.ForceDictType(ipolicy[key], constants.ISPECS_PARAMETER_TYPES)
|
|
859 | 856 |
else: |
860 |
if key in constants.IPOLICY_PARAMETERS: |
|
861 |
# FIXME: we assume all such values are float |
|
862 |
try: |
|
863 |
ipolicy[key] = float(value) |
|
864 |
except (TypeError, ValueError), err: |
|
865 |
raise errors.OpPrereqError("Invalid value for attribute" |
|
866 |
" '%s': '%s', error: %s" % |
|
867 |
(key, value, err), errors.ECODE_INVAL) |
|
868 |
else: |
|
869 |
# FIXME: we assume all others are lists; this should be redone |
|
870 |
# in a nicer way |
|
871 |
ipolicy[key] = list(value) |
|
857 |
# FIXME: we assume all others are lists; this should be redone |
|
858 |
# in a nicer way |
|
859 |
ipolicy[key] = list(value) |
|
872 | 860 |
try: |
873 | 861 |
objects.InstancePolicy.CheckParameterSyntax(ipolicy, not group_policy) |
874 | 862 |
except errors.ConfigurationError, err: |
b/lib/objects.py | ||
---|---|---|
82 | 82 |
return ret_dict |
83 | 83 |
|
84 | 84 |
|
85 |
def _FillMinMaxISpecs(default_specs, custom_specs): |
|
86 |
assert frozenset(default_specs.keys()) == constants.ISPECS_MINMAX_KEYS |
|
87 |
ret_specs = {} |
|
88 |
for key in constants.ISPECS_MINMAX_KEYS: |
|
89 |
ret_specs[key] = FillDict(default_specs[key], |
|
90 |
custom_specs.get(key, {})) |
|
91 |
return ret_specs |
|
92 |
|
|
93 |
|
|
94 | 85 |
def FillIPolicy(default_ipolicy, custom_ipolicy): |
95 | 86 |
"""Fills an instance policy with defaults. |
96 | 87 |
|
97 | 88 |
""" |
98 | 89 |
assert frozenset(default_ipolicy.keys()) == constants.IPOLICY_ALL_KEYS |
99 |
ret_dict = {} |
|
100 |
# Instance specs |
|
101 |
new_mm = _FillMinMaxISpecs(default_ipolicy[constants.ISPECS_MINMAX], |
|
102 |
custom_ipolicy.get(constants.ISPECS_MINMAX, {})) |
|
103 |
ret_dict[constants.ISPECS_MINMAX] = new_mm |
|
104 |
new_std = FillDict(default_ipolicy[constants.ISPECS_STD], |
|
105 |
custom_ipolicy.get(constants.ISPECS_STD, {})) |
|
106 |
ret_dict[constants.ISPECS_STD] = new_std |
|
107 |
# list items |
|
108 |
for key in [constants.IPOLICY_DTS]: |
|
109 |
ret_dict[key] = list(custom_ipolicy.get(key, default_ipolicy[key])) |
|
110 |
# other items which we know we can directly copy (immutables) |
|
111 |
for key in constants.IPOLICY_PARAMETERS: |
|
112 |
ret_dict[key] = custom_ipolicy.get(key, default_ipolicy[key]) |
|
113 |
|
|
90 |
ret_dict = copy.deepcopy(custom_ipolicy) |
|
91 |
for key in default_ipolicy: |
|
92 |
if key not in ret_dict: |
|
93 |
ret_dict[key] = copy.deepcopy(default_ipolicy[key]) |
|
94 |
elif key == constants.ISPECS_STD: |
|
95 |
ret_dict[key] = FillDict(default_ipolicy[key], ret_dict[key]) |
|
114 | 96 |
return ret_dict |
115 | 97 |
|
116 | 98 |
|
... | ... | |
198 | 180 |
"""Create empty IPolicy dictionary. |
199 | 181 |
|
200 | 182 |
""" |
201 |
return { |
|
202 |
constants.ISPECS_MINMAX: { |
|
203 |
constants.ISPECS_MIN: {}, |
|
204 |
constants.ISPECS_MAX: {}, |
|
205 |
}, |
|
206 |
constants.ISPECS_STD: {}, |
|
207 |
} |
|
183 |
return {} |
|
208 | 184 |
|
209 | 185 |
|
210 | 186 |
class ConfigObject(outils.ValidatedSlots): |
... | ... | |
954 | 930 |
utils.CommaJoin(wrong_keys)) |
955 | 931 |
|
956 | 932 |
@classmethod |
933 |
def _CheckIncompleteSpec(cls, spec, keyname): |
|
934 |
missing_params = constants.ISPECS_PARAMETERS - frozenset(spec.keys()) |
|
935 |
if missing_params: |
|
936 |
msg = ("Missing instance specs parameters for %s: %s" % |
|
937 |
(keyname, utils.CommaJoin(missing_params))) |
|
938 |
raise errors.ConfigurationError(msg) |
|
939 |
|
|
940 |
@classmethod |
|
957 | 941 |
def CheckISpecSyntax(cls, ipolicy, check_std): |
958 | 942 |
"""Check the instance policy specs for validity. |
959 | 943 |
|
... | ... | |
977 | 961 |
if missing: |
978 | 962 |
msg = "Missing instance specification: %s" % utils.CommaJoin(missing) |
979 | 963 |
raise errors.ConfigurationError(msg) |
964 |
for (key, spec) in minmaxspecs.items(): |
|
965 |
InstancePolicy._CheckIncompleteSpec(spec, key) |
|
966 |
if check_std: |
|
967 |
InstancePolicy._CheckIncompleteSpec(stdspec, constants.ISPECS_STD) |
|
980 | 968 |
for param in constants.ISPECS_PARAMETERS: |
981 | 969 |
InstancePolicy._CheckISpecParamSyntax(minmaxspecs, stdspec, param, |
982 | 970 |
check_std) |
... | ... | |
1002 | 990 |
""" |
1003 | 991 |
minspec = minmaxspecs[constants.ISPECS_MIN] |
1004 | 992 |
maxspec = minmaxspecs[constants.ISPECS_MAX] |
1005 |
min_v = minspec.get(name, 0)
|
|
993 |
min_v = minspec[name]
|
|
1006 | 994 |
|
1007 | 995 |
if check_std: |
1008 | 996 |
std_v = stdspec.get(name, min_v) |
... | ... | |
1011 | 999 |
std_v = min_v |
1012 | 1000 |
std_msg = "-" |
1013 | 1001 |
|
1014 |
max_v = maxspec.get(name, std_v)
|
|
1002 |
max_v = maxspec[name]
|
|
1015 | 1003 |
if min_v > std_v or std_v > max_v: |
1016 | 1004 |
err = ("Invalid specification of min/max/std values for %s: %s/%s/%s" % |
1017 |
(name, |
|
1018 |
minspec.get(name, "-"), |
|
1019 |
maxspec.get(name, "-"), |
|
1020 |
std_msg)) |
|
1005 |
(name, min_v, max_v, std_msg)) |
|
1021 | 1006 |
raise errors.ConfigurationError(err) |
1022 | 1007 |
|
1023 | 1008 |
@classmethod |
b/src/Ganeti/Objects.hs | ||
---|---|---|
66 | 66 |
, PartialISpecParams(..) |
67 | 67 |
, fillISpecParams |
68 | 68 |
, allISpecParamFields |
69 |
, FilledMinMaxISpecs(..) |
|
70 |
, PartialMinMaxISpecs(..) |
|
71 |
, fillMinMaxISpecs |
|
69 |
, MinMaxISpecs(..) |
|
72 | 70 |
, FilledIPolicy(..) |
73 | 71 |
, PartialIPolicy(..) |
74 | 72 |
, fillIPolicy |
... | ... | |
505 | 503 |
, simpleField C.ispecSpindleUse [t| Int |] |
506 | 504 |
]) |
507 | 505 |
|
508 |
-- | Partial min-max instance specs. These is not built via buildParam since |
|
509 |
-- it has a special 2-level inheritance mode. |
|
510 |
$(buildObject "PartialMinMaxISpecs" "mmis" |
|
511 |
[ renameField "MinSpecP" $ simpleField "min" [t| PartialISpecParams |] |
|
512 |
, renameField "MaxSpecP" $ simpleField "max" [t| PartialISpecParams |] |
|
513 |
]) |
|
514 |
|
|
515 |
-- | Filled min-max instance specs. This is not built via buildParam since |
|
516 |
-- it has a special 2-level inheritance mode. |
|
517 |
$(buildObject "FilledMinMaxISpecs" "mmis" |
|
506 |
$(buildObject "MinMaxISpecs" "mmis" |
|
518 | 507 |
[ renameField "MinSpec" $ simpleField "min" [t| FilledISpecParams |] |
519 | 508 |
, renameField "MaxSpec" $ simpleField "max" [t| FilledISpecParams |] |
520 | 509 |
]) |
... | ... | |
523 | 512 |
-- has a special 2-level inheritance mode. |
524 | 513 |
$(buildObject "PartialIPolicy" "ipolicy" |
525 | 514 |
[ optionalField . renameField "MinMaxISpecsP" |
526 |
$ simpleField C.ispecsMinmax [t| PartialMinMaxISpecs |] |
|
527 |
, renameField "StdSpecP" $ simpleField "std" [t| PartialISpecParams |] |
|
515 |
$ simpleField C.ispecsMinmax [t| MinMaxISpecs |] |
|
516 |
, optionalField . renameField "StdSpecP" |
|
517 |
$ simpleField "std" [t| PartialISpecParams |] |
|
528 | 518 |
, optionalField . renameField "SpindleRatioP" |
529 | 519 |
$ simpleField "spindle-ratio" [t| Double |] |
530 | 520 |
, optionalField . renameField "VcpuRatioP" |
... | ... | |
537 | 527 |
-- has a special 2-level inheritance mode. |
538 | 528 |
$(buildObject "FilledIPolicy" "ipolicy" |
539 | 529 |
[ renameField "MinMaxISpecs" |
540 |
$ simpleField C.ispecsMinmax [t| FilledMinMaxISpecs |]
|
|
530 |
$ simpleField C.ispecsMinmax [t| MinMaxISpecs |] |
|
541 | 531 |
, renameField "StdSpec" $ simpleField "std" [t| FilledISpecParams |] |
542 | 532 |
, simpleField "spindle-ratio" [t| Double |] |
543 | 533 |
, simpleField "vcpu-ratio" [t| Double |] |
544 | 534 |
, simpleField "disk-templates" [t| [DiskTemplate] |] |
545 | 535 |
]) |
546 | 536 |
|
547 |
-- | Custom filler for the min-max instance specs. |
|
548 |
fillMinMaxISpecs :: FilledMinMaxISpecs -> Maybe PartialMinMaxISpecs -> |
|
549 |
FilledMinMaxISpecs |
|
550 |
fillMinMaxISpecs fminmax Nothing = fminmax |
|
551 |
fillMinMaxISpecs (FilledMinMaxISpecs { mmisMinSpec = fmin |
|
552 |
, mmisMaxSpec = fmax }) |
|
553 |
(Just PartialMinMaxISpecs { mmisMinSpecP = pmin |
|
554 |
, mmisMaxSpecP = pmax }) = |
|
555 |
FilledMinMaxISpecs { mmisMinSpec = fillISpecParams fmin pmin |
|
556 |
, mmisMaxSpec = fillISpecParams fmax pmax } |
|
557 |
|
|
558 | 537 |
-- | Custom filler for the ipolicy types. |
559 | 538 |
fillIPolicy :: FilledIPolicy -> PartialIPolicy -> FilledIPolicy |
560 | 539 |
fillIPolicy (FilledIPolicy { ipolicyMinMaxISpecs = fminmax |
... | ... | |
567 | 546 |
, ipolicySpindleRatioP = pspindleRatio |
568 | 547 |
, ipolicyVcpuRatioP = pvcpuRatio |
569 | 548 |
, ipolicyDiskTemplatesP = pdiskTemplates}) = |
570 |
FilledIPolicy { ipolicyMinMaxISpecs = fillMinMaxISpecs fminmax pminmax |
|
571 |
, ipolicyStdSpec = fillISpecParams fstd pstd |
|
549 |
FilledIPolicy { ipolicyMinMaxISpecs = fromMaybe fminmax pminmax |
|
550 |
, ipolicyStdSpec = case pstd of |
|
551 |
Nothing -> fstd |
|
552 |
Just p -> fillISpecParams fstd p |
|
572 | 553 |
, ipolicySpindleRatio = fromMaybe fspindleRatio pspindleRatio |
573 | 554 |
, ipolicyVcpuRatio = fromMaybe fvcpuRatio pvcpuRatio |
574 | 555 |
, ipolicyDiskTemplates = fromMaybe fdiskTemplates |
b/test/hs/Test/Ganeti/Objects.hs | ||
---|---|---|
143 | 143 |
-- | FIXME: This generates completely random data, without normal |
144 | 144 |
-- validation rules. |
145 | 145 |
$(genArbitrary ''PartialISpecParams) |
146 |
$(genArbitrary ''PartialMinMaxISpecs) |
|
147 | 146 |
|
148 | 147 |
-- | FIXME: This generates completely random data, without normal |
149 | 148 |
-- validation rules. |
150 | 149 |
$(genArbitrary ''PartialIPolicy) |
151 | 150 |
|
152 | 151 |
$(genArbitrary ''FilledISpecParams) |
153 |
$(genArbitrary ''FilledMinMaxISpecs)
|
|
152 |
$(genArbitrary ''MinMaxISpecs) |
|
154 | 153 |
$(genArbitrary ''FilledIPolicy) |
155 | 154 |
$(genArbitrary ''IpFamily) |
156 | 155 |
$(genArbitrary ''FilledNDParams) |
b/test/py/ganeti.cmdlib_unittest.py | ||
---|---|---|
1733 | 1733 |
"""Tests for cmdlib._GetUpdatedIPolicy()""" |
1734 | 1734 |
_OLD_CLUSTER_POLICY = { |
1735 | 1735 |
constants.IPOLICY_VCPU_RATIO: 1.5, |
1736 |
constants.ISPECS_MINMAX: { |
|
1737 |
constants.ISPECS_MIN: { |
|
1738 |
constants.ISPEC_MEM_SIZE: 20, |
|
1739 |
constants.ISPEC_CPU_COUNT: 2, |
|
1740 |
}, |
|
1741 |
constants.ISPECS_MAX: {}, |
|
1742 |
}, |
|
1743 |
constants.ISPECS_STD: {}, |
|
1736 |
constants.ISPECS_MINMAX: constants.ISPECS_MINMAX_DEFAULTS, |
|
1737 |
constants.ISPECS_STD: constants.IPOLICY_DEFAULTS[constants.ISPECS_STD], |
|
1744 | 1738 |
} |
1745 | 1739 |
_OLD_GROUP_POLICY = { |
1746 | 1740 |
constants.IPOLICY_SPINDLE_RATIO: 2.5, |
1747 | 1741 |
constants.ISPECS_MINMAX: { |
1748 | 1742 |
constants.ISPECS_MIN: { |
1749 |
constants.ISPEC_DISK_SIZE: 20, |
|
1750 |
constants.ISPEC_NIC_COUNT: 2, |
|
1743 |
constants.ISPEC_MEM_SIZE: 128, |
|
1744 |
constants.ISPEC_CPU_COUNT: 1, |
|
1745 |
constants.ISPEC_DISK_COUNT: 1, |
|
1746 |
constants.ISPEC_DISK_SIZE: 1024, |
|
1747 |
constants.ISPEC_NIC_COUNT: 1, |
|
1748 |
constants.ISPEC_SPINDLE_USE: 1, |
|
1749 |
}, |
|
1750 |
constants.ISPECS_MAX: { |
|
1751 |
constants.ISPEC_MEM_SIZE: 32768, |
|
1752 |
constants.ISPEC_CPU_COUNT: 8, |
|
1753 |
constants.ISPEC_DISK_COUNT: 5, |
|
1754 |
constants.ISPEC_DISK_SIZE: 1024 * 1024, |
|
1755 |
constants.ISPEC_NIC_COUNT: 3, |
|
1756 |
constants.ISPEC_SPINDLE_USE: 12, |
|
1751 | 1757 |
}, |
1752 |
constants.ISPECS_MAX: {}, |
|
1753 | 1758 |
}, |
1754 | 1759 |
} |
1755 | 1760 |
|
1756 | 1761 |
def _TestSetSpecs(self, old_policy, isgroup): |
1757 |
ispec_key = constants.ISPECS_MIN |
|
1758 |
diff_ispec = { |
|
1759 |
constants.ISPEC_MEM_SIZE: 50, |
|
1760 |
constants.ISPEC_DISK_SIZE: 30, |
|
1762 |
diff_minmax = { |
|
1763 |
constants.ISPECS_MIN: { |
|
1764 |
constants.ISPEC_MEM_SIZE: 64, |
|
1765 |
constants.ISPEC_CPU_COUNT: 1, |
|
1766 |
constants.ISPEC_DISK_COUNT: 2, |
|
1767 |
constants.ISPEC_DISK_SIZE: 64, |
|
1768 |
constants.ISPEC_NIC_COUNT: 1, |
|
1769 |
constants.ISPEC_SPINDLE_USE: 1, |
|
1770 |
}, |
|
1771 |
constants.ISPECS_MAX: { |
|
1772 |
constants.ISPEC_MEM_SIZE: 16384, |
|
1773 |
constants.ISPEC_CPU_COUNT: 10, |
|
1774 |
constants.ISPEC_DISK_COUNT: 12, |
|
1775 |
constants.ISPEC_DISK_SIZE: 1024, |
|
1776 |
constants.ISPEC_NIC_COUNT: 9, |
|
1777 |
constants.ISPEC_SPINDLE_USE: 18, |
|
1778 |
}, |
|
1761 | 1779 |
} |
1780 |
diff_std = { |
|
1781 |
constants.ISPEC_DISK_COUNT: 10, |
|
1782 |
constants.ISPEC_DISK_SIZE: 512, |
|
1783 |
} |
|
1762 | 1784 |
diff_policy = { |
1763 |
constants.ISPECS_MINMAX: { |
|
1764 |
ispec_key: diff_ispec, |
|
1765 |
}, |
|
1785 |
constants.ISPECS_MINMAX: diff_minmax |
|
1766 | 1786 |
} |
1767 | 1787 |
if not isgroup: |
1768 |
diff_std = { |
|
1769 |
constants.ISPEC_CPU_COUNT: 3, |
|
1770 |
constants.ISPEC_DISK_COUNT: 3, |
|
1771 |
} |
|
1772 | 1788 |
diff_policy[constants.ISPECS_STD] = diff_std |
1773 | 1789 |
new_policy = cmdlib._GetUpdatedIPolicy(old_policy, diff_policy, |
1774 | 1790 |
group_policy=isgroup) |
1775 | 1791 |
|
1776 | 1792 |
self.assertTrue(constants.ISPECS_MINMAX in new_policy) |
1777 |
new_ispec = new_policy[constants.ISPECS_MINMAX][ispec_key] |
|
1778 |
for key in diff_ispec: |
|
1779 |
self.assertTrue(key in new_ispec) |
|
1780 |
self.assertEqual(new_ispec[key], diff_ispec[key]) |
|
1793 |
self.assertEqual(new_policy[constants.ISPECS_MINMAX], diff_minmax) |
|
1781 | 1794 |
for key in old_policy: |
1782 | 1795 |
if not key in diff_policy: |
1783 | 1796 |
self.assertTrue(key in new_policy) |
1784 | 1797 |
self.assertEqual(new_policy[key], old_policy[key]) |
1785 | 1798 |
|
1786 |
if constants.ISPECS_MINMAX in old_policy: |
|
1787 |
old_minmax = old_policy[constants.ISPECS_MINMAX] |
|
1788 |
for key in old_minmax: |
|
1789 |
if key != ispec_key: |
|
1790 |
self.assertTrue(key in new_policy[constants.ISPECS_MINMAX]) |
|
1791 |
self.assertEqual(new_policy[constants.ISPECS_MINMAX][key], |
|
1792 |
old_minmax[key]) |
|
1793 |
old_ispec = old_policy[constants.ISPECS_MINMAX][ispec_key] |
|
1794 |
for key in old_ispec: |
|
1795 |
if not key in diff_ispec: |
|
1796 |
self.assertTrue(key in new_ispec) |
|
1797 |
self.assertEqual(new_ispec[key], old_ispec[key]) |
|
1798 |
|
|
1799 | 1799 |
if not isgroup: |
1800 | 1800 |
new_std = new_policy[constants.ISPECS_STD] |
1801 | 1801 |
for key in diff_std: |
1802 | 1802 |
self.assertTrue(key in new_std) |
1803 | 1803 |
self.assertEqual(new_std[key], diff_std[key]) |
1804 |
old_std = old_policy.get(constants.ISPECS_STD, {}) |
|
1805 |
for key in old_std: |
|
1806 |
self.assertTrue(key in new_std) |
|
1807 |
if key not in diff_std: |
|
1808 |
self.assertEqual(new_std[key], old_std[key]) |
|
1804 | 1809 |
|
1805 |
|
|
1806 |
def _TestSet(self, old_policy, isgroup): |
|
1807 |
diff_policy = { |
|
1808 |
constants.IPOLICY_VCPU_RATIO: 3, |
|
1809 |
constants.IPOLICY_SPINDLE_RATIO: 1.9, |
|
1810 |
} |
|
1810 |
def _TestSet(self, old_policy, diff_policy, isgroup): |
|
1811 | 1811 |
new_policy = cmdlib._GetUpdatedIPolicy(old_policy, diff_policy, |
1812 | 1812 |
group_policy=isgroup) |
1813 | 1813 |
for key in diff_policy: |
... | ... | |
1819 | 1819 |
self.assertEqual(new_policy[key], old_policy[key]) |
1820 | 1820 |
|
1821 | 1821 |
def testSet(self): |
1822 |
self._TestSet(self._OLD_GROUP_POLICY, True) |
|
1822 |
diff_policy = { |
|
1823 |
constants.IPOLICY_VCPU_RATIO: 3, |
|
1824 |
constants.IPOLICY_DTS: [constants.DT_FILE], |
|
1825 |
} |
|
1826 |
self._TestSet(self._OLD_GROUP_POLICY, diff_policy, True) |
|
1823 | 1827 |
self._TestSetSpecs(self._OLD_GROUP_POLICY, True) |
1824 |
self._TestSet(self._OLD_CLUSTER_POLICY, False) |
|
1828 |
self._TestSet({}, diff_policy, True) |
|
1829 |
self._TestSetSpecs({}, True) |
|
1830 |
self._TestSet(self._OLD_CLUSTER_POLICY, diff_policy, False) |
|
1825 | 1831 |
self._TestSetSpecs(self._OLD_CLUSTER_POLICY, False) |
1826 | 1832 |
|
1827 | 1833 |
def testUnset(self): |
... | ... | |
1838 | 1844 |
self.assertTrue(key in new_policy) |
1839 | 1845 |
self.assertEqual(new_policy[key], old_policy[key]) |
1840 | 1846 |
|
1847 |
self.assertRaises(errors.OpPrereqError, cmdlib._GetUpdatedIPolicy, |
|
1848 |
old_policy, diff_policy, group_policy=False) |
|
1849 |
|
|
1841 | 1850 |
def _TestInvalidKeys(self, old_policy, isgroup): |
1851 |
INVALID_KEY = "this_key_shouldnt_be_allowed" |
|
1842 | 1852 |
INVALID_DICT = { |
1843 |
"this_key_shouldnt_be_allowed": 3,
|
|
1853 |
INVALID_KEY: 3,
|
|
1844 | 1854 |
} |
1845 | 1855 |
invalid_policy = INVALID_DICT |
1846 | 1856 |
self.assertRaises(errors.OpPrereqError, cmdlib._GetUpdatedIPolicy, |
... | ... | |
1848 | 1858 |
invalid_ispecs = { |
1849 | 1859 |
constants.ISPECS_MINMAX: INVALID_DICT, |
1850 | 1860 |
} |
1851 |
self.assertRaises(errors.OpPrereqError, cmdlib._GetUpdatedIPolicy,
|
|
1861 |
self.assertRaises(errors.TypeEnforcementError, cmdlib._GetUpdatedIPolicy,
|
|
1852 | 1862 |
old_policy, invalid_ispecs, group_policy=isgroup) |
1853 |
for key in constants.ISPECS_MINMAX_KEYS: |
|
1854 |
invalid_ispec = { |
|
1855 |
constants.ISPECS_MINMAX: { |
|
1856 |
key: INVALID_DICT, |
|
1857 |
}, |
|
1863 |
if isgroup: |
|
1864 |
invalid_for_group = { |
|
1865 |
constants.ISPECS_STD: constants.IPOLICY_DEFAULTS[constants.ISPECS_STD], |
|
1858 | 1866 |
} |
1867 |
self.assertRaises(errors.OpPrereqError, cmdlib._GetUpdatedIPolicy, |
|
1868 |
old_policy, invalid_for_group, group_policy=isgroup) |
|
1869 |
good_ispecs = self._OLD_CLUSTER_POLICY[constants.ISPECS_MINMAX] |
|
1870 |
invalid_ispecs = copy.deepcopy(good_ispecs) |
|
1871 |
invalid_policy = { |
|
1872 |
constants.ISPECS_MINMAX: invalid_ispecs, |
|
1873 |
} |
|
1874 |
for key in constants.ISPECS_MINMAX_KEYS: |
|
1875 |
ispec = invalid_ispecs[key] |
|
1876 |
ispec[INVALID_KEY] = None |
|
1859 | 1877 |
self.assertRaises(errors.TypeEnforcementError, cmdlib._GetUpdatedIPolicy, |
1860 |
old_policy, invalid_ispec, group_policy=isgroup) |
|
1878 |
old_policy, invalid_policy, group_policy=isgroup) |
|
1879 |
del ispec[INVALID_KEY] |
|
1880 |
for par in constants.ISPECS_PARAMETERS: |
|
1881 |
oldv = ispec[par] |
|
1882 |
ispec[par] = "this_is_not_good" |
|
1883 |
self.assertRaises(errors.TypeEnforcementError, |
|
1884 |
cmdlib._GetUpdatedIPolicy, |
|
1885 |
old_policy, invalid_policy, group_policy=isgroup) |
|
1886 |
ispec[par] = oldv |
|
1887 |
# This is to make sure that no two errors were present during the tests |
|
1888 |
cmdlib._GetUpdatedIPolicy(old_policy, invalid_policy, group_policy=isgroup) |
|
1861 | 1889 |
|
1862 | 1890 |
def testInvalidKeys(self): |
1863 | 1891 |
self._TestInvalidKeys(self._OLD_GROUP_POLICY, True) |
1864 | 1892 |
self._TestInvalidKeys(self._OLD_CLUSTER_POLICY, False) |
1865 | 1893 |
|
1894 |
def testInvalidValues(self): |
|
1895 |
for par in (constants.IPOLICY_PARAMETERS | |
|
1896 |
frozenset([constants.IPOLICY_DTS])): |
|
1897 |
bad_policy = { |
|
1898 |
par: "invalid_value", |
|
1899 |
} |
|
1900 |
self.assertRaises(errors.OpPrereqError, cmdlib._GetUpdatedIPolicy, {}, |
|
1901 |
bad_policy, group_policy=True) |
|
1866 | 1902 |
|
1867 | 1903 |
if __name__ == "__main__": |
1868 | 1904 |
testutils.GanetiTestProgram() |
b/test/py/ganeti.config_unittest.py | ||
---|---|---|
436 | 436 |
# depending on the owner (cluster or group) |
437 | 437 |
if isgroup: |
438 | 438 |
errs = cfg.VerifyConfig() |
439 |
# FIXME: A bug in FillIPolicy (issue 401) makes this test fail, so we |
|
440 |
# invert the assertions for the time being |
|
441 |
self.assertFalse(len(errs) >= 1) |
|
439 |
self.assertTrue(len(errs) >= 1) |
|
442 | 440 |
errstr = "%s has invalid instance policy" % ipowner |
443 |
self.assertFalse(_IsErrorInList(errstr, errs))
|
|
441 |
self.assertTrue(_IsErrorInList(errstr, errs))
|
|
444 | 442 |
else: |
445 | 443 |
self.assertRaises(AssertionError, cfg.VerifyConfig) |
446 | 444 |
del ipolicy[INVALID_KEY] |
... | ... | |
461 | 459 |
else: |
462 | 460 |
del ipolicy[key] |
463 | 461 |
|
464 |
ispeclist = [ |
|
465 |
(ipolicy[constants.ISPECS_MINMAX][constants.ISPECS_MIN], |
|
466 |
"%s/%s" % (constants.ISPECS_MINMAX, constants.ISPECS_MIN)), |
|
467 |
(ipolicy[constants.ISPECS_MINMAX][constants.ISPECS_MAX], |
|
468 |
"%s/%s" % (constants.ISPECS_MINMAX, constants.ISPECS_MAX)), |
|
469 |
(ipolicy[constants.ISPECS_STD], constants.ISPECS_STD), |
|
470 |
] |
|
462 |
ispeclist = [] |
|
463 |
if constants.ISPECS_MINMAX in ipolicy: |
|
464 |
ispeclist.extend([ |
|
465 |
(ipolicy[constants.ISPECS_MINMAX][constants.ISPECS_MIN], |
|
466 |
"%s/%s" % (constants.ISPECS_MINMAX, constants.ISPECS_MIN)), |
|
467 |
(ipolicy[constants.ISPECS_MINMAX][constants.ISPECS_MAX], |
|
468 |
"%s/%s" % (constants.ISPECS_MINMAX, constants.ISPECS_MAX)), |
|
469 |
]) |
|
470 |
if constants.ISPECS_STD in ipolicy: |
|
471 |
ispeclist.append((ipolicy[constants.ISPECS_STD], constants.ISPECS_STD)) |
|
472 |
|
|
471 | 473 |
for (ispec, ispecpath) in ispeclist: |
472 | 474 |
ispec[INVALID_KEY] = None |
473 | 475 |
errs = cfg.VerifyConfig() |
... | ... | |
494 | 496 |
errs = cfg.VerifyConfig() |
495 | 497 |
self.assertFalse(errs) |
496 | 498 |
|
499 |
if constants.ISPECS_MINMAX in ipolicy: |
|
500 |
# Test partial minmax specs |
|
501 |
minmax = ipolicy[constants.ISPECS_MINMAX] |
|
502 |
for key in constants.ISPECS_MINMAX_KEYS: |
|
503 |
self.assertTrue(key in minmax) |
|
504 |
ispec = minmax[key] |
|
505 |
del minmax[key] |
|
506 |
errs = cfg.VerifyConfig() |
|
507 |
self.assertTrue(len(errs) >= 1) |
|
508 |
self.assertTrue(_IsErrorInList("Missing instance specification", errs)) |
|
509 |
minmax[key] = ispec |
|
510 |
for par in constants.ISPECS_PARAMETERS: |
|
511 |
oldv = ispec[par] |
|
512 |
del ispec[par] |
|
513 |
errs = cfg.VerifyConfig() |
|
514 |
self.assertTrue(len(errs) >= 1) |
|
515 |
self.assertTrue(_IsErrorInList("Missing instance specs parameters", |
|
516 |
errs)) |
|
517 |
ispec[par] = oldv |
|
518 |
errs = cfg.VerifyConfig() |
|
519 |
self.assertFalse(errs) |
|
520 |
|
|
497 | 521 |
def _TestVerifyConfigGroupIPolicy(self, groupinfo, cfg): |
498 | 522 |
old_ipolicy = groupinfo.ipolicy |
499 | 523 |
ipolicy = cfg.GetClusterInfo().SimpleFillIPolicy({}) |
... | ... | |
506 | 530 |
errs = cfg.VerifyConfig() |
507 | 531 |
self.assertFalse(errs) |
508 | 532 |
ipolicy[key] = oldv |
509 |
# Test partial minmax specs |
|
510 |
minmax = ipolicy[constants.ISPECS_MINMAX] |
|
511 |
for ispec_key in minmax.keys(): |
|
512 |
ispec = minmax[ispec_key] |
|
513 |
for par in constants.ISPECS_PARAMETERS: |
|
514 |
oldv = ispec[par] |
|
515 |
del ispec[par] |
|
516 |
errs = cfg.VerifyConfig() |
|
517 |
self.assertFalse(errs) |
|
518 |
ispec[par] = oldv |
|
519 | 533 |
groupinfo.ipolicy = old_ipolicy |
520 | 534 |
|
521 | 535 |
def _TestVerifyConfigClusterIPolicy(self, ipolicy, cfg): |
... | ... | |
526 | 540 |
del ipolicy[key] |
527 | 541 |
self.assertRaises(AssertionError, cfg.VerifyConfig) |
528 | 542 |
ipolicy[key] = oldv |
529 |
# Test partial minmax specs |
|
530 |
minmax = ipolicy[constants.ISPECS_MINMAX] |
|
531 |
for key in constants.ISPECS_MINMAX_KEYS: |
|
532 |
self.assertTrue(key in minmax) |
|
533 |
oldv = minmax[key] |
|
534 |
del minmax[key] |
|
535 |
self.assertRaises(AssertionError, cfg.VerifyConfig) |
|
536 |
minmax[key] = oldv |
|
543 |
errs = cfg.VerifyConfig() |
|
544 |
self.assertFalse(errs) |
|
545 |
# Partial standard specs |
|
546 |
ispec = ipolicy[constants.ISPECS_STD] |
|
547 |
for par in constants.ISPECS_PARAMETERS: |
|
548 |
oldv = ispec[par] |
|
549 |
del ispec[par] |
|
550 |
errs = cfg.VerifyConfig() |
|
551 |
self.assertTrue(len(errs) >= 1) |
|
552 |
self.assertTrue(_IsErrorInList("Missing instance specs parameters", |
|
553 |
errs)) |
|
554 |
ispec[par] = oldv |
|
537 | 555 |
errs = cfg.VerifyConfig() |
538 | 556 |
self.assertFalse(errs) |
539 | 557 |
|
b/test/py/ganeti.objects_unittest.py | ||
---|---|---|
460 | 460 |
def testCheckISpecParamSyntax(self): |
461 | 461 |
par = "my_parameter" |
462 | 462 |
for check_std in [True, False]: |
463 |
# Only one policy limit |
|
464 |
for key in constants.ISPECS_MINMAX_KEYS: |
|
465 |
minmax = dict((k, {}) for k in constants.ISPECS_MINMAX_KEYS) |
|
466 |
minmax[key][par] = 11 |
|
467 |
objects.InstancePolicy._CheckISpecParamSyntax(minmax, {}, par, |
|
468 |
check_std) |
|
469 |
if check_std: |
|
470 |
minmax = dict((k, {}) for k in constants.ISPECS_MINMAX_KEYS) |
|
471 |
stdspec = {par: 11} |
|
472 |
objects.InstancePolicy._CheckISpecParamSyntax(minmax, stdspec, par, |
|
473 |
check_std) |
|
474 |
|
|
475 | 463 |
# Min and max only |
476 | 464 |
good_values = [(11, 11), (11, 40), (0, 0)] |
477 | 465 |
for (mn, mx) in good_values: |
... | ... | |
588 | 576 |
self._AssertIPolicyIsFull(policy) |
589 | 577 |
self._AssertIPolicyMerged(constants.IPOLICY_DEFAULTS, diff_pol, policy) |
590 | 578 |
|
591 |
def testFillIPolicySpecs(self): |
|
592 |
partial_ipolicies = [ |
|
593 |
{ |
|
594 |
constants.ISPECS_MINMAX: { |
|
595 |
constants.ISPECS_MIN: {constants.ISPEC_MEM_SIZE: 32}, |
|
596 |
constants.ISPECS_MAX: {constants.ISPEC_CPU_COUNT: 1024} |
|
597 |
}, |
|
598 |
}, |
|
599 |
{ |
|
600 |
constants.ISPECS_MINMAX: { |
|
601 |
constants.ISPECS_MAX: { |
|
602 |
constants.ISPEC_DISK_COUNT: constants.MAX_DISKS - 1, |
|
603 |
constants.ISPEC_NIC_COUNT: constants.MAX_NICS - 1, |
|
604 |
}, |
|
605 |
constants.ISPECS_MIN: {}, |
|
606 |
}, |
|
607 |
constants.ISPECS_STD: {constants.ISPEC_DISK_SIZE: 2048}, |
|
608 |
}, |
|
609 |
{ |
|
610 |
constants.ISPECS_STD: {constants.ISPEC_SPINDLE_USE: 3}, |
|
611 |
}, |
|
612 |
] |
|
613 |
for diff_pol in partial_ipolicies: |
|
614 |
policy = objects.FillIPolicy(constants.IPOLICY_DEFAULTS, diff_pol) |
|
615 |
objects.InstancePolicy.CheckParameterSyntax(policy, True) |
|
616 |
self._AssertIPolicyIsFull(policy) |
|
617 |
self._AssertIPolicyMerged(constants.IPOLICY_DEFAULTS, diff_pol, policy) |
|
618 |
|
|
619 | 579 |
|
620 | 580 |
if __name__ == "__main__": |
621 | 581 |
testutils.GanetiTestProgram() |
Also available in: Unified diff