+
+ @classmethod
+ def CheckParameterSyntax(cls, hvparams):
+ """Check the given parameters for validity.
+
+ This should check the passed set of parameters for
+ validity. Classes should extend, not replace, this function.
+
+ @type hvparams: dict
+ @param hvparams: dictionary with parameter names/value
+ @raise errors.HypervisorError: when a parameter is not valid
+
+ """
+ for key in hvparams:
+ if key not in cls.PARAMETERS:
+ raise errors.HypervisorError("Parameter '%s' is not supported" % key)
+
+ # cheap tests that run on the master, should not access the world
+ for name, (required, check_fn, errstr, _, _) in cls.PARAMETERS.items():
+ if name not in hvparams:
+ raise errors.HypervisorError("Parameter '%s' is missing" % name)
+ value = hvparams[name]
+ if not required and not value:
+ continue
+ if not value:
+ raise errors.HypervisorError("Parameter '%s' is required but"
+ " is currently not defined" % (name, ))
+ if check_fn is not None and not check_fn(value):
+ raise errors.HypervisorError("Parameter '%s' fails syntax"
+ " check: %s (current value: '%s')" %
+ (name, errstr, value))
+
+ @classmethod
+ def ValidateParameters(cls, hvparams):
+ """Check the given parameters for validity.
+
+ This should check the passed set of parameters for
+ validity. Classes should extend, not replace, this function.
+
+ @type hvparams: dict
+ @param hvparams: dictionary with parameter names/value
+ @raise errors.HypervisorError: when a parameter is not valid
+
+ """
+ for name, (required, _, _, check_fn, errstr) in cls.PARAMETERS.items():
+ value = hvparams[name]
+ if not required and not value:
+ continue
+ if check_fn is not None and not check_fn(value):
+ raise errors.HypervisorError("Parameter '%s' fails"
+ " validation: %s (current value: '%s')" %
+ (name, errstr, value))
+
+ def GetLinuxNodeInfo(self):
+ """For linux systems, return actual OS information.
+
+ This is an abstraction for all non-hypervisor-based classes, where
+ the node actually sees all the memory and CPUs via the /proc
+ interface and standard commands. The other case if for example
+ xen, where you only see the hardware resources via xen-specific
+ tools.
+
+ @return: a dict with the following keys (values in MiB):
+ - memory_total: the total memory size on the node
+ - memory_free: the available memory on the node for instances
+ - memory_dom0: the memory used by the node itself, if available
+
+ """
+ try:
+ fh = file("/proc/meminfo")
+ try:
+ data = fh.readlines()
+ finally:
+ fh.close()
+ except EnvironmentError, err:
+ raise errors.HypervisorError("Failed to list node info: %s" % (err,))
+
+ result = {}
+ sum_free = 0
+ try:
+ for line in data:
+ splitfields = line.split(":", 1)
+
+ if len(splitfields) > 1:
+ key = splitfields[0].strip()
+ val = splitfields[1].strip()
+ if key == 'MemTotal':
+ result['memory_total'] = int(val.split()[0])/1024
+ elif key in ('MemFree', 'Buffers', 'Cached'):
+ sum_free += int(val.split()[0])/1024
+ elif key == 'Active':
+ result['memory_dom0'] = int(val.split()[0])/1024
+ except (ValueError, TypeError), err:
+ raise errors.HypervisorError("Failed to compute memory usage: %s" %
+ (err,))
+ result['memory_free'] = sum_free
+
+ cpu_total = 0
+ try:
+ fh = open("/proc/cpuinfo")
+ try:
+ cpu_total = len(re.findall("(?m)^processor\s*:\s*[0-9]+\s*$",
+ fh.read()))
+ finally:
+ fh.close()
+ except EnvironmentError, err:
+ raise errors.HypervisorError("Failed to list node info: %s" % (err,))
+ result['cpu_total'] = cpu_total
+ # FIXME: export correct data here
+ result['cpu_nodes'] = 1
+ result['cpu_sockets'] = 1
+
+ return result