X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fiotlab%2Fiotlabdriver.py;h=699e11185f2bff05c6efa5d32f6d1318a1589c18;hb=fae309c53ba7e65f1b51047d8c8fbb7a10477713;hp=55764317cc437c6c87bf196f7d47e7e6863e9d5f;hpb=4e2ec73ee3208dedc36a6954d99f2c2ab3f6baf3;p=sfa.git diff --git a/sfa/iotlab/iotlabdriver.py b/sfa/iotlab/iotlabdriver.py index 55764317..699e1118 100644 --- a/sfa/iotlab/iotlabdriver.py +++ b/sfa/iotlab/iotlabdriver.py @@ -4,17 +4,20 @@ Implements what a driver should provide for SFA to work. from sfa.util.faults import SliverDoesNotExist, UnknownSfaType from sfa.util.sfalogging import logger from sfa.storage.model import RegRecord +from sfa.util.sfatime import utcparse, datetime_to_string from sfa.managers.driver import Driver from sfa.rspecs.version_manager import VersionManager from sfa.rspecs.rspec import RSpec -from sfa.util.xrn import Xrn, hrn_to_urn, get_authority +from sfa.iotlab.iotlabxrn import xrn_object +from sfa.util.xrn import Xrn, hrn_to_urn, get_authority, urn_to_hrn -from sfa.iotlab.iotlabaggregate import IotlabAggregate, iotlab_xrn_to_hostname +from sfa.iotlab.iotlabaggregate import IotlabAggregate +from sfa.iotlab.iotlabxrn import xrn_to_hostname from sfa.iotlab.iotlabslices import IotlabSlices - +from sfa.storage.model import SliverAllocation from sfa.iotlab.iotlabshell import IotlabShell @@ -38,7 +41,7 @@ class IotlabDriver(Driver): """ Driver.__init__(self, api) - self.api=api + self.api = api config = api.config self.testbed_shell = IotlabShell(api) self.cache = None @@ -366,7 +369,7 @@ class IotlabDriver(Driver): if get_authority(lease['component_id']) == \ self.testbed_shell.root_auth: single_requested_lease['hostname'] = \ - iotlab_xrn_to_hostname(\ + xrn_to_hostname(\ lease.get('component_id').strip()) single_requested_lease['start_time'] = \ lease.get('start_time') @@ -434,6 +437,7 @@ class IotlabDriver(Driver): return xp_dict + def create_sliver(self, slice_urn, slice_hrn, creds, rspec_string, users, options): """Answer to CreateSliver. @@ -523,17 +527,14 @@ class IotlabDriver(Driver): login=sfa_slice['login'], version=rspec.version) - def delete_sliver(self, slice_urn, slice_hrn, creds, options): + def delete(self, slice_urns, options): """ Deletes the lease associated with the slice hrn and the credentials if the slice belongs to iotlab. Answer to DeleteSliver. :param slice_urn: urn of the slice - :param slice_hrn: name of the slice - :param creds: slice credenials :type slice_urn: string - :type slice_hrn: string - :type creds: ? unused + :returns: 1 if the slice to delete was not found on iotlab, True if the deletion was successful, False otherwise otherwise. @@ -544,6 +545,20 @@ class IotlabDriver(Driver): .. note:: creds are unused, and are not used either in the dummy driver delete_sliver . """ + # collect sliver ids so we can update sliver allocation states after + # we remove the slivers. + aggregate = IotlabAggregate(self) + slivers = aggregate.get_slivers(slice_urns) + if slivers: + slice_id = slivers[0]['slice_id'] + node_ids = [] + sliver_ids = [] + for sliver in slivers: + node_ids.append(sliver['node_id']) + sliver_ids.append(sliver['sliver_id']) + logger.debug("IOTLABDRIVER.PY delete_sliver slivers %s slice_urns %s" + % (slivers, slice_urns)) + slice_hrn = urn_to_hrn(slice_urns[0])[0] sfa_slice_list = self.testbed_shell.GetSlices( slice_filter=slice_hrn, @@ -564,9 +579,19 @@ class IotlabDriver(Driver): \r\n \t sfa_slice %s " % (peer, sfa_slice)) try: self.testbed_shell.DeleteSliceFromNodes(sfa_slice) - return True + dbsession = self.api.dbsession() + SliverAllocation.delete_allocations(sliver_ids,dbsession) except: - return False + logger.log_exc("IOTLABDRIVER.PY delete error ") + + # prepare return struct + geni_slivers = [] + for sliver in slivers: + geni_slivers.append( + {'geni_sliver_urn': sliver['sliver_id'], + 'geni_allocation_status': 'geni_unallocated', + 'geni_expires': datetime_to_string(utcparse(sliver['expires']))}) + return geni_slivers def list_resources (self, slice_urn, slice_hrn, creds, options): """ @@ -795,3 +820,169 @@ class IotlabDriver(Driver): slice_filter_type='slice_hrn'): ret = self.testbed_shell.DeleteSlice(sfa_record) return True + + def check_sliver_credentials(self, creds, urns): + # build list of cred object hrns + slice_cred_names = [] + for cred in creds: + slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn() + slicename = Xrn(xrn=slice_cred_hrn).iotlab_slicename() + logger.debug("IOTLABDRIVER.PY \t check_sliver_credentials slicename %s \r\n \r\n" + % (slicename)) + slice_cred_names.append(slicename) + + # look up slice name of slivers listed in urns arg + + slice_ids = [] + for urn in urns: + sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts() + try: + slice_ids.append(int(sliver_id_parts[0])) + except ValueError: + pass + + if not slice_ids: + raise Forbidden("sliver urn not provided") + + slices = self.testbed_shell.GetSlices(slice_ids) + sliver_names = [single_slice['name'] for single_slice in slices] + + # make sure we have a credential for every specified sliver ierd + for sliver_name in sliver_names: + if sliver_name not in slice_cred_names: + msg = "Valid credential not found for target: %s" % sliver_name + raise Forbidden(msg) + + ######################################## + ########## aggregate oriented + ######################################## + + + def testbed_name (self): return "iotlab" + + def aggregate_version (self): + return {} + + # first 2 args are None in case of resource discovery + def list_resources (self, version=None, options={}): + aggregate = IotlabAggregate(self) + rspec = aggregate.list_resources(version=version, options=options) + return rspec + + def describe(self, urns, version, options={}): + aggregate = IotlabAggregate(self) + return aggregate.describe(urns, version=version, options=options) + + def status (self, urns, options={}): + aggregate = IotlabAggregate(self) + desc = aggregate.describe(urns, version='GENI 3') + status = {'geni_urn': desc['geni_urn'], + 'geni_slivers': desc['geni_slivers']} + return status + + + def allocate (self, urn, rspec_string, expiration, options={}): + xrn = Xrn(urn) + aggregate = IotlabAggregate(self) + + slices = IotlabSlices(self) + peer = slices.get_peer(xrn.get_hrn()) + sfa_peer = slices.get_sfa_peer(xrn.get_hrn()) + + + slice_record = None + users = options.get('geni_users', []) + + sfa_users = options.get('sfa_users', []) + if sfa_users: + slice_record = sfa_users[0].get('slice_record', []) + logger.debug("IOTLABDRIVER.PY \t ===============allocate \t\ + \r\n \r\n options %s slice_record %s" % (options,slice_record)) + # parse rspec + rspec = RSpec(rspec_string) + # requested_attributes = rspec.version.get_slice_attributes() + + # ensure site record exists + # site = slices.verify_site(xrn.hrn, slice_record, peer, sfa_peer, options=options) + # ensure slice record exists + + current_slice = slices.verify_slice(xrn.hrn, slice_record, sfa_peer) + logger.debug("IOTLABDRIVER.PY \t ===============allocate \t\ + \r\n \r\n current_slice %s" % (current_slice)) + # ensure person records exists + + # oui c'est degueulasse, le slice_record se retrouve modifie + # dans la methode avec les infos du user, els infos sont propagees + # dans verify_slice_leases + persons = slices.verify_persons(xrn.hrn, slice_record, users, options=options) + # ensure slice attributes exists + # slices.verify_slice_attributes(slice, requested_attributes, options=options) + + # add/remove slice from nodes + requested_xp_dict = self._process_requested_xp_dict(rspec) + + logger.debug("IOTLABDRIVER.PY \tallocate requested_xp_dict %s " + % (requested_xp_dict)) + request_nodes = rspec.version.get_nodes_with_slivers() + nodes_list = [] + for start_time in requested_xp_dict: + lease = requested_xp_dict[start_time] + for hostname in lease['hostname']: + nodes_list.append(hostname) + + # nodes = slices.verify_slice_nodes(slice_record,request_nodes, peer) + logger.debug("IOTLABDRIVER.PY \tallocate nodes_list %s slice_record %s" + % (nodes_list, slice_record)) + + # add/remove leases + rspec_requested_leases = rspec.version.get_leases() + leases = slices.verify_slice_leases(slice_record, requested_xp_dict, peer) + logger.debug("IOTLABDRIVER.PY \tallocate leases %s rspec_requested_leases %s" + % (leases,rspec_requested_leases)) + # update sliver allocations + for hostname in nodes_list: + client_id = hostname + node_urn = xrn_object(self.testbed_shell.root_auth, hostname).urn + component_id = node_urn + slice_urn = current_slice['reg-urn'] + for lease in leases: + if hostname in lease['reserved_nodes']: + index = lease['reserved_nodes'].index(hostname) + sliver_hrn = '%s.%s-%s' % (self.hrn, lease['lease_id'], + lease['resource_ids'][index] ) + sliver_id = Xrn(sliver_hrn, type='sliver').urn + record = SliverAllocation(sliver_id=sliver_id, client_id=client_id, + component_id=component_id, + slice_urn = slice_urn, + allocation_state='geni_allocated') + + logger.debug("\r\n \ + ===============================IOTLABDRIVER.PY \tallocate sliver_id %s slice_urn %s \r\n" + % (sliver_id,slice_urn)) + record.sync(self.api.dbsession()) + # add/remove links links + # slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes) + + + + return aggregate.describe([xrn.get_urn()], version=rspec.version) + + def provision(self, urns, options={}): + # update users + slices = IotlabSlices(self) + aggregate = IotlabAggregate(self) + slivers = aggregate.get_slivers(urns) + current_slice = slivers[0] + peer = slices.get_peer(current_slice['hrn']) + sfa_peer = slices.get_sfa_peer(current_slice['hrn']) + users = options.get('geni_users', []) + # persons = slices.verify_persons(current_slice['hrn'], + # current_slice, users, peer, sfa_peer, options=options) + # slices.handle_peer(None, None, persons, peer) + # update sliver allocation states and set them to geni_provisioned + sliver_ids = [sliver['sliver_id'] for sliver in slivers] + dbsession =self.api.dbsession() + SliverAllocation.set_allocations(sliver_ids, 'geni_provisioned',dbsession) + version_manager = VersionManager() + rspec_version = version_manager.get_version(options['geni_rspec_version']) + return self.describe(urns, rspec_version, options=options)