use context manager to save and read node session
[bootmanager.git] / source / BootAPI.py
index b3bbffb..db17356 100644 (file)
@@ -1,5 +1,5 @@
 #!/usr/bin/python
 #!/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
@@ -28,7 +29,7 @@ def create_auth_structure( vars, call_params ):
     keys in vars, such as node_id or node_key)
     """
 
     keys in vars, such as node_id or node_key)
     """
 
-    auth= {}
+    auth = {}
 
     try:
         auth_session = {}
 
     try:
         auth_session = {}
@@ -36,57 +37,59 @@ def create_auth_structure( vars, call_params ):
 
         if not vars.has_key('NODE_SESSION'):
             # Try to load /etc/planetlab/session if it exists.
 
         if not vars.has_key('NODE_SESSION'):
             # Try to load /etc/planetlab/session if it exists.
-            sessionfile = open('/etc/planetlab/session', 'r')
-            session = sessionfile.read().strip()
+            with open('/etc/planetlab/session', 'r') as sessionfile:
+                session = sessionfile.read().strip()
 
             auth_session['session'] = session
             # Test session.  Faults if it's no good.
             vars['API_SERVER_INST'].AuthCheck(auth_session)
             vars['NODE_SESSION'] = session
 
 
             auth_session['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']
 
         auth = auth_session
 
     except:
         else:
             auth_session['session'] = vars['NODE_SESSION']
 
         auth = auth_session
 
     except:
-        import traceback; traceback.print_exc()
-        auth['AuthMethod']= 'hmac'
+        auth['AuthMethod'] = 'hmac'
 
         try:
             auth['node_id'] = vars['NODE_ID']
             auth['node_ip'] = vars['INTERFACE_SETTINGS']['ip']
 
         try:
             auth['node_id'] = vars['NODE_ID']
             auth['node_ip'] = vars['INTERFACE_SETTINGS']['ip']
-        except KeyError, e:
+        except KeyError as e:
             return None
 
             return None
 
-        node_hmac= hmac.new(vars['NODE_KEY'], "[]".encode('utf-8'), sha).hexdigest()
-        auth['value']= node_hmac
+        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
         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 
+                # NOTE: save session value to /etc/planetlab/session for
                 # RunlevelAgent and future BootManager runs
                 # RunlevelAgent and future BootManager runs
-                sessionfile = open('/etc/planetlab/session', 'w')
-                sessionfile.write( vars['NODE_SESSION'] )
-                sessionfile.close()
+                if not os.path.exists("/etc/planetlab"):
+                    os.makedirs("/etc/planetlab")
+                with open('/etc/planetlab/session', 'w') as sessionfile:
+                    sessionfile.write(vars['NODE_SESSION'])
+
             else:
                 auth_session['session'] = vars['NODE_SESSION']
 
             auth_session['AuthMethod'] = 'session'
             auth = auth_session
 
             else:
                 auth_session['session'] = vars['NODE_SESSION']
 
             auth_session['AuthMethod'] = 'session'
             auth = auth_session
 
-        except Exception, e:
-            print e
-            pass
+        except Exception as e:
+            # NOTE: BM has failed to authenticate utterly.
+            import traceback
+            traceback.print_exc()
+            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
@@ -96,8 +99,8 @@ 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):
             values += serialize_params(param)
     for param in call_params:
         if isinstance(param,list) or isinstance(param,tuple):
             values += serialize_params(param)
@@ -113,11 +116,11 @@ def serialize_params( call_params ):
                 values.append("False")
         else:
             values.append(unicode(param))
                 values.append("False")
         else:
             values.append(unicode(param))
-                
+
     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
@@ -128,9 +131,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:
@@ -138,29 +141,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."
-    
-    params= (auth,)
-    params= params + user_params
+        raise BootManagerException(
+              "Could not create auth structure, missing values.")
+
+    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):
@@ -168,18 +171,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