+ if fill_all:
+ minmax_out[key] = \
+ objects.FillDict(constants.ISPECS_MINMAX_DEFAULTS[key], ispecs[key])
+ else:
+ 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],
+ ispecs[constants.ISPECS_STD])
+ else:
+ ipolicy[constants.ISPECS_STD] = ispecs[constants.ISPECS_STD]
+
+
+def _ParseSpecUnit(spec, keyname):
+ ret = spec.copy()
+ for k in [constants.ISPEC_DISK_SIZE, constants.ISPEC_MEM_SIZE]:
+ if k in ret:
+ try:
+ ret[k] = utils.ParseUnit(ret[k])
+ except (TypeError, ValueError, errors.UnitParseError), err:
+ raise errors.OpPrereqError(("Invalid parameter %s (%s) in %s instance"
+ " specs: %s" % (k, ret[k], keyname, err)),
+ errors.ECODE_INVAL)
+ return ret
+
+
+def _ParseISpec(spec, keyname, required):
+ ret = _ParseSpecUnit(spec, keyname)
+ utils.ForceDictType(ret, constants.ISPECS_PARAMETER_TYPES)
+ missing = constants.ISPECS_PARAMETERS - frozenset(ret.keys())
+ if required and missing:
+ raise errors.OpPrereqError("Missing parameters in ipolicy spec %s: %s" %
+ (keyname, utils.CommaJoin(missing)),
+ errors.ECODE_INVAL)
+ return ret
+
+
+def _GetISpecsInAllowedValues(minmax_ispecs, allowed_values):
+ ret = None
+ if (minmax_ispecs and allowed_values and len(minmax_ispecs) == 1 and
+ len(minmax_ispecs[0]) == 1):
+ for (key, spec) in minmax_ispecs[0].items():
+ # This loop is executed exactly once
+ if key in allowed_values and not spec:
+ ret = key
+ return ret
+
+
+def _InitISpecsFromFullOpts(ipolicy_out, minmax_ispecs, std_ispecs,
+ group_ipolicy, allowed_values):
+ found_allowed = _GetISpecsInAllowedValues(minmax_ispecs, allowed_values)
+ if found_allowed is not None:
+ ipolicy_out[constants.ISPECS_MINMAX] = found_allowed
+ elif minmax_ispecs is not None:
+ minmax_out = []
+ for mmpair in minmax_ispecs:
+ mmpair_out = {}
+ for (key, spec) in mmpair.items():
+ if key not in constants.ISPECS_MINMAX_KEYS:
+ msg = "Invalid key in bounds instance specifications: %s" % key
+ raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
+ mmpair_out[key] = _ParseISpec(spec, key, True)
+ minmax_out.append(mmpair_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)