[Kimchi-devel] [PATCH 06/13] refactor model: Create a separated model for libvirt connection

Aline Manera alinefm at linux.vnet.ibm.com
Fri Jan 17 02:24:42 UTC 2014


From: Aline Manera <alinefm at br.ibm.com>

Libvirt connection is a base facility for kimchi model, so each
resource model should be able to access it directly.

Signed-off-by: Aline Manera <alinefm at br.ibm.com>
---
 src/kimchi/model.py                    |   93 +-----------------------
 src/kimchi/model_/libvirtconnection.py |  123 ++++++++++++++++++++++++++++++++
 2 files changed, 124 insertions(+), 92 deletions(-)
 create mode 100644 src/kimchi/model_/libvirtconnection.py

diff --git a/src/kimchi/model.py b/src/kimchi/model.py
index 2c6d3a1..0577088 100644
--- a/src/kimchi/model.py
+++ b/src/kimchi/model.py
@@ -67,6 +67,7 @@ from kimchi.exception import MissingParameter, NotFoundError, OperationFailed
 from kimchi.featuretests import FeatureTests
 from kimchi.iscsi import TargetClient
 from kimchi.isoinfo import IsoImage
+from kimchi.model_.libvirtconnection import LibvirtConnection
 from kimchi.objectstore import ObjectStore
 from kimchi.scan import Scanner
 from kimchi.screenshot import VMScreenshot
