refactor of reboot_slivers() to cover f21 -- only ipv6 part is affected.
[nodemanager.git] / tools.py
index 42d63d1..fdfe50d 100644 (file)
--- a/tools.py
+++ b/tools.py
@@ -215,10 +215,11 @@ class NMLock:
 # running ifconfig inside of the slice's context.
 
 def get_sliver_process(slice_name, process_cmdline):
-    """ Utility function to find a process inside of an LXC sliver. Returns
-        (cgroup_fn, pid). cgroup_fn is the filename of the cgroup file for
-        the process, for example /proc/2592/cgroup. Pid is the process id of
-        the process. If the process is not found then (None, None) is returned.
+    """
+    Utility function to find a process inside of an LXC sliver. Returns
+    (cgroup_fn, pid). cgroup_fn is the filename of the cgroup file for
+    the process, for example /proc/2592/cgroup. Pid is the process id of
+    the process. If the process is not found then (None, None) is returned.
     """
     try:
         cmd = 'grep %s /proc/*/cgroup | grep freezer'%slice_name
@@ -236,11 +237,25 @@ def get_sliver_process(slice_name, process_cmdline):
             path = l.split(':')[0]
             comp = l.rsplit(':')[-1]
             slice_name_check = comp.rsplit('/')[-1]
-            # the lines above were added by Guilherme <gsm@machados.org>
-            # due to the ipv6 plugin requirements
+            # the lines below were added by Guilherme <gsm@machados.org>
+            # due to the LXC requirements
+            # What we have to consider here is that libervirt on Fedora 18
+            # uses the following line:
+            # /proc/1253/cgroup:6:freezer:/machine.slice/auto_sirius.libvirt-lxc
+            # While the libvirt on Fedora 20 and 21 uses the following line:
+            # /proc/1253/cgroup:6:freezer:/machine.slice/machine-lxc\x2del_sirius.scope
+            # Further documentation on:
+            # https://libvirt.org/cgroups.html#systemdScope
             virt=get_node_virt()
             if virt=='lxc':
-                slice_name_check = slice_name_check.rsplit('.')[0]
+                # This is for Fedora 20 or later
+                regexf20orlater = re.compile(r'machine-lxc\\x2d(.+).scope')
+                isf20orlater = regexf20orlater.search(slice_name_check)
+                if isf20orlater:
+                    slice_name_check = isf20orlater.group(1)
+                else:
+                    # This is for Fedora 18
+                    slice_name_check = slice_name_check.rsplit('.')[0]
 
             if (slice_name_check == slice_name):
                 slice_path = path
@@ -262,9 +277,12 @@ def get_sliver_process(slice_name, process_cmdline):
 # Added by Guilherme Sperb Machado <gsm@machados.org>
 ###################################################
 
-import re
-import socket
-import fileinput
+try:
+    import re
+    import socket
+    import fileinput
+except:
+    logger.log("Could not import 're', 'socket', or 'fileinput' python packages.")
 
 # TODO: is there anything better to do if the "libvirt", "sliver_libvirt",
 # and "sliver_lxc" are not in place?
@@ -273,13 +291,14 @@ try:
     from sliver_libvirt import Sliver_Libvirt
     import sliver_lxc
 except:
-    logger.log("Could not import sliver_lxc or libvirt or sliver_libvirt -- which is required here.")
+    logger.log("Could not import 'sliver_lxc' or 'libvirt' or 'sliver_libvirt'.")
 ###################################################
 
 def get_sliver_ifconfig(slice_name, device="eth0"):
-    """ return the output of "ifconfig" run from inside the sliver.
+    """
+    return the output of "ifconfig" run from inside the sliver.
 
-        side effects: adds "/usr/sbin" to sys.path
+    side effects: adds "/usr/sbin" to sys.path
     """
 
     # See if setns is installed. If it's not then we're probably not running
@@ -404,12 +423,23 @@ def reboot_slivers():
     domains = connLibvirt.listAllDomains()
     for domain in domains:
         try:
-            domain.destroy()
-            logger.log("tools: DESTROYED %s" % (domain.name()) )
-            domain.create()
-            logger.log("tools: CREATED %s" % (domain.name()) )
-        except:
-            logger.log("tools: FAILED to reboot %s" % (domain.name()) )
+            # set the flag VIR_DOMAIN_REBOOT_INITCTL, which uses "initctl"
+            result = domain.reboot(0x04)
+            if result==0: logger.log("tools: REBOOT %s" % (domain.name()) )
+            else:
+                raise Exception()
+        except Exception, e:
+            logger.log("tools: FAILED to reboot %s (%s)" % (domain.name(), e) )
+            logger.log("tools: Trying to DESTROY/CREATE %s instead..." % (domain.name()) )
+            try:
+                result = domain.destroy()
+                if result==0: logger.log("tools: DESTROYED %s" % (domain.name()) )
+                else: logger.log("tools: FAILED in the DESTROY call of %s" % (domain.name()) )
+                result = domain.create()
+                if result==0: logger.log("tools: CREATED %s" % (domain.name()) )
+                else: logger.log("tools: FAILED in the CREATE call of %s" % (domain.name()) )
+            except Exception, e:
+                logger.log("tools: FAILED to DESTROY/CREATE %s (%s)" % (domain.name(), e) )
 
 ###################################################
 # Author: Guilherme Sperb Machado <gsm@machados.org>
@@ -425,14 +455,25 @@ def get_hosts_file_path(slicename):
 ###################################################
 # Search if there is a specific ipv6 address in the
 # /etc/hosts file of a given slice
+# If the parameter 'ipv6addr' is None, then search
+# for any ipv6 address
 ###################################################
 def search_ipv6addr_hosts(slicename, ipv6addr):
     hostsFilePath = get_hosts_file_path(slicename)
     found=False
     try:
         for line in fileinput.input(r'%s' % (hostsFilePath)):
-            if re.search(r'%s' % (ipv6addr), line):
-                found=True
+            if ipv6addr is not None:
+                if re.search(r'%s' % (ipv6addr), line):
+                    found=True
+            else:
+                search = re.search(r'^(.*)\s+.*$', line)
+                if search:
+                    ipv6candidate = search.group(1)
+                    ipv6candidatestrip = ipv6candidate.strip()
+                    valid = is_valid_ipv6(ipv6candidatestrip)
+                    if valid:
+                        found=True
         fileinput.close()
         return found
     except: