Francesco Romani has uploaded a new change for review.

Change subject: hypervisor interface: introduce CachingInterface
......................................................................

hypervisor interface: introduce CachingInterface

CachingInterface is an interface which minimizes
the call to the hypervisor leveraging bluk APIs
and ExpiringCache.

Change-Id: I54cd218d40cb501f5164a2a60093ebc8f8695878
Signed-off-by: Francesco Romani <[email protected]>
---
A mom/HypervisorInterfaces/CachingInterface.py
M mom/HypervisorInterfaces/vdsmInterface.py
M mom/HypervisorInterfaces/vdsmrpcInterface.py
3 files changed, 109 insertions(+), 77 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/mom refs/changes/45/41145/1

diff --git a/mom/HypervisorInterfaces/CachingInterface.py 
b/mom/HypervisorInterfaces/CachingInterface.py
new file mode 100644
index 0000000..29f9483
--- /dev/null
+++ b/mom/HypervisorInterfaces/CachingInterface.py
@@ -0,0 +1,64 @@
+# Memory Overcommitment Manager
+# Copyright (C) 2015 Francesco Romani, Red Hat Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import contextlib
+import json
+import logging
+import os
+import threading
+import time
+import traceback
+import uuid
+
+from mom.ExpiringCache import ExpiringCache
+from mom.HypervisorInterfaces.HypervisorInterface import HypervisorInterface, \
+    HypervisorInterfaceError
+
+
+class CachingInterface(HypervisorInterface):
+
+    def __init__(self, config):
+        self._config = config
+        self._cache = ExpiringCache(
+            self._config.getint('vdsm', 'cache-lifetime'))
+
+    def getVmInfo(self, vmId):
+        stats = self._getVmStats(vmId)
+        return {
+            'uuid': vmId,
+            'pid': stats['pid'],
+            'name': stats.get('vmName', 'VM-%s' % vmId)
+        }
+
+    def _getVmStats(self, vmId):
+        stats = self._cache.get(vmId)
+        if stats is None:
+            self._refresh()
+
+            stats = self._cache.get(vmId)
+            if stats is None:
+                raise vdsmException('unavailable stats for %s' % vmId,
+                                    self.logger)
+        return stats
+
+    def _refresh(self):
+        all_stats = self._refreshVmStats()
+        for stats in all_stats:
+            try:
+                self._cache[stats['vmId']] = stats
+            except KeyError:
+                pass
+        return all_stats
diff --git a/mom/HypervisorInterfaces/vdsmInterface.py 
b/mom/HypervisorInterfaces/vdsmInterface.py
index 4dd8655..c38bfc3 100644
--- a/mom/HypervisorInterfaces/vdsmInterface.py
+++ b/mom/HypervisorInterfaces/vdsmInterface.py
@@ -20,11 +20,13 @@
 import supervdsm
 import logging
 import traceback
+
+from mom.HypervisorInterfaces.CachingInterface import CachingInterface
 from mom.HypervisorInterfaces.HypervisorInterface import HypervisorInterface, \
     HypervisorInterfaceError
 
 
-class vdsmInterface(HypervisorInterface):
+class vdsmInterface(CachingInterface):
     """
     vdsmInterface provides a wrapper for the VDSM API so that VDSM-
     related error handling can be consolidated in one place.  An instance of
@@ -33,6 +35,7 @@
     """
 
     def __init__(self):
+        super(vdsmInterface, self).__init__(config)
         self.logger = logging.getLogger('mom.vdsmInterface')
         try:
             self.vdsm_api = API.Global()
@@ -85,29 +88,14 @@
             return None
 
     def getAllVmStats(self):
-        try:
-            response = self.vdsm_api.getAllVmStats()
-            self._check_status(response)
-            stats_list = response['statsList']
-            vm_stats = dict(
-                (stat['vmId'], translate_stats(stat))
-                for stat in stats_list)
-            self.logger.debug('VM Stats: %s', vm_stats.keys())
-            return vm_stats
-        except vdsmException, e:
-            e.handle_exception()
-            return None
+        return self._refresh()
 
     def getVmMemoryStats(self, uuid):
         try:
-            vm = API.VM(uuid)
-            response = vm.getStats()
-            self._check_status(response)
-            stats = response['statsList'][0]
-            err_msg = _check_vm_memory_stats(stats)
-            if err_msg:
-                raise HypervisorInterfaceError(err_msg)
-            ret = _memory_info_from_vm_stats(stats)
+            ret = {}
+            stats = self._getVmStats(uuid)
+            for field in self.getStatsFields():
+                ret[field] = stats[field]
             self.logger.debug('Memory stats: %s', ret)
             return ret
         except vdsmException, e:
@@ -121,15 +109,6 @@
         except vdsmException, e:
             e.handle_exception()
 
