shebags mention python2 explicitly
[bootmanager.git] / source / steps / ReadNodeConfiguration.py
index 295a365..efa44c4 100644 (file)
@@ -1,5 +1,5 @@
 #!/usr/bin/python2
 #!/usr/bin/python2
-
+#
 # Copyright (c) 2003 Intel Corporation
 # All rights reserved.
 #
 # Copyright (c) 2003 Intel Corporation
 # All rights reserved.
 #
@@ -17,15 +17,15 @@ from Exceptions import *
 import BootServerRequest
 import BootAPI
 import notify_messages
 import BootServerRequest
 import BootAPI
 import notify_messages
-import UpdateBootStateWithPLC
+import UpdateRunLevelWithPLC
 
 
 # two possible names of the configuration files
 
 
 # two possible names of the configuration files
-NEW_CONF_FILE_NAME= "plnode.txt"
-OLD_CONF_FILE_NAME= "planet.cnf"
+NEW_CONF_FILE_NAME = "plnode.txt"
+OLD_CONF_FILE_NAME = "planet.cnf"
 
 
 
 
-def Run( vars, log ):   
+def Run(vars, log):   
     """
     read the machines node configuration file, which contains
     the node key and the node_id for this machine.
     """
     read the machines node configuration file, which contains
     the node key and the node_id for this machine.
@@ -50,16 +50,13 @@ def Run( vars, log ):
     and read, return 1.
 
     Expect the following variables from the store:
     and read, return 1.
 
     Expect the following variables from the store:
-    BOOT_CD_VERSION          A tuple of the current bootcd version
-    SUPPORT_FILE_DIR         directory on the boot servers containing
-                             scripts and support files
     
     Sets the following variables from the configuration file:
     WAS_NODE_ID_IN_CONF         Set to 1 if the node id was in the conf file
     WAS_NODE_KEY_IN_CONF         Set to 1 if the node key was in the conf file
     NONE_ID                     The db node_id for this machine
     NODE_KEY                    The key for this node
     
     Sets the following variables from the configuration file:
     WAS_NODE_ID_IN_CONF         Set to 1 if the node id was in the conf file
     WAS_NODE_KEY_IN_CONF         Set to 1 if the node key was in the conf file
     NONE_ID                     The db node_id for this machine
     NODE_KEY                    The key for this node
-    NETWORK_SETTINGS            A dictionary of the values from the network
+    INTERFACE_SETTINGS            A dictionary of the values from the network
                                 configuration file. keys set:
                                    method               IP_METHOD
                                    ip                   IP_ADDRESS
                                 configuration file. keys set:
                                    method               IP_METHOD
                                    ip                   IP_ADDRESS
@@ -72,297 +69,291 @@ def Run( vars, log ):
                                    dns2                 IP_DNS2
                                    hostname             HOST_NAME
                                    domainname           DOMAIN_NAME
                                    dns2                 IP_DNS2
                                    hostname             HOST_NAME
                                    domainname           DOMAIN_NAME
+                                -- wlan oriented --
+                                   ssid                 WLAN_SSID
+                                   iwconfig             WLAN_IWCONFIG
 
     the mac address is read from the machine unless it exists in the
     configuration file.
     """
 
 
     the mac address is read from the machine unless it exists in the
     configuration file.
     """
 
-    log.write( "\n\nStep: Reading node configuration file.\n" )
+    log.write("\n\nStep: Reading node configuration file.\n")
 
 
     # make sure we have the variables we need
 
 
     # make sure we have the variables we need
-    try:
-        BOOT_CD_VERSION= vars["BOOT_CD_VERSION"]
-        if BOOT_CD_VERSION == "":
-            raise ValueError, "BOOT_CD_VERSION"
-
-        SUPPORT_FILE_DIR= vars["SUPPORT_FILE_DIR"]
-        if SUPPORT_FILE_DIR == None:
-            raise ValueError, "SUPPORT_FILE_DIR"
-
-    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
-
-
-    NETWORK_SETTINGS= {}
-    NETWORK_SETTINGS['method']= "dhcp"
-    NETWORK_SETTINGS['ip']= ""
-    NETWORK_SETTINGS['mac']= ""
-    NETWORK_SETTINGS['gateway']= ""
-    NETWORK_SETTINGS['network']= ""
-    NETWORK_SETTINGS['broadcast']= ""
-    NETWORK_SETTINGS['netmask']= ""
-    NETWORK_SETTINGS['dns1']= ""
-    NETWORK_SETTINGS['dns2']= ""
-    NETWORK_SETTINGS['hostname']= "localhost"
-    NETWORK_SETTINGS['domainname']= "localdomain"
-    vars['NETWORK_SETTINGS']= NETWORK_SETTINGS
-
-    vars['NODE_ID']= 0
-    vars['NODE_KEY']= ""
-
-    vars['WAS_NODE_ID_IN_CONF']= 0
-    vars['WAS_NODE_KEY_IN_CONF']= 0
-
-    vars['DISCONNECTED_OPERATION']= ''
+
+    INTERFACE_SETTINGS = {}
+    INTERFACE_SETTINGS['method'] = "dhcp"
+    INTERFACE_SETTINGS['ip'] = ""
+    INTERFACE_SETTINGS['mac'] = ""
+    INTERFACE_SETTINGS['gateway'] = ""
+    INTERFACE_SETTINGS['network'] = ""
+    INTERFACE_SETTINGS['broadcast'] = ""
+    INTERFACE_SETTINGS['netmask'] = ""
+    INTERFACE_SETTINGS['dns1'] = ""
+    INTERFACE_SETTINGS['dns2'] = ""
+    INTERFACE_SETTINGS['hostname'] = "localhost"
+    INTERFACE_SETTINGS['domainname'] = "localdomain"
+    vars['INTERFACE_SETTINGS'] = INTERFACE_SETTINGS
+
+    vars['NODE_ID'] = 0
+    vars['NODE_KEY'] = ""
+
+    vars['WAS_NODE_ID_IN_CONF'] = 0
+    vars['WAS_NODE_KEY_IN_CONF'] = 0
+
+    vars['DISCONNECTED_OPERATION'] = ''
 
     # for any devices that need to be mounted to get the configuration
     # file, mount them here.
 
     # for any devices that need to be mounted to get the configuration
     # file, mount them here.
