From: Daniel Hokka Zakrisson Date: Thu, 16 Aug 2007 20:13:46 +0000 (+0000) Subject: Disconnected operation. X-Git-Url: http://git.onelab.eu/?p=bootmanager.git;a=commitdiff_plain;h=07139b606dfc3c657ef7d06da25c084c1679b660 Disconnected operation. --- diff --git a/source/BootAPI.py b/source/BootAPI.py index c0d0c3b..9565128 100644 --- a/source/BootAPI.py +++ b/source/BootAPI.py @@ -12,9 +12,12 @@ import xml.parsers.expat import hmac import string import sha +import cPickle +import utils from Exceptions import * +stash = None def create_auth_structure( vars, call_params ): """ @@ -86,12 +89,22 @@ def call_api_function( vars, function, user_params ): If the call fails, a BootManagerException is raised. """ - + global stash + try: api_server= vars['API_SERVER_INST'] except KeyError, e: raise BootManagerException, "No connection to the API server exists." + if api_server is None: + if not stash: + load(vars) + for i in stash: + if i[0] == function and i[1] == user_params: + return i[2] + raise BootManagerException, \ + "Disconnected operation failed, insufficient stash." + auth= create_auth_structure(vars,user_params) if auth is None: raise BootManagerException, \ @@ -102,6 +115,9 @@ def call_api_function( vars, function, user_params ): try: exec( "rc= api_server.%s(*params)" % function ) + if stash is None: + stash = [] + stash += [ [ function, user_params, rc ] ] return rc except xmlrpclib.Fault, fault: raise BootManagerException, "API Fault: %s" % fault @@ -109,3 +125,35 @@ def call_api_function( vars, function, user_params ): raise BootManagerException,"XML RPC protocol error: %s" % err except xml.parsers.expat.ExpatError, err: raise BootManagerException,"XML parsing error: %s" % err + + +class Stash(file): + mntpnt = '/tmp/stash' + def __init__(self, vars, mode): + utils.makedirs(self.mntpnt) + try: + utils.sysexec('mount -t auto -U %s %s' % (vars['DISCONNECTED_OPERATION'], self.mntpnt)) + # make sure it's not read-only + f = file('%s/api.cache' % self.mntpnt, 'a') + f.close() + file.__init__(self, '%s/api.cache' % self.mntpnt, mode) + except: + utils.sysexec_noerr('umount %s' % 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) + +def load(vars): + global stash + s = Stash(vars, 'r') + stash = cPickle.load(s) + s.close() + +def save(vars): + global stash + if vars['DISCONNECTED_OPERATION']: + s = Stash(vars, 'w') + cPickle.dump(stash, s) + s.close() diff --git a/source/steps/AuthenticateWithPLC.py b/source/steps/AuthenticateWithPLC.py index 55511dc..dddb5ee 100644 --- a/source/steps/AuthenticateWithPLC.py +++ b/source/steps/AuthenticateWithPLC.py @@ -56,6 +56,13 @@ def Run( vars, log ): return 1 except BootManagerException, e: log.write( "Authentication failed: %s.\n" % e ) + except: + # This is ugly. + if vars['DISCONNECTED_OPERATION']: + vars['API_SERVER_INST']= None + return 1 + else: + raise # increment auth failure auth_failure_count= 0 diff --git a/source/steps/ChainBootNode.py b/source/steps/ChainBootNode.py index b04756d..3e76d9c 100644 --- a/source/steps/ChainBootNode.py +++ b/source/steps/ChainBootNode.py @@ -151,6 +151,8 @@ def Run( vars, log ): utils.sysexec( "cp %s/boot/kernel-boot%s /tmp/kernel" % (SYSIMG_PATH,option), log ) utils.sysexec( "cp %s/boot/initrd-boot%s /tmp/initrd" % (SYSIMG_PATH,option), log ) + BootAPI.save(vars) + log.write( "Unmounting disks.\n" ) try: # backwards compat, though, we should never hit this case post PL 3.2 @@ -234,7 +236,7 @@ def Run( vars, log ): # problems during chain boot, such as USB host # controller drivers (HCDs) (PL6577). # if int(parts[2]) == 0: - if re.search('_hcd$', parts[0]): + if False and re.search('_hcd$', parts[0]): if usb_usage > 0: log.write( "NOT unloading %s since USB may be in use\n" % parts[0] ) else: diff --git a/source/steps/ReadNodeConfiguration.py b/source/steps/ReadNodeConfiguration.py index c04cadf..d19439e 100644 --- a/source/steps/ReadNodeConfiguration.py +++ b/source/steps/ReadNodeConfiguration.py @@ -116,6 +116,8 @@ def Run( vars, log ): vars['WAS_NODE_ID_IN_CONF']= 0 vars['WAS_NODE_KEY_IN_CONF']= 0 + vars['DISCONNECTED_OPERATION']= '' + # for any devices that need to be mounted to get the configuration # file, mount them here. mount_point= "/tmp/conffilemount" @@ -439,7 +441,10 @@ def __parse_configuration_file( vars, log, file_contents ): if name == "NET_DEVICE": NETWORK_SETTINGS['mac']= string.upper(value) - + + if name == "DISCONNECTED_OPERATION": + vars['DISCONNECTED_OPERATION']= value.strip() + except IndexError, e: log.write( "Unable to parse configuration file\n" ) @@ -622,7 +627,7 @@ def __parse_configuration_file( vars, log, file_contents ): vars["NETWORK_SETTINGS"]= NETWORK_SETTINGS - if not hostname_resolve_ok: + if not hostname_resolve_ok and not vars['DISCONNECTED_OPERATION']: log.write( "Hostname does not resolve correctly, will not continue.\n" ) if can_make_api_call: