done prettifying
[bootmanager.git] / source / steps / UpdateNodeConfiguration.py
index b404ce2..4d16b16 100644 (file)
@@ -1,13 +1,25 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2003 Intel Corporation
+# All rights reserved.
+#
+# Copyright (c) 2004-2006 The Trustees of Princeton University
+# All rights reserved.
+
+
 import os
 
-import InstallWriteConfig
-import InstallBuildVServer
 from Exceptions import *
 import utils
 
 
+# if this file is present in the vservers /etc directory,
+# the resolv.conf and hosts files will automatically be updated
+# by the bootmanager
+UPDATE_FILE_FLAG = "AUTO_UPDATE_NET_FILES"
 
-def Run( vars, log ):
+
+def Run(vars, log):
     """
     Reconfigure a node if necessary, including rewriting any network init
     scripts based on what PLC has. Also, update any slivers on the machine
@@ -22,105 +34,182 @@ def Run( vars, log ):
     SYSIMG_PATH              the path where the system image will be mounted
                              (always starts with TEMP_PATH)
     ROOT_MOUNTED             the node root file system is mounted
-    NETWORK_SETTINGS  A dictionary of the values from the network
+    INTERFACE_SETTINGS  A dictionary of the values from the network
                                 configuration file
-    NODE_SESSION             the unique session val set when we requested
-                             the current boot state
-    PLCONF_DIR               The directory to store PL configuration files in
     """
     
-    log.write( "\n\nStep: Updating node configuration.\n" )
+    log.write("\n\nStep: Updating node configuration.\n")
 
     # make sure we have the variables we need
     try:
-        NETWORK_SETTINGS= vars["NETWORK_SETTINGS"]
-        if NETWORK_SETTINGS == "":
-            raise ValueError, "NETWORK_SETTINGS"
+        INTERFACE_SETTINGS = vars["INTERFACE_SETTINGS"]
+        if INTERFACE_SETTINGS == "":
+            raise ValueError("INTERFACE_SETTINGS")
 
-        SYSIMG_PATH= vars["SYSIMG_PATH"]
+        SYSIMG_PATH = vars["SYSIMG_PATH"]
         if SYSIMG_PATH == "":
-            raise ValueError, "SYSIMG_PATH"
+            raise ValueError("SYSIMG_PATH")
 
-        ROOT_MOUNTED= vars["ROOT_MOUNTED"]
+        ROOT_MOUNTED = vars["ROOT_MOUNTED"]
         if ROOT_MOUNTED == "":
-            raise ValueError, "ROOT_MOUNTED"
-
-        PLCONF_DIR= vars["PLCONF_DIR"]
-        if PLCONF_DIR == "":
-            raise ValueError, "PLCONF_DIR"
+            raise ValueError("ROOT_MOUNTED")
 
-        # its ok if this is blank
-        NODE_SESSION= vars["NODE_SESSION"]
-
-    except KeyError, var:
-        raise BootManagerException, "Missing variable in vars: %s\n" % var
-    except ValueError, var:
-        raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
+    except KeyError as var:
+        raise BootManagerException("Missing variable in vars: {}\n".format(var))
+    except ValueError as var:
+        raise BootManagerException("Variable in vars, shouldn't be: {}\n".format(var))
 
     try:
-        ip= NETWORK_SETTINGS['ip']
-        method= NETWORK_SETTINGS['method']
-        hostname= NETWORK_SETTINGS['hostname']
-        domainname= NETWORK_SETTINGS['domainname']
-    except KeyError, var:
-        raise BootManagerException, \
-              "Missing network value %s in var NETWORK_SETTINGS\n" % var
+        ip = INTERFACE_SETTINGS['ip']
+        method = INTERFACE_SETTINGS['method']
+        hostname = INTERFACE_SETTINGS['hostname']
+        domainname = INTERFACE_SETTINGS['domainname']
+    except KeyError as var:
+        raise BootManagerException(
+              "Missing network value {} in var INTERFACE_SETTINGS\n".format(var))
 
     
     if not ROOT_MOUNTED:
-        raise BootManagerException, "Root isn't mounted on SYSIMG_PATH\n"
-
-
-    log.write( "Updating node network configuration\n" )
-    InstallWriteConfig.write_network_configuration( vars, log )
+        raise BootManagerException("Root isn't mounted on SYSIMG_PATH\n")
 
-
-    log.write( "Updating vserver's /etc/hosts and /etc/resolv.conf files\n" )
+    log.write("Updating vserver's /etc/hosts and /etc/resolv.conf files\n")
 
     # create a list of the full directory paths of all the vserver images that
     # need to be updated.
-    update_path_list= []
+    update_path_list = []
 
-    for base_dir in ('/vservers','/vservers/.vcache'):
+    for base_dir in ('/vservers', '/vservers/.vref', '/vservers/.vcache'):
         try:
-            full_dir_path= "%s/%s" % (SYSIMG_PATH,base_dir)
-            slices= os.listdir( full_dir_path )
+            full_dir_path = "{}/{}".format(SYSIMG_PATH, base_dir)
+            slices = os.listdir(full_dir_path)
 
             try:
                 slices.remove("lost+found")
-            except ValueError, e:
+            except ValueError as e:
                 pass
             
