for python3: specfile and makefile, taking this chance for some overdue cleanups
[nodemanager.git] / sliver_libvirt.py
index a70d18f..cf6b0c2 100644 (file)
@@ -24,12 +24,33 @@ STATES = {
     libvirt.VIR_DOMAIN_CRASHED:  'crashed',
 }
 
-REASONS = {
-    libvirt.VIR_CONNECT_CLOSE_REASON_ERROR: 'Misc I/O error',
-    libvirt.VIR_CONNECT_CLOSE_REASON_EOF: 'End-of-file from server',
-    libvirt.VIR_CONNECT_CLOSE_REASON_KEEPALIVE: 'Keepalive timer triggered',
-    libvirt.VIR_CONNECT_CLOSE_REASON_CLIENT: 'Client requested it',
-}
+# with fedora24 and (broken) libvirt-python-1.3.3-3,
+# the following symbols are not available
+# kashyap on IRC reported that libvirt-python-1.3.5-1.fc24.x86_64
+# did not have the issue though
+try:
+    REASONS = {
+        # 0
+        libvirt.VIR_CONNECT_CLOSE_REASON_ERROR: 'Misc I/O error',
+        # 1
+        libvirt.VIR_CONNECT_CLOSE_REASON_EOF: 'End-of-file from server',
+        # 2
+        libvirt.VIR_CONNECT_CLOSE_REASON_KEEPALIVE: 'Keepalive timer triggered',
+        # 3
+        libvirt.VIR_CONNECT_CLOSE_REASON_CLIENT: 'Client requested it',
+    }
+except:
+    REASONS = {
+        # libvirt.VIR_CONNECT_CLOSE_REASON_ERROR
+        0 : 'Misc I/O error',
+        # libvirt.VIR_CONNECT_CLOSE_REASON_EOF
+        1 : 'End-of-file from server',
+        # libvirt.VIR_CONNECT_CLOSE_REASON_KEEPALIVE
+        2 : 'Keepalive timer triggered',
+        # libvirt.VIR_CONNECT_CLOSE_REASON_CLIENT
+        3 : 'Client requested it',
+    }
+    logger.log("WARNING : using hard-wired constants instead of symbolic names for CONNECT_CLOSE*")
 
 connections = dict()
 
@@ -41,11 +62,33 @@ class Sliver_Libvirt(Account):
 
     @staticmethod
     def getConnection(sliver_type):
-        # TODO: error checking
-        # vtype is of the form sliver.[LXC/QEMU] we need to lower case to lxc/qemu
+        """
+        returns a connection to the underlying libvirt service
+        a single connection is created and shared among slivers
+        this call ensures the connection is alive
+        and will reconnect if it appears to be necessary
+        """
+        # sliver_type comes from rec['type'] and is of the form sliver.{LXC,QEMU}
+        # so we need to lower case to lxc/qemu
         vtype = sliver_type.split('.')[1].lower()
-        uri = vtype + '://'
-        return connections.setdefault(uri, libvirt.open(uri))
+        uri = vtype + ':///'
+        if uri not in connections:
+            # create connection
+            conn = libvirt.open(uri)
+            connections[uri] = conn
+            return conn
+        else:
+            # connection already available : check for health
+            conn = connections[uri]
+            # see if a reconnection is needed
+            try:
+                numDomains = conn.numOfDomains()
+            except:
+                logger.log("libvirt connection to {} looks broken - reconnecting".format(uri))
+                conn = libvirt.open(uri)
+                # if this fails then an expection is thrown outside of this function
+                numDomains = conn.numOfDomains()
+            return conn
 
     def __init__(self, rec):
         self.name = rec['name']
@@ -146,6 +189,7 @@ class Sliver_Libvirt(Account):
         bwlimit.ebtables("-A INPUT -i veth{} -j mark --set-mark {}"
                          .format(self.xid, self.xid))
 
+    ### this is confusing, because it seems it is not used in fact
     def stop(self):
         logger.verbose('sliver_libvirt: {} stop'.format(self.name))