X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fiotlab%2Fiotlabdriver.py;h=855dc350cc81d103eded751769d1de933fb8b130;hb=acd13fb68264ecdc1996954f3f464537806f7380;hp=0e0af7851a1deabd160020409e9ffda48fc530dd;hpb=426504ceb81f60de2ee4711c7783a3df681f363a;p=sfa.git diff --git a/sfa/iotlab/iotlabdriver.py b/sfa/iotlab/iotlabdriver.py index 0e0af785..855dc350 100644 --- a/sfa/iotlab/iotlabdriver.py +++ b/sfa/iotlab/iotlabdriver.py @@ -16,10 +16,10 @@ from sfa.managers.driver import Driver from sfa.rspecs.version_manager import VersionManager from sfa.rspecs.rspec import RSpec -from sfa.iotlab.iotlabxrn import IotlabXrn, xrn_object +from sfa.iotlab.iotlabxrn import IotlabXrn, xrn_object, xrn_to_hostname from sfa.util.xrn import Xrn, hrn_to_urn, get_authority, urn_to_hrn from sfa.iotlab.iotlabaggregate import IotlabAggregate -from sfa.iotlab.iotlabxrn import xrn_to_hostname + from sfa.iotlab.iotlabslices import IotlabSlices from sfa.trust.credential import Credential @@ -42,10 +42,11 @@ class IotlabDriver(Driver): """ Sets the iotlab SFA config parameters, - instanciates the testbed api and the iotlab database. + instanciates the testbed api . - :param config: iotlab SFA configuration object - :type config: Config object + :param api: SfaApi configuration object. Holds reference to the + database. + :type api: SfaApi object """ Driver.__init__(self, api) @@ -152,13 +153,13 @@ class IotlabDriver(Driver): ret = self.testbed_shell.ldap.LdapAddUser(record) if ret['bool'] is True: - record['hrn'] = self.testbed_shell.root_auth + '.' + ret['uid'] + #record['hrn'] = self.testbed_shell.root_auth + '.' + ret['uid'] logger.debug("IOTLAB_API AddPerson return code %s record %s " % (ret, record)) - self.__add_person_to_db(record) + #self.__add_person_to_db(record) return ret - def __add_person_to_db(self, user_dict): + def add_person_to_db(self, user_dict): """ Add a federated user straight to db when the user issues a lease request with iotlab nodes and that he has not registered with iotlab @@ -178,20 +179,21 @@ class IotlabDriver(Driver): " %(user_dict)) hrn = user_dict['hrn'] person_urn = hrn_to_urn(hrn, 'user') - pubkey = user_dict['pkey'] try: + pubkey = user_dict['pkey'] pkey = convert_public_key(pubkey) except TypeError: #key not good. create another pkey - logger.warn('__add_person_to_db: unable to convert public \ + logger.warn('__add_person_to_db: no public key or unable to convert public \ key for %s' %(hrn )) pkey = Keypair(create=True) if pubkey is not None and pkey is not None : hierarchy = Hierarchy() + # We fake the parent in order to be able to create a valid GID person_gid = hierarchy.create_gid(person_urn, create_uuid(), \ - pkey) + pkey, force_parent='iotlab') if user_dict['email']: logger.debug("__add_person_to_db \r\n \r\n \ IOTLAB IMPORTER PERSON EMAIL OK email %s "\ @@ -201,7 +203,7 @@ class IotlabDriver(Driver): user_record = RegUser(hrn=hrn , pointer= '-1', \ authority=get_authority(hrn), \ email=user_dict['email'], gid = person_gid) - user_record.reg_keys = [RegKey(user_dict['pkey'])] + #user_record.reg_keys = [RegKey(user_dict['pkey'])] user_record.just_created() self.api.dbsession().add (user_record) self.api.dbsession().commit() @@ -213,7 +215,7 @@ class IotlabDriver(Driver): """ Get the slice record based on the slice hrn. Fetch the record of the user associated with the slice by using joinedload based on the - reg_researcher relationship. + reg_researchers relationship. :param slice_filter: the slice hrn we are looking for :type slice_filter: string @@ -232,7 +234,7 @@ class IotlabDriver(Driver): raw_slicerec = self.api.dbsession().query(RegSlice).options(joinedload('reg_researchers')).filter_by(hrn=slice_filter).first() #raw_slicerec = self.api.dbsession().query(RegRecord).filter_by(hrn = slice_filter).first() if raw_slicerec: - #load_reg_researcher + #load_reg_researchers #raw_slicerec.reg_researchers raw_slicerec = raw_slicerec.__dict__ logger.debug(" IOTLAB_API \t _sql_get_slice_info slice_filter %s \ @@ -420,8 +422,6 @@ class IotlabDriver(Driver): return_slicerec_dictlist.append(slicerec_dict) - logger.debug("IOTLAB_API.PY \tGetSlices \ - OHOHOHOH %s" %(return_slicerec_dictlist)) logger.debug("IOTLAB_API.PY \tGetSlices \ slicerec_dict %s return_slicerec_dictlist %s \ @@ -553,7 +553,7 @@ class IotlabDriver(Driver): Two purposes: -Fetch all the jobs from OAR (running, waiting..) complete the reservation information with slice hrn - found in testbed_xp table. If not available in the table, + found in lease_table . If not available in the table, assume it is a iotlab slice. -Updates the iotlab table, deleting jobs when necessary. @@ -642,7 +642,7 @@ class IotlabDriver(Driver): if lease_filter_dict is None: reservation_list = unfiltered_reservation_list - self.update_experiments_in_additional_sfa_db(job_oar_list, jobs_psql_id_list) + self.update_experiments_in_lease_table(job_oar_list, jobs_psql_id_list) logger.debug(" IOTLAB_API.PY \tGetLeases reservation_list %s" % (reservation_list)) @@ -650,9 +650,9 @@ class IotlabDriver(Driver): - def update_experiments_in_additional_sfa_db(self, + def update_experiments_in_lease_table(self, experiment_list_from_testbed, experiment_list_in_db): - """ Cleans the iotlab db by deleting expired and cancelled jobs. + """ Cleans the lease_table by deleting expired and cancelled jobs. Compares the list of experiment ids given by the testbed with the experiment ids that are already in the database, deletes the @@ -671,7 +671,7 @@ class IotlabDriver(Driver): set_experiment_list_in_db = set(experiment_list_in_db) kept_experiments = set(experiment_list_from_testbed).intersection(set_experiment_list_in_db) - logger.debug("\r\n \t update_experiments_in_additional_sfa_db \ + logger.debug("\r\n \t update_experiments_in_lease_table \ experiment_list_in_db %s \r\n \ experiment_list_from_testbed %s \ kept_experiments %s " @@ -685,6 +685,8 @@ class IotlabDriver(Driver): request.filter(LeaseTableXP.experiment_id.in_(deleted_experiments)).delete(synchronize_session='fetch') self.api.dbsession().commit() return + + def AddSlice(self, slice_record, user_record): """ @@ -703,14 +705,14 @@ class IotlabDriver(Driver): sfa_record = RegSlice(hrn=slice_record['hrn'], gid=slice_record['gid'], - pointer=slice_record['slice_id'], + #pointer=slice_record['slice_id'], authority=slice_record['authority']) logger.debug("IOTLAB_API.PY AddSlice sfa_record %s user_record %s" % (sfa_record, user_record)) sfa_record.just_created() self.api.dbsession().add(sfa_record) self.api.dbsession().commit() - #Update the reg-researcher dependance table + #Update the reg-researchers dependency table sfa_record.reg_researchers = [user_record] self.api.dbsession().commit() @@ -1087,7 +1089,7 @@ class IotlabDriver(Driver): - def delete(self, slice_urns, options={}): + def delete(self, slice_urns, options=None): """ Deletes the lease associated with the slice hrn and the credentials if the slice belongs to iotlab. Answer to DeleteSliver. @@ -1105,6 +1107,7 @@ class IotlabDriver(Driver): .. note:: creds are unused, and are not used either in the dummy driver delete_sliver . """ + if options is None: options={} # collect sliver ids so we can update sliver allocation states after # we remove the slivers. aggregate = IotlabAggregate(self) @@ -1397,7 +1400,8 @@ class IotlabDriver(Driver): 'geni_ad_rspec_versions': ad_rspec_versions} # first 2 args are None in case of resource discovery - def list_resources (self, version=None, options={}): + def list_resources (self, version=None, options=None): + if options is None: options={} aggregate = IotlabAggregate(self) rspec = aggregate.list_resources(version=version, options=options) return rspec @@ -1406,7 +1410,8 @@ class IotlabDriver(Driver): aggregate = IotlabAggregate(self) return aggregate.describe(urns, version=version, options=options) - def status (self, urns, options={}): + def status (self, urns, options=None): + if options is None: options={} aggregate = IotlabAggregate(self) desc = aggregate.describe(urns, version='GENI 3') status = {'geni_urn': desc['geni_urn'], @@ -1414,7 +1419,8 @@ class IotlabDriver(Driver): return status - def allocate (self, urn, rspec_string, expiration, options={}): + def allocate (self, urn, rspec_string, expiration, options=None): + if options is None: options={} xrn = Xrn(urn) aggregate = IotlabAggregate(self) @@ -1422,13 +1428,41 @@ class IotlabDriver(Driver): peer = slices.get_peer(xrn.get_hrn()) sfa_peer = slices.get_sfa_peer(xrn.get_hrn()) + caller_hrn = options.get('actual_caller_hrn', []) + caller_xrn = Xrn(caller_hrn) + caller_urn = caller_xrn.get_urn() - slice_record = None - users = options.get('geni_users', []) + logger.debug("IOTLABDRIVER.PY :: Allocate caller = %s" % (caller_urn)) + slice_record = {} + users = options.get('geni_users', []) sfa_users = options.get('sfa_users', []) + if sfa_users: - slice_record = sfa_users[0].get('slice_record', []) + user = None + # Looking for the user who actually called the Allocate function in the list of users of the slice + for u in sfa_users: + if 'urn' in u and u['urn'] == caller_urn: + user = u + logger.debug("user = %s" % u) + # If we find the user in the list we use it, else we take the 1st in the list as before + if user: + user_hrn = caller_hrn + else: + user = sfa_users[0] + # XXX Always empty ??? no slice_record in the Allocate call + #slice_record = sfa_users[0].get('slice_record', []) + user_xrn = Xrn(sfa_users[0]['urn']) + user_hrn = user_xrn.get_hrn() + + slice_record = user.get('slice_record', {}) + slice_record['user'] = {'keys': user['keys'], + 'email': user['email'], + 'hrn': user_hrn} + slice_record['authority'] = xrn.get_authority_hrn() + + logger.debug("IOTLABDRIVER.PY \t urn %s allocate options %s " + % (urn, options)) # parse rspec rspec = RSpec(rspec_string) @@ -1436,28 +1470,59 @@ class IotlabDriver(Driver): # ensure site record exists - # 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 + for user in users: + # XXX LOIC using hrn is a workaround because the function + # Xrn.get_urn returns 'urn:publicid:IDN+onelab:upmc+timur_friedman' + # Instead of this 'urn:publicid:IDN+onelab:upmc+user+timur_friedman' + user['hrn'] = urn_to_hrn(user['urn'])[0] + # XXX LOIC adding the users of the slice to reg-researchers + # reg-researchers is used in iotlabslices.py verify_slice in order to add the slice + if 'reg-researchers' not in slice_record: + slice_record['reg-researchers'] = list() + slice_record['reg-researchers'].append(user['hrn']) + if caller_hrn == user['hrn']: + #hierarchical_user = user['hrn'].split(".") + #user['login'] = hierarchical_user[-1] + #slice_record['login'] = user['login'] + slice_record['user']=user # 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 + logger.debug("IOTLABDRIVER.PY BEFORE slices.verify_persons") + + # XXX JORDAN XXX slice_record devrait recevoir le caller_xrn... + # LOIC maintenant c'est fait au dessus + logger.debug("IOTLABDRIVER.PY - LOIC - slice_record[user][hrn] = %s" % slice_record['user']['hrn']) + logger.debug("IOTLABDRIVER.PY - LOIC - slice_record[reg-researchers] = %s" % slice_record['reg-researchers']) persons = slices.verify_persons(xrn.hrn, slice_record, users, options=options) + logger.debug("IOTLABDRIVER.PY AFTER slices.verify_persons") + logger.debug("LOIC - slice_record[user] = %s" % slice_record['user']) + logger.debug("IOTLABDRIVER.PY - LOIC - slice_record[reg-researchers] = %s" % slice_record['reg-researchers']) + + # ensure slice record exists + current_slice = slices.verify_slice(xrn.hrn, slice_record, sfa_peer) + logger.debug("LOIC - AFTER verify_slice - slice_record[user] = %s" % slice_record['user']) + logger.debug("IOTLABDRIVER.PY - LOIC - slice_record[reg-researchers] = %s" % slice_record['reg-researchers']) + logger.debug("IOTLABDRIVER.PY \t ===============allocate \t\ + \r\n \r\n current_slice %s" % (current_slice)) + # ensure slice attributes exists # slices.verify_slice_attributes(slice, requested_attributes, # options=options) # add/remove slice from nodes + # XXX JORDAN ensure requested_xp_dict returns a dict with all new leases 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() + + + # JORDAN: nodes_list will contain a list of newly allocated nodes nodes_list = [] for start_time in requested_xp_dict: lease = requested_xp_dict[start_time] @@ -1472,30 +1537,45 @@ class IotlabDriver(Driver): rspec_requested_leases = rspec.version.get_leases() leases = slices.verify_slice_leases(slice_record, requested_xp_dict, peer) + # JORDAN: + # leases = already in slice + # rspec_requested_leases = newly requested logger.debug("IOTLABDRIVER.PY \tallocate leases %s \ rspec_requested_leases %s" % (leases, rspec_requested_leases)) - # update sliver allocations + # update sliver allocations + # JORDAN Here we loop over newly allocated nodes 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'] + if 'reg-urn' in current_slice: + slice_urn = current_slice['reg-urn'] + else: + slice_urn = current_slice['urn'] + + # JORDAN: We loop over leases previously in the slice 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, + 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') - record.sync(self.api.dbsession()) + record.sync(self.api.dbsession()) - return aggregate.describe([xrn.get_urn()], version=rspec.version) + # JORDAN : added describe_options which was not specified at all + describe_options = { + 'geni_slice_urn': urn, + 'list_leases': 'all', + } + return aggregate.describe([xrn.get_urn()], version=rspec.version, options=describe_options) - def provision(self, urns, options={}): + def provision(self, urns, options=None): + if options is None: options={} # update users slices = IotlabSlices(self) aggregate = IotlabAggregate(self) @@ -1515,4 +1595,10 @@ class IotlabDriver(Driver): version_manager = VersionManager() rspec_version = version_manager.get_version(options[ 'geni_rspec_version']) - return self.describe(urns, rspec_version, options=options) + # JORDAN : added describe_options instead of options + # urns at the begining ??? + describe_options = { + 'geni_slice_urn': current_slice['urn'], + 'list_leases': 'all', + } + return self.describe(urns, rspec_version, options=describe_options)