-    mount_point= "/tmp/conffilemount"
-    utils.makedirs( mount_point )
+    mount_point = "/tmp/conffilemount"
+    utils.makedirs(mount_point)
 
 
-    old_conf_file_contents= None
-    conf_file_contents= None
+    old_conf_file_contents = None
+    conf_file_contents = None
     
     
     # 1. check the regular floppy device
     
     
     # 1. check the regular floppy device
-    log.write( "Checking standard floppy disk for plnode.txt file.\n" )
+    log.write("Checking standard floppy disk for plnode.txt file.\n")
 
 
-    log.write( "Mounting /dev/fd0 on %s\n" % mount_point )
-    utils.sysexec_noerr( "mount -o ro -t ext2,msdos /dev/fd0 %s " \
-                         % mount_point, log )
+    log.write("Mounting /dev/fd0 on {}\n".format(mount_point))
+    utils.sysexec_noerr("mount -o ro -t ext2,msdos /dev/fd0 {} "
+                        .format(mount_point), log)
 
 
-    conf_file_path= "%s/%s" % (mount_point,NEW_CONF_FILE_NAME)
+    conf_file_path = "{}/{}".format(mount_point, NEW_CONF_FILE_NAME)
     
     
-    log.write( "Checking for existence of %s\n" % conf_file_path )
-    if os.access( conf_file_path, os.R_OK ):
+#    log.write("Checking for existence of {}\n".format(conf_file_path))
+    if os.access(conf_file_path, os.R_OK):
         try:
         try:
-            conf_file= file(conf_file_path,"r")
-            conf_file_contents= conf_file.read()
+            conf_file = file(conf_file_path,"r")
+            conf_file_contents = conf_file.read()
             conf_file.close()
             conf_file.close()
-            log.write( "Read in contents of file %s\n" % conf_file_path )
-        except IOError, e:
-            log.write( "Unable to read file %s\n" % conf_file_path )
+            log.write("Read in contents of file {}\n".format(conf_file_path))
+        except IOError as e:
+            log.write("Unable to read file {}\n".format(conf_file_path))
             pass
 
             pass
 
-        utils.sysexec_noerr( "umount %s" % mount_point, log )
-        if __parse_configuration_file( vars, log, conf_file_contents):
+        utils.sysexec_noerr("umount {}".format(mount_point), log)
+        if __parse_configuration_file(vars, log, conf_file_contents):
+            log.write("ReadNodeConfiguration: [1] using {} from floppy /dev/fd0\n"
+                      .format(NEW_CONF_FILE_NAME))
             return 1
         else:
             return 1
         else:
-            raise BootManagerException( "Found configuration file plnode.txt " \
-                                        "on floppy, but was unable to parse it." )
+            raise BootManagerException("Found configuration file plnode.txt "
+                                        "on floppy, but was unable to parse it.")
 
 
     # try the old file name, same device. its actually number 3 on the search
     # order, but do it now to save mounting/unmounting the disk twice.
     # try to parse it later...
 
 
     # try the old file name, same device. its actually number 3 on the search
     # order, but do it now to save mounting/unmounting the disk twice.
     # try to parse it later...
-    conf_file_path= "%s/%s" % (mount_point,OLD_CONF_FILE_NAME)
+    conf_file_path = "{}/{}".format(mount_point, OLD_CONF_FILE_NAME)
 
 
-    log.write( "Checking for existence of %s (used later)\n" % conf_file_path )
-    if os.access( conf_file_path, os.R_OK ):
+# this message really does not convey any useful information
+#    log.write("Checking for existence of %s (used later)\n" % conf_file_path)
+    if os.access(conf_file_path, os.R_OK):
         try:
         try:
-            old_conf_file= file(conf_file_path,"r")
-            old_conf_file_contents= old_conf_file.read()
+            old_conf_file = file(conf_file_path, "r")
+            old_conf_file_contents = old_conf_file.read()
             old_conf_file.close()
             old_conf_file.close()
-            log.write( "Read in contents of file %s\n" % conf_file_path )
-        except IOError, e:
-            log.write( "Unable to read file %s\n" % conf_file_path )
+            log.write("Read in contents of file {}\n".format(conf_file_path))
+        except IOError as e:
+            log.write("Unable to read file {}\n".format(conf_file_path))
             pass
         
             pass
         
