X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=source%2FBootAPI.py;h=db173565895d51ef835e2603cf03c911aaffb792;hb=3d1aa2ec9d43ee03243c0808a85bdcc578a7ace8;hp=bedf7275f6d9d179c8da6cd4c22d5f611c562dfe;hpb=79ea11f05210d17197030e6405e74345c7dcb690;p=bootmanager.git diff --git a/source/BootAPI.py b/source/BootAPI.py index bedf727..db17356 100644 --- a/source/BootAPI.py +++ b/source/BootAPI.py @@ -1,5 +1,5 @@ -#!/usr/bin/python2 - +#!/usr/bin/python +# # Copyright (c) 2003 Intel Corporation # All rights reserved. # @@ -14,12 +14,13 @@ import string import sha import cPickle import utils +import os 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 @@ -27,39 +28,68 @@ 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) """ - - 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 = {} - if not vars.has_key('SESSION'): - session = vars['API_SERVER_INST'].GetSession(auth) + auth_session['AuthMethod'] = 'session' + + if not vars.has_key('NODE_SESSION'): + # Try to load /etc/planetlab/session if it exists. + with open('/etc/planetlab/session', 'r') as sessionfile: + session = sessionfile.read().strip() + 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 + else: - auth_session['session'] = vars['SESSION'] - auth_session['AuthMethod'] = 'session' + auth_session['session'] = vars['NODE_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") + 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 + + except Exception as e: + # NOTE: BM has failed to authenticate utterly. + import traceback + traceback.print_exc() + raise BootManagerAuthenticationException("{}".format(e)) + 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 @@ -69,8 +99,8 @@ def serialize_params( call_params ): 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) @@ -86,11 +116,11 @@ def serialize_params( call_params ): values.append("False") else: values.append(unicode(param)) - + 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 @@ -101,9 +131,9 @@ def call_api_function( vars, function, user_params ): 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: @@ -111,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] - 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: - 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: - 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 - 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): @@ -141,18 +171,18 @@ class Stash(file): 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 - f = file('%s/api.cache' % self.mntpnt, 'a') + f = file('{}/api.cache'.format(self.mntpnt), 'a') f.close() - file.__init__(self, '%s/api.cache' % self.mntpnt, mode) + file.__init__(self, '{}/api.cache'.format(self.mntpnt), mode) 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) - utils.sysexec_noerr('umount %s' % self.mntpnt) + utils.sysexec_noerr('umount {}'.format(self.mntpnt)) def load(vars): global stash