From: Iustin Pop <[email protected]>
Currently both hv_fake and hv_kvm implement practically identical code
to get the node information. Since future container-like hypervisors
will also need this functionality, this patch moves it into the base
class (as a separate function) which can then be called from classes
which need this info.
---
Whoever added hv_kvm should have done this in the first place :)
This also adds an extra check for int() conversions.
lib/hypervisor/hv_base.py | 64 +++++++++++++++++++++++++++++++++++++++++++++
lib/hypervisor/hv_fake.py | 48 ++-------------------------------
lib/hypervisor/hv_kvm.py | 48 ++-------------------------------
3 files changed, 70 insertions(+), 90 deletions(-)
diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py
index b094b37..e5de1b7 100644
--- a/lib/hypervisor/hv_base.py
+++ b/lib/hypervisor/hv_base.py
@@ -23,6 +23,9 @@
"""
+import re
+
+
from ganeti import errors
@@ -187,3 +190,64 @@ class BaseHypervisor(object):
"""
pass
+
+ 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
diff --git a/lib/hypervisor/hv_fake.py b/lib/hypervisor/hv_fake.py
index 48e645b..ccac842 100644
--- a/lib/hypervisor/hv_fake.py
+++ b/lib/hypervisor/hv_fake.py
@@ -155,61 +155,19 @@ class FakeHypervisor(hv_base.BaseHypervisor):
def GetNodeInfo(self):
"""Return information about the node.
+ This is just a wrapper over the base GetLinuxNodeInfo method.
+
@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
"""
- # global ram usage from the xm info command
- # memory : 3583
- # free_memory : 747
- # note: in xen 3, memory has changed to total_memory
- try:
- fh = file("/proc/meminfo")
- try:
- data = fh.readlines()
- finally:
- fh.close()
- except IOError, err:
- raise errors.HypervisorError("Failed to list node info: %s" % err)
-
- result = {}
- sum_free = 0
- 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
- result['memory_free'] = sum_free
-
+ result = self.GetLinuxNodeInfo()
# substract running instances
all_instances = self.GetAllInstancesInfo()
result['memory_free'] -= min(result['memory_free'],
sum([row[2] for row in all_instances]))
-
- 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
@classmethod
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index 246c7f9..7e2fdea 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -618,57 +618,15 @@ class KVMHypervisor(hv_base.BaseHypervisor):
def GetNodeInfo(self):
"""Return information about the node.
+ This is just a wrapper over the base GetLinuxNodeInfo method.
+
@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
"""
- # global ram usage from the xm info command
- # memory : 3583
- # free_memory : 747
- # note: in xen 3, memory has changed to total_memory
- 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
- 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
- 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
+ return self.GetLinuxNodeInfo()
@classmethod
def GetShellCommandForConsole(cls, instance, hvparams, beparams):
--
1.6.2.4