from steps import *
from Exceptions import *
import notify_messages
+import BootServerRequest
# all output is written to this file
LOG_FILE= "/tmp/bm.log"
-CURL_PATH= "curl"
-
+UPLOAD_LOG_PATH = "/alpina-logs/upload.php"
# the new contents of PATH when the boot manager is running
BIN_PATH= ('/usr/local/bin',
'/usr/local/planetlab/bin')
+# the set of valid node run states
+NodeRunStates = {}
class log:
def __init__( self, OutputFilePath= None ):
-
- self.UPLOAD_LOG_URL= None
-
if OutputFilePath:
try:
self.OutputFilePath= OutputFilePath
self.OutputFile.flush()
+
def write( self, str ):
"""
make log behave like a writable file object (for traceback
self.LogEntry( str, 0, 1 )
- def SetUploadServer( self, server ):
- """
- set the url we should use to upload the logs to
- """
- self.UPLOAD_LOG_URL = "http://%s/alpina-logs/upload.php" % server
-
def Upload( self ):
"""
upload the contents of the log to the server
"""
- if self.OutputFile is not None and self.UPLOAD_LOG_URL is not None:
- self.LogEntry( "Uploading logs to %s" % self.UPLOAD_LOG_URL )
+ if self.OutputFile is not None:
+ self.LogEntry( "Uploading logs to %s" % UPLOAD_LOG_PATH )
self.OutputFile.close()
self.OutputFile= None
-
- curl_cmd= "%s -s --connect-timeout 60 --max-time 600 " \
- "--form log=@%s %s" % \
- (CURL_PATH, self.OutputFilePath, self.UPLOAD_LOG_URL)
- os.system( curl_cmd )
+
+ bs_request = BootServerRequest.BootServerRequest()
+ bs_request.MakeRequest(PartialPath = UPLOAD_LOG_PATH,
+ GetVars = None, PostVars = None,
+ FormData = ["log=@" + self.OutputFilePath],
+ DoSSL = True, DoCertCheck = True)
VARS_FILE = "configuration"
- def __init__(self, log):
+ def __init__(self, log, forceState):
+ # override machine's current state from the command line
+ self.forceState = forceState
+
# this contains a set of information used and updated
# by each step
self.VARS= {}
# 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,":")
-
+
self.CAN_RUN= 1
-
-
-
def ReadBMConf(self):
"""
return 1
-
def Run(self):
"""
core boot manager logic.
For exact return values and expected operations, see the comments
at the top of each of the invididual step functions.
"""
-
+
+ def _nodeNotInstalled():
+ # called by the _xxxState() functions below upon failure
+ self.VARS['BOOT_STATE']= 'dbg'
+ self.VARS['STATE_CHANGE_NOTIFY']= 1
+ self.VARS['STATE_CHANGE_NOTIFY_MESSAGE']= \
+ notify_messages.MSG_NODE_NOT_INSTALLED
+ UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
+
+ def _rinsRun():
+ # implements the reinstall logic, which will check whether
+ # 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['BOOT_STATE']= 'dbg'
+ UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
+ raise BootManagerException, "Hardware requirements not met."
+
+ self.RunInstaller()
+
+ if ValidateNodeInstall.Run( self.VARS, self.LOG ):
+ SendHardwareConfigToPLC.Run( self.VARS, self.LOG )
+ ChainBootNode.Run( self.VARS, self.LOG )
+ else:
+ _nodeNotInstalled()
+
+ def _newRun():
+ # implements the new install logic, which will first check
+ # with the user whether it is ok to install on this
+ # machine, switch to 'rins' state and then invoke the rins
+ # logic. See rinsState logic comments for further
+ # details.
+ if not ConfirmInstallWithUser.Run( self.VARS, self.LOG ):
+ return 0
+ self.VARS['BOOT_STATE']= 'rins'
+ UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
+ _rinsRun()
+
+ def _bootRun():
+ # implements the boot logic, which consists of first
+ # double checking that the node was properly installed,
+ # checking whether someone added or changed disks, and
+ # then finally chain boots.
+
+ if ValidateNodeInstall.Run( self.VARS, self.LOG ):
+ UpdateNodeConfiguration.Run( self.VARS, self.LOG )
+ CheckForNewDisks.Run( self.VARS, self.LOG )
+ SendHardwareConfigToPLC.Run( self.VARS, self.LOG )
+ ChainBootNode.Run( self.VARS, self.LOG )
+ else:
+ _nodeNotInstalled()
+
+
+ def _debugRun():
+ # implements debug logic, which just starts the sshd
+ # and just waits around
+ StartDebug.Run( self.VARS, self.LOG )
+
+ def _badRun():
+ # should never happen; log event
+ self.LOG.write( "\nInvalid BOOT_STATE = %s\n" % self.VARS['BOOT_STATE'])
+ self.VARS['BOOT_STATE']= 'dbg'
+ UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
+ StartDebug.Run( self.VARS, self.LOG )
+
+ global NodeRunStates
+ # setup state -> function hash table
+ NodeRunStates['new'] = _newRun
+ NodeRunStates['inst'] = _newRun
+ NodeRunStates['rins'] = _rinsRun
+ NodeRunStates['boot'] = _bootRun
+ NodeRunStates['dbg'] = _debugRun
+
try:
InitializeBootManager.Run( self.VARS, self.LOG )
ReadNodeConfiguration.Run( self.VARS, self.LOG )
AuthenticateWithPLC.Run( self.VARS, self.LOG )
GetAndUpdateNodeDetails.Run( self.VARS, self.LOG )
-
- if self.VARS['BOOT_STATE'] == 'new' or \
- self.VARS['BOOT_STATE'] == 'inst':
- if not ConfirmInstallWithUser.Run( self.VARS, self.LOG ):
- return 0
-
- self.VARS['BOOT_STATE']= 'rins'
+
+ # 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 )
-
- if not CheckHardwareRequirements.Run( self.VARS, self.LOG ):
- self.VARS['BOOT_STATE']= 'dbg'
- UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
- raise BootManagerException, "Hardware requirements not met."
-
- self.RunInstaller()
-
- if ValidateNodeInstall.Run( self.VARS, self.LOG ):
- SendHardwareConfigToPLC.Run( self.VARS, self.LOG )
- ChainBootNode.Run( self.VARS, self.LOG )
- else:
- self.VARS['BOOT_STATE']= 'dbg'
- self.VARS['STATE_CHANGE_NOTIFY']= 1
- self.VARS['STATE_CHANGE_NOTIFY_MESSAGE']= \
- notify_messages.MSG_NODE_NOT_INSTALLED
- UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
-
-
- elif self.VARS['BOOT_STATE'] == 'rins':
- if not CheckHardwareRequirements.Run( self.VARS, self.LOG ):
- self.VARS['BOOT_STATE']= 'dbg'
- UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
- raise BootManagerException, "Hardware requirements not met."
-
- self.RunInstaller()
-
- if ValidateNodeInstall.Run( self.VARS, self.LOG ):
- SendHardwareConfigToPLC.Run( self.VARS, self.LOG )
- ChainBootNode.Run( self.VARS, self.LOG )
- else:
- self.VARS['BOOT_STATE']= 'dbg'
- self.VARS['STATE_CHANGE_NOTIFY']= 1
- self.VARS['STATE_CHANGE_NOTIFY_MESSAGE']= \
- notify_messages.MSG_NODE_NOT_INSTALLED
- UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
-
- elif self.VARS['BOOT_STATE'] == 'boot':
- if ValidateNodeInstall.Run( self.VARS, self.LOG ):
- UpdateNodeConfiguration.Run( self.VARS, self.LOG )
- CheckForNewDisks.Run( self.VARS, self.LOG )
- SendHardwareConfigToPLC.Run( self.VARS, self.LOG )
- ChainBootNode.Run( self.VARS, self.LOG )
- else:
- self.VARS['BOOT_STATE']= 'dbg'
- self.VARS['STATE_CHANGE_NOTIFY']= 1
- self.VARS['STATE_CHANGE_NOTIFY_MESSAGE']= \
- notify_messages.MSG_NODE_NOT_INSTALLED
- UpdateBootStateWithPLC.Run( self.VARS, self.LOG )
-
- elif self.VARS['BOOT_STATE'] == 'dbg':
- StartDebug.Run( self.VARS, self.LOG )
+
+ stateRun = NodeRunStates.get(self.VARS['BOOT_STATE'],_badRun)
+ stateRun()
except KeyError, e:
self.LOG.write( "\n\nKeyError while running: %s\n" % str(e) )
InstallInit.Run( self.VARS, self.LOG )
InstallPartitionDisks.Run( self.VARS, self.LOG )
InstallBootstrapRPM.Run( self.VARS, self.LOG )
- InstallBase.Run( self.VARS, self.LOG )
InstallWriteConfig.Run( self.VARS, self.LOG )
InstallBuildVServer.Run( self.VARS, self.LOG )
InstallNodeInit.Run( self.VARS, self.LOG )
SendHardwareConfigToPLC.Run( self.VARS, self.LOG )
-
-if __name__ == "__main__":
-
- # set to 0 if no error occurred
- error= 1
+def main(argv):
+ global NodeRunStates
+ NodeRunStates = {'new':None,
+ 'inst':None,
+ 'rins':None,
+ 'boot':None,
+ 'dbg':None}
+
+ # set to 1 if error occurred
+ error= 0
# all output goes through this class so we can save it and post
# the data back to PlanetLab central
strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()) )
try:
- bm= BootManager(LOG)
+ forceState = None
+ if len(argv) == 2:
+ fState = argv[1]
+ if NodeRunStates.has_key(fState):
+ forceState = fState
+ else:
+ LOG.LogEntry("FATAL: cannot force node run state to=%s" % fState)
+ error = 1
+ except:
+ traceback.print_exc(file=LOG.OutputFile)
+ traceback.print_exc()
+
+ if error:
+ LOG.LogEntry( "BootManager finished at: %s" % \
+ strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()) )
+ LOG.Upload()
+ return error
+
+ try:
+ bm= BootManager(LOG,forceState)
if bm.CAN_RUN == 0:
LOG.LogEntry( "Unable to initialize BootManager." )
else:
LOG.LogEntry( "\nDone!" );
else:
LOG.LogEntry( "\nError occurred!" );
-
+ error = 1
except:
traceback.print_exc(file=LOG.OutputFile)
traceback.print_exc()
LOG.LogEntry( "BootManager finished at: %s" % \
strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()) )
-
LOG.Upload()
+
+ return error
+
+if __name__ == "__main__":
+ error = main(sys.argv)
sys.exit(error)