From 9f7ec7438cee94d3049307b2c0edefb119a0b465 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Thu, 14 Apr 2011 15:15:26 +0200 Subject: [PATCH] slice_status is now SliverStatus and handles call_id first slice manager implementation that merges results (and turned off the import from registry) --- sfa/client/sfi.py | 2 +- sfa/managers/aggregate_manager_pl.py | 23 ++++++-------- sfa/managers/aggregate_manager_vini.py | 2 +- sfa/managers/component_manager_pl.py | 2 +- sfa/managers/registry_manager_pl.py | 3 +- sfa/managers/slice_manager_pl.py | 44 +++++++++++++++++++++++--- sfa/methods/RenewSliver.py | 2 +- sfa/methods/SliverStatus.py | 5 +-- 8 files changed, 58 insertions(+), 25 deletions(-) diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index 01071429..bc6cc60f 100755 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -970,7 +970,7 @@ class Sfi: delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority)) creds.append(delegated_cred) server = self.get_server_from_opts(opts) - print server.SliverStatus(slice_urn, creds) + print server.SliverStatus(slice_urn, creds, unique_call_id()) def shutdown(self, opts, args): diff --git a/sfa/managers/aggregate_manager_pl.py b/sfa/managers/aggregate_manager_pl.py index 5355f97b..887d2f30 100644 --- a/sfa/managers/aggregate_manager_pl.py +++ b/sfa/managers/aggregate_manager_pl.py @@ -95,8 +95,10 @@ def __get_hostnames(nodes): hostnames.append(node.hostname) return hostnames -def slice_status(api, slice_xrn, creds): - hrn, type = urn_to_hrn(slice_xrn) +def SliverStatus(api, slice_xrn, creds, call_id): + if Callids().already_handled(call_id): return {} + + (hrn, type) = urn_to_hrn(slice_xrn) # find out where this slice is currently running api.logger.info(hrn) slicename = hrn_to_pl_slicename(hrn) @@ -106,19 +108,12 @@ def slice_status(api, slice_xrn, creds): raise Exception("Slice %s not found (used %s as slicename internally)" % slice_xrn, slicename) slice = slices[0] - nodes = api.plshell.GetNodes(api.plauth, slice['node_ids'], - ['hostname', 'site_id', 'boot_state', 'last_contact']) + # report about the local nodes only + nodes = api.plshell.GetNodes(api.plauth, {'node_id':slice['node_ids'],'peer_id':None}, + ['hostname', 'site_id', 'boot_state', 'last_contact']) site_ids = [node['site_id'] for node in nodes] sites = api.plshell.GetSites(api.plauth, site_ids, ['site_id', 'login_base']) - sites_dict = {} - for site in sites: - sites_dict[site['site_id']] = site['login_base'] - - # XX remove me - #api.logger.info(slice_xrn) - #api.logger.info(slice) - #api.logger.info(nodes) - # XX remove me + sites_dict = dict ( [ (site['site_id'],site['login_base'] ) for site in sites ] ) result = {} top_level_status = 'unknown' @@ -134,7 +129,7 @@ def slice_status(api, slice_xrn, creds): res['pl_hostname'] = node['hostname'] res['pl_boot_state'] = node['boot_state'] res['pl_last_contact'] = node['last_contact'] - if not node['last_contact'] is None: + if node['last_contact'] is not None: res['pl_last_contact'] = datetime.datetime.fromtimestamp(node['last_contact']).ctime() res['geni_urn'] = hostname_to_urn(api.hrn, sites_dict[node['site_id']], node['hostname']) if node['boot_state'] == 'boot': diff --git a/sfa/managers/aggregate_manager_vini.py b/sfa/managers/aggregate_manager_vini.py index 92e0bdc4..66fb5ccd 100644 --- a/sfa/managers/aggregate_manager_vini.py +++ b/sfa/managers/aggregate_manager_vini.py @@ -26,7 +26,7 @@ from sfa.util.callids import Callids # VINI aggregate is almost identical to PLC aggregate for many operations, # so lets just import the methods form the PLC manager from sfa.managers.aggregate_manager_pl import ( -start_slice, stop_slice, RenewSliver, reset_slice, ListSlices, get_ticket, slice_status) +start_slice, stop_slice, RenewSliver, reset_slice, ListSlices, get_ticket, SliverStatus) def GetVersion(api): diff --git a/sfa/managers/component_manager_pl.py b/sfa/managers/component_manager_pl.py index 3d4f76ac..6100e763 100644 --- a/sfa/managers/component_manager_pl.py +++ b/sfa/managers/component_manager_pl.py @@ -21,7 +21,7 @@ def init_server(): sfa_component_setup.get_credential(force=True) sfa_component_setup.get_trusted_certs() -def slice_status(api, slice_xrn, creds): +def SliverStatus(api, slice_xrn, creds): result = {} result['geni_urn'] = slice_xrn result['geni_status'] = 'unknown' diff --git a/sfa/managers/registry_manager_pl.py b/sfa/managers/registry_manager_pl.py index dc364b3e..9dba54db 100644 --- a/sfa/managers/registry_manager_pl.py +++ b/sfa/managers/registry_manager_pl.py @@ -13,7 +13,8 @@ from sfa.trust.credential import Credential from sfa.trust.certificate import Certificate, Keypair from sfa.trust.gid import create_uuid from sfa.util.version import version_core -from sfa.managers.aggregate_manager_pl import slice_status +# Thierry - turning this off, it's a slice interface not a registry one ?!? +#from sfa.managers.aggregate_manager_pl import SliverStatus # The GENI GetVersion call def GetVersion(api): diff --git a/sfa/managers/slice_manager_pl.py b/sfa/managers/slice_manager_pl.py index 44b1a5e8..89910970 100644 --- a/sfa/managers/slice_manager_pl.py +++ b/sfa/managers/slice_manager_pl.py @@ -25,10 +25,6 @@ import sfa.plc.peers as peers from sfa.util.version import version_core from sfa.util.callids import Callids -# XX FIX ME: should merge result from multiple aggregates instead of -# calling aggregate implementation -from sfa.managers.aggregate_manager_pl import slice_status - # we have specialized xmlrpclib.ServerProxy to remember the input url # OTOH it's not clear if we're only dealing with XMLRPCServerProxy instances def get_serverproxy_url (server): @@ -384,6 +380,46 @@ def ListResources(api, creds, options, call_id): return merged_rspec +# first draft at a merging SliverStatus +def SliverStatus(api, slice_xrn, creds, call_id): + if Callids().already_handled(call_id): return {} + # attempt to use delegated credential first + credential = api.getDelegatedCredential(creds) + if not credential: + credential = api.getCredential() + threads = ThreadManager() + for aggregate in api.aggregates: + server = api.aggregates[aggregate] + threads.run (server.SliverStatus, slice_xrn, credential, call_id) + results = threads.get_results() + + # get rid of any void result - e.g. when call_id was hit where by convention we return {} + results = [ result in results if result and result['geni_resources']] + + # do not try to combine if there's no result + if not results : return {} + + # otherwise let's merge stuff + overall = {} + + # mmh, it is expected that all results carry the same urn + overall['geni_urn'] = results[0]['geni_urn'] + + # consolidate geni_status - simple model using max on a total order + states = [ 'ready', 'configuring', 'failed', 'unknown' ] + # hash name to index + shash = dict ( zip ( states, range(len(states)) ) ) + def combine_status (x,y): + return shash [ max (shash(x),shash(y)) ] + overall['geni_status'] = reduce (combine_status, [ result['geni_status'] for result in results], 'ready' ) + + # {'ready':0,'configuring':1,'failed':2,'unknown':3} + # append all geni_resources + overall['geni_resources'] = \ + reduce (lambda x,y: x+y, [ result['geni_resources'] for result in results] , []) + + return overall + def main(): r = RSpec() r.parseFile(sys.argv[1]) diff --git a/sfa/methods/RenewSliver.py b/sfa/methods/RenewSliver.py index b426a3db..6cbde77c 100644 --- a/sfa/methods/RenewSliver.py +++ b/sfa/methods/RenewSliver.py @@ -35,7 +35,7 @@ class RenewSliver(Method): # Validate that the time does not go beyond the credential's expiration time requested_time = utcparse(expiration_time) if requested_time > Credential(string=valid_creds[0]).get_expiration(): - raise InsufficientRights('SliverStatus: Credential expires before requested expiration time') + raise InsufficientRights('Renewsliver: Credential expires before requested expiration time') if requested_time > datetime.datetime.utcnow() + datetime.timedelta(days=60): raise Exception('Cannot renew > 60 days from now') manager = self.api.get_interface_manager() diff --git a/sfa/methods/SliverStatus.py b/sfa/methods/SliverStatus.py index 842c3e45..231bec56 100644 --- a/sfa/methods/SliverStatus.py +++ b/sfa/methods/SliverStatus.py @@ -15,17 +15,18 @@ class SliverStatus(Method): Parameter(str, "Slice URN"), Mixed(Parameter(str, "Credential string"), Parameter(type([str]), "List of credentials")), + Parameter(str, "call_id"), ] returns = Parameter(dict, "Status details") - def call(self, slice_xrn, creds): + def call(self, slice_xrn, creds, call_id=""): hrn, type = urn_to_hrn(slice_xrn) valid_creds = self.api.auth.checkCredentials(creds, 'sliverstatus', hrn) self.api.logger.info("interface: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, hrn, self.name)) manager = self.api.get_interface_manager() - status = manager.slice_status(self.api, hrn, valid_creds) + status = manager.SliverStatus(self.api, hrn, valid_creds, call_id) return status -- 2.43.0