X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fiotlab%2Fiotlabshell.py;h=34de4b1e9d5bf60bad779107df21d8e74261f6cd;hb=95015fd08e08729c3aaeec2c000995595ea7a7e0;hp=081eb4eee520ab928c4a22a0abbae23711d32e7d;hpb=c6f8288bc13c54c464504e041eb3609781e7dbde;p=sfa.git diff --git a/sfa/iotlab/iotlabshell.py b/sfa/iotlab/iotlabshell.py index 081eb4ee..34de4b1e 100644 --- a/sfa/iotlab/iotlabshell.py +++ b/sfa/iotlab/iotlabshell.py @@ -7,28 +7,18 @@ holding information about which slice is running which job. from datetime import datetime from sfa.util.sfalogging import logger +from sfa.util.sfatime import SFATIME_FORMAT -from sfa.storage.alchemy import dbsession -from sqlalchemy.orm import joinedload -from sfa.storage.model import RegRecord, RegUser, RegSlice, RegKey -from sfa.iotlab.iotlabpostgres import TestbedAdditionalSfaDB, 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.trust.certificate import Keypair, convert_public_key -from sfa.trust.gid import create_uuid -from sfa.trust.hierarchy import Hierarchy - -from sfa.iotlab.iotlabaggregate import iotlab_xrn_object class IotlabShell(): """ Class enabled to use LDAP and OAR api calls. """ _MINIMUM_DURATION = 10 # 10 units of granularity 60 s, 10 mins - def __init__(self, api): + def __init__(self, config): """Creates an instance of OARrestapi and LDAPapi which will be used to issue calls to OAR or LDAP methods. Set the time format and the testbed granularity used for OAR @@ -37,12 +27,11 @@ class IotlabShell(): :param config: configuration object from sfa.util.config :type config: Config object """ - self.api=api - config=api.config - self.leases_db = TestbedAdditionalSfaDB(config) + + # self.leases_db = TestbedAdditionalSfaDB(config) self.oar = OARrestapi() self.ldap = LDAPapi() - self.time_format = "%Y-%m-%d %H:%M:%S" + self.time_format = SFATIME_FORMAT self.root_auth = config.SFA_REGISTRY_ROOT_AUTH self.grain = 60 # 10 mins lease minimum, 60 sec granularity #import logging, logging.handlers @@ -60,49 +49,7 @@ class IotlabShell(): return IotlabShell._MINIMUM_DURATION - def GetPeers(self, peer_filter=None ): - """ Gathers registered authorities in SFA DB and looks for specific peer - if peer_filter is specified. - :param peer_filter: name of the site authority looked for. - :type peer_filter: string - :returns: list of records. - - """ - - existing_records = {} - existing_hrns_by_types = {} - logger.debug("IOTLAB_API \tGetPeers peer_filter %s " % (peer_filter)) - all_records = dbsession.query(RegRecord).filter(RegRecord.type.like('%authority%')).all() - for record in all_records: - existing_records[(record.hrn, record.type)] = record - if record.type not in existing_hrns_by_types: - existing_hrns_by_types[record.type] = [record.hrn] - else: - existing_hrns_by_types[record.type].append(record.hrn) - - logger.debug("IOTLAB_API \tGetPeer\texisting_hrns_by_types %s " - % (existing_hrns_by_types)) - records_list = [] - - try: - if peer_filter: - records_list.append(existing_records[(peer_filter, - 'authority')]) - else: - for hrn in existing_hrns_by_types['authority']: - records_list.append(existing_records[(hrn, 'authority')]) - - logger.debug("IOTLAB_API \tGetPeer \trecords_list %s " - % (records_list)) - - except KeyError: - pass - - return_records = records_list - logger.debug("IOTLAB_API \tGetPeer return_records %s " - % (return_records)) - return return_records #TODO : Handling OR request in make_ldap_filters_from_records #instead of the for loop @@ -236,9 +183,10 @@ class IotlabShell(): def GetJobsResources(self, job_id, username = None): """ Gets the list of nodes associated with the job_id and username if provided. - Transforms the iotlab hostnames to the corresponding - SFA nodes hrns. - Rertuns dict key :'node_ids' , value : hostnames list + + Transforms the iotlab hostnames to the corresponding SFA nodes hrns. + Returns dict key :'node_ids' , value : hostnames list. + :param username: user's LDAP login :paran job_id: job's OAR identifier. :type username: string @@ -246,7 +194,8 @@ class IotlabShell(): :returns: dicionary with nodes' hostnames belonging to the job. :rtype: dict - .. warning: Unused. SA 16/10/13 + + .. warning:: Unused. SA 16/10/13 """ req = "GET_jobs_id_resources" @@ -255,9 +204,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" / @@ -267,33 +220,6 @@ class IotlabShell(): return job_info - #def get_info_on_reserved_nodes(self, job_info, node_list_name): - #""" - #..warning:unused SA 23/05/13 - #""" - ##Get the list of the testbed nodes records and make a - ##dictionnary keyed on the hostname out of it - #node_list_dict = self.GetNodes() - ##node_hostname_list = [] - #node_hostname_list = [node['hostname'] for node in node_list_dict] - ##for node in node_list_dict: - ##node_hostname_list.append(node['hostname']) - #node_dict = dict(zip(node_hostname_list, node_list_dict)) - #try : - #reserved_node_hostname_list = [] - #for index in range(len(job_info[node_list_name])): - ##job_info[node_list_name][k] = - #reserved_node_hostname_list[index] = \ - #node_dict[job_info[node_list_name][index]]['hostname'] - - #logger.debug("IOTLAB_API \t get_info_on_reserved_nodes \ - #reserved_node_hostname_list %s" \ - #%(reserved_node_hostname_list)) - #except KeyError: - #logger.error("IOTLAB_API \t get_info_on_reserved_nodes KEYERROR " ) - - #return reserved_node_hostname_list - def GetNodesCurrentlyInUse(self): """Returns a list of all the nodes already involved in an oar running job. @@ -301,7 +227,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 @@ -318,7 +245,6 @@ class IotlabShell(): hostname_list.append(\ oar_id_node_dict[resource_id]['hostname']) - #hostname_list.append(oar_id_node_dict[resource_id]['hostname']) return hostname_list def GetReservedNodes(self, username=None): @@ -407,36 +333,7 @@ class IotlabShell(): return return_node_list - def AddSlice(self, slice_record, user_record): - """ - - Add slice to the local iotlab sfa tables if the slice comes - from a federated site and is not yet in the iotlab sfa DB, - although the user has already a LDAP login. - Called by verify_slice during lease/sliver creation. - :param slice_record: record of slice, must contain hrn, gid, slice_id - and authority of the slice. - :type slice_record: dictionary - :param user_record: record of the user - :type user_record: RegUser - - """ - - sfa_record = RegSlice(hrn=slice_record['hrn'], - gid=slice_record['gid'], - 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() - dbsession.add(sfa_record) - dbsession.commit() - #Update the reg-researcher dependance table - sfa_record.reg_researchers = [user_record] - dbsession.commit() - - return def GetSites(self, site_filter_name_list=None, return_fields_list=None): @@ -527,79 +424,10 @@ class IotlabShell(): return delete_failed or True - 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 - yet (that is he does not have a LDAP entry yet). - Uses parts of the routines in IotlabImport when importing user from LDAP. - Called by AddPerson, right after LdapAddUser. - :param user_dict: Must contain email, hrn and pkey to get a GID - and be added to the SFA db. - :type user_dict: dict - """ - check_if_exists = \ - dbsession.query(RegUser).filter_by(email = user_dict['email']).first() - #user doesn't exists - if not check_if_exists: - logger.debug("__add_person_to_db \t Adding %s \r\n \r\n \ - " %(user_dict)) - hrn = user_dict['hrn'] - person_urn = hrn_to_urn(hrn, 'user') - pubkey = user_dict['pkey'] - try: - pkey = convert_public_key(pubkey) - except TypeError: - #key not good. create another pkey - logger.warn('__add_person_to_db: unable to convert public \ - key for %s' %(hrn )) - pkey = Keypair(create=True) - - - if pubkey is not None and pkey is not None : - hierarchy = Hierarchy() - person_gid = hierarchy.create_gid(person_urn, create_uuid(), \ - pkey) - if user_dict['email']: - logger.debug("__add_person_to_db \r\n \r\n \ - IOTLAB IMPORTER PERSON EMAIL OK email %s "\ - %(user_dict['email'])) - person_gid.set_email(user_dict['email']) - - 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.just_created() - dbsession.add (user_record) - dbsession.commit() - return - def AddPerson(self, record): - """ - Adds a new account. Any fields specified in records are used, - otherwise defaults are used. Creates an appropriate login by calling - LdapAddUser. - - :param record: dictionary with the sfa user's properties. - :returns: a dicitonary with the status. If successful, the dictionary - boolean is set to True and there is a 'uid' key with the new login - added to LDAP, otherwise the bool is set to False and a key - 'message' is in the dictionary, with the error message. - :rtype: dict - - """ - ret = self.ldap.LdapAddUser(record) - - if ret['bool'] is True: - record['hrn'] = self.root_auth + '.' + ret['uid'] - logger.debug("IOTLAB_API AddPerson return code %s record %s " - % (ret, record)) - self.__add_person_to_db(record) - return ret @@ -670,7 +498,9 @@ class IotlabShell(): # Put the duration in seconds first #desired_walltime = duration * 60 desired_walltime = duration - total_walltime = desired_walltime + 240 #+4 min Update SA 23/10/12 + # JORDAN : removed the 4 minutes added by default in iotlab + # XXX total_walltime = desired_walltime + 240 #+4 min Update SA 23/10/12 + total_walltime = desired_walltime # Needed to have slots aligned in MySlice (temp fix) # JA 11/07/2014 sleep_walltime = desired_walltime # 0 sec added Update SA 23/10/12 walltime = [] #Put the walltime back in str form @@ -732,10 +562,12 @@ class IotlabShell(): #They will be set to None. if lease_dict['lease_start_time'] is not '0': #Readable time accepted by OAR + # converting timestamp to date in the local timezone tz = None start_time = datetime.fromtimestamp( \ - int(lease_dict['lease_start_time'])).\ + int(lease_dict['lease_start_time']), tz=None).\ strftime(lease_dict['time_format']) - reqdict['reservation'] = start_time + + reqdict['reservation'] = str(start_time) #If there is not start time, Immediate XP. No need to add special # OAR parameters @@ -766,7 +598,11 @@ class IotlabShell(): lease_dict['slice_name'] = slice_name lease_dict['slice_user'] = slice_user lease_dict['grain'] = self.GetLeaseGranularity() - lease_dict['time_format'] = self.time_format + # I don't know why the SFATIME_FORMAT has changed... + # from sfa.util.sfatime import SFATIME_FORMAT + # Let's use a fixed format %Y-%m-%d %H:%M:%S + #lease_dict['time_format'] = self.time_format + lease_dict['time_format'] = '%Y-%m-%d %H:%M:%S' logger.debug("IOTLAB_API.PY \tLaunchExperimentOnOAR slice_user %s\ @@ -799,61 +635,7 @@ class IotlabShell(): return jobid - def AddLeases(self, hostname_list, slice_record, - lease_start_time, lease_duration): - """Creates a job in OAR corresponding to the information provided - as parameters. Adds the job id and the slice hrn in the iotlab - database so that we are able to know which slice has which nodes. - - :param hostname_list: list of nodes' OAR hostnames. - :param slice_record: sfa slice record, must contain login and hrn. - :param lease_start_time: starting time , unix timestamp format - :param lease_duration: duration in minutes - - :type hostname_list: list - :type slice_record: dict - :type lease_start_time: integer - :type lease_duration: integer - - """ - logger.debug("IOTLAB_API \r\n \r\n \t AddLeases hostname_list %s \ - slice_record %s lease_start_time %s lease_duration %s "\ - %( hostname_list, slice_record , lease_start_time, \ - lease_duration)) - - #tmp = slice_record['reg-researchers'][0].split(".") - username = slice_record['login'] - #username = tmp[(len(tmp)-1)] - job_id = self.LaunchExperimentOnOAR(hostname_list, \ - slice_record['hrn'], \ - lease_start_time, lease_duration, \ - username) - start_time = \ - datetime.fromtimestamp(int(lease_start_time)).\ - strftime(self.time_format) - end_time = lease_start_time + lease_duration - - - logger.debug("IOTLAB_API \r\n \r\n \t AddLeases TURN ON LOGGING SQL \ - %s %s %s "%(slice_record['hrn'], job_id, end_time)) - - - logger.debug("IOTLAB_API \r\n \r\n \t AddLeases %s %s %s " \ - %(type(slice_record['hrn']), type(job_id), type(end_time))) - - iotlab_ex_row = LeaseTableXP(slice_hrn = slice_record['hrn'], experiment_id=job_id, - end_time= end_time) - - logger.debug("IOTLAB_API \r\n \r\n \t AddLeases iotlab_ex_row %s" \ - %(iotlab_ex_row)) - self.leases_db.testbed_session.add(iotlab_ex_row) - self.leases_db.testbed_session.commit() - - logger.debug("IOTLAB_API \t AddLeases hostname_list start_time %s " \ - %(start_time)) - - return #Delete the jobs from job_iotlab table @@ -882,8 +664,8 @@ class IotlabShell(): oar_bool_answer.update(ret) else: - oar_bool_answer = [self.DeleteJobs(slice_record['oar_job_id'], - slice_record['user'])] + oar_bool_answer = self.DeleteJobs(slice_record['oar_job_id'], + slice_record['user']) return oar_bool_answer @@ -899,178 +681,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) - - for reservation in reservation_list: - if 't_from' in reservation and \ - reservation['t_from'] > filter_value: - filtered_reservation_list.remove(reservation) + # @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). - return filtered_reservation_list + # """ + # filtered_reservation_list = list(reservation_list) + # for reservation in reservation_list: + # if 't_from' in reservation and \ + # reservation['t_from'] > timespan: + # filtered_reservation_list.remove(reservation) - def GetLeases(self, lease_filter_dict=None, login=None): - """ + # return filtered_reservation_list - Get the list of leases from OAR with complete information - about which slice owns which jobs and nodes. - 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, - assume it is a iotlab slice. - -Updates the iotlab table, deleting jobs when necessary. - - :returns: reservation_list, list of dictionaries with 'lease_id', - 'reserved_nodes','slice_id', 'state', 'user', 'component_id_list', - 'slice_hrn', 'resource_ids', 't_from', 't_until' - :rtype: list - """ - - unfiltered_reservation_list = self.GetReservedNodes(login) - - reservation_list = [] - #Find the slice associated with this user iotlab ldap uid - logger.debug(" IOTLAB_API.PY \tGetLeases login %s\ - unfiltered_reservation_list %s " - % (login, unfiltered_reservation_list)) - #Create user dict first to avoid looking several times for - #the same user in LDAP SA 27/07/12 - job_oar_list = [] - - jobs_psql_query = self.leases_db.testbed_session.query(LeaseTableXP).all() - jobs_psql_dict = dict([(row.experiment_id, row.__dict__) - for row in jobs_psql_query]) - #jobs_psql_dict = jobs_psql_dict) - logger.debug("IOTLAB_API \tGetLeases jobs_psql_dict %s" - % (jobs_psql_dict)) - jobs_psql_id_list = [row.experiment_id for row in jobs_psql_query] - - for resa in unfiltered_reservation_list: - logger.debug("IOTLAB_API \tGetLeases USER %s" - % (resa['user'])) - #Construct list of jobs (runing, waiting..) in oar - job_oar_list.append(resa['lease_id']) - #If there is information on the job in IOTLAB DB ] - #(slice used and job id) - if resa['lease_id'] in jobs_psql_dict: - job_info = jobs_psql_dict[resa['lease_id']] - logger.debug("IOTLAB_API \tGetLeases job_info %s" - % (job_info)) - resa['slice_hrn'] = job_info['slice_hrn'] - resa['slice_id'] = hrn_to_urn(resa['slice_hrn'], 'slice') - - #otherwise, assume it is a iotlab slice: - else: - resa['slice_id'] = hrn_to_urn(self.root_auth + '.' + - resa['user'] + "_slice", 'slice') - resa['slice_hrn'] = Xrn(resa['slice_id']).get_hrn() - - resa['component_id_list'] = [] - #Transform the hostnames into urns (component ids) - for node in resa['reserved_nodes']: - - iotlab_xrn = iotlab_xrn_object(self.root_auth, node) - resa['component_id_list'].append(iotlab_xrn.urn) - - if lease_filter_dict: - 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 - } - 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] ) - - # Filter the reservation list with a maximum timespan so that the - # leases and jobs running after this timestamp do not appear - # in the result leases. - # if 'start_time' in : - # if resa['start_time'] < lease_filter_dict['start_time']: - # reservation_list.append(resa) - - - # if 'name' in lease_filter_dict and \ - # lease_filter_dict['name'] == resa['slice_hrn']: - # reservation_list.append(resa) - - - if lease_filter_dict is None: - reservation_list = unfiltered_reservation_list - - self.leases_db.update_experiments_in_additional_sfa_db(job_oar_list, jobs_psql_id_list) - - logger.debug(" IOTLAB_API.PY \tGetLeases reservation_list %s" - % (reservation_list)) - return 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 - - #""" - #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 @@ -1108,36 +783,7 @@ class IotlabShell(): #return - def GetKeys(self, key_filter=None): - """Returns a dict of dict based on the key string. Each dict entry - contains the key id, the ssh key, the user's email and the - user's hrn. - If key_filter is specified and is an array of key identifiers, - only keys matching the filter will be returned. - - Admin may query all keys. Non-admins may only query their own keys. - FROM PLC API DOC - - :returns: dict with ssh key as key and dicts as value. - :rtype: dict - """ - if key_filter is None: - keys = dbsession.query(RegKey).options(joinedload('reg_user')).all() - else: - keys = dbsession.query(RegKey).options(joinedload('reg_user')).filter(RegKey.key.in_(key_filter)).all() - key_dict = {} - for key in keys: - key_dict[key.key] = {'key_id': key.key_id, 'key': key.key, - 'email': key.reg_user.email, - 'hrn': key.reg_user.hrn} - - #ldap_rslt = self.ldap.LdapSearch({'enabled']=True}) - #user_by_email = dict((user[1]['mail'][0], user[1]['sshPublicKey']) \ - #for user in ldap_rslt) - - logger.debug("IOTLAB_API GetKeys -key_dict %s \r\n " % (key_dict)) - return key_dict #TODO : test def DeleteKey(self, user_record, key_string): @@ -1154,6 +800,7 @@ class IotlabShell(): :rtype: Boolean """ + all_user_keys = user_record['keys'] all_user_keys.remove(key_string) new_attributes = {'sshPublicKey':all_user_keys} @@ -1162,278 +809,9 @@ class IotlabShell(): return ret['bool'] - def _sql_get_slice_info(self, slice_filter): - """ - 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. - :param slice_filter: the slice hrn we are looking for - :type slice_filter: string - :returns: the slice record enhanced with the user's information if the - slice was found, None it wasn't. - :rtype: dict or None. - """ - #DO NOT USE RegSlice - reg_researchers to get the hrn - #of the user otherwise will mess up the RegRecord in - #Resolve, don't know why - SA 08/08/2012 - - #Only one entry for one user = one slice in testbed_xp table - #slicerec = dbsession.query(RegRecord).filter_by(hrn = slice_filter).first() - raw_slicerec = dbsession.query(RegSlice).options(joinedload('reg_researchers')).filter_by(hrn=slice_filter).first() - #raw_slicerec = dbsession.query(RegRecord).filter_by(hrn = slice_filter).first() - if raw_slicerec: - #load_reg_researcher - #raw_slicerec.reg_researchers - raw_slicerec = raw_slicerec.__dict__ - logger.debug(" IOTLAB_API \t _sql_get_slice_info slice_filter %s \ - raw_slicerec %s" % (slice_filter, raw_slicerec)) - slicerec = raw_slicerec - #only one researcher per slice so take the first one - #slicerec['reg_researchers'] = raw_slicerec['reg_researchers'] - #del slicerec['reg_researchers']['_sa_instance_state'] - return slicerec - else: - return None - - def _sql_get_slice_info_from_user(self, slice_filter): - """ - Get the slice record based on the user recordid by using a joinedload - on the relationship reg_slices_as_researcher. Format the sql record - into a dict with the mandatory fields for user and slice. - :returns: dict with slice record and user record if the record was found - based on the user's id, None if not.. - :rtype:dict or None.. - """ - #slicerec = dbsession.query(RegRecord).filter_by(record_id = slice_filter).first() - raw_slicerec = dbsession.query(RegUser).options(joinedload('reg_slices_as_researcher')).filter_by(record_id=slice_filter).first() - #raw_slicerec = dbsession.query(RegRecord).filter_by(record_id = slice_filter).first() - #Put it in correct order - user_needed_fields = ['peer_authority', 'hrn', 'last_updated', - 'classtype', 'authority', 'gid', 'record_id', - 'date_created', 'type', 'email', 'pointer'] - slice_needed_fields = ['peer_authority', 'hrn', 'last_updated', - 'classtype', 'authority', 'gid', 'record_id', - 'date_created', 'type', 'pointer'] - if raw_slicerec: - #raw_slicerec.reg_slices_as_researcher - raw_slicerec = raw_slicerec.__dict__ - slicerec = {} - slicerec = \ - dict([(k, raw_slicerec[ - 'reg_slices_as_researcher'][0].__dict__[k]) - for k in slice_needed_fields]) - slicerec['reg_researchers'] = dict([(k, raw_slicerec[k]) - for k in user_needed_fields]) - #TODO Handle multiple slices for one user SA 10/12/12 - #for now only take the first slice record associated to the rec user - ##slicerec = raw_slicerec['reg_slices_as_researcher'][0].__dict__ - #del raw_slicerec['reg_slices_as_researcher'] - #slicerec['reg_researchers'] = raw_slicerec - ##del slicerec['_sa_instance_state'] - - return slicerec - - else: - return None - - def _get_slice_records(self, slice_filter=None, - slice_filter_type=None): - """ - Get the slice record depending on the slice filter and its type. - :param slice_filter: Can be either the slice hrn or the user's record - id. - :type slice_filter: string - :param slice_filter_type: describes the slice filter type used, can be - slice_hrn or record_id_user - :type: string - :returns: the slice record - :rtype:dict - .. seealso::_sql_get_slice_info_from_user - .. seealso:: _sql_get_slice_info - """ - - #Get list of slices based on the slice hrn - if slice_filter_type == 'slice_hrn': - - #if get_authority(slice_filter) == self.root_auth: - #login = slice_filter.split(".")[1].split("_")[0] - - slicerec = self._sql_get_slice_info(slice_filter) - - if slicerec is None: - return None - #return login, None - - #Get slice based on user id - if slice_filter_type == 'record_id_user': - - slicerec = self._sql_get_slice_info_from_user(slice_filter) - - if slicerec: - fixed_slicerec_dict = slicerec - #At this point if there is no login it means - #record_id_user filter has been used for filtering - #if login is None : - ##If theslice record is from iotlab - #if fixed_slicerec_dict['peer_authority'] is None: - #login = fixed_slicerec_dict['hrn'].split(".")[1].split("_")[0] - #return login, fixed_slicerec_dict - return fixed_slicerec_dict - else: - return None - - - def GetSlices(self, slice_filter=None, slice_filter_type=None, - login=None): - """Get the slice records from the iotlab db and add lease information - if any. - - :param slice_filter: can be the slice hrn or slice record id in the db - depending on the slice_filter_type. - :param slice_filter_type: defines the type of the filtering used, Can be - either 'slice_hrn' or "record_id'. - :type slice_filter: string - :type slice_filter_type: string - :returns: a slice dict if slice_filter and slice_filter_type - are specified and a matching entry is found in the db. The result - is put into a list.Or a list of slice dictionnaries if no filters - arespecified. - - :rtype: list - - """ - #login = None - authorized_filter_types_list = ['slice_hrn', 'record_id_user'] - return_slicerec_dictlist = [] - - #First try to get information on the slice based on the filter provided - if slice_filter_type in authorized_filter_types_list: - fixed_slicerec_dict = self._get_slice_records(slice_filter, - slice_filter_type) - # if the slice was not found in the sfa db - if fixed_slicerec_dict is None: - return return_slicerec_dictlist - - slice_hrn = fixed_slicerec_dict['hrn'] - - logger.debug(" IOTLAB_API \tGetSlices login %s \ - slice record %s slice_filter %s \ - slice_filter_type %s " % (login, - fixed_slicerec_dict, slice_filter, - slice_filter_type)) - - - #Now we have the slice record fixed_slicerec_dict, get the - #jobs associated to this slice - leases_list = [] - - leases_list = self.GetLeases(login=login) - #If no job is running or no job scheduled - #return only the slice record - if leases_list == [] and fixed_slicerec_dict: - return_slicerec_dictlist.append(fixed_slicerec_dict) - - # if the jobs running don't belong to the user/slice we are looking - # for - leases_hrn = [lease['slice_hrn'] for lease in leases_list] - if slice_hrn not in leases_hrn: - return_slicerec_dictlist.append(fixed_slicerec_dict) - #If several jobs for one slice , put the slice record into - # each lease information dict - for lease in leases_list: - slicerec_dict = {} - logger.debug("IOTLAB_API.PY \tGetSlices slice_filter %s \ - \t lease['slice_hrn'] %s" - % (slice_filter, lease['slice_hrn'])) - if lease['slice_hrn'] == slice_hrn: - slicerec_dict['oar_job_id'] = lease['lease_id'] - #Update lease dict with the slice record - if fixed_slicerec_dict: - fixed_slicerec_dict['oar_job_id'] = [] - fixed_slicerec_dict['oar_job_id'].append( - slicerec_dict['oar_job_id']) - slicerec_dict.update(fixed_slicerec_dict) - #slicerec_dict.update({'hrn':\ - #str(fixed_slicerec_dict['slice_hrn'])}) - slicerec_dict['slice_hrn'] = lease['slice_hrn'] - slicerec_dict['hrn'] = lease['slice_hrn'] - slicerec_dict['user'] = lease['user'] - slicerec_dict.update( - {'list_node_ids': - {'hostname': lease['reserved_nodes']}}) - slicerec_dict.update({'node_ids': lease['reserved_nodes']}) - - - - 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 \ - lease['reserved_nodes'] \ - %s" % (slicerec_dict, return_slicerec_dictlist, - lease['reserved_nodes'])) - - logger.debug("IOTLAB_API.PY \tGetSlices RETURN \ - return_slicerec_dictlist %s" - % (return_slicerec_dictlist)) - - return return_slicerec_dictlist - - - else: - #Get all slices from the iotlab sfa database , - #put them in dict format - #query_slice_list = dbsession.query(RegRecord).all() - query_slice_list = \ - dbsession.query(RegSlice).options(joinedload('reg_researchers')).all() - - for record in query_slice_list: - tmp = record.__dict__ - tmp['reg_researchers'] = tmp['reg_researchers'][0].__dict__ - #del tmp['reg_researchers']['_sa_instance_state'] - return_slicerec_dictlist.append(tmp) - #return_slicerec_dictlist.append(record.__dict__) - - #Get all the jobs reserved nodes - leases_list = self.GetReservedNodes() - - for fixed_slicerec_dict in return_slicerec_dictlist: - slicerec_dict = {} - #Check if the slice belongs to a iotlab user - if fixed_slicerec_dict['peer_authority'] is None: - owner = fixed_slicerec_dict['hrn'].split( - ".")[1].split("_")[0] - else: - owner = None - for lease in leases_list: - if owner == lease['user']: - slicerec_dict['oar_job_id'] = lease['lease_id'] - - #for reserved_node in lease['reserved_nodes']: - logger.debug("IOTLAB_API.PY \tGetSlices lease %s " - % (lease)) - slicerec_dict.update(fixed_slicerec_dict) - slicerec_dict.update({'node_ids': - lease['reserved_nodes']}) - slicerec_dict.update({'list_node_ids': - {'hostname': - lease['reserved_nodes']}}) - - #slicerec_dict.update({'hrn':\ - #str(fixed_slicerec_dict['slice_hrn'])}) - #return_slicerec_dictlist.append(slicerec_dict) - fixed_slicerec_dict.update(slicerec_dict) - - logger.debug("IOTLAB_API.PY \tGetSlices RETURN \ - return_slicerec_dictlist %s \slice_filter %s " \ - %(return_slicerec_dictlist, slice_filter)) - - return return_slicerec_dictlist