-    utils.sysexec_noerr( "umount %s" % mount_point, log )
-
+    utils.sysexec_noerr("umount {}".format(mount_point), log)
 
 
+    # 2. check flash devices on 3.0 based cds
+    log.write("Checking flash devices for plnode.txt file.\n")
 
 
-    if BOOT_CD_VERSION[0] >= 3:
-        # 2. check flash devices on 3.0 based cds
-        log.write( "Checking flash devices for plnode.txt file.\n" )
+    # this is done the same way the 3.0 cds do it, by attempting
+    # to mount and sd*1 devices that are removable
+    devices = os.listdir("/sys/block/")
 
 
-        # this is done the same way the 3.0 cds do it, by attempting
-        # to mount and sd*1 devices that are removable
-        devices= os.listdir("/sys/block/")
+    for device in devices:
+        if device[:2] != "sd":
+            log.write("Skipping non-scsi device {}\n".format(device))
+            continue
 
 
-        for device in devices:
-            if device[:2] != "sd":
-                log.write( "Skipping non-scsi device %s\n" % device )
+        # test removable
+        removable_file_path = "/sys/block/{}/removable".format(device)
+        try:
+            removable = int(file(removable_file_path,"r").read().strip())
+        except ValueError as e:
+            continue
+        except IOError as e:
+            continue
+
+        if not removable:
+            log.write("Skipping non-removable device {}\n".format(device))
+            continue
+
+        log.write("Checking removable device {}\n".format(device))
+
+        partitions = file("/proc/partitions", "r")
+        for line in partitions:
+            found_file = 0
+            parsed_file = 0
+            
+            if not re.search("{}[0-9]*$".format(device), line):
                 continue
 
                 continue
 
-            # test removable
-            removable_file_path= "/sys/block/%s/removable" % device
             try:
             try:
-                removable= int(file(removable_file_path,"r").read().strip())
-            except ValueError, e:
-                continue
-            except IOError, e:
-                continue
+                # major minor  #blocks  name
+                parts = string.split(line)
 
 
-            if not removable:
-                log.write( "Skipping non-removable device %s\n" % device )
+                # ok, try to mount it and see if we have a conf file.
+                full_device = "/dev/{}".format(parts[3])
+            except IndexError as e:
+                log.write("Incorrect /proc/partitions line:\n{}\n".format(line))
                 continue
 
                 continue
 
-            log.write( "Checking removable device %s\n" % device )
-
-            partitions= file("/proc/partitions", "r")
-            for line in partitions:
-                found_file= 0
-                parsed_file= 0
-                
-                if not re.search("%s[0-9]*$" % device, line):
-                    continue
-
-                try:
-                    # major minor  #blocks  name
-                    parts= string.split(line)
+            log.write("Mounting {} on {}\n".format(full_device, mount_point))
+            try:
+                utils.sysexec("mount -o ro -t ext2,msdos {} {}"
+                              .format(full_device, mount_point), log)
+            except BootManagerException as e:
+                log.write("Unable to mount, trying next partition\n")
+                continue
 
 
-                    # ok, try to mount it and see if we have a conf file.
-                    full_device= "/dev/%s" % parts[3]
-                except IndexError, e:
-                    log.write( "Incorrect /proc/partitions line:\n%s\n" % line )
-                    continue
+            conf_file_path = "{}/{}".format(mount_point, NEW_CONF_FILE_NAME)
 
 
-                log.write( "Mounting %s on %s\n" % (full_device,mount_point) )
+            log.write("Checking for existence of {}\n".format(conf_file_path))
+            if os.access(conf_file_path, os.R_OK):
                 try:
                 try:
-                    utils.sysexec( "mount -o ro -t ext2,msdos %s %s" \
-                                   % (full_device,mount_point), log )
-                except BootManagerException, e:
-                    log.write( "Unable to mount, trying next partition\n" )
-                    continue
-
-                conf_file_path= "%s/%s" % (mount_point,NEW_CONF_FILE_NAME)
-
-                log.write( "Checking for existence of %s\n" % conf_file_path )
-                if os.access( conf_file_path, os.R_OK ):
-                    try:
-                        conf_file= file(conf_file_path,"r")
-                        conf_file_contents= conf_file.read()
-                        conf_file.close()
-                        found_file= 1
-                        log.write( "Read in contents of file %s\n" % \
-                                   conf_file_path )
-
-                        if __parse_configuration_file( vars, log, \
-                                                       conf_file_contents):
-                            parsed_file= 1
-                    except IOError, e:
-                        log.write( "Unable to read file %s\n" % conf_file_path )
-
-                utils.sysexec_noerr( "umount %s" % mount_point, log )
-                if found_file:
-                    if parsed_file:
-                        return 1
-                    else:
-                        raise BootManagerException( \
-                            "Found configuration file plnode.txt " \
-                            "on floppy, but was unable to parse it.")
+                    conf_file = file(conf_file_path,"r")
+                    conf_file_contents = conf_file.read()
+                    conf_file.close()
+                    found_file = 1
+                    log.write("Read in contents of file {}\n"
+                              .format(conf_file_path))
+
+                    if __parse_configuration_file(vars, log, conf_file_contents):
+                        parsed_file = 1
+                except IOError as e:
+                    log.write("Unable to read file {}\n".format(conf_file_path))
+
+            utils.sysexec_noerr("umount {}".format(mount_point), log)
+            if found_file:
+                if parsed_file:
+                    log.write("ReadNodeConfiguration: [2] using {} from partition {}\n"
+                              .format(NEW_CONF_FILE_NAME, full_device))
+                    return 1
+                else:
+                    raise BootManagerException("Found configuration file on {}, "
+                                               "but was unable to parse it.".format(full_device))
 
 
             
     # 3. check standard floppy disk for old file name planet.cnf
 
 
             
     # 3. check standard floppy disk for old file name planet.cnf
-    log.write( "Checking standard floppy disk for planet.cnf file " \
-               "(from earlier.\n" )
+    log.write("Checking standard floppy disk for planet.cnf file (for legacy nodes).\n")
 
     if old_conf_file_contents:
 
     if old_conf_file_contents:
-        if __parse_configuration_file( vars, log, old_conf_file_contents):
+        if __parse_configuration_file(vars, log, old_conf_file_contents):
+            log.write("ReadNodeConfiguration: [3] using {} from floppy /dev/fd0\n"
+                      .format(OLD_CONF_FILE_NAME))
             return 1
         else:
             return 1
         else:
