From 426504ceb81f60de2ee4711c7783a3df681f363a Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Wed, 18 Dec 2013 15:04:00 +0100 Subject: [PATCH] Cleaning and documenting Iotlab files. --- sfa/importer/iotlabimporter.py | 10 +- sfa/iotlab/iotlabaggregate.py | 3 +- sfa/iotlab/iotlabdriver.py | 97 +++---------- sfa/iotlab/iotlabpostgres.py | 258 ++------------------------------- sfa/iotlab/iotlabshell.py | 122 ++++++++-------- sfa/iotlab/iotlabslices.py | 35 ++--- sfa/iotlab/iotlabxrn.py | 97 +++++++++---- 7 files changed, 177 insertions(+), 445 deletions(-) diff --git a/sfa/importer/iotlabimporter.py b/sfa/importer/iotlabimporter.py index c29457c9..17891cf3 100644 --- a/sfa/importer/iotlabimporter.py +++ b/sfa/importer/iotlabimporter.py @@ -71,7 +71,7 @@ class IotlabImporter: - def exists(self, tablename, engine): + def exists(self, tablename): """ Checks if the table specified as tablename exists. :param tablename: name of the table in the db that has to be checked. @@ -518,11 +518,9 @@ class IotlabImporter: #No slice update upon import in iotlab else: # xxx update the record ... - self.logger.warning("Slice update not yet implemented") - pass - # record current users affiliated with the slice - + self.logger.warning("Iotlab Slice update not implemented") + # record current users affiliated with the slice slice_record.reg_researchers = [user_record] try: global_dbsession.commit() @@ -549,7 +547,7 @@ class IotlabImporter: # leases_db = TestbedAdditionalSfaDB(config) #Create special slice table for iotlab - if not self.exists('lease_table', engine): + if not self.exists('lease_table'): init_tables(engine) self.logger.info("IotlabImporter.run: lease_table table created ") diff --git a/sfa/iotlab/iotlabaggregate.py b/sfa/iotlab/iotlabaggregate.py index 7ada1089..25b1445a 100644 --- a/sfa/iotlab/iotlabaggregate.py +++ b/sfa/iotlab/iotlabaggregate.py @@ -367,7 +367,8 @@ class IotlabAggregate: :param sliver_allocations: dictionary of slivers :type sliver_allocations: dict - :returns: Node dictionary with all necessary data. . + :returns: Node dictionary with all necessary data. + .. seealso:: node_to_rspec_node """ rspec_node = self.node_to_rspec_node(sliver) diff --git a/sfa/iotlab/iotlabdriver.py b/sfa/iotlab/iotlabdriver.py index 13344aa3..0e0af785 100644 --- a/sfa/iotlab/iotlabdriver.py +++ b/sfa/iotlab/iotlabdriver.py @@ -66,7 +66,8 @@ class IotlabDriver(Driver): existing_records = {} existing_hrns_by_types = {} logger.debug("IOTLAB_API \tGetPeers peer_filter %s " % (peer_filter)) - all_records = self.api.dbsession().query(RegRecord).filter(RegRecord.type.like('%authority%')).all() + query = self.api.dbsession().query(RegRecord) + all_records = query.filter(RegRecord.type.like('%authority%')).all() for record in all_records: existing_records[(record.hrn, record.type)] = record @@ -227,6 +228,7 @@ class IotlabDriver(Driver): #Only one entry for one user = one slice in testbed_xp table #slicerec = dbsession.query(RegRecord).filter_by(hrn = slice_filter).first() + 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: @@ -612,16 +614,17 @@ class IotlabDriver(Driver): logger.debug("IOTLAB_API \tGetLeases \ \r\n leasefilter %s" % ( lease_filter_dict)) - filter_dict_functions = { - 'slice_hrn' : IotlabShell.filter_lease_name, - 't_from' : IotlabShell.filter_lease_start_time - } + # filter_dict_functions = { + # 'slice_hrn' : IotlabShell.filter_lease_name, + # 't_from' : IotlabShell.filter_lease_start_time + # } reservation_list = list(unfiltered_reservation_list) for filter_type in lease_filter_dict: logger.debug("IOTLAB_API \tGetLeases reservation_list %s" \ % (reservation_list)) - reservation_list = filter_dict_functions[filter_type](\ - reservation_list,lease_filter_dict[filter_type] ) + reservation_list = self.testbed_shell.filter_lease( + reservation_list,filter_type, + lease_filter_dict[filter_type] ) # Filter the reservation list with a maximum timespan so that the # leases and jobs running after this timestamp do not appear @@ -678,7 +681,8 @@ class IotlabDriver(Driver): kept_experiments) deleted_experiments = list(deleted_experiments) if len(deleted_experiments) > 0: - self.api.dbsession().query(LeaseTableXP).filter(LeaseTableXP.experiment_id.in_(deleted_experiments)).delete(synchronize_session='fetch') + request = self.api.dbsession().query(LeaseTableXP) + request.filter(LeaseTableXP.experiment_id.in_(deleted_experiments)).delete(synchronize_session='fetch') self.api.dbsession().commit() return def AddSlice(self, slice_record, user_record): @@ -833,7 +837,7 @@ class IotlabDriver(Driver): recslice.update( {'PI': [recuser['hrn']], 'researcher': [recuser['hrn']], - 'name': record['hrn'], + 'name': recuser['hrn'], 'node_ids': [], 'oar_job_id': [], 'person_ids': [recuser['record_id']]}) @@ -1160,73 +1164,7 @@ class IotlabDriver(Driver): 'geni_expires': datetime_to_string(utcparse(sliver['expires']))}) return geni_slivers - # def list_resources (self, slice_urn, slice_hrn, creds, options): - # """ - - # List resources from the iotlab aggregate and returns a Rspec - # advertisement with resources found when slice_urn and slice_hrn are - # None (in case of resource discovery). - # If a slice hrn and urn are provided, list experiment's slice - # nodes in a rspec format. Answer to ListResources. - # Caching unused. - - # :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 - # :param options: options used when listing resources (list_leases, info, - # geni_available) - # :returns: rspec string in xml - # :rtype: string - - # .. note:: creds are unused - # """ - - # #cached_requested = options.get('cached', True) - - # version_manager = VersionManager() - # # get the rspec's return format from options - # rspec_version = \ - # version_manager.get_version(options.get('geni_rspec_version')) - # version_string = "rspec_%s" % (rspec_version) - - # #panos adding the info option to the caching key (can be improved) - # if options.get('info'): - # version_string = version_string + "_" + \ - # options.get('info', 'default') - - # # Adding the list_leases option to the caching key - # if options.get('list_leases'): - # version_string = version_string + "_" + \ - # options.get('list_leases', 'default') - - # # Adding geni_available to caching key - # if options.get('geni_available'): - # version_string = version_string + "_" + \ - # str(options.get('geni_available')) - - # # look in cache first - # #if cached_requested and self.cache and not slice_hrn: - # #rspec = self.cache.get(version_string) - # #if rspec: - # #logger.debug("IotlabDriver.ListResources: \ - # #returning cached advertisement") - # #return rspec - - # #panos: passing user-defined options - # aggregate = IotlabAggregate(self) - - # rspec = aggregate.get_rspec(slice_xrn=slice_urn, - # version=rspec_version, options=options) - - # # cache the result - # #if self.cache and not slice_hrn: - # #logger.debug("Iotlab.ListResources: stores advertisement in cache") - # #self.cache.add(version_string, rspec) - - # return rspec + def list_slices(self, creds, options): @@ -1309,7 +1247,7 @@ class IotlabDriver(Driver): TODO: needs review .. warning:: SA 12/12/13 - Removed. should be done in iotlabimporter - since users, keys and slice are managed by the LDAP. + since users, keys and slice are managed by the LDAP. """ # pointer = old_sfa_record['pointer'] @@ -1497,7 +1435,7 @@ class IotlabDriver(Driver): # 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) @@ -1532,7 +1470,8 @@ class IotlabDriver(Driver): # add/remove leases rspec_requested_leases = rspec.version.get_leases() - leases = slices.verify_slice_leases(slice_record, requested_xp_dict, peer) + 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)) diff --git a/sfa/iotlab/iotlabpostgres.py b/sfa/iotlab/iotlabpostgres.py index de74dc93..097e61e5 100644 --- a/sfa/iotlab/iotlabpostgres.py +++ b/sfa/iotlab/iotlabpostgres.py @@ -1,40 +1,22 @@ """ -File defining classes to handle the table in the iotlab dedicated database. +File holding a class to define the table in the iotlab dedicated table. +The table is the SFA dtabase, therefore all the access mecanism +(session, engine...) is handled by alchemy.py. + +..seealso:: alchemy.py """ -# from sqlalchemy import create_engine -# from sqlalchemy.orm import sessionmaker -# from sfa.util.config import Config -# from sfa.util.sfalogging import logger -from sfa.storage.model import Base, AlchemyObj +from sfa.storage.model import Base from sqlalchemy import Column, Integer, String -# from sqlalchemy import Table, MetaData -# # from sqlalchemy.ext.declarative import declarative_base - -# # from sqlalchemy.dialects import postgresql - -# from sqlalchemy.exc import NoSuchTableError - - -#Dict holding the columns names of the table as keys -#and their type, used for creation of the table -slice_table = {'record_id_user': 'integer PRIMARY KEY references X ON DELETE \ - CASCADE ON UPDATE CASCADE', 'oar_job_id': 'integer DEFAULT -1', - 'record_id_slice': 'integer', 'slice_hrn': 'text NOT NULL'} - -#Dict with all the specific iotlab tables -# tablenames_dict = {'lease_table': slice_table} -# TestbedBase = declarative_base() - -# class LeaseTableXP (TestbedBase): -# class LeaseTableXP (Base,AlchemyObj): class LeaseTableXP (Base): - """ SQL alchemy class to manipulate the rows of the slice_iotlab table in - lease_table database. Handles the records representation and creates the - table if it does not exist yet. + """ SQL alchemy class to manipulate the rows of the lease_table table in the + SFA database. Handles the records representation and creates. + Table creation is made by the importer if it is not in the database yet. + + .. seealso:: init_tables in model.py, run in iotlabimporter.py """ __tablename__ = 'lease_table' @@ -45,7 +27,7 @@ class LeaseTableXP (Base): def __init__(self, slice_hrn=None, experiment_id=None, end_time=None): """ - Defines a row of the slice_iotlab table + Defines a row of the lease_table table """ if slice_hrn: self.slice_hrn = slice_hrn @@ -58,218 +40,8 @@ class LeaseTableXP (Base): """Prints the SQLAlchemy record to the format defined by the function. """ - result = " 0: - # self.testbed_session.query(LeaseTableXP).filter(LeaseTableXP.experiment_id.in_(deleted_experiments)).delete(synchronize_session='fetch') - # self.testbed_session.commit() - # return - - # def __init__(self, config, debug=False): - # self.sl_base = TestbedBase - - # # Check whether we already have an instance - # if TestbedAdditionalSfaDB._connection_singleton is None: - # TestbedAdditionalSfaDB._connection_singleton = \ - # TestbedAdditionalSfaDB.Singleton(config, debug) - - # # Store instance reference as the only member in the handle - # self._EventHandler_singleton = \ - # TestbedAdditionalSfaDB._connection_singleton - - # def __getattr__(self, aAttr): - # """ - # Delegate access to implementation. - - # :param aAttr: Attribute wanted. - # :returns: Attribute - # """ - # return getattr(self._connection_singleton, aAttr) - - - - # # def __setattr__(self, aAttr, aValue): - # # """Delegate access to implementation. - - # # :param attr: Attribute wanted. - # # :param value: Vaule to be set. - # # :return: Result of operation. - # # """ - # # return setattr(self._connection_singleton, aAttr, aValue) - - # def exists(self, tablename): - # """ - # Checks if the table specified as tablename exists. - # :param tablename: name of the table in the db that has to be checked. - # :type tablename: string - # :returns: True if the table exists, False otherwise. - # :rtype: bool - - # """ - # metadata = MetaData(bind=self.testbed_engine) - # try: - # table = Table(tablename, metadata, autoload=True) - # return True - - # except NoSuchTableError: - # logger.log_exc("SLABPOSTGRES tablename %s does not exist" - # % (tablename)) - # return False - - # def createtable(self): - # """ - # Creates all the table sof the engine. - # Uses the global dictionnary holding the tablenames and the table schema. - - # """ - - # logger.debug("IOTLABPOSTGRES createtable \ - # TestbedBase.metadata.sorted_tables %s \r\n engine %s" - # % (TestbedBase.metadata.sorted_tables, self.testbed_engine)) - # TestbedBase.metadata.create_all(self.testbed_engine) - # return diff --git a/sfa/iotlab/iotlabshell.py b/sfa/iotlab/iotlabshell.py index 406bed90..ba62ca91 100644 --- a/sfa/iotlab/iotlabshell.py +++ b/sfa/iotlab/iotlabshell.py @@ -2,22 +2,15 @@ File containing the IotlabShell, used to interact with nodes, users, slices, leases and keys, as well as the dedicated iotlab database and table, holding information about which slice is running which job. -TODO: Remove interactons with the SFA DB and put it in the driver iotlabdriver -instead. """ from datetime import datetime from sfa.util.sfalogging import logger - -from sfa.iotlab.iotlabpostgres import LeaseTableXP from sfa.iotlab.OARrestapi import OARrestapi from sfa.iotlab.LDAPapi import LDAPapi -from sfa.util.xrn import Xrn, hrn_to_urn, get_authority - -from sfa.iotlab.iotlabxrn import xrn_object class IotlabShell(): """ Class enabled to use LDAP and OAR api calls. """ @@ -210,9 +203,13 @@ class IotlabShell(): #Get job resources list from OAR node_id_list = self.oar.parser.SendRequest(req, job_id, username) logger.debug("IOTLAB_API \t GetJobsResources %s " %(node_id_list)) - + resources = self.GetNodes() + oar_id_node_dict = {} + for node in resources: + oar_id_node_dict[node['oar_id']] = node['hostname'] hostname_list = \ - self.__get_hostnames_from_oar_node_ids(node_id_list) + self.__get_hostnames_from_oar_node_ids(oar_id_node_dict, + node_id_list) #Replaces the previous entry "assigned_network_address" / @@ -229,7 +226,8 @@ class IotlabShell(): """ return self.oar.parser.SendRequest("GET_running_jobs") - def __get_hostnames_from_oar_node_ids(self, oar_id_node_dict, + @staticmethod + def __get_hostnames_from_oar_node_ids(oar_id_node_dict, resource_id_list ): """Get the hostnames of the nodes from their OAR identifiers. Get the list of nodes dict using GetNodes and find the hostname @@ -674,77 +672,71 @@ class IotlabShell(): @staticmethod - def filter_lease_name(reservation_list, filter_value): + def filter_lease(reservation_list, filter_type, filter_value ): + """Filters the lease reservation list by removing each lease whose + filter_type is not equal to the filter_value provided. Returns the list + of leases in one slice, defined by the slice_hrn if filter_type + is 'slice_hrn'. Otherwise, returns all leases scheduled starting from + the filter_value if filter_type is 't_from'. + + :param reservation_list: leases list + :type reservation_list: list of dictionary + :param filter_type: can be either 't_from' or 'slice hrn' + :type filter_type: string + :param filter_value: depending on the filter_type, can be the slice_hrn + or can be defining a timespan. + :type filter_value: if filter_type is 't_from', filter_value is int. + if filter_type is 'slice_hrn', filter_value is a string. + + + :returns: filtered_reservation_list, contains only leases running or + scheduled in the given slice (wanted_slice).Dict keys are + 'lease_id','reserved_nodes','slice_id', 'state', 'user', + 'component_id_list','slice_hrn', 'resource_ids', 't_from', 't_until' + :rtype: list of dict + + """ filtered_reservation_list = list(reservation_list) logger.debug("IOTLAB_API \t filter_lease_name reservation_list %s" \ % (reservation_list)) - for reservation in reservation_list: - if 'slice_hrn' in reservation and \ - reservation['slice_hrn'] != filter_value: - filtered_reservation_list.remove(reservation) + try: + for reservation in reservation_list: + if \ + (filter_type is 'slice_hrn' and \ + reservation['slice_hrn'] != filter_value) or \ + (filter_type is 't_from' and \ + reservation['t_from'] > filter_value): + filtered_reservation_list.remove(reservation) + except TypeError: + logger.log_exc("Iotlabshell filter_lease : filter_type %s \ + filter_value %s not in lease" %(filter_type, + filter_value)) - logger.debug("IOTLAB_API \t filter_lease_name filtered_reservation_list\ - %s" % (filtered_reservation_list)) return filtered_reservation_list - @staticmethod - def filter_lease_start_time(reservation_list, filter_value): - filtered_reservation_list = list(reservation_list) + # @staticmethod + # def filter_lease_start_time(reservation_list, timespan): + # """Filters the lease reservation list by removing each lease whose + # slice_hrn is not the wanted_slice provided. Returns the list of leases + # in one slice (wanted_slice). - for reservation in reservation_list: - if 't_from' in reservation and \ - reservation['t_from'] > filter_value: - filtered_reservation_list.remove(reservation) + # """ + # filtered_reservation_list = list(reservation_list) - return filtered_reservation_list + # for reservation in reservation_list: + # if 't_from' in reservation and \ + # reservation['t_from'] > timespan: + # filtered_reservation_list.remove(reservation) + # return filtered_reservation_list -#TODO FUNCTIONS SECTION 04/07/2012 SA - - ##TODO : Is UnBindObjectFromPeer still necessary ? Currently does nothing - ##04/07/2012 SA - #@staticmethod - #def UnBindObjectFromPeer( auth, object_type, object_id, shortname): - #""" This method is a hopefully temporary hack to let the sfa correctly - #detach the objects it creates from a remote peer object. This is - #needed so that the sfa federation link can work in parallel with - #RefreshPeer, as RefreshPeer depends on remote objects being correctly - #marked. - #Parameters: - #auth : struct, API authentication structure - #AuthMethod : string, Authentication method to use - #object_type : string, Object type, among 'site','person','slice', - #'node','key' - #object_id : int, object_id - #shortname : string, peer shortname - #FROM PLC DOC - - #""" - #logger.warning("IOTLAB_API \tUnBindObjectFromPeer EMPTY-\ - #DO NOTHING \r\n ") - #return - ##TODO Is BindObjectToPeer still necessary ? Currently does nothing - ##04/07/2012 SA - #|| Commented out 28/05/13 SA - #def BindObjectToPeer(self, auth, object_type, object_id, shortname=None, \ - #remote_object_id=None): - #"""This method is a hopefully temporary hack to let the sfa correctly - #attach the objects it creates to a remote peer object. This is needed - #so that the sfa federation link can work in parallel with RefreshPeer, - #as RefreshPeer depends on remote objects being correctly marked. - #Parameters: - #shortname : string, peer shortname - #remote_object_id : int, remote object_id, set to 0 if unknown - #FROM PLC API DOC +#TODO FUNCTIONS SECTION 04/07/2012 SA - #""" - #logger.warning("IOTLAB_API \tBindObjectToPeer EMPTY - DO NOTHING \r\n ") - #return ##TODO UpdateSlice 04/07/2012 SA || Commented out 28/05/13 SA ##Funciton should delete and create another job since oin iotlab slice=job diff --git a/sfa/iotlab/iotlabslices.py b/sfa/iotlab/iotlabslices.py index f5ebfa7c..c441d65b 100644 --- a/sfa/iotlab/iotlabslices.py +++ b/sfa/iotlab/iotlabslices.py @@ -133,7 +133,8 @@ class IotlabSlices: job['duration'] = \ str(int(job['duration']) \ * self.driver.testbed_shell.GetLeaseGranularity()) - if job['duration'] < self.driver.testbed_shell.GetLeaseGranularity(): + if job['duration'] < \ + self.driver.testbed_shell.GetLeaseGranularity(): del requested_jobs_dict[job['start_time']] #Requested jobs @@ -313,7 +314,7 @@ class IotlabSlices: if slices_list: for sl in slices_list: - logger.debug("SLABSLICE \t verify_slice slicename %s \ + logger.debug("IOTLABSLICES \t verify_slice slicename %s \ slices_list %s sl %s \r slice_record %s" % (slicename, slices_list, sl, slice_record)) sfa_slice = sl @@ -338,7 +339,8 @@ class IotlabSlices: } if ldap_user: - hrn = self.driver.testbed_shell.root_auth + '.' + ldap_user['uid'] + hrn = self.driver.testbed_shell.root_auth + '.' \ + + ldap_user['uid'] user = self.driver.get_user_record(hrn) logger.debug(" IOTLABSLICES \tverify_slice hrn %s USER %s" @@ -354,7 +356,7 @@ class IotlabSlices: def verify_persons(self, slice_hrn, slice_record, users, options={}): """Ensures the users in users list exist and are enabled in LDAP. Adds - person if needed. + person if needed (AddPerson). Checking that a user exist is based on the user's email. If the user is still not found in the LDAP, it means that the user comes from another @@ -366,8 +368,8 @@ class IotlabSlices: :param slice_record: record of the slice_hrn :param users: users is a record list. Records can either be local records or users records from known and trusted federated - sites.If the user is from another site that iotlab doesn't trust yet, - then Resolve will raise an error before getting to create_sliver. + sites.If the user is from another site that iotlab doesn't trust + yet, then Resolve will raise an error before getting to allocate. :type slice_hrn: string :type slice_record: string @@ -378,7 +380,6 @@ class IotlabSlices: """ - #TODO SA 21/08/12 verify_persons Needs review logger.debug("IOTLABSLICES \tverify_persons \tslice_hrn %s \ \t slice_record %s\r\n users %s \t " @@ -400,7 +401,7 @@ class IotlabSlices: users_by_email[info['email']] = info users_dict[info['email']] = info - logger.debug("SLABSLICE.PY \t verify_person \ + logger.debug("IOTLABSLICES.PY \t verify_person \ users_dict %s \r\n user_by_email %s \r\n " % (users_dict, users_by_email)) @@ -443,28 +444,28 @@ class IotlabSlices: ldap_reslt = self.driver.testbed_shell.ldap.LdapSearch(req) if ldap_reslt: - logger.debug(" SLABSLICE.PY \tverify_person users \ + logger.debug(" IOTLABSLICES.PY \tverify_person users \ USER already in Iotlab \t ldap_reslt %s \ " % (ldap_reslt)) existing_users.append(ldap_reslt[1]) else: #User not existing in LDAP - logger.debug("SLABSLICE.PY \tverify_person users \ + logger.debug("IOTLABSLICES.PY \tverify_person users \ not in ldap ...NEW ACCOUNT NEEDED %s \r\n \t \ ldap_reslt %s " % (users, ldap_reslt)) requested_user_emails = users_by_email.keys() requested_user_hrns = \ [users_by_email[user]['hrn'] for user in users_by_email] - logger.debug("SLABSLICE.PY \tverify_person \ + logger.debug("IOTLABSLICES.PY \tverify_person \ users_by_email %s " % (users_by_email)) #Check that the user of the slice in the slice record #matches one of the existing users try: if slice_record['reg-researchers'][0] in requested_user_hrns: - logger.debug(" SLABSLICE \tverify_person ['PI']\ + logger.debug(" IOTLABSLICES \tverify_person ['PI']\ slice_record %s" % (slice_record)) except KeyError: @@ -487,7 +488,7 @@ class IotlabSlices: #requested_user_email is in existing_user_emails if len(added_user_emails) == 0: slice_record['login'] = users_dict[requested_user_emails[0]]['uid'] - logger.debug(" SLABSLICE \tverify_person QUICK DIRTY %s" + logger.debug(" IOTLABSLICES \tverify_person QUICK DIRTY %s" % (slice_record)) for added_user_email in added_user_emails: @@ -515,7 +516,7 @@ class IotlabSlices: # error message in ret logger.debug(" IOTLABSLICES ret message %s" %(ret)) - logger.debug(" SLABSLICE \r\n \r\n \t THE SECOND verify_person\ + logger.debug(" IOTLABSLICES \r\n \r\n \t THE SECOND verify_person\ person %s" % (person)) #Update slice_Record with the id now known to LDAP @@ -570,12 +571,6 @@ class IotlabSlices: #key['key_id'], peer['shortname'], \ #remote_key_id) - #finally: - #if peer: - #self.driver.testbed_shell.BindObjectToPeer('person', \ - #person['person_id'], peer['shortname'], \ - #user['person_id']) - # remove old keys (only if we are not appending) append = options.get('append', True) if append is False: diff --git a/sfa/iotlab/iotlabxrn.py b/sfa/iotlab/iotlabxrn.py index c7a147ca..bae70361 100644 --- a/sfa/iotlab/iotlabxrn.py +++ b/sfa/iotlab/iotlabxrn.py @@ -1,4 +1,5 @@ -# specialized Xrn class for Dummy TB +""" specialized Xrn class for Iotlab. SA +""" import re from sfa.util.xrn import Xrn @@ -31,31 +32,59 @@ def xrn_object(root_auth, hostname): # temporary helper functions to use this module instead of namespace def hostname_to_hrn (auth, hostname): - return IotlabXrn(auth=auth ,hostname=hostname).get_hrn() + """Turns node hostname into hrn. + :param auth: Site authority. + :type auth: string + :param hostname: Node hostname. + :type hostname: string. + + :returns: Node's hrn. + :rtype: string + """ + return IotlabXrn(auth=auth, hostname=hostname).get_hrn() + def hostname_to_urn(auth, hostname): - return IotlabXrn(auth=auth,hostname=hostname).get_urn() -def slicename_to_hrn (auth_hrn, slicename): - return IotlabXrn(auth=auth_hrn,slicename=slicename).get_hrn() + """Turns node hostname into urn. + :param auth: Site authority. + :type auth: string + :param hostname: Node hostname. + :type hostname: string. -def hrn_to_iotlab_slicename (hrn): - return IotlabXrn(xrn=hrn,type='slice').iotlab_slicename() -def hrn_to_iotlab_authname (hrn): - return IotlabXrn(xrn=hrn,type='any').iotlab_authname() + :returns: Node's urn. + :rtype: string + """ + return IotlabXrn(auth=auth, hostname=hostname).get_urn() +# def slicename_to_hrn (auth_hrn, slicename): + # return IotlabXrn(auth=auth_hrn, slicename=slicename).get_hrn() + +# def hrn_to_iotlab_slicename (hrn): +# return IotlabXrn(xrn=hrn, type='slice').iotlab_slicename() + +# def hrn_to_iotlab_authname (hrn): +# return IotlabXrn(xrn=hrn, type='any').iotlab_authname() -class IotlabXrn (Xrn): +class IotlabXrn (Xrn): + """ + Defines methods to turn a hrn/urn into a urn/hrn, or to get the name + of the slice/user from the hrn. + """ @staticmethod def site_hrn (auth): + """Returns the site hrn, which is also the testbed authority in + iotlab/cortexlab. + """ return auth - def __init__ (self, auth=None, hostname=None, login=None, slicename=None,**kwargs): + def __init__ (self, auth=None, hostname=None, login=None, + slicename=None, **kwargs): #def hostname_to_hrn(auth_hrn, login_base, hostname): if hostname is not None: - self.type ='node' + self.type = 'node' # keep only the first part of the DNS name # escape the '.' in the hostname - self.hrn ='.'.join( [auth, Xrn.escape(hostname)] ) + self.hrn = '.'.join( [auth, Xrn.escape(hostname)] ) self.hrn_to_urn() elif login is not None: @@ -64,17 +93,23 @@ class IotlabXrn (Xrn): self.hrn_to_urn() #def slicename_to_hrn(auth_hrn, slicename): elif slicename is not None: - self.type ='slice' + self.type = 'slice' slicename = '_'.join([login, "slice"]) self.hrn = '.'.join([auth, slicename]) self.hrn_to_urn() # split at the first _ else: - Xrn.__init__ (self,**kwargs) + Xrn.__init__ (self, **kwargs) + - #def hrn_to_pl_slicename(hrn): def iotlab_slicename (self): + """Returns the slice name from an iotlab slice hrn. + + :rtype: string + :returns: slice name. + """ + self._normalize() leaf = self.leaf sliver_id_parts = leaf.split(':') @@ -83,22 +118,22 @@ class IotlabXrn (Xrn): return name #def hrn_to_pl_authname(hrn): - def iotlab_authname (self): - self._normalize() - return self.authority[-1] + # def iotlab_authname (self): + # self._normalize() + # return self.authority[-1] - def iotlab_login_base (self): - self._normalize() - if self.type and self.type.startswith('authority'): - base = self.leaf - else: - base = self.authority[-1] + # def iotlab_login_base (self): + # self._normalize() + # if self.type and self.type.startswith('authority'): + # base = self.leaf + # else: + # base = self.authority[-1] - # Fix up names of GENI Federates - base = base.lower() - base = re.sub('\\\[^a-zA-Z0-9]', '', base) + # # Fix up names of GENI Federates + # base = base.lower() + # base = re.sub('\\\[^a-zA-Z0-9]', '', base) - if len(base) > 20: - base = base[len(base)-20:] + # if len(base) > 20: + # base = base[len(base)-20:] - return base + # return base -- 2.43.0