Revision a5728081
b/lib/bootstrap.py | ||
---|---|---|
38 | 38 |
from ganeti import constants |
39 | 39 |
from ganeti import objects |
40 | 40 |
from ganeti import ssconf |
41 |
from ganeti import hypervisor |
|
41 | 42 |
|
42 | 43 |
|
43 | 44 |
def _InitSSHSetup(): |
... | ... | |
204 | 205 |
raise errors.OpPrereqError("Init.d script '%s' missing or not" |
205 | 206 |
" executable." % constants.NODE_INITD_SCRIPT) |
206 | 207 |
|
207 |
utils.CheckBEParams(beparams) |
|
208 |
utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES) |
|
209 |
# hvparams is a mapping of hypervisor->hvparams dict |
|
210 |
for hv_name, hv_params in hvparams.iteritems(): |
|
211 |
utils.ForceDictType(hv_params, constants.HVS_PARAMETER_TYPES) |
|
212 |
hv_class = hypervisor.GetHypervisor(hv_name) |
|
213 |
hv_class.CheckParameterSyntax(hv_params) |
|
208 | 214 |
|
209 | 215 |
# set up the inter-node password and certificate |
210 | 216 |
_InitGanetiServerSetup() |
b/lib/cli.py | ||
---|---|---|
50 | 50 |
"ListTags", "AddTags", "RemoveTags", "TAG_SRC_OPT", |
51 | 51 |
"FormatError", "SplitNodeOption", "SubmitOrSend", |
52 | 52 |
"JobSubmittedException", "FormatTimestamp", "ParseTimespec", |
53 |
"ValidateBeParams", "ToStderr", "ToStdout", "UsesRPC",
|
|
53 |
"ToStderr", "ToStdout", "UsesRPC", |
|
54 | 54 |
"GetOnlineNodes", "JobExecutor", "SYNC_OPT", |
55 | 55 |
] |
56 | 56 |
|
... | ... | |
409 | 409 |
return (value, None) |
410 | 410 |
|
411 | 411 |
|
412 |
def ValidateBeParams(bep): |
|
413 |
"""Parse and check the given beparams. |
|
414 |
|
|
415 |
The function will update in-place the given dictionary. |
|
416 |
|
|
417 |
@type bep: dict |
|
418 |
@param bep: input beparams |
|
419 |
@raise errors.ParameterError: if the input values are not OK |
|
420 |
@raise errors.UnitParseError: if the input values are not OK |
|
421 |
|
|
422 |
""" |
|
423 |
if constants.BE_MEMORY in bep: |
|
424 |
bep[constants.BE_MEMORY] = utils.ParseUnit(bep[constants.BE_MEMORY]) |
|
425 |
|
|
426 |
if constants.BE_VCPUS in bep: |
|
427 |
try: |
|
428 |
bep[constants.BE_VCPUS] = int(bep[constants.BE_VCPUS]) |
|
429 |
except ValueError: |
|
430 |
raise errors.ParameterError("Invalid number of VCPUs") |
|
431 |
|
|
432 |
|
|
433 | 412 |
def UsesRPC(fn): |
434 | 413 |
def wrapper(*args, **kwargs): |
435 | 414 |
rpc.Init() |
... | ... | |
695 | 674 |
elif isinstance(err, errors.JobQueueFull): |
696 | 675 |
obuf.write("Failure: the job queue is full and doesn't accept new" |
697 | 676 |
" job submissions until old jobs are archived\n") |
677 |
elif isinstance(err, errors.TypeEnforcementError): |
|
678 |
obuf.write("Parameter Error: %s" % msg) |
|
698 | 679 |
elif isinstance(err, errors.GenericError): |
699 | 680 |
obuf.write("Unhandled Ganeti error: %s" % msg) |
700 | 681 |
elif isinstance(err, luxi.NoMasterError): |
b/lib/cmdlib.py | ||
---|---|---|
1409 | 1409 |
if the given volume group is valid. |
1410 | 1410 |
|
1411 | 1411 |
""" |
1412 |
# FIXME: This only works because there is only one parameter that can be |
|
1413 |
# changed or removed. |
|
1414 | 1412 |
if self.op.vg_name is not None and not self.op.vg_name: |
1415 | 1413 |
instances = self.cfg.GetAllInstancesInfo().values() |
1416 | 1414 |
for inst in instances: |
... | ... | |
1439 | 1437 |
self.cluster = cluster = self.cfg.GetClusterInfo() |
1440 | 1438 |
# validate beparams changes |
1441 | 1439 |
if self.op.beparams: |
1442 |
utils.CheckBEParams(self.op.beparams)
|
|
1440 |
utils.ForceDictType(self.op.beparams, constants.BES_PARAMETER_TYPES)
|
|
1443 | 1441 |
self.new_beparams = cluster.FillDict( |
1444 | 1442 |
cluster.beparams[constants.BEGR_DEFAULT], self.op.beparams) |
1445 | 1443 |
|
... | ... | |
1467 | 1465 |
hv_name in self.op.enabled_hypervisors)): |
1468 | 1466 |
# either this is a new hypervisor, or its parameters have changed |
1469 | 1467 |
hv_class = hypervisor.GetHypervisor(hv_name) |
1468 |
utils.ForceDictType(hv_params, constants.HVS_PARAMETER_TYPES) |
|
1470 | 1469 |
hv_class.CheckParameterSyntax(hv_params) |
1471 | 1470 |
_CheckHVParams(self, node_list, hv_name, hv_params) |
1472 | 1471 |
|
... | ... | |
4227 | 4226 |
",".join(enabled_hvs))) |
4228 | 4227 |
|
4229 | 4228 |
# check hypervisor parameter syntax (locally) |
4230 |
|
|
4229 |
utils.ForceDictType(self.op.hvparams, constants.HVS_PARAMETER_TYPES) |
|
4231 | 4230 |
filled_hvp = cluster.FillDict(cluster.hvparams[self.op.hypervisor], |
4232 | 4231 |
self.op.hvparams) |
4233 | 4232 |
hv_type = hypervisor.GetHypervisor(self.op.hypervisor) |
4234 | 4233 |
hv_type.CheckParameterSyntax(filled_hvp) |
4235 | 4234 |
|
4236 | 4235 |
# fill and remember the beparams dict |
4237 |
utils.CheckBEParams(self.op.beparams)
|
|
4236 |
utils.ForceDictType(self.op.beparams, constants.BES_PARAMETER_TYPES)
|
|
4238 | 4237 |
self.be_full = cluster.FillDict(cluster.beparams[constants.BEGR_DEFAULT], |
4239 | 4238 |
self.op.beparams) |
4240 | 4239 |
|
... | ... | |
5608 | 5607 |
self.op.hvparams or self.op.beparams): |
5609 | 5608 |
raise errors.OpPrereqError("No changes submitted") |
5610 | 5609 |
|
5611 |
utils.CheckBEParams(self.op.beparams) |
|
5612 |
|
|
5613 | 5610 |
# Disk validation |
5614 | 5611 |
disk_addremove = 0 |
5615 | 5612 |
for disk_op, disk_dict in self.op.disks: |
... | ... | |
5731 | 5728 |
del i_hvdict[key] |
5732 | 5729 |
except KeyError: |
5733 | 5730 |
pass |
5734 |
elif val == constants.VALUE_NONE: |
|
5735 |
i_hvdict[key] = None |
|
5736 | 5731 |
else: |
5737 | 5732 |
i_hvdict[key] = val |
5738 | 5733 |
cluster = self.cfg.GetClusterInfo() |
5734 |
utils.ForceDictType(i_hvdict, constants.HVS_PARAMETER_TYPES) |
|
5739 | 5735 |
hv_new = cluster.FillDict(cluster.hvparams[instance.hypervisor], |
5740 | 5736 |
i_hvdict) |
5741 | 5737 |
# local check |
... | ... | |
5759 | 5755 |
else: |
5760 | 5756 |
i_bedict[key] = val |
5761 | 5757 |
cluster = self.cfg.GetClusterInfo() |
5758 |
utils.ForceDictType(i_bedict, constants.BES_PARAMETER_TYPES) |
|
5762 | 5759 |
be_new = cluster.FillDict(cluster.beparams[constants.BEGR_DEFAULT], |
5763 | 5760 |
i_bedict) |
5764 | 5761 |
self.be_new = be_new # the new actual values |
b/lib/constants.py | ||
---|---|---|
277 | 277 |
INSTANCE_REBOOT_HARD, |
278 | 278 |
INSTANCE_REBOOT_FULL]) |
279 | 279 |
|
280 |
VTYPE_STRING = 'string' |
|
281 |
VTYPE_BOOL = 'bool' |
|
282 |
VTYPE_SIZE = 'size' # size, in MiBs |
|
283 |
VTYPE_INT = 'int' |
|
284 |
ENFORCEABLE_TYPES = frozenset([ |
|
285 |
VTYPE_STRING, |
|
286 |
VTYPE_BOOL, |
|
287 |
VTYPE_SIZE, |
|
288 |
VTYPE_INT, |
|
289 |
]) |
|
290 |
|
|
280 | 291 |
# HV parameter names (global namespace) |
281 | 292 |
HV_BOOT_ORDER = "boot_order" |
282 | 293 |
HV_CDROM_IMAGE_PATH = "cdrom_image_path" |
... | ... | |
294 | 305 |
HV_SERIAL_CONSOLE = "serial_console" |
295 | 306 |
HV_USB_MOUSE = "usb_mouse" |
296 | 307 |
|
297 |
HVS_PARAMETERS = frozenset([ |
|
298 |
HV_BOOT_ORDER, |
|
299 |
HV_CDROM_IMAGE_PATH, |
|
300 |
HV_NIC_TYPE, |
|
301 |
HV_DISK_TYPE, |
|
302 |
HV_VNC_BIND_ADDRESS, |
|
303 |
HV_VNC_TLS, |
|
304 |
HV_VNC_X509, |
|
305 |
HV_VNC_X509_VERIFY, |
|
306 |
HV_ACPI, |
|
307 |
HV_PAE, |
|
308 |
HV_KERNEL_PATH, |
|
309 |
HV_INITRD_PATH, |
|
310 |
HV_ROOT_PATH, |
|
311 |
HV_SERIAL_CONSOLE, |
|
312 |
HV_USB_MOUSE, |
|
313 |
]) |
|
308 |
HVS_PARAMETER_TYPES = { |
|
309 |
HV_BOOT_ORDER: VTYPE_STRING, |
|
310 |
HV_CDROM_IMAGE_PATH: VTYPE_STRING, |
|
311 |
HV_NIC_TYPE: VTYPE_STRING, |
|
312 |
HV_DISK_TYPE: VTYPE_STRING, |
|
313 |
HV_VNC_BIND_ADDRESS: VTYPE_STRING, |
|
314 |
HV_VNC_TLS: VTYPE_BOOL, |
|
315 |
HV_VNC_X509: VTYPE_STRING, |
|
316 |
HV_VNC_X509_VERIFY: VTYPE_BOOL, |
|
317 |
HV_ACPI: VTYPE_BOOL, |
|
318 |
HV_PAE: VTYPE_BOOL, |
|
319 |
HV_KERNEL_PATH: VTYPE_STRING, |
|
320 |
HV_INITRD_PATH: VTYPE_STRING, |
|
321 |
HV_ROOT_PATH: VTYPE_STRING, |
|
322 |
HV_SERIAL_CONSOLE: VTYPE_BOOL, |
|
323 |
HV_USB_MOUSE: VTYPE_STRING, |
|
324 |
} |
|
325 |
|
|
326 |
HVS_PARAMETERS = frozenset(HVS_PARAMETER_TYPES.keys()) |
|
314 | 327 |
|
315 | 328 |
# BE parameter names |
316 | 329 |
BE_MEMORY = "memory" |
317 | 330 |
BE_VCPUS = "vcpus" |
318 | 331 |
BE_AUTO_BALANCE = "auto_balance" |
319 | 332 |
|
320 |
BES_PARAMETERS = frozenset([ |
|
321 |
BE_MEMORY, |
|
322 |
BE_VCPUS, |
|
323 |
BE_AUTO_BALANCE, |
|
324 |
]) |
|
333 |
BES_PARAMETER_TYPES = { |
|
334 |
BE_MEMORY: VTYPE_SIZE, |
|
335 |
BE_VCPUS: VTYPE_INT, |
|
336 |
BE_AUTO_BALANCE: VTYPE_BOOL, |
|
337 |
} |
|
338 |
|
|
339 |
BES_PARAMETERS = frozenset(BES_PARAMETER_TYPES.keys()) |
|
325 | 340 |
|
326 | 341 |
# BE GROUP |
327 | 342 |
BEGR_DEFAULT = "default" |
... | ... | |
457 | 472 |
HVC_DEFAULTS = { |
458 | 473 |
HT_XEN_PVM: { |
459 | 474 |
HV_KERNEL_PATH: "/boot/vmlinuz-2.6-xenU", |
460 |
HV_INITRD_PATH: None,
|
|
475 |
HV_INITRD_PATH: '',
|
|
461 | 476 |
HV_ROOT_PATH: '/dev/sda', |
462 | 477 |
}, |
463 | 478 |
HT_XEN_HVM: { |
464 | 479 |
HV_BOOT_ORDER: "cd", |
465 |
HV_CDROM_IMAGE_PATH: None,
|
|
480 |
HV_CDROM_IMAGE_PATH: '',
|
|
466 | 481 |
HV_NIC_TYPE: HT_NIC_RTL8139, |
467 | 482 |
HV_DISK_TYPE: HT_DISK_PARAVIRTUAL, |
468 | 483 |
HV_VNC_BIND_ADDRESS: '0.0.0.0', |
... | ... | |
471 | 486 |
}, |
472 | 487 |
HT_KVM: { |
473 | 488 |
HV_KERNEL_PATH: "/boot/vmlinuz-2.6-kvmU", |
474 |
HV_INITRD_PATH: None,
|
|
489 |
HV_INITRD_PATH: '',
|
|
475 | 490 |
HV_ROOT_PATH: '/dev/vda', |
476 | 491 |
HV_ACPI: True, |
477 | 492 |
HV_SERIAL_CONSOLE: True, |
478 |
HV_VNC_BIND_ADDRESS: None,
|
|
493 |
HV_VNC_BIND_ADDRESS: '',
|
|
479 | 494 |
HV_VNC_TLS: False, |
480 | 495 |
HV_VNC_X509: '', |
481 | 496 |
HV_VNC_X509_VERIFY: False, |
482 |
HV_CDROM_IMAGE_PATH: None,
|
|
497 |
HV_CDROM_IMAGE_PATH: '',
|
|
483 | 498 |
HV_BOOT_ORDER: "disk", |
484 | 499 |
HV_NIC_TYPE: HT_NIC_PARAVIRTUAL, |
485 | 500 |
HV_DISK_TYPE: HT_DISK_PARAVIRTUAL, |
486 |
HV_USB_MOUSE: None,
|
|
501 |
HV_USB_MOUSE: '',
|
|
487 | 502 |
}, |
488 | 503 |
HT_FAKE: { |
489 | 504 |
}, |
b/lib/errors.py | ||
---|---|---|
198 | 198 |
|
199 | 199 |
""" |
200 | 200 |
|
201 |
class TypeEnforcementError(GenericError): |
|
202 |
"""Unable to enforce data type. |
|
203 |
|
|
204 |
""" |
|
201 | 205 |
|
202 | 206 |
class SshKeyError(GenericError): |
203 | 207 |
"""Invalid SSH key. |
b/lib/utils.py | ||
---|---|---|
387 | 387 |
logging.warning('%s missing keys %s', logname, ', '.join(missing)) |
388 | 388 |
|
389 | 389 |
|
390 |
def ForceDictType(target, key_types, allowed_values=None): |
|
391 |
"""Force the values of a dict to have certain types. |
|
392 |
|
|
393 |
@type target: dict |
|
394 |
@param target: the dict to update |
|
395 |
@type key_types: dict |
|
396 |
@param key_types: dict mapping target dict keys to types |
|
397 |
in constants.ENFORCEABLE_TYPES |
|
398 |
@type allowed_values: list |
|
399 |
@keyword allowed_values: list of specially allowed values |
|
400 |
|
|
401 |
""" |
|
402 |
if allowed_values is None: |
|
403 |
allowed_values = [] |
|
404 |
|
|
405 |
for key in target: |
|
406 |
if key not in key_types: |
|
407 |
msg = "Unknown key '%s'" % key |
|
408 |
raise errors.TypeEnforcementError(msg) |
|
409 |
|
|
410 |
if target[key] in allowed_values: |
|
411 |
continue |
|
412 |
|
|
413 |
type = key_types[key] |
|
414 |
if type not in constants.ENFORCEABLE_TYPES: |
|
415 |
msg = "'%s' has non-enforceable type %s" % (key, type) |
|
416 |
raise errors.ProgrammerError(msg) |
|
417 |
|
|
418 |
if type == constants.VTYPE_STRING: |
|
419 |
if not isinstance(target[key], basestring): |
|
420 |
if isinstance(target[key], bool) and not target[key]: |
|
421 |
target[key] = '' |
|
422 |
else: |
|
423 |
msg = "'%s' (value %s) is not a valid string" % (key, target[key]) |
|
424 |
raise errors.TypeEnforcementError(msg) |
|
425 |
elif type == constants.VTYPE_BOOL: |
|
426 |
if isinstance(target[key], basestring) and target[key]: |
|
427 |
if target[key].lower() == constants.VALUE_FALSE: |
|
428 |
target[key] = False |
|
429 |
elif target[key].lower() == constants.VALUE_TRUE: |
|
430 |
target[key] = True |
|
431 |
else: |
|
432 |
msg = "'%s' (value %s) is not a valid boolean" % (key, target[key]) |
|
433 |
raise errors.TypeEnforcementError(msg) |
|
434 |
elif target[key]: |
|
435 |
target[key] = True |
|
436 |
else: |
|
437 |
target[key] = False |
|
438 |
elif type == constants.VTYPE_SIZE: |
|
439 |
try: |
|
440 |
target[key] = ParseUnit(target[key]) |
|
441 |
except errors.UnitParseError, err: |
|
442 |
msg = "'%s' (value %s) is not a valid size. error: %s" % \ |
|
443 |
(key, target[key], err) |
|
444 |
raise errors.TypeEnforcementError(msg) |
|
445 |
elif type == constants.VTYPE_INT: |
|
446 |
try: |
|
447 |
target[key] = int(target[key]) |
|
448 |
except (ValueError, TypeError): |
|
449 |
msg = "'%s' (value %s) is not a valid integer" % (key, target[key]) |
|
450 |
raise errors.TypeEnforcementError(msg) |
|
451 |
|
|
452 |
|
|
390 | 453 |
def IsProcessAlive(pid): |
391 | 454 |
"""Check if a given pid exists on the system. |
392 | 455 |
|
... | ... | |
558 | 621 |
return os.path.isdir("/sys/class/net/%s/bridge" % bridge) |
559 | 622 |
|
560 | 623 |
|
561 |
def CheckBEParams(beparams): |
|
562 |
"""Checks whether the user-supplied be-params are valid, |
|
563 |
and converts them from string format where appropriate. |
|
564 |
|
|
565 |
@type beparams: dict |
|
566 |
@param beparams: new params dict |
|
567 |
|
|
568 |
""" |
|
569 |
if beparams: |
|
570 |
for item in beparams: |
|
571 |
if item not in constants.BES_PARAMETERS: |
|
572 |
raise errors.OpPrereqError("Unknown backend parameter %s" % item) |
|
573 |
if item in (constants.BE_MEMORY, constants.BE_VCPUS): |
|
574 |
val = beparams[item] |
|
575 |
if val != constants.VALUE_DEFAULT: |
|
576 |
try: |
|
577 |
val = int(val) |
|
578 |
except ValueError, err: |
|
579 |
raise errors.OpPrereqError("Invalid %s size: %s" % (item, err)) |
|
580 |
beparams[item] = val |
|
581 |
if item in (constants.BE_AUTO_BALANCE): |
|
582 |
val = beparams[item] |
|
583 |
if not isinstance(val, bool): |
|
584 |
if val == constants.VALUE_TRUE: |
|
585 |
beparams[item] = True |
|
586 |
elif val == constants.VALUE_FALSE: |
|
587 |
beparams[item] = False |
|
588 |
else: |
|
589 |
raise errors.OpPrereqError("Invalid %s value: %s" % (item, val)) |
|
590 |
|
|
591 |
|
|
592 | 624 |
def NiceSort(name_list): |
593 | 625 |
"""Sort a list of strings based on digit and non-digit groupings. |
594 | 626 |
|
b/scripts/gnt-backup | ||
---|---|---|
136 | 136 |
(didx, err)) |
137 | 137 |
disks[didx] = ddict |
138 | 138 |
|
139 |
ValidateBeParams(opts.beparams) |
|
139 |
utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_TYPES) |
|
140 |
utils.ForceDictType(opts.hvparams, constants.HVS_PARAMETER_TYPES) |
|
140 | 141 |
|
141 | 142 |
op = opcodes.OpCreateInstance(instance_name=instance, |
142 | 143 |
disk_template=opts.disk_template, |
b/scripts/gnt-cluster | ||
---|---|---|
88 | 88 |
for parameter in constants.BES_PARAMETERS: |
89 | 89 |
if parameter not in beparams: |
90 | 90 |
beparams[parameter] = constants.BEC_DEFAULTS[parameter] |
91 |
|
|
92 |
# type wrangling |
|
93 |
try: |
|
94 |
beparams[constants.BE_VCPUS] = int(beparams[constants.BE_VCPUS]) |
|
95 |
except ValueError: |
|
96 |
ToStderr("%s must be an integer", constants.BE_VCPUS) |
|
97 |
return 1 |
|
98 |
|
|
99 |
if not isinstance(beparams[constants.BE_MEMORY], int): |
|
100 |
beparams[constants.BE_MEMORY] = utils.ParseUnit( |
|
101 |
beparams[constants.BE_MEMORY]) |
|
91 |
utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES) |
|
102 | 92 |
|
103 | 93 |
# prepare hvparams dict |
104 | 94 |
for hv in constants.HYPER_TYPES: |
... | ... | |
107 | 97 |
for parameter in constants.HVC_DEFAULTS[hv]: |
108 | 98 |
if parameter not in hvparams[hv]: |
109 | 99 |
hvparams[hv][parameter] = constants.HVC_DEFAULTS[hv][parameter] |
100 |
utils.ForceDictType(hvparams[hv], constants.HVS_PARAMETER_TYPES) |
|
110 | 101 |
|
111 | 102 |
for hv in hvlist: |
112 | 103 |
if hv not in constants.HYPER_TYPES: |
... | ... | |
486 | 477 |
if hvparams: |
487 | 478 |
# a list of (name, dict) we can pass directly to dict() |
488 | 479 |
hvparams = dict(opts.hvparams) |
480 |
for hv, hv_params in hvparams.iteritems(): |
|
481 |
utils.ForceDictType(hv_params, constants.HVS_PARAMETER_TYPES) |
|
489 | 482 |
|
490 | 483 |
beparams = opts.beparams |
484 |
utils.ForceDictType(beparams, constants.BES_PARAMETER_TYPES) |
|
491 | 485 |
|
492 | 486 |
op = opcodes.OpSetClusterParams(vg_name=opts.vg_name, |
493 | 487 |
enabled_hypervisors=hvlist, |
b/scripts/gnt-instance | ||
---|---|---|
355 | 355 |
(didx, err)) |
356 | 356 |
disks[didx] = ddict |
357 | 357 |
|
358 |
ValidateBeParams(opts.beparams) |
|
359 |
|
|
360 |
## kernel_path = _TransformPath(opts.kernel_path) |
|
361 |
## initrd_path = _TransformPath(opts.initrd_path) |
|
362 |
|
|
363 |
## hvm_acpi = opts.hvm_acpi == _VALUE_TRUE |
|
364 |
## hvm_pae = opts.hvm_pae == _VALUE_TRUE |
|
365 |
|
|
366 |
## if ((opts.hvm_cdrom_image_path is not None) and |
|
367 |
## (opts.hvm_cdrom_image_path.lower() == constants.VALUE_NONE)): |
|
368 |
## hvm_cdrom_image_path = None |
|
369 |
## else: |
|
370 |
## hvm_cdrom_image_path = opts.hvm_cdrom_image_path |
|
358 |
utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_TYPES) |
|
359 |
utils.ForceDictType(opts.hvparams, constants.HVS_PARAMETER_TYPES) |
|
371 | 360 |
|
372 | 361 |
op = opcodes.OpCreateInstance(instance_name=instance, |
373 | 362 |
disks=disks, |
... | ... | |
492 | 481 |
|
493 | 482 |
nic0 = {'ip': specs['ip'], 'bridge': specs['bridge'], 'mac': specs['mac']} |
494 | 483 |
|
484 |
utils.ForceDictType(specs['backend'], constants.BES_PARAMETER_TYPES) |
|
485 |
utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES) |
|
486 |
|
|
495 | 487 |
op = opcodes.OpCreateInstance(instance_name=name, |
496 | 488 |
disks=disks, |
497 | 489 |
disk_template=specs['template'], |
... | ... | |
1187 | 1179 |
if isinstance(opts.beparams[param], basestring): |
1188 | 1180 |
if opts.beparams[param].lower() == "default": |
1189 | 1181 |
opts.beparams[param] = constants.VALUE_DEFAULT |
1190 |
elif opts.beparams[param].lower() == "none": |
|
1191 |
opts.beparams[param] = constants.VALUE_NONE |
|
1192 |
elif param == constants.BE_MEMORY: |
|
1193 |
opts.beparams[constants.BE_MEMORY] = \ |
|
1194 |
utils.ParseUnit(opts.beparams[constants.BE_MEMORY]) |
|
1182 |
|
|
1183 |
utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_TYPES, |
|
1184 |
allowed_values=[constants.VALUE_DEFAULT]) |
|
1195 | 1185 |
|
1196 | 1186 |
for param in opts.hypervisor: |
1197 | 1187 |
if isinstance(opts.hypervisor[param], basestring): |
1198 | 1188 |
if opts.hypervisor[param].lower() == "default": |
1199 | 1189 |
opts.hypervisor[param] = constants.VALUE_DEFAULT |
1200 |
elif opts.hypervisor[param].lower() == "none": |
|
1201 |
opts.hypervisor[param] = constants.VALUE_NONE |
|
1190 |
|
|
1191 |
utils.ForceDictType(opts.hypervisor, constants.HVS_PARAMETER_TYPES, |
|
1192 |
allowed_values=[constants.VALUE_DEFAULT]) |
|
1202 | 1193 |
|
1203 | 1194 |
for idx, (nic_op, nic_dict) in enumerate(opts.nics): |
1204 | 1195 |
try: |
b/test/ganeti.utils_unittest.py | ||
---|---|---|
38 | 38 |
import testutils |
39 | 39 |
from ganeti import constants |
40 | 40 |
from ganeti import utils |
41 |
from ganeti import errors |
|
41 | 42 |
from ganeti.utils import IsProcessAlive, RunCmd, \ |
42 | 43 |
RemoveFile, CheckDict, MatchNameComponent, FormatUnit, \ |
43 | 44 |
ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \ |
44 | 45 |
ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \ |
45 | 46 |
SetEtcHostsEntry, RemoveEtcHostsEntry, FirstFree, OwnIpAddress, \ |
46 |
TailFile |
|
47 |
TailFile, ForceDictType
|
|
47 | 48 |
|
48 | 49 |
from ganeti.errors import LockError, UnitParseError, GenericError, \ |
49 | 50 |
ProgrammerError |
... | ... | |
921 | 922 |
self.failIf(f.NonMatching(["b12", "c"])) |
922 | 923 |
self.failUnless(f.NonMatching(["a", "1"])) |
923 | 924 |
|
925 |
class TestForceDictType(unittest.TestCase): |
|
926 |
"""Test case for ForceDictType""" |
|
927 |
|
|
928 |
def setUp(self): |
|
929 |
self.key_types = { |
|
930 |
'a': constants.VTYPE_INT, |
|
931 |
'b': constants.VTYPE_BOOL, |
|
932 |
'c': constants.VTYPE_STRING, |
|
933 |
'd': constants.VTYPE_SIZE, |
|
934 |
} |
|
935 |
|
|
936 |
def _fdt(self, dict, allowed_values=None): |
|
937 |
if allowed_values is None: |
|
938 |
ForceDictType(dict, self.key_types) |
|
939 |
else: |
|
940 |
ForceDictType(dict, self.key_types, allowed_values=allowed_values) |
|
941 |
|
|
942 |
return dict |
|
943 |
|
|
944 |
def testSimpleDict(self): |
|
945 |
self.assertEqual(self._fdt({}), {}) |
|
946 |
self.assertEqual(self._fdt({'a': 1}), {'a': 1}) |
|
947 |
self.assertEqual(self._fdt({'a': '1'}), {'a': 1}) |
|
948 |
self.assertEqual(self._fdt({'a': 1, 'b': 1}), {'a':1, 'b': True}) |
|
949 |
self.assertEqual(self._fdt({'b': 1, 'c': 'foo'}), {'b': True, 'c': 'foo'}) |
|
950 |
self.assertEqual(self._fdt({'b': 1, 'c': False}), {'b': True, 'c': ''}) |
|
951 |
self.assertEqual(self._fdt({'b': 'false'}), {'b': False}) |
|
952 |
self.assertEqual(self._fdt({'b': 'False'}), {'b': False}) |
|
953 |
self.assertEqual(self._fdt({'b': 'true'}), {'b': True}) |
|
954 |
self.assertEqual(self._fdt({'b': 'True'}), {'b': True}) |
|
955 |
self.assertEqual(self._fdt({'d': '4'}), {'d': 4}) |
|
956 |
self.assertEqual(self._fdt({'d': '4M'}), {'d': 4}) |
|
957 |
|
|
958 |
def testErrors(self): |
|
959 |
self.assertRaises(errors.TypeEnforcementError, self._fdt, {'a': 'astring'}) |
|
960 |
self.assertRaises(errors.TypeEnforcementError, self._fdt, {'c': True}) |
|
961 |
self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': 'astring'}) |
|
962 |
self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': '4 L'}) |
|
963 |
|
|
924 | 964 |
|
925 | 965 |
if __name__ == '__main__': |
926 | 966 |
unittest.main() |
Also available in: Unified diff