-            raise BootManagerException( "Found configuration file planet.cnf " \
-                                        "on floppy, but was unable to parse it." )
+            raise BootManagerException("Found configuration file planet.cnf "
+                                        "on floppy, but was unable to parse it.")
 
 
     # 4. check for plnode.txt in / (ramdisk)
 
 
     # 4. check for plnode.txt in / (ramdisk)
-    log.write( "Checking / (ramdisk) for plnode.txt file.\n" )
+    log.write("Checking / (ramdisk) for plnode.txt file.\n")
     
     
-    conf_file_path= "/%s" % NEW_CONF_FILE_NAME
+    conf_file_path = "/{}".format(NEW_CONF_FILE_NAME)
 
 
-    log.write( "Checking for existence of %s\n" % conf_file_path )
+    log.write("Checking for existence of {}\n".format(conf_file_path))
     if os.access(conf_file_path,os.R_OK):
         try:
     if os.access(conf_file_path,os.R_OK):
         try:
-            conf_file= file(conf_file_path,"r")
-            conf_file_contents= conf_file.read()
+            conf_file = file(conf_file_path,"r")
+            conf_file_contents = conf_file.read()
             conf_file.close()
             conf_file.close()
-            log.write( "Read in contents of file %s\n" % conf_file_path )
-        except IOError, e:
-            log.write( "Unable to read file %s\n" % conf_file_path )
+            log.write("Read in contents of file {}\n".format(conf_file_path))
+        except IOError as e:
+            log.write("Unable to read file {}\n".format(conf_file_path))
             pass
     
             pass
     
-        if __parse_configuration_file( vars, log, conf_file_contents):            
+        if __parse_configuration_file(vars, log, conf_file_contents):            
+            log.write("ReadNodeConfiguration: [4] using {} from ramdisk\n"
+                      .format(NEW_CONF_FILE_NAME))
             return 1
         else:
             return 1
         else:
-            raise BootManagerException( "Found configuration file plnode.txt " \
+            raise BootManagerException("Found configuration file plnode.txt "
                                         "in /, but was unable to parse it.")
 
     
     # 5. check for plnode.txt in /usr/boot (mounted already)
                                         "in /, but was unable to parse it.")
 
     
     # 5. check for plnode.txt in /usr/boot (mounted already)
-    log.write( "Checking /usr/boot (cd) for plnode.txt file.\n" )
+    log.write("Checking /usr/boot (cd) for plnode.txt file.\n")
     
     
-    conf_file_path= "/usr/boot/%s" % NEW_CONF_FILE_NAME
+    conf_file_path = "/usr/boot/{}".format(NEW_CONF_FILE_NAME)
 
 
-    log.write( "Checking for existence of %s\n" % conf_file_path )
+    log.write("Checking for existence of {}\n".format(conf_file_path))
     if os.access(conf_file_path,os.R_OK):
         try:
     if os.access(conf_file_path,os.R_OK):
         try:
-            conf_file= file(conf_file_path,"r")
-            conf_file_contents= conf_file.read()
+            conf_file = file(conf_file_path,"r")
+            conf_file_contents = conf_file.read()
             conf_file.close()
             conf_file.close()
-            log.write( "Read in contents of file %s\n" % conf_file_path )
-        except IOError, e:
-            log.write( "Unable to read file %s\n" % conf_file_path )
+            log.write("Read in contents of file {}\n".format(conf_file_path))
+        except IOError as e:
+            log.write("Unable to read file {}\n".format(conf_file_path))
             pass
     
             pass
     
-        if __parse_configuration_file( vars, log, conf_file_contents):            
+        if __parse_configuration_file(vars, log, conf_file_contents):            
+            log.write("ReadNodeConfiguration: [5] using {} from CD in /usr/boot\n"
+                      .format(NEW_CONF_FILE_NAME))
             return 1
         else:
             return 1
         else:
-            raise BootManagerException( "Found configuration file plnode.txt " \
+            raise BootManagerException("Found configuration file plnode.txt "
                                         "in /usr/boot, but was unable to parse it.")
 
 
 
     # 6. check for plnode.txt in /usr (mounted already)
                                         "in /usr/boot, but was unable to parse it.")
 
 
 
     # 6. check for plnode.txt in /usr (mounted already)
-    log.write( "Checking /usr (cd) for plnode.txt file.\n" )
+    log.write("Checking /usr (cd) for plnode.txt file.\n")
     
     
-    conf_file_path= "/usr/%s" % NEW_CONF_FILE_NAME
+    conf_file_path = "/usr/{}".format(NEW_CONF_FILE_NAME)
 
 
-    log.write( "Checking for existence of %s\n" % conf_file_path )
+    log.write("Checking for existence of {}\n".format(conf_file_path))
     if os.access(conf_file_path,os.R_OK):
         try:
     if os.access(conf_file_path,os.R_OK):
         try:
-            conf_file= file(conf_file_path,"r")
-            conf_file_contents= conf_file.read()
+            conf_file = file(conf_file_path,"r")
+            conf_file_contents = conf_file.read()
             conf_file.close()
             conf_file.close()
-            log.write( "Read in contents of file %s\n" % conf_file_path )
-        except IOError, e:
-            log.write( "Unable to read file %s\n" % conf_file_path )
+            log.write("Read in contents of file {}\n".format(conf_file_path))
+        except IOError as e:
+            log.write("Unable to read file {}\n".format(conf_file_path))
             pass    
     
             pass    
     