-    def getVmInfo(self, id):
-        data = {}
-        data['uuid'] = id
-        data['pid'] = self.getVmPid(id)
-        data['name'] = self.getVmName(id)
-        if None in data.values():
-            return None
-        return data
-
     def getStatsFields(self=None):
         return set(['mem_available', 'mem_unused', 'mem_free',
                     'major_fault', 'minor_fault', 'swap_in', 'swap_out',
@@ -137,27 +116,22 @@
 
     def getVmBalloonInfo(self, uuid):
         try:
-            vm = API.VM(uuid)
-            response = vm.getStats()
-            self._check_status(response)
-            ret = _balloon_info_from_vm_stats(response['statsList'][0])
-            if ret:
-                return ret
-            return None
+            ret = {}
+            stats = self._getVmStats(uuid)
+            for field in ("balloon_max", "balloon_min", "balloon_cur"):
+                ret[field] = stats[field]
+            return ret
         except vdsmException, e:
             e.handle_exception()
 
     def getVmCpuTuneInfo(self, uuid):
         try:
-            vm = API.VM(uuid)
-            response = vm.getStats()
-            self._check_status(response)
-            ret = _cpu_tune_info_from_vm_stats(response['statsList'][0])
-            if ret:
-                return ret
-            return None
-        except vdsmException, e:
-            e.handle_exception()
+            ret = {}
+            stats = self._getVmStats(uuid)
+            for field in ('vcpu_user_limit', 'vcpu_quota',
+                          'vcpu_period', 'vcpu_count'):
+                ret[field] = stats[field]
+            return ret
 
     def setVmCpuTune(self, uuid, quota, period):
         vm = API.VM(uuid)
@@ -178,6 +152,23 @@
         superVdsm = supervdsm.getProxy()
         superVdsm.ksmTune(tuningParams)
 
+    def _refreshVmStats(self):
+        return self._getAllVmStats()
+
+    def _getAllVmStats(self):
+        try:
+            response = self.vdsm_api.getAllVmStats()
+            self._check_status(response)
+            stats_list = response['statsList']
+            vm_stats = dict(
+                (stat['vmId'], translate_stats(stat))
+                for stat in stats_list)
+            self.logger.debug('VM Stats: %s', vm_stats.keys())
+            return vm_stats
+        except vdsmException, e:
+            e.handle_exception()
+            return None
+
 
 def _check_vm_memory_stats(vm_stats):
     usage = int(vm_stats['memUsage'])
diff --git a/mom/HypervisorInterfaces/vdsmrpcInterface.py 
b/mom/HypervisorInterfaces/vdsmrpcInterface.py
index b80bf44..81ddeec 100644
--- a/mom/HypervisorInterfaces/vdsmrpcInterface.py
+++ b/mom/HypervisorInterfaces/vdsmrpcInterface.py
@@ -27,20 +27,19 @@
 import stomp.exception
 
 from mom.ExpiringCache import ExpiringCache
+from mom.HypervisorInterfaces.CachingInterface import CachingInterface
 from mom.HypervisorInterfaces.HypervisorInterface import HypervisorInterface, \
     HypervisorInterfaceError
 from mom.HypervisorInterfaces.vdsmInterface import translate_stats
 
 
-class vdsmrpcInterface(HypervisorInterface):
+class vdsmrpcInterface(CachingInterface):
 
     def __init__(self, config):
-        self._config = config
+        super(vdsmrpcInterface, self).__init__(config)
         self.logger = logging.getLogger('mom.vdsmRpcInterface')
         self._intf = _json_rpc_interface_from_config(
             self.logger, self.config)
-        self._cache = ExpiringCache(
-            self._config.getint('vdsm', 'cache-lifetime'))
         self._intf.connect()
 
     def getVmList(self):
@@ -99,14 +98,6 @@
             self._call('VM.setBalloonTarget', vmID=uuid, target=target)
         except vdsmException, e:
             e.handle_exception()
-
-    def getVmInfo(self, vmId):
-        stats = self._getVmStats(vmId)
-        return {
-            'uuid': vmId,
-            'pid': stats['pid'],
-            'name': stats.get('vmName', 'VM-%s' % vmId)
-        }
 
     def getStatsFields(self=None):
         return set([
@@ -178,26 +169,12 @@
         for (key, val) in tuningParams.items():
             write_value('/sys/kernel/mm/ksm/%s' % key, val)
 
-    def _getVmStats(self, vmId):
-        stats = self._cache.get(vmId)
-        if stats is None:
-            self._refresh()
-
-            stats = self._cache.get(vmId)
-            if stats is None:
-                raise vdsmException('unavailable stats for %s' % vmId,
-                                    self.logger)
-        return stats
-
-    def _refresh(self):
+    def _refreshVmStats(self):
         self._logger.debug('refreshing all stats')
-        res = self._intf.call('Host.getAllVmStats')
-        if res['status']['code'] == 0:
-            for stats in res['statsList']:
-                try:
-                    self._cache[stats['vmId']] = stats
-                except KeyError:
-                    pass
+        try:
+            return self._getAllVmStats()
+        except vdsmException, e:
+            return []
 
 
 def _translate_memory_stats(ret, stats):


-- 
To view, visit https://gerrit.ovirt.org/41145
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I54cd218d40cb501f5164a2a60093ebc8f8695878
Gerrit-PatchSet: 1
Gerrit-Project: mom
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to