a first stab at upgrading nodes
[bootmanager.git] / source / BootAPI.py
index 3cf074c..c24afbc 100644 (file)
@@ -1,5 +1,5 @@
-#!/usr/bin/python2
-
+#!/usr/bin/python
+#
 # Copyright (c) 2003 Intel Corporation
 # All rights reserved.
 #
 # Copyright (c) 2003 Intel Corporation
 # All rights reserved.
 #
@@ -14,12 +14,13 @@ import string
 import sha
 import cPickle
 import utils
 import sha
 import cPickle
 import utils
+import os
 
 from Exceptions import *
 
 stash = None
 
 
 from Exceptions import *
 
 stash = None
 
-def create_auth_structure( vars, call_params ):
+def create_auth_structure(vars, call_params):
     """
     create and return an authentication structure for a Boot API
     call. Vars contains the boot manager runtime variables, and
     """
     create and return an authentication structure for a Boot API
     call. Vars contains the boot manager runtime variables, and
@@ -27,39 +28,67 @@ def create_auth_structure( vars, call_params ):
     API call. Return None if unable to (typically due to missing
     keys in vars, such as node_id or node_key)
     """
     API call. Return None if unable to (typically due to missing
     keys in vars, such as node_id or node_key)
     """
-    
-    auth= {}
-    auth['AuthMethod']= 'hmac'
 
 
-    try:
-        auth['node_id'] = vars['NODE_ID']
-        auth['node_ip'] = vars['NETWORK_SETTINGS']['ip']
-    except KeyError, e:
-        return None
-
-    #params= serialize_params(call_params)
-    #params.sort()
-    #msg= "[" + "".join(params) + "]"
-    #node_hmac= hmac.new(vars['NODE_KEY'], msg.encode('utf-8'), sha).hexdigest()
-    node_hmac= hmac.new(vars['NODE_KEY'], "[]".encode('utf-8'), sha).hexdigest()
-    auth['value']= node_hmac
+    auth = {}
+
     try:
         auth_session = {}
     try:
         auth_session = {}
+        auth_session['AuthMethod'] = 'session'
+
         if not vars.has_key('NODE_SESSION'):
         if not vars.has_key('NODE_SESSION'):
-            session = vars['API_SERVER_INST'].GetSession(auth)
+            # Try to load /etc/planetlab/session if it exists.
+            sessionfile = open('/etc/planetlab/session', 'r')
+            session = sessionfile.read().strip()
+
             auth_session['session'] = session
             auth_session['session'] = session
-            vars['SESSION'] = session
+            # Test session.  Faults if it's no good.
+            vars['API_SERVER_INST'].AuthCheck(auth_session)
+            vars['NODE_SESSION'] = session
+
+            sessionfile.close()
         else:
             auth_session['session'] = vars['NODE_SESSION']
         else:
             auth_session['session'] = vars['NODE_SESSION']
-        auth_session['AuthMethod'] = 'session'
+
         auth = auth_session
         auth = auth_session
-    except Exception, e:
-        print e
-        pass
+
+    except:
+        auth['AuthMethod'] = 'hmac'
+
+        try:
+            auth['node_id'] = vars['NODE_ID']
+            auth['node_ip'] = vars['INTERFACE_SETTINGS']['ip']
+        except KeyError as e:
+            return None
+
+        node_hmac = hmac.new(vars['NODE_KEY'], "[]".encode('utf-8'), sha).hexdigest()
+        auth['value'] = node_hmac
+        try:
+            auth_session = {}
+            if not vars.has_key('NODE_SESSION'):
+                session = vars['API_SERVER_INST'].GetSession(auth)
+                auth_session['session'] = session
+                vars['NODE_SESSION'] = session
+                # NOTE: save session value to /etc/planetlab/session for 
+                # RunlevelAgent and future BootManager runs
+                if not os.path.exists("/etc/planetlab"):
+                    os.makedirs("/etc/planetlab")
+                sessionfile = open('/etc/planetlab/session', 'w')
+                sessionfile.write(vars['NODE_SESSION'])
+                sessionfile.close()
+            else:
+                auth_session['session'] = vars['NODE_SESSION']
+
+            auth_session['AuthMethod'] = 'session'
+            auth = auth_session
+
+        except Exception as e:
+            # NOTE: BM has failed to authenticate utterly.
+            raise BootManagerAuthenticationException("{}".format(e))
+
     return auth
 
 
     return auth
 
 
-def serialize_params( call_params ):
+def serialize_params(call_params):
     """
     convert a list of parameters into a format that will be used in the
     hmac generation. both the boot manager and plc must have a common
     """
     convert a list of parameters into a format that will be used in the
     hmac generation. both the boot manager and plc must have a common
