use BootServerRequest to upload logs to the right server
[bootmanager.git] / source / BootManager.py
index 517fb43..b49d978 100755 (executable)
@@ -56,13 +56,13 @@ from gzip import GzipFile
 from steps import *
 from Exceptions import *
 import notify_messages
 from steps import *
 from Exceptions import *
 import notify_messages
+import BootServerRequest
 
 
 
 # all output is written to this file
 LOG_FILE= "/tmp/bm.log"
 
 
 
 # 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',
 
 # the new contents of PATH when the boot manager is running
 BIN_PATH= ('/usr/local/bin',
@@ -78,9 +78,6 @@ BIN_PATH= ('/usr/local/bin',
 class log:
 
     def __init__( self, OutputFilePath= None ):
 class log:
 
     def __init__( self, OutputFilePath= None ):
-
-        self.UPLOAD_LOG_URL= None
-        
         if OutputFilePath:
             try:
                 self.OutputFilePath= OutputFilePath
         if OutputFilePath:
             try:
                 self.OutputFilePath= OutputFilePath
@@ -106,6 +103,7 @@ class log:
             self.OutputFile.flush()
 
             
             self.OutputFile.flush()
 
             
+
     def write( self, str ):
         """
         make log behave like a writable file object (for traceback
     def write( self, str ):
         """
         make log behave like a writable file object (for traceback
@@ -114,28 +112,23 @@ class log:
         self.LogEntry( str, 0, 1 )
 
 
         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
         """
 
     
     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
             
             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)
         
     
 
         
     
 
@@ -172,11 +165,8 @@ class BootManager:
         # 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,":")
         # 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
         self.CAN_RUN= 1
-        
-
-
 
     def ReadBMConf(self):
         """
 
     def ReadBMConf(self):
         """
@@ -206,7 +196,6 @@ class BootManager:
 
         return 1
     
 
         return 1
     
-
     def Run(self):
         """
         core boot manager logic.
     def Run(self):
         """
         core boot manager logic.
@@ -227,72 +216,86 @@ class BootManager:
         For exact return values and expected operations, see the comments
         at the top of each of the invididual step functions.
         """
         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 )            
+
+        # setup state -> function hash table
+        states = {'new':_newRun,
+                  'inst':_newRun,
+                  'rins':_rinsRun,
+                  'boot':_bootRun,
+                  '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 )
         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'
-                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 = states.get(self.VARS['BOOT_STATE'],_badRun)
+            stateRun()
 
         except KeyError, e:
             self.LOG.write( "\n\nKeyError while running: %s\n" % str(e) )
 
         except KeyError, e:
             self.LOG.write( "\n\nKeyError while running: %s\n" % str(e) )