-        if __parse_configuration_file( vars, log, conf_file_contents):            
+        if __parse_configuration_file(vars, log, conf_file_contents):            
+            log.write("ReadNodeConfiguration: [6] using {} from /usr\n"
+                      .format(NEW_CONF_FILE_NAME))
             return 1
         else:
             return 1
         else:
-            raise BootManagerException( "Found configuration file plnode.txt " \
+            raise BootManagerException("Found configuration file plnode.txt "
                                         "in /usr, but was unable to parse it.")
 
 
                                         "in /usr, but was unable to parse it.")
 
 
-    raise BootManagerException, "Unable to find and read a node configuration file."
+    raise BootManagerException("Unable to find and read a node configuration file.")
     
 
 
 
     
 
 
 
-def __parse_configuration_file( vars, log, file_contents ):
+def __parse_configuration_file(vars, log, file_contents):
     """
     """
-    parse a configuration file, set keys in var NETWORK_SETTINGS
+    parse a configuration file, set keys in var INTERFACE_SETTINGS
     in vars (see comment for function ReadNodeConfiguration). this
     also reads the mac address from the machine if successful parsing
     of the configuration file is completed.
     """
 
     in vars (see comment for function ReadNodeConfiguration). this
     also reads the mac address from the machine if successful parsing
     of the configuration file is completed.
     """
 
-    BOOT_CD_VERSION= vars["BOOT_CD_VERSION"]
-    SUPPORT_FILE_DIR= vars["SUPPORT_FILE_DIR"]
-    NETWORK_SETTINGS= vars["NETWORK_SETTINGS"]
+    INTERFACE_SETTINGS = vars["INTERFACE_SETTINGS"]
     
     if file_contents is None:
     
     if file_contents is None:
-        log.write( "__parse_configuration_file called with no file contents\n" )
+        log.write("__parse_configuration_file called with no file contents\n")
         return 0
     
     try:
         return 0
     
     try:
-        line_num= 0
+        line_num = 0
         for line in file_contents.split("\n"):
 
             line_num = line_num + 1
         for line in file_contents.split("\n"):
 
             line_num = line_num + 1
@@ -372,206 +363,183 @@ def __parse_configuration_file( vars, log, file_contents ):
                 continue
 
             # file is setup as name="value" pairs
                 continue
 
             # file is setup as name="value" pairs
-            parts= string.split(line,"=")
-            if len(parts) != 2:
-                log.write( "Invalid line %d in configuration file:\n" % line_num )
-                log.write( line + "\n" )
-                return 0
+            parts = string.split(line, "=", 1)
 
 
-            name= string.strip(parts[0])
-            value= string.strip(parts[1])
+            name = string.strip(parts[0])
+            value = string.strip(parts[1])
 
             # make sure value starts and ends with
             # single or double quotes
 
             # make sure value starts and ends with
             # single or double quotes
-            quotes= value[0] + value[len(value)-1]
+            quotes = value[0] + value[len(value)-1]
             if quotes != "''" and quotes != '""':
             if quotes != "''" and quotes != '""':
-                log.write( "Invalid line %d in configuration file:\n" % line_num )
-                log.write( line + "\n" )
+                log.write("Invalid line {} in configuration file:\n".format(line_num))
+                log.write(line + "\n")
                 return 0
 
             # get rid of the quotes around the value
                 return 0
 
             # get rid of the quotes around the value
-            value= string.strip(value[1:len(value)-1])
+            value = string.strip(value[1:len(value)-1])
 
             if name == "NODE_ID":
                 try:
 
             if name == "NODE_ID":
                 try:
-                    vars['NODE_ID']= int(value)
-                    vars['WAS_NODE_ID_IN_CONF']= 1
-                except ValueError, e:
-                    log.write( "Non-numeric node_id in configuration file.\n" )
+                    vars['NODE_ID'] = int(value)
+                    vars['WAS_NODE_ID_IN_CONF'] = 1
+                except ValueError as e:
+                    log.write("Non-numeric node_id in configuration file.\n")
                     return 0
 
             if name == "NODE_KEY":
                     return 0
 
             if name == "NODE_KEY":
-                vars['NODE_KEY']= value
-                vars['WAS_NODE_KEY_IN_CONF']= 1
+                vars['NODE_KEY'] = value
+                vars['WAS_NODE_KEY_IN_CONF'] = 1
 
             if name == "IP_METHOD":
 
             if name == "IP_METHOD":
-                value= string.lower(value)
+                value = string.lower(value)
                 if value != "static" and value != "dhcp":
                 if value != "static" and value != "dhcp":
-                    log.write( "Invalid IP_METHOD in configuration file:\n" )
-                    log.write( line + "\n" )
+                    log.write("Invalid IP_METHOD in configuration file:\n")
+                    log.write(line + "\n")
                     return 0
                     return 0
-                NETWORK_SETTINGS['method']= value.strip()
+                INTERFACE_SETTINGS['method'] = value.strip()
 
             if name == "IP_ADDRESS":
 
             if name == "IP_ADDRESS":
-                NETWORK_SETTINGS['ip']= value.strip()
+                INTERFACE_SETTINGS['ip'] = value.strip()
 
             if name == "IP_GATEWAY":
 
             if name == "IP_GATEWAY":
-                NETWORK_SETTINGS['gateway']= value.strip()
+                INTERFACE_SETTINGS['gateway'] = value.strip()
 
             if name == "IP_NETMASK":
 
             if name == "IP_NETMASK":
-                NETWORK_SETTINGS['netmask']= value.strip()
+                INTERFACE_SETTINGS['netmask'] = value.strip()
 
             if name == "IP_NETADDR":
 
             if name == "IP_NETADDR":