@@ -1733,95 +1734,3 @@ def _get_volume_xml(**kwargs):
     </volume>
     """ % kwargs
     return xml
-
-
-class LibvirtConnection(object):
-    def __init__(self, uri):
-        self.uri = uri
-        self._connections = {}
-        self._connectionLock = threading.Lock()
-        self.wrappables = self.get_wrappable_objects()
-
-    def get_wrappable_objects(self):
-        """
-        When a wrapped function returns an instance of another libvirt object,
-        we also want to wrap that object so we can catch errors that happen when
-        calling its methods.
-        """
-        objs = []
-        for name in ('virDomain', 'virDomainSnapshot', 'virInterface',
-                     'virNWFilter', 'virNetwork', 'virNodeDevice', 'virSecret',
-                     'virStoragePool', 'virStorageVol', 'virStream'):
-            try:
-                attr = getattr(libvirt, name)
-            except AttributeError:
-                pass
-            objs.append(attr)
-        return tuple(objs)
-
-    def get(self, conn_id=0):
-        """
-        Return current connection to libvirt or open a new one.  Wrap all
-        callable libvirt methods so we can catch connection errors and handle
-        them by restarting the server.
-        """
-        def wrapMethod(f):
-            def wrapper(*args, **kwargs):
-                try:
-                    ret = f(*args, **kwargs)
-                    return ret
-                except libvirt.libvirtError as e:
-                    edom = e.get_error_domain()
-                    ecode = e.get_error_code()
-                    EDOMAINS = (libvirt.VIR_FROM_REMOTE,
-                                libvirt.VIR_FROM_RPC)
-                    ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
-                              libvirt.VIR_ERR_INTERNAL_ERROR,
-                              libvirt.VIR_ERR_NO_CONNECT,
-                              libvirt.VIR_ERR_INVALID_CONN)
-                    if edom in EDOMAINS and ecode in ECODES:
-                        kimchi_log.error('Connection to libvirt broken. '
-                                         'Recycling. ecode: %d edom: %d' %
-                                         (ecode, edom))
-                        with self._connectionLock:
-                            self._connections[conn_id] = None
-                    raise
-            wrapper.__name__ = f.__name__
-            wrapper.__doc__ = f.__doc__
-            return wrapper
-
-        with self._connectionLock:
-            conn = self._connections.get(conn_id)
-            if not conn:
-                retries = 5
-                while True:
-                    retries = retries - 1
-                    try:
-                        conn = libvirt.open(self.uri)
-                        break
-                    except libvirt.libvirtError:
-                        kimchi_log.error('Unable to connect to libvirt.')
-                        if not retries:
-                            kimchi_log.error('Libvirt is not available, exiting.')
-                            cherrypy.engine.stop()
-                            raise
-                    time.sleep(2)
-
-                for name in dir(libvirt.virConnect):
-                    method = getattr(conn, name)
-                    if callable(method) and not name.startswith('_'):
-                        setattr(conn, name, wrapMethod(method))
-
-                for cls in self.wrappables:
-                    for name in dir(cls):
-                        method = getattr(cls, name)
-                        if callable(method) and not name.startswith('_'):
-                            setattr(cls, name, wrapMethod(method))
-
-                self._connections[conn_id] = conn
-                # In case we're running into troubles with keeping the connections
-                # alive we should place here:
-                # conn.setKeepAlive(interval=5, count=3)
-                # However the values need to be considered wisely to not affect
-                # hosts which are hosting a lot of virtual machines
-            return conn
diff --git a/src/kimchi/model_/libvirtconnection.py b/src/kimchi/model_/libvirtconnection.py
new file mode 100644
index 0000000..9276acc
--- /dev/null
+++ b/src/kimchi/model_/libvirtconnection.py
@@ -0,0 +1,123 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# Authors:
+#  Adam Litke <agl at linux.vnet.ibm.com>
+#  Aline Manera <alinefm at linux.vnet.ibm.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+
+import cherrypy
+import libvirt
+import threading
+import time
+
+
+from kimchi.utils import kimchi_log
+
+
+class LibvirtConnection(object):
+    def __init__(self, uri):
+        self.uri = uri
+        self._connections = {}
+        self._connectionLock = threading.Lock()
+        self.wrappables = self.get_wrappable_objects()
+
+    def get_wrappable_objects(self):
+        """
+        When a wrapped function returns an instance of another libvirt object,
+        we also want to wrap that object so we can catch errors that happen
+        when calling its methods.
+        """
+        objs = []
+        for name in ('virDomain', 'virDomainSnapshot', 'virInterface',
+                     'virNWFilter', 'virNetwork', 'virNodeDevice', 'virSecret',
+                     'virStoragePool', 'virStorageVol', 'virStream'):
+            try:
+                attr = getattr(libvirt, name)
+            except AttributeError:
+                pass
+            objs.append(attr)
+        return tuple(objs)
+
+    def get(self, conn_id=0):
+        """
+        Return current connection to libvirt or open a new one.  Wrap all
+        callable libvirt methods so we can catch connection errors and handle
+        them by restarting the server.
+        """
+        def wrapMethod(f):
+            def wrapper(*args, **kwargs):
+                try:
+                    ret = f(*args, **kwargs)
+                    return ret
+                except libvirt.libvirtError as e:
+                    edom = e.get_error_domain()
+                    ecode = e.get_error_code()
+                    EDOMAINS = (libvirt.VIR_FROM_REMOTE,
+                                libvirt.VIR_FROM_RPC)
+                    ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
+                              libvirt.VIR_ERR_INTERNAL_ERROR,
+                              libvirt.VIR_ERR_NO_CONNECT,
+                              libvirt.VIR_ERR_INVALID_CONN)
+                    if edom in EDOMAINS and ecode in ECODES:
+                        kimchi_log.error('Connection to libvirt broken. '
+                                         'Recycling. ecode: %d edom: %d' %
+                                         (ecode, edom))
+                        with self._connectionLock:
+                            self._connections[conn_id] = None
+                    raise
+            wrapper.__name__ = f.__name__
+            wrapper.__doc__ = f.__doc__
+            return wrapper
+
+        with self._connectionLock:
+            conn = self._connections.get(conn_id)
+            if not conn:
+                retries = 5
+                while True:
+                    retries = retries - 1
+                    try:
+                        conn = libvirt.open(self.uri)
+                        break
+                    except libvirt.libvirtError:
+                        kimchi_log.error('Unable to connect to libvirt.')
+                        if not retries:
+                            msg = 'Libvirt is not available, exiting.'
+                            kimchi_log.error(msg)
+                            cherrypy.engine.stop()
+                            raise
+                    time.sleep(2)
+
+                for name in dir(libvirt.virConnect):
+                    method = getattr(conn, name)
+                    if callable(method) and not name.startswith('_'):
+                        setattr(conn, name, wrapMethod(method))
+
+                for cls in self.wrappables:
+                    for name in dir(cls):
+                        method = getattr(cls, name)
+                        if callable(method) and not name.startswith('_'):
+                            setattr(cls, name, wrapMethod(method))
+
+                self._connections[conn_id] = conn
+                # In case we're running into troubles with keeping the
+                # connections alive we should place here:
+                # conn.setKeepAlive(interval=5, count=3)
+                # However the values need to be considered wisely to not affect
+                # hosts which are hosting a lot of virtual machines
+            return conn
-- 
1.7.10.4




More information about the Kimchi-devel mailing list