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 *
_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):
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
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:
"""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)
"""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)
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.
_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)