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):
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)
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'
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':
# 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):
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'
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):
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):
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])
# 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()
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