-                NETWORK_SETTINGS['network']= value.strip()
+                INTERFACE_SETTINGS['network'] = value.strip()
 
             if name == "IP_BROADCASTADDR":
 
             if name == "IP_BROADCASTADDR":
-                NETWORK_SETTINGS['broadcast']= value.strip()
+                INTERFACE_SETTINGS['broadcast'] = value.strip()
 
             if name == "IP_DNS1":
 
             if name == "IP_DNS1":
-                NETWORK_SETTINGS['dns1']= value.strip()
+                INTERFACE_SETTINGS['dns1'] = value.strip()
 
             if name == "IP_DNS2":
 
             if name == "IP_DNS2":
-                NETWORK_SETTINGS['dns2']= value.strip()
+                INTERFACE_SETTINGS['dns2'] = value.strip()
 
             if name == "HOST_NAME":
 
             if name == "HOST_NAME":
-                NETWORK_SETTINGS['hostname']= string.lower(value)
+                INTERFACE_SETTINGS['hostname'] = string.lower(value)
 
             if name == "DOMAIN_NAME":
 
             if name == "DOMAIN_NAME":
-                NETWORK_SETTINGS['domainname']= string.lower(value)
+                INTERFACE_SETTINGS['domainname'] = string.lower(value)
 
             if name == "NET_DEVICE":
 
             if name == "NET_DEVICE":
-                NETWORK_SETTINGS['mac']= string.upper(value)
+                INTERFACE_SETTINGS['mac'] = string.upper(value)
 
             if name == "DISCONNECTED_OPERATION":
 
             if name == "DISCONNECTED_OPERATION":
-                vars['DISCONNECTED_OPERATION']= value.strip()
+                vars['DISCONNECTED_OPERATION'] = value.strip()
 
 
-
-    except IndexError, e:
-        log.write( "Unable to parse configuration file\n" )
+    except IndexError as e:
+        log.write("Unable to parse configuration file\n")
         return 0
 
     # now if we are set to dhcp, clear out any fields
     # that don't make sense
         return 0
 
     # now if we are set to dhcp, clear out any fields
     # that don't make sense
-    if NETWORK_SETTINGS["method"] == "dhcp":
-        NETWORK_SETTINGS["ip"]= ""
-        NETWORK_SETTINGS["gateway"]= ""     
-        NETWORK_SETTINGS["netmask"]= ""
-        NETWORK_SETTINGS["network"]= ""
-        NETWORK_SETTINGS["broadcast"]= ""
-        NETWORK_SETTINGS["dns1"]= ""
-        NETWORK_SETTINGS["dns2"]= ""
+    if INTERFACE_SETTINGS["method"] == "dhcp":
+        INTERFACE_SETTINGS["ip"] = ""
+        INTERFACE_SETTINGS["gateway"] = ""     
+        INTERFACE_SETTINGS["netmask"] = ""
+        INTERFACE_SETTINGS["network"] = ""
+        INTERFACE_SETTINGS["broadcast"] = ""
+        INTERFACE_SETTINGS["dns1"] = ""
+        INTERFACE_SETTINGS["dns2"] = ""
 
 
-    log.write("Successfully read and parsed node configuration file.\n" )
+    log.write("Successfully read and parsed node configuration file.\n")
 
     # if the mac wasn't specified, read it in from the system.
 
     # if the mac wasn't specified, read it in from the system.
-    if NETWORK_SETTINGS["mac"] == "":
-        device= "eth0"
-        mac_addr= utils.get_mac_from_interface(device)
+    if INTERFACE_SETTINGS["mac"] == "":
+        device = "eth0"
+        mac_addr = utils.get_mac_from_interface(device)
 
         if mac_addr is None:
 
         if mac_addr is None:
-            log.write( "Could not get mac address for device eth0.\n" )
+            log.write("Could not get mac address for device eth0.\n")
             return 0
 
             return 0
 
-        NETWORK_SETTINGS["mac"]= string.upper(mac_addr)
+        INTERFACE_SETTINGS["mac"] = string.upper(mac_addr)
 
 
-        log.write( "Got mac address %s for device %s\n" %
-                   (NETWORK_SETTINGS["mac"],device) )
+        log.write("Got mac address {} for device {}\n"
+                  .format(INTERFACE_SETTINGS["mac"], device))
         
 
     # now, if the conf file didn't contain a node id, post the mac address
     # to plc to get the node_id value
     if vars['NODE_ID'] is None or vars['NODE_ID'] == 0:
         
 
     # now, if the conf file didn't contain a node id, post the mac address
     # to plc to get the node_id value
     if vars['NODE_ID'] is None or vars['NODE_ID'] == 0:
-        log.write( "Configuration file does not contain the node_id value.\n" )
-        log.write( "Querying PLC for node_id.\n" )
+        log.write("Configuration file does not contain the node_id value.\n")
+        log.write("Querying PLC for node_id.\n")
 
 
-        bs_request= BootServerRequest.BootServerRequest()
+        bs_request = BootServerRequest.BootServerRequest(vars)
         
         
-        postVars= {"mac_addr" : NETWORK_SETTINGS["mac"]}
-        result= bs_request.DownloadFile( "%s/getnodeid.php" %
-                                         SUPPORT_FILE_DIR,
+        postVars = {"mac_addr" : INTERFACE_SETTINGS["mac"]}
+        result = bs_request.DownloadFile("/boot/getnodeid.php",
                                          None, postVars, 1, 1,
                                          "/tmp/node_id")
         if result == 0:
                                          None, postVars, 1, 1,
                                          "/tmp/node_id")
         if result == 0:
-            log.write( "Unable to make request to get node_id.\n" )
+            log.write("Unable to make request to get node_id.\n")
             return 0
 
         try:
             return 0
 
         try:
