X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/8dc76d54bb231d20f4e9f8a6a80052f1c76aab67..525939d91ad44e90b7a60ba91d1fff71cd01a0ee:/lib/utils/__init__.py diff --git a/lib/utils/__init__.py b/lib/utils/__init__.py index 9f7cb24..d3319c1 100644 --- a/lib/utils/__init__.py +++ b/lib/utils/__init__.py @@ -41,12 +41,14 @@ import signal from ganeti import errors from ganeti import constants from ganeti import compat +from ganeti import pathutils from ganeti.utils.algo import * from ganeti.utils.filelock import * from ganeti.utils.hash import * from ganeti.utils.io import * from ganeti.utils.log import * +from ganeti.utils.lvm import * from ganeti.utils.mlock import * from ganeti.utils.nodesetup import * from ganeti.utils.process import * @@ -58,8 +60,7 @@ from ganeti.utils.x509 import * _VALID_SERVICE_NAME_RE = re.compile("^[-_.a-zA-Z0-9]{1,128}$") -UUID_RE = re.compile("^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-" - "[a-f0-9]{4}-[a-f0-9]{12}$") +UUID_RE = re.compile(constants.UUID_REGEX) def ForceDictType(target, key_types, allowed_values=None): @@ -155,6 +156,46 @@ def ValidateServiceName(name): return name +def _ComputeMissingKeys(key_path, options, defaults): + """Helper functions to compute which keys a invalid. + + @param key_path: The current key path (if any) + @param options: The user provided options + @param defaults: The default dictionary + @return: A list of invalid keys + + """ + defaults_keys = frozenset(defaults.keys()) + invalid = [] + for key, value in options.items(): + if key_path: + new_path = "%s/%s" % (key_path, key) + else: + new_path = key + + if key not in defaults_keys: + invalid.append(new_path) + elif isinstance(value, dict): + invalid.extend(_ComputeMissingKeys(new_path, value, defaults[key])) + + return invalid + + +def VerifyDictOptions(options, defaults): + """Verify a dict has only keys set which also are in the defaults dict. + + @param options: The user provided options + @param defaults: The default dictionary + @raise error.OpPrereqError: If one of the keys is not supported + + """ + invalid = _ComputeMissingKeys("", options, defaults) + + if invalid: + raise errors.OpPrereqError("Provided option keys not supported: %s" % + CommaJoin(invalid), errors.ECODE_INVAL) + + def ListVolumeGroups(): """List volume groups and their size @@ -287,7 +328,7 @@ def GetHomeDir(user, default=None): The user can be passed either as a string (denoting the name) or as an integer (denoting the user id). If the user is not found, the - 'default' argument is returned, which defaults to None. + C{default} argument is returned, which defaults to C{None}. """ try: @@ -426,7 +467,7 @@ def EnsureDaemon(name): """Check for and start daemon if not alive. """ - result = RunCmd([constants.DAEMON_UTIL, "check-and-start", name]) + result = RunCmd([pathutils.DAEMON_UTIL, "check-and-start", name]) if result.failed: logging.error("Can't start daemon '%s', failure %s, output: %s", name, result.fail_reason, result.output) @@ -439,7 +480,7 @@ def StopDaemon(name): """Stop daemon """ - result = RunCmd([constants.DAEMON_UTIL, "stop", name]) + result = RunCmd([pathutils.DAEMON_UTIL, "stop", name]) if result.failed: logging.error("Can't stop daemon '%s', failure %s, output: %s", name, result.fail_reason, result.output) @@ -448,31 +489,6 @@ def StopDaemon(name): return True -def CheckVolumeGroupSize(vglist, vgname, minsize): - """Checks if the volume group list is valid. - - The function will check if a given volume group is in the list of - volume groups and has a minimum size. - - @type vglist: dict - @param vglist: dictionary of volume group names and their size - @type vgname: str - @param vgname: the volume group we should check - @type minsize: int - @param minsize: the minimum size we accept - @rtype: None or str - @return: None for success, otherwise the error message - - """ - vgsize = vglist.get(vgname, None) - if vgsize is None: - return "volume group '%s' missing" % vgname - elif vgsize < minsize: - return ("volume group '%s' too small (%s MiB required, %d MiB found)" % - (vgname, minsize, vgsize)) - return None - - def SplitTime(value): """Splits time as floating point number into a tuple. @@ -607,9 +623,11 @@ class SignalWakeupFd(object): _set_wakeup_fd_fn = signal.set_wakeup_fd except AttributeError: # Not supported + def _SetWakeupFd(self, _): # pylint: disable=R0201 return -1 else: + def _SetWakeupFd(self, fd): return self._set_wakeup_fd_fn(fd)