tweak privatebridge to remove exception message when ovs is not installed - prints...
[nodemanager.git] / sliver_libvirt.py
index 6828bb3..5407cdc 100644 (file)
@@ -2,6 +2,7 @@
 
 import sys
 import os, os.path
+import re
 import subprocess
 import pprint
 import random
@@ -70,6 +71,23 @@ class Sliver_Libvirt(Account):
             dom = self.conn.lookupByName(self.name)
         self.dom = dom
 
+    @staticmethod
+    def dom_details (dom):
+        output=""
+        output += " id=%s - OSType=%s"%(dom.ID(),dom.OSType())
+        # calling state() seems to be working fine
+        (state,reason)=dom.state()
+        output += " state=%s, reason=%s"%(STATES.get(state,state),REASONS.get(reason,reason))
+        try:
+            # try to use info() - this however does not work for some reason on f20
+            # info cannot get info operation failed: Cannot read cputime for domain
+            [state, maxmem, mem, ncpu, cputime] = dom.info()
+            output += " [info: maxmem = %s, mem = %s, ncpu = %s, cputime = %s]" % (STATES.get(state, state), maxmem, mem, ncpu, cputime)
+        except:
+            # too bad but libvirt.py prints out stuff on stdout when this fails, don't know how to get rid of that..
+            output += " [info: not available]"
+        return output
+
     def __repr__(self):
         ''' Helper method to get a "nice" output of the domain struct for debug purposes'''
         output="Domain %s"%self.name
@@ -77,20 +95,23 @@ class Sliver_Libvirt(Account):
         if dom is None: 
             output += " [no attached dom ?!?]"
         else:
-            output += " id=%s - OSType=%s"%(dom.ID(),dom.OSType())
-            # calling state() seems to be working fine
-            (state,reason)=dom.state()
-            output += " state=%s, reason=%s"%(STATES.get(state,state),REASONS.get(reason,reason))
-            try:
-                # try to use info() - this however does not work for some reason on f20
-                # info cannot get info operation failed: Cannot read cputime for domain
-                [state, maxmem, mem, ncpu, cputime] = dom.info()
-                output += " [info: maxmem = %s, mem = %s, ncpu = %s, cputime = %s]" % (STATES.get(state, state), maxmem, mem, ncpu, cputime)
-            except:
-                # too bad but libvirt.py prints out stuff on stdout when this fails, don't know how to get rid of that..
-                output += " [info: not available]"
+            output += Sliver_Libvirt.dom_details (dom)
         return output
-            
+
+    # Thierry : I am not quite sure if /etc/libvirt/lxc/<>.xml holds a reliably up-to-date
+    # copy of the sliver XML config; I feel like issuing a virsh dumpxml first might be safer
+    def repair_veth(self):
+        # See workaround email, 2-14-2014, "libvirt 1.2.1 rollout"
+        xml = open("/etc/libvirt/lxc/%s.xml" % self.name).read()
+        veths = re.findall("<target dev='veth[0-9]*'/>", xml)
+        veths = [x[13:-3] for x in veths]
+        for veth in veths:
+            command = ["ip", "link", "delete", veth]
+            logger.log_call(command)
+
+        logger.log("trying to redefine the VM")
+        command = ["virsh", "define", "/etc/libvirt/lxc/%s.xml" % self.name]
+        logger.log_call(command)
 
     def start(self, delay=0):
         ''' Just start the sliver '''
@@ -99,7 +120,18 @@ class Sliver_Libvirt(Account):
         # Check if it's running to avoid throwing an exception if the
         # domain was already running, create actually means start
         if not self.is_running():
-            self.dom.create()
+            try:
+                self.dom.create()
+            except Exception, e:
+                # XXX smbaker: attempt to resolve slivers that are stuck in
+                #   "failed to allocate free veth".
+                if "ailed to allocate free veth" in str(e):
+                     logger.log("failed to allocate free veth on %s" % self.name)
+                     self.repair_veth()
+                     logger.log("trying dom.create again")
+                     self.dom.create()
+                else:
+                    raise
         else:
             logger.verbose('sliver_libvirt: sliver %s already started'%(self.name))