-            node_id_file= file("/tmp/node_id","r")
-            node_id= string.strip(node_id_file.read())
+            node_id_file = file("/tmp/node_id","r")
+            node_id = string.strip(node_id_file.read())
             node_id_file.close()
         except IOError:
             node_id_file.close()
         except IOError:
-            log.write( "Unable to read node_id from /tmp/node_id\n" )
+            log.write("Unable to read node_id from /tmp/node_id\n")
             return 0
 
         try:
             return 0
 
         try:
-            node_id= int(string.strip(node_id))
+            node_id = int(string.strip(node_id))
         except ValueError:
         except ValueError:
-            log.write( "Got node_id from PLC, but not numeric: %s" % str(node_id) )
+            log.write("Got node_id from PLC, but not numeric: {}".format(node_id))
             return 0
 
         if node_id == -1:
             return 0
 
         if node_id == -1:
-            log.write( "Got node_id, but it returned -1\n\n" )
-
-            log.write( "------------------------------------------------------\n" )
-            log.write( "This indicates that this node could not be identified\n" )
-            log.write( "by PLC. You will need to add the node to your site,\n" )
-            log.write( "and regenerate the network configuration file.\n" )
-            log.write( "See the Technical Contact guide for node setup\n" )
-            log.write( "procedures.\n\n" )
-            log.write( "Boot process canceled until this is completed.\n" )
-            log.write( "------------------------------------------------------\n" )
+            log.write("Got node_id, but it returned -1\n\n")
+
+            log.write("------------------------------------------------------\n")
+            log.write("This indicates that this node could not be identified\n")
+            log.write("by PLC. You will need to add the node to your site,\n")
+            log.write("and regenerate the network configuration file.\n")
+            log.write("See the Technical Contact guide for node setup\n")
+            log.write("procedures.\n\n")
+            log.write("Boot process canceled until this is completed.\n")
+            log.write("------------------------------------------------------\n")
             
             
-            cancel_boot_flag= "/tmp/CANCEL_BOOT"
+            cancel_boot_flag = "/tmp/CANCEL_BOOT"
             # this will make the initial script stop requesting scripts from PLC
             # this will make the initial script stop requesting scripts from PLC
-            utils.sysexec( "touch %s" % cancel_boot_flag, log )
+            utils.sysexec("touch {}".format(cancel_boot_flag), log)
 
             return 0
 
 
             return 0
 
-        log.write( "Got node_id from PLC: %s\n" % str(node_id) )
-        vars['NODE_ID']= node_id
+        log.write("Got node_id from PLC: {}\n".format(node_id))
+        vars['NODE_ID'] = node_id
 
 
 
     if vars['NODE_KEY'] is None or vars['NODE_KEY'] == "":
 
 
 
     if vars['NODE_KEY'] is None or vars['NODE_KEY'] == "":
-        log.write( "Configuration file does not contain a node_key value.\n" )
-        log.write( "Using boot nonce instead.\n" )
+        log.write("Configuration file does not contain a node_key value.\n")
+        log.write("Using boot nonce instead.\n")
 
         # 3.x cds stored the file in /tmp/nonce in ascii form, so they
         # can be read and used directly. 2.x cds stored in the same place
         # but in binary form, so we need to convert it to ascii the same
         # way the old boot scripts did so it matches whats in the db
         # (php uses bin2hex, 
 
         # 3.x cds stored the file in /tmp/nonce in ascii form, so they
         # can be read and used directly. 2.x cds stored in the same place
         # but in binary form, so we need to convert it to ascii the same
         # way the old boot scripts did so it matches whats in the db
         # (php uses bin2hex, 
-        if BOOT_CD_VERSION[0] == 2:
-            read_mode= "rb"
-        else:
-            read_mode= "r"
+        read_mode = "r"
             
         try:
             
         try:
-            nonce_file= file("/tmp/nonce",read_mode)
-            nonce= nonce_file.read()
+            nonce_file = file("/tmp/nonce",read_mode)
+            nonce = nonce_file.read()
             nonce_file.close()
         except IOError:
             nonce_file.close()
         except IOError:
-            log.write( "Unable to read nonce from /tmp/nonce\n" )
+            log.write("Unable to read nonce from /tmp/nonce\n")
             return 0
 
             return 0
 
-        if BOOT_CD_VERSION[0] == 2:
-            nonce= nonce.encode('hex')
-
-            # there is this nice bug in the php that currently accepts the
-            # nonce for the old scripts, in that if the nonce contains
-            # null chars (2.x cds sent as binary), then
-            # the nonce is truncated. so, do the same here, truncate the nonce
-            # at the first null ('00'). This could leave us with an empty string.
-            nonce_len= len(nonce)
-            for byte_index in range(0,nonce_len,2):
-                if nonce[byte_index:byte_index+2] == '00':
-                    nonce= nonce[:byte_index]
-                    break
-        else:
-            nonce= string.strip(nonce)
+        nonce = string.strip(nonce)
 
 
-        log.write( "Read nonce, using as key.\n" )
-        vars['NODE_KEY']= nonce
+        log.write("Read nonce, using as key.\n")
+        vars['NODE_KEY'] = nonce
         
         
     # at this point, we've read the network configuration file.
         
         
     # at this point, we've read the network configuration file.
@@ -583,73 +551,78 @@ def __parse_configuration_file( vars, log, file_contents ):
     # in the configuration file matches the ip address. if it fails
     # notify the owners
 
     # in the configuration file matches the ip address. if it fails
     # notify the owners
 
-    hostname= NETWORK_SETTINGS['hostname'] + "." + \
-              NETWORK_SETTINGS['domainname']
+    hostname = INTERFACE_SETTINGS['hostname'] + "." + \
+              INTERFACE_SETTINGS['domainname']
 
     # set to 0 if any part of the hostname resolution check fails
 
     # set to 0 if any part of the hostname resolution check fails
-    hostname_resolve_ok= 1
+    hostname_resolve_ok = 1
 
     # set to 0 if the above fails, and, we are using dhcp in which
     # case we don't know the ip of this machine (without having to
     # parse ifconfig or something). In that case, we won't be able
     # to make api calls, so printing a message to the screen will
     # have to suffice.
 
     # set to 0 if the above fails, and, we are using dhcp in which
     # case we don't know the ip of this machine (without having to
     # parse ifconfig or something). In that case, we won't be able
     # to make api calls, so printing a message to the screen will
     # have to suffice.
-    can_make_api_call= 1
+    can_make_api_call = 1
 
 
-    log.write( "Checking that hostname %s resolves\n" % hostname )
+    log.write("Checking that hostname {} resolves\n".format(hostname))
 
     # try a regular dns lookup first
     try:
 
     # try a regular dns lookup first
     try:
-        resolved_node_ip= socket.gethostbyname(hostname)
-    except socket.gaierror, e:
-        hostname_resolve_ok= 0
+        resolved_node_ip = socket.gethostbyname(hostname)
+    except socket.gaierror as e:
+        hostname_resolve_ok = 0
         
 
         
 
-    if NETWORK_SETTINGS['method'] == "dhcp":
+    if INTERFACE_SETTINGS['method'] == "dhcp":
         if hostname_resolve_ok:
         if hostname_resolve_ok:
-            NETWORK_SETTINGS['ip']= resolved_node_ip
-            node_ip= resolved_node_ip
+            INTERFACE_SETTINGS['ip'] = resolved_node_ip
+            node_ip = resolved_node_ip
         else:
         else:
-            can_make_api_call= 0
+            can_make_api_call = 0
     else:
     else:
-        node_ip= NETWORK_SETTINGS['ip']
+        node_ip = INTERFACE_SETTINGS['ip']
 
     # make sure the dns lookup matches what the configuration file says
     if hostname_resolve_ok:
         if node_ip != resolved_node_ip:
 
     # make sure the dns lookup matches what the configuration file says
     if hostname_resolve_ok:
         if node_ip != resolved_node_ip:
-            log.write( "Hostname %s does not resolve to %s, but %s:\n" % \
-                       (hostname,node_ip,resolved_node_ip) )
-            hostname_resolve_ok= 0
+            log.write("Hostname {} does not resolve to {}, but {}:\n"
+                      .format(hostname, node_ip, resolved_node_ip))
+            hostname_resolve_ok = 0
         else:
         else:
-            log.write( "Hostname %s correctly resolves to %s:\n" %
-                       (hostname,node_ip) )
+            log.write("Hostname {} correctly resolves to {}:\n"
+                      .format(hostname, node_ip))
 
         
 
         
-    vars["NETWORK_SETTINGS"]= NETWORK_SETTINGS
+    vars["INTERFACE_SETTINGS"] = INTERFACE_SETTINGS
 
 
-    if not hostname_resolve_ok and not vars['DISCONNECTED_OPERATION']:
-        log.write( "Hostname does not resolve correctly, will not continue.\n" )
+    if (not hostname_resolve_ok and not vars['DISCONNECTED_OPERATION'] and
+        'NAT_MODE' not in vars):
+        log.write("Hostname does not resolve correctly, will not continue.\n")
 
         if can_make_api_call:
 
         if can_make_api_call:
-            log.write( "Notifying contacts of problem.\n" )
+            log.write("Notifying contacts of problem.\n")
 
 
-            vars['BOOT_STATE']= 'dbg'
-            vars['STATE_CHANGE_NOTIFY']= 1
-            vars['STATE_CHANGE_NOTIFY_MESSAGE']= \
+            vars['RUN_LEVEL'] = 'failboot'
+            vars['STATE_CHANGE_NOTIFY'] = 1
+            vars['STATE_CHANGE_NOTIFY_MESSAGE'] = \
                                      notify_messages.MSG_HOSTNAME_NOT_RESOLVE
             
                                      notify_messages.MSG_HOSTNAME_NOT_RESOLVE
             
-            UpdateBootStateWithPLC.Run( vars, log )
+            UpdateRunLevelWithPLC.Run(vars, log)
                     
                     
-        log.write( "\n\n" )
-        log.write( "The hostname and/or ip in the network configuration\n" )
-        log.write( "file do not resolve and match.\n" )
-        log.write( "Please make sure the hostname set in the network\n" )
-        log.write( "configuration file resolves to the ip also specified\n" )
-        log.write( "there.\n\n" )
-        log.write( "Debug mode is being started on this cd. When the above\n" )
-        log.write( "is corrected, reboot the machine to try again.\n" )
+        log.write("\n\n")
+        log.write("The hostname and/or ip in the network configuration\n")
+        log.write("file do not resolve and match.\n")
+        log.write("Please make sure the hostname set in the network\n")
+        log.write("configuration file resolves to the ip also specified\n")
+        log.write("there.\n\n")
+        log.write("Debug mode is being started on this cd. When the above\n")
+        log.write("is corrected, reboot the machine to try again.\n")
         
         
-        raise BootManagerException, \
-              "Configured node hostname does not resolve."
+        raise BootManagerException("Configured node hostname does not resolve.")
     
     
+    try:
+        log.write("Using NODE_ID {}\n".format(vars['NODE_ID']))
+    except:
+        log.write("Unknown NODE_ID")
+
     return 1
     return 1