# Copyright (c) 2004-2006 The Trustees of Princeton University
# All rights reserved.
+from __future__ import print_function
+
+import sys, os
+import traceback
import string
-import sys, os, traceback
import time
import gzip
import utils
# all output is written to this file
-BM_NODE_LOG= "/tmp/bm.log"
+BM_NODE_LOG = "/tmp/bm.log"
VARS_FILE = "configuration"
# the new contents of PATH when the boot manager is running
-BIN_PATH= ('/usr/local/bin',
- '/usr/local/sbin',
- '/usr/bin',
- '/usr/sbin',
- '/bin',
- '/sbin')
+BIN_PATH = ('/usr/local/bin',
+ '/usr/local/sbin',
+ '/usr/bin',
+ '/usr/sbin',
+ '/bin',
+ '/sbin')
def read_configuration_file(filename):
# read in and store all variables in VARS_FILE into each line
# removed. everything after the = to the end of the line is
# the value
vars = {}
- vars_file= file(filename,'r')
+ vars_file = file(filename,'r')
validConfFile = True
for line in vars_file:
# if its a comment or a whitespace line, ignore
if line[:1] == "#" or string.strip(line) == "":
continue
- parts= string.split(line,"=")
+ parts = string.split(line, "=")
if len(parts) != 2:
validConfFile = False
- raise Exception( "Invalid line in vars file: %s" % line )
+ raise Exception("Invalid line in vars file: {}".format(line))
- name= string.strip(parts[0])
- value= string.strip(parts[1])
- value= value.replace("'", "") # remove quotes
- value= value.replace('"', "") # remove quotes
- vars[name]= value
+ name = string.strip(parts[0])
+ value = string.strip(parts[1])
+ value = value.replace("'", "") # remove quotes
+ value = value.replace('"', "") # remove quotes
+ vars[name] = value
vars_file.close()
if not validConfFile:
- raise Exception( "Unable to read configuration vars." )
+ raise Exception("Unable to read configuration vars.")
# find out which directory we are running it, and set a variable
# for that. future steps may need to get files out of the bootmanager
# directory
- current_dir= os.getcwd()
- vars['BM_SOURCE_DIR']= current_dir
+ current_dir = os.getcwd()
+ vars['BM_SOURCE_DIR'] = current_dir
return vars
##############################
class log:
- format="%H:%M:%S(%Z) "
+ format = "%H:%M:%S(%Z) "
- def __init__( self, OutputFilePath= None ):
+ def __init__(self, OutputFilePath=None):
try:
- self.OutputFile= open( OutputFilePath, "w")
- self.OutputFilePath= OutputFilePath
+ self.OutputFile = open(OutputFilePath, "w")
+ self.OutputFilePath = OutputFilePath
except:
- print( "bootmanager log : Unable to open output file %r, continuing"%OutputFilePath )
- self.OutputFile= None
+ print("bootmanager log : Unable to open output file {}, continuing"\
+ .format(OutputFilePath))
+ self.OutputFile = None
self.VARS = None
try:
vars = read_configuration_file(VARS_FILE)
self.VARS = vars
except Exception, e:
- self.LogEntry( str(e) )
+ self.LogEntry(str(e))
return
-
- def LogEntry( self, str, inc_newline= 1, display_screen= 1 ):
- now=time.strftime(log.format, time.localtime())
+
+ def LogEntry(self, str, inc_newline = 1, display_screen = 1):
+ now = time.strftime(log.format, time.localtime())
if self.OutputFile:
- self.OutputFile.write( now+str )
+ self.OutputFile.write(now + str)
if display_screen:
- sys.stdout.write( now+str )
-
+ sys.stdout.write(now + str)
+
if inc_newline:
if display_screen:
- sys.stdout.write( "\n" )
+ sys.stdout.write("\n")
if self.OutputFile:
- self.OutputFile.write( "\n" )
+ self.OutputFile.write("\n")
if self.OutputFile:
self.OutputFile.flush()
- def write( self, str ):
+ def write(self, str):
+ """
+ make log behave like a writable file object
+ (for traceback prints)
+ """
+ self.LogEntry(str, 0, 1)
+
+ def print_stack(self):
"""
- make log behave like a writable file object (for traceback
- prints)
+ dump current stack in log
"""
- self.LogEntry( str, 0, 1 )
-
+ self.write(traceback.format_exc())
+
# bm log uploading is available back again, as of nodeconfig-5.0-2
- def Upload( self, extra_file=None ):
+ def Upload(self, extra_file=None):
"""
upload the contents of the log to the server
"""
if self.OutputFile is not None:
self.OutputFile.flush()
- self.LogEntry( "Uploading logs to %s" % self.VARS['UPLOAD_LOG_SCRIPT'] )
-
+ self.LogEntry("Uploading logs to {}".format(self.VARS['UPLOAD_LOG_SCRIPT']))
+
self.OutputFile.close()
- self.OutputFile= None
+ self.OutputFile = None
- hostname= self.VARS['INTERFACE_SETTINGS']['hostname'] + "." + \
- self.VARS['INTERFACE_SETTINGS']['domainname']
+ hostname = self.VARS['INTERFACE_SETTINGS']['hostname'] + "." + \
+ self.VARS['INTERFACE_SETTINGS']['domainname']
bs_request = BootServerRequest.BootServerRequest(self.VARS)
try:
# this was working until f10
GetVars = None, PostVars = None,
DoSSL = True, DoCertCheck = True,
FormData = ["log=@" + self.OutputFilePath,
- "hostname=" + hostname,
+ "hostname=" + hostname,
"type=bm.log"])
except:
# new pycurl
("hostname",hostname),
("type","bm.log")])
if extra_file is not None:
- # NOTE: for code-reuse, evoke the bash function 'upload_logs';
+ # NOTE: for code-reuse, evoke the bash function 'upload_logs';
# by adding --login, bash reads .bash_profile before execution.
# Also, never fail, since this is an optional feature.
- utils.sysexec_noerr( """bash --login -c "upload_logs %s" """ % extra_file, self)
+ utils.sysexec_noerr("""bash --login -c "upload_logs {}" """.format(extra_file), self)
##############################
# file containing initial variables/constants
# the set of valid node run states
- NodeRunStates = {'reinstall':None,
- 'boot':None,
- 'safeboot':None,
- 'disabled':None,
+ NodeRunStates = {'reinstall' : None,
+ 'upgrade' : None,
+ 'boot' : None,
+ 'safeboot' : None,
+ 'disabled' : None,
}
-
+
def __init__(self, log, forceState):
# override machine's current state from the command line
self.forceState = forceState
# the main logging point
- self.LOG= log
+ self.LOG = log
# set to 1 if we can run after initialization
self.CAN_RUN = 0
if log.VARS:
# this contains a set of information used and updated by each step
- self.VARS= log.VARS
+ self.VARS = log.VARS
else:
return
-
+
# not sure what the current PATH is set to, replace it with what
# we know will work with all the boot cds
- os.environ['PATH']= string.join(BIN_PATH,":")
+ os.environ['PATH'] = string.join(BIN_PATH,":")
- self.CAN_RUN= 1
+ self.CAN_RUN = 1
def Run(self):
"""
If requriements not met, but tests were succesfull, return 0.
for steps that run within the installer, they are expected to either
- complete succesfully and return 1, or throw an execption.
+ complete succesfully and return 1, or throw an exception.
For exact return values and expected operations, see the comments
at the top of each of the invididual step functions.
def _nodeNotInstalled(message='MSG_NODE_NOT_INSTALLED'):
# called by the _xxxState() functions below upon failure
- self.VARS['RUN_LEVEL']= 'failboot'
+ self.VARS['RUN_LEVEL'] = 'failboot'
notify = getattr(notify_messages, message)
- self.VARS['STATE_CHANGE_NOTIFY']= 1
- self.VARS['STATE_CHANGE_NOTIFY_MESSAGE']= notify
+ self.VARS['STATE_CHANGE_NOTIFY'] = 1
+ self.VARS['STATE_CHANGE_NOTIFY_MESSAGE'] = notify
raise BootManagerException, notify
def _bootRun():
# then finally chain boots.
# starting the fallback/debug ssh daemon for safety:
- # if the node install somehow hangs, or if it simply takes ages,
+ # if the node install somehow hangs, or if it simply takes ages,
# we can still enter and investigate
try:
StartDebug.Run(self.VARS, self.LOG, last_resort = False)
except:
pass
- InstallInit.Run( self.VARS, self.LOG )
- ret = ValidateNodeInstall.Run( self.VARS, self.LOG )
+ InstallInit.Run(self.VARS, self.LOG)
+ ret = ValidateNodeInstall.Run(self.VARS, self.LOG)
if ret == 1:
- WriteModprobeConfig.Run( self.VARS, self.LOG )
- WriteNetworkConfig.Run( self.VARS, self.LOG )
- CheckForNewDisks.Run( self.VARS, self.LOG )
- SendHardwareConfigToPLC.Run( self.VARS, self.LOG )
- ChainBootNode.Run( self.VARS, self.LOG )
+# Thierry - feb. 2013 turning off WriteModprobeConfig for now on lxc
+# for one thing this won't work at all with f18, as modules.pcimap
+# has disappeared (Daniel suggested modules.aliases could be used instead)
+# and second, in any case it's been years now that modprobe.conf was deprecated
+# so most likely this code has no actual effect
+ if self.VARS['virt'] == 'vs':
+ WriteModprobeConfig.Run(self.VARS, self.LOG)
+ WriteNetworkConfig.Run(self.VARS, self.LOG)
+ CheckForNewDisks.Run(self.VARS, self.LOG)
+ SendHardwareConfigToPLC.Run(self.VARS, self.LOG)
+ ChainBootNode.Run(self.VARS, self.LOG)
elif ret == -1:
_nodeNotInstalled('MSG_NODE_FILESYSTEM_CORRUPT')
elif ret == -2:
else:
_nodeNotInstalled()
- def _reinstallRun():
+ def _reinstallRun(upgrade=False):
# starting the fallback/debug ssh daemon for safety:
- # if the node install somehow hangs, or if it simply takes ages,
+ # if the node install somehow hangs, or if it simply takes ages,
# we can still enter and investigate
try:
StartDebug.Run(self.VARS, self.LOG, last_resort = False)
# the min. hardware requirements are met, install the
# software, and upon correct installation will switch too
# 'boot' state and chainboot into the production system
- if not CheckHardwareRequirements.Run( self.VARS, self.LOG ):
- self.VARS['RUN_LEVEL']= 'failboot'
- raise BootManagerException, "Hardware requirements not met."
+ if not CheckHardwareRequirements.Run(self.VARS, self.LOG):
+ self.VARS['RUN_LEVEL'] = 'failboot'
+ raise BootManagerException("Hardware requirements not met.")
# runinstaller
- InstallInit.Run( self.VARS, self.LOG )
- InstallPartitionDisks.Run( self.VARS, self.LOG )
- InstallBootstrapFS.Run( self.VARS, self.LOG )
- InstallWriteConfig.Run( self.VARS, self.LOG )
- InstallUninitHardware.Run( self.VARS, self.LOG )
- self.VARS['BOOT_STATE']= 'boot'
- self.VARS['STATE_CHANGE_NOTIFY']= 1
- self.VARS['STATE_CHANGE_NOTIFY_MESSAGE']= \
+ InstallInit.Run(self.VARS, self.LOG)
+ # do not erase disks in upgrade mode
+ if not upgrade:
+ InstallPartitionDisks.Run(self.VARS, self.LOG)
+ # pass upgrade boolean to this step so we can do extra cleanup
+ InstallBootstrapFS.Run(self.VARS, upgrade, self.LOG)
+ InstallWriteConfig.Run(self.VARS, self.LOG)
+ InstallUninitHardware.Run(self.VARS, self.LOG)
+ self.VARS['BOOT_STATE'] = 'boot'
+ self.VARS['STATE_CHANGE_NOTIFY'] = 1
+ self.VARS['STATE_CHANGE_NOTIFY_MESSAGE'] = \
notify_messages.MSG_INSTALL_FINISHED
- UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
+ AnsibleHook.Run(self.VARS, self.LOG)
+ UpdateBootStateWithPLC.Run(self.VARS, self.LOG)
_bootRun()
-
+
def _installRun():
# implements the new install logic, which will first check
# with the user whether it is ok to install on this
# machine, switch to 'reinstall' state and then invoke the reinstall
# logic. See reinstallState logic comments for further
# details.
- if not ConfirmInstallWithUser.Run( self.VARS, self.LOG ):
+ if not ConfirmInstallWithUser.Run(self.VARS, self.LOG):
return 0
- self.VARS['BOOT_STATE']= 'reinstall'
- UpdateRunLevelWithPLC.Run( self.VARS, self.LOG )
+ self.VARS['BOOT_STATE'] = 'reinstall'
+
+ AnsibleHook.Run(self.VARS, self.LOG)
_reinstallRun()
def _debugRun(state='failboot'):
# implements debug logic, which starts the sshd and just waits around
- self.VARS['RUN_LEVEL']=state
- UpdateRunLevelWithPLC.Run( self.VARS, self.LOG )
- StartDebug.Run( self.VARS, self.LOG )
+ self.VARS['RUN_LEVEL'] = state
+ StartDebug.Run(self.VARS, self.LOG)
# fsck/mount fs if present, and ignore return value if it's not.
- ValidateNodeInstall.Run( self.VARS, self.LOG )
+ ValidateNodeInstall.Run(self.VARS, self.LOG)
def _badstateRun():
# should never happen; log event
- self.LOG.write( "\nInvalid BOOT_STATE = %s\n" % self.VARS['BOOT_STATE'])
+ self.LOG.write("\nInvalid BOOT_STATE = {}\n".format(self.VARS['BOOT_STATE']))
_debugRun()
# setup state -> function hash table
- BootManager.NodeRunStates['reinstall'] = _reinstallRun
+ BootManager.NodeRunStates['reinstall'] = lambda : _reinstallRun(upgrade=False)
+ BootManager.NodeRunStates['upgrade'] = lambda : _reinstallRun(upgrade=True)
BootManager.NodeRunStates['boot'] = _bootRun
BootManager.NodeRunStates['safeboot'] = lambda : _debugRun('safeboot')
BootManager.NodeRunStates['disabled'] = lambda : _debugRun('disabled')
success = 0
try:
- InitializeBootManager.Run( self.VARS, self.LOG )
- ReadNodeConfiguration.Run( self.VARS, self.LOG )
- AuthenticateWithPLC.Run( self.VARS, self.LOG )
- StartRunlevelAgent.Run( self.VARS, self.LOG )
- GetAndUpdateNodeDetails.Run( self.VARS, self.LOG )
+ InitializeBootManager.Run(self.VARS, self.LOG)
+ ReadNodeConfiguration.Run(self.VARS, self.LOG)
+ AuthenticateWithPLC.Run(self.VARS, self.LOG)
+ UpdateLastBootOnce.Run(self.VARS, self.LOG)
+ StartRunlevelAgent.Run(self.VARS, self.LOG)
+ GetAndUpdateNodeDetails.Run(self.VARS, self.LOG)
# override machine's current state from the command line
if self.forceState is not None:
- self.VARS['BOOT_STATE']= self.forceState
- UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
- UpdateRunLevelWithPLC.Run( self.VARS, self.LOG )
+ self.VARS['BOOT_STATE'] = self.forceState
+ UpdateBootStateWithPLC.Run(self.VARS, self.LOG)
- stateRun = BootManager.NodeRunStates.get(self.VARS['BOOT_STATE'],_badstateRun)
+ stateRun = BootManager.NodeRunStates.get(self.VARS['BOOT_STATE'], _badstateRun)
stateRun()
success = 1
- except KeyError, e:
- self.LOG.write( "\n\nKeyError while running: %s\n" % str(e) )
- except BootManagerException, e:
- self.LOG.write( "\n\nException while running: %s\n" % str(e) )
- except BootManagerAuthenticationException, e:
- self.LOG.write( "\n\nFailed to Authenticate Node: %s\n" % str(e) )
+ except KeyError as e:
+ self.LOG.write("\n\nKeyError while running: {}\n".format(e))
+ self.LOG.print_stack()
+ except BootManagerException as e:
+ self.LOG.write("\n\nException while running: {}\n".format(e))
+ self.LOG.print_stack()
+ except BootManagerAuthenticationException as e:
+ self.LOG.write("\n\nFailed to Authenticate Node: {}\n".format(e))
+ self.LOG.print_stack()
# sets /tmp/CANCEL_BOOT flag
- StartDebug.Run(self.VARS, self.LOG )
+ StartDebug.Run(self.VARS, self.LOG)
# Return immediately b/c any other calls to API will fail
return success
except:
- self.LOG.write( "\n\nImplementation Error\n")
- traceback.print_exc(file=self.LOG.OutputFile)
- traceback.print_exc()
+ self.LOG.write("\n\nImplementation Error\n")
+ self.LOG.print_stack()
if not success:
try:
_debugRun()
except BootManagerException, e:
- self.LOG.write( "\n\nException while running: %s\n" % str(e) )
+ self.LOG.write("\n\nException while running: {}\n".format(e))
except:
- self.LOG.write( "\n\nImplementation Error\n")
+ self.LOG.write("\n\nImplementation Error\n")
traceback.print_exc(file=self.LOG.OutputFile)
traceback.print_exc()
return success
-
-
+
def main(argv):
import utils
utils.prompt_for_breakpoint_mode()
- utils.breakpoint ("Entering BootManager::main")
-
+# utils.breakpoint("Entering BootManager::main")
+
# set to 1 if error occurred
- error= 0
-
+ error = 0
+
# all output goes through this class so we can save it and post
# the data back to PlanetLab central
- LOG= log( BM_NODE_LOG )
+ LOG = log(BM_NODE_LOG)
# NOTE: assume CWD is BM's source directory, but never fail
utils.sysexec_noerr("./setup_bash_history_scripts.sh", LOG)
- LOG.LogEntry( "BootManager started at: %s" % \
- time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) )
+ LOG.LogEntry("BootManager started at: {}"\
+ .format(time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())))
try:
forceState = None
if BootManager.NodeRunStates.has_key(fState):
forceState = fState
else:
- LOG.LogEntry("FATAL: cannot force node run state to=%s" % fState)
+ LOG.LogEntry("FATAL: cannot force node run state to={}".format(fState))
error = 1
except:
traceback.print_exc(file=LOG.OutputFile)
traceback.print_exc()
-
+
if error:
- LOG.LogEntry( "BootManager finished at: %s" % \
- time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) )
+ LOG.LogEntry("BootManager finished at: {}"\
+ .format(time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())))
LOG.Upload()
return error
try:
- bm= BootManager(LOG,forceState)
+ bm = BootManager(LOG, forceState)
if bm.CAN_RUN == 0:
- LOG.LogEntry( "Unable to initialize BootManager." )
+ LOG.LogEntry("Unable to initialize BootManager.")
else:
- LOG.LogEntry( "Running version %s of BootManager." % bm.VARS['VERSION'] )
- success= bm.Run()
+ LOG.LogEntry("Running version {} of BootManager.".format(bm.VARS['VERSION']))
+ success = bm.Run()
if success:
- LOG.LogEntry( "\nDone!" );
+ LOG.LogEntry("\nDone!");
else:
- LOG.LogEntry( "\nError occurred!" );
+ LOG.LogEntry("\nError occurred!");
error = 1
except:
traceback.print_exc(file=LOG.OutputFile)
traceback.print_exc()
- LOG.LogEntry( "BootManager finished at: %s" % \
- time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()) )
+ LOG.LogEntry("BootManager finished at: {}"\
+ .format(time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())))
LOG.Upload()
return error
-
if __name__ == "__main__":
error = main(sys.argv)
sys.exit(error)