@@ -69,7 +98,7 @@ def serialize_params( call_params ):
     them into one long string encased in a set of braces.
     """
 
     them into one long string encased in a set of braces.
     """
 
-    values= []
+    values = []
     
     for param in call_params:
         if isinstance(param,list) or isinstance(param,tuple):
     
     for param in call_params:
         if isinstance(param,list) or isinstance(param,tuple):
@@ -90,7 +119,7 @@ def serialize_params( call_params ):
     return values
 
     
     return values
 
     
-def call_api_function( vars, function, user_params ):
+def call_api_function(vars, function, user_params):
     """
     call the named api function with params, and return the
     value to the caller. the authentication structure is handled
     """
     call the named api function with params, and return the
     value to the caller. the authentication structure is handled
@@ -101,9 +130,9 @@ def call_api_function( vars, function, user_params ):
     global stash
 
     try:
     global stash
 
     try:
-        api_server= vars['API_SERVER_INST']
-    except KeyError, e:
-        raise BootManagerException, "No connection to the API server exists."
+        api_server = vars['API_SERVER_INST']
+    except KeyError as e:
+        raise BootManagerException("No connection to the API server exists.")
 
     if api_server is None:
         if not stash:
 
     if api_server is None:
         if not stash:
@@ -111,29 +140,29 @@ def call_api_function( vars, function, user_params ):
         for i in stash:
             if i[0] == function and i[1] == user_params:
                return i[2]
         for i in stash:
             if i[0] == function and i[1] == user_params:
                return i[2]
-        raise BootManagerException, \
-              "Disconnected operation failed, insufficient stash."
+        raise BootManagerException(
+              "Disconnected operation failed, insufficient stash.")
 
 
-    auth= create_auth_structure(vars,user_params)
+    auth = create_auth_structure(vars,user_params)
     if auth is None:
     if auth is None:
-        raise BootManagerException, \
-              "Could not create auth structure, missing values."
+        raise BootManagerException(
+              "Could not create auth structure, missing values.")
     
     
-    params= (auth,)
-    params= params + user_params
+    params = (auth,)
+    params = params + user_params
 
     try:
 
     try:
-        exec( "rc= api_server.%s(*params)" % function )
+        exec("rc= api_server.{}(*params)".format(function))
         if stash is None:
             stash = []
         stash += [ [ function, user_params, rc ] ]
         return rc
         if stash is None:
             stash = []
         stash += [ [ function, user_params, rc ] ]
         return rc
-    except xmlrpclib.Fault, fault:
-        raise BootManagerException, "API Fault: %s" % fault
-    except xmlrpclib.ProtocolError, err:
-        raise BootManagerException,"XML RPC protocol error: %s" % err
-    except xml.parsers.expat.ExpatError, err:
-        raise BootManagerException,"XML parsing error: %s" % err
+    except xmlrpclib.Fault as fault:
+        raise BootManagerException("API Fault: {}".format(fault))
+    except xmlrpclib.ProtocolError as err:
+        raise BootManagerException("XML RPC protocol error: {}".format(err))
+    except xml.parsers.expat.ExpatError as err:
+        raise BootManagerException("XML parsing error: {}".format(err))
 
 
 class Stash(file):
 
 
 class Stash(file):
@@ -141,18 +170,18 @@ class Stash(file):
     def __init__(self, vars, mode):
         utils.makedirs(self.mntpnt)
         try:
     def __init__(self, vars, mode):
         utils.makedirs(self.mntpnt)
         try:
-            utils.sysexec('mount -t auto -U %s %s' % (vars['DISCONNECTED_OPERATION'], self.mntpnt))
+            utils.sysexec('mount -t auto -U {} {}'.format(vars['DISCONNECTED_OPERATION'], self.mntpnt))
             # make sure it's not read-only
             # make sure it's not read-only
-            f = file('%s/api.cache' % self.mntpnt, 'a')
+            f = file('{}/api.cache'.format(self.mntpnt), 'a')
             f.close()
             f.close()
-            file.__init__(self, '%s/api.cache' % self.mntpnt, mode)
+            file.__init__(self, '{}/api.cache'.format(self.mntpnt), mode)
         except:
         except:
-            utils.sysexec_noerr('umount %s' % self.mntpnt)
-            raise BootManagerException, "Couldn't find API-cache for disconnected operation"
+            utils.sysexec_noerr('umount {}'.format(self.mntpnt))
+            raise BootManagerException("Couldn't find API-cache for disconnected operation")
 
     def close(self):
         file.close(self)
 
     def close(self):
         file.close(self)
-        utils.sysexec_noerr('umount %s' % self.mntpnt)
+        utils.sysexec_noerr('umount {}'.format(self.mntpnt))
 
 def load(vars):
     global stash
 
 def load(vars):
     global stash