-            update_path_list= update_path_list + map(lambda x: \
+            update_path_list = update_path_list + map(lambda x: \
                                                      full_dir_path+"/"+x,
                                                      slices)
-        except OSError, e:
+        except OSError as e:
             continue
 
 
-    log.write( "Updating network configuration in:\n" )
+    log.write("Updating network configuration in:\n")
     if len(update_path_list) == 0:
-        log.write( "No vserver images found to update.\n" )
+        log.write("No vserver images found to update.\n")
     else:
         for base_dir in update_path_list:
-            log.write( "%s\n" % base_dir )
+            log.write("{}\n".format(base_dir))
 
 
     # now, update /etc/hosts and /etc/resolv.conf in each dir if
     # the update flag is there
     for base_dir in update_path_list:
-        InstallBuildVServer.update_vserver_network_files(base_dir,vars,log)
+        update_vserver_network_files(base_dir, vars, log)
+    
+    return
 
 
-    # write out the session value /etc/planetlab/session
+
+def update_vserver_network_files(vserver_dir, vars, log):
+    """
+    Update the /etc/resolv.conf and /etc/hosts files in the specified
+    vserver directory. If the files do not exist, write them out. If they
+    do exist, rewrite them with new values if the file UPDATE_FILE_FLAG
+    exists it /etc. if this is called with the vserver-reference directory,
+    always update the network config files and create the UPDATE_FILE_FLAG.
+
+    This is currently called when setting up the initial vserver reference,
+    and later when nodes boot to update existing vserver images.
+
+    Expect the following variables from the store:
+    SYSIMG_PATH        the path where the system image will be mounted
+                       (always starts with TEMP_PATH)
+    INTERFACE_SETTINGS   A dictionary of the values from the network
+                       configuration file
+    """
+
     try:
-        session_file_path= "%s/%s/session" % (SYSIMG_PATH,PLCONF_DIR)
-        session_file= file( session_file_path, "w" )
-        session_file.write( str(NODE_SESSION) )
-        session_file.close()
-        session_file= None
-        log.write( "Updated /etc/planetlab/session" )
-    except IOError, e:
-        log.write( "Unable to write out /etc/planetlab/session, continuing anyway" )
-    
-    return
+        SYSIMG_PATH = vars["SYSIMG_PATH"]
+        if SYSIMG_PATH == "":
+            raise ValueError("SYSIMG_PATH")
+
+        INTERFACE_SETTINGS = vars["INTERFACE_SETTINGS"]
+        if INTERFACE_SETTINGS == "":
+            raise ValueError("INTERFACE_SETTINGS")
+
+    except KeyError as var:
+        raise BootManagerException("Missing variable in vars: {}\n".format(var))
+    except ValueError as var:
+        raise BootManagerException("Variable in vars, shouldn't be: {}\n".format(var))
+
+    try:
+        ip = INTERFACE_SETTINGS['ip']
+        method = INTERFACE_SETTINGS['method']
+        hostname = INTERFACE_SETTINGS['hostname']
+        domainname = INTERFACE_SETTINGS['domainname']
+    except KeyError as var:
+        raise BootManagerException(
+              "Missing network value {} in var INTERFACE_SETTINGS\n".format(var))
+
+    try:
+        os.listdir(vserver_dir)
+    except OSError:
+        log.write("Directory {} does not exist to write network conf in.\n"
+                  .format(vserver_dir))
+        return
+
+    file_path = "{}/etc/{}".format(vserver_dir, UPDATE_FILE_FLAG)
+    update_files = 0
+    if os.access(file_path, os.F_OK):
+        update_files = 1
+
+        
+    # Thierry - 2012/03 - I'm renaming vserver-reference into sliceimage
+    # however I can't quite grasp the reason for this test below, very likely 
+    # compatibility with very old node images or something
+    if '/.vref/' in vserver_dir or \
+       '/.vcache/' in vserver_dir or \
+       '/vserver-reference' in vserver_dir:
+        log.write("Forcing update on vserver reference directory:\n{}\n"
+                  .format(vserver_dir))
+        utils.sysexec_noerr("echo '{}' > {}/etc/{}"
+                            .format(UPDATE_FILE_FLAG, vserver_dir, UPDATE_FILE_FLAG),
+                             log)
+        update_files = 1
+        
+
+    if update_files:
+        log.write("Updating network files in {}.\n".format(vserver_dir))
+        try:
+            # NOTE: this works around a recurring problem on public pl,
+            # suspected to be due to mismatch between 2.6.12 bootcd and
+            # 2.6.22/f8 root environment.  files randomly show up with the
+            # immutible attribute set.  this clears it before trying to write
+            # the files below.
+            utils.sysexec("chattr -i {}/etc/hosts".format(vserver_dir), log)
+            utils.sysexec("chattr -i {}/etc/resolv.conf".format(vserver_dir), log)
+        except:
+            pass
+
+        
+        file_path = "{}/etc/hosts".format(vserver_dir)
+        hosts_file = file(file_path, "w")
+        hosts_file.write("127.0.0.1       localhost\n")
+        if method == "static":
+            hosts_file.write("{} {}.{}\n".format(ip, hostname, domainname))
+        hosts_file.close()
+        hosts_file = None
+
+        file_path = "{}/etc/resolv.conf".format(vserver_dir)
+        if method == "dhcp":
+            # copy the resolv.conf from the boot cd env.
+            utils.sysexec("cp /etc/resolv.conf {}/etc".format(vserver_dir), log)
+        else:
+            # copy the generated resolv.conf from the system image, since
+            # we generated it via static settings
+            utils.sysexec("cp {}/etc/resolv.conf {}/etc"
+                          .format(SYSIMG_PATH, vserver_dir), log)
+            
+    return