1 from sfa.util.faults import SliverDoesNotExist, UnknownSfaType
2 from sfa.util.sfalogging import logger
3 from sfa.storage.alchemy import dbsession
4 from sfa.storage.model import RegRecord
8 from sfa.managers.driver import Driver
9 from sfa.rspecs.version_manager import VersionManager
10 from sfa.rspecs.rspec import RSpec
12 from sfa.util.xrn import Xrn, hrn_to_urn, get_authority
15 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
16 from sfa.iotlab.iotlabpostgres import IotlabDB
18 from sfa.senslab.slabpostgres import SlabDB
21 from sfa.senslab.slabaggregate import SlabAggregate, slab_xrn_to_hostname
23 from sfa.senslab.slabslices import SlabSlices
24 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
27 from sfa.iotlab.iotlabaggregate import IotlabAggregate, iotlab_xrn_to_hostname
29 from sfa.iotlab.iotlabslices import IotlabSlices
32 from sfa.iotlab.iotlabapi import IotlabTestbedAPI
35 class IotlabDriver(Driver):
36 """ Iotlab Driver class inherited from Driver generic class.
38 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
40 class SlabDriver(Driver):
41 """ Senslab Driver class inherited from Driver generic class.
43 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
44 Contains methods compliant with the SFA standard and the testbed
45 infrastructure (calls to LDAP and OAR).
47 ..seealso:: Driver class
50 def __init__(self, config):
53 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
54 Sets the iotlab SFA config parameters ,
55 instanciates the testbed api and the iotlab database.
57 :param config: iotlab SFA configuration object
59 Sets the senslab SFA config parameters ,
60 instanciates the testbed api and the senslab database.
62 :param config: senslab SFA configuration object
63 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
64 :type config: Config object
66 Driver.__init__ (self, config)
69 self.db = IotlabDB(config, debug = False)
70 self.iotlab_api = IotlabTestbedAPI(config)
73 def augment_records_with_testbed_info (self, record_list ):
76 Adds specific testbed info to the records.
78 :param record_list: list of sfa dictionaries records
79 :type record_list: list
80 :return: list of records with extended information in each record
83 return self.fill_record_info (record_list)
85 def fill_record_info(self, record_list):
87 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
88 For each SFA record, fill in the iotlab specific and SFA specific
90 For each SFA record, fill in the senslab specific and SFA specific
91 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
94 :param record_list: list of sfa dictionaries records
95 :type record_list: list
96 :return: list of records with extended information in each record
99 .. warnings:: Should not be modifying record_list directly because modi
100 fication are kept outside the method's scope. Howerver, there is no
101 other way to do it given the way it's called in registry manager.
104 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
105 logger.debug("IOTLABDRIVER \tfill_record_info records %s " %(record_list))
107 logger.debug("SLABDRIVER \tfill_record_info records %s " %(record_list))
108 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
109 if not isinstance(record_list, list):
110 record_list = [record_list]
114 for record in record_list:
115 #If the record is a SFA slice record, then add information
116 #about the user of this slice. This kind of
117 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
118 #information is in the Iotlab's DB.
120 #information is in the Senslab's DB.
121 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
122 if str(record['type']) == 'slice':
123 if 'reg_researchers' in record and \
124 isinstance(record['reg_researchers'], list) :
125 record['reg_researchers'] = \
126 record['reg_researchers'][0].__dict__
127 record.update({'PI':[record['reg_researchers']['hrn']],
128 'researcher': [record['reg_researchers']['hrn']],
129 'name':record['hrn'],
132 'person_ids':[record['reg_researchers']['record_id']],
133 'geni_urn':'', #For client_helper.py compatibility
134 'keys':'', #For client_helper.py compatibility
135 'key_ids':''}) #For client_helper.py compatibility
138 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
139 #Get iotlab slice record and oar job id if any.
140 recslice_list = self.iotlab_api.GetSlices(slice_filter = \
142 #Get slab slice record and oar job id if any.
143 recslice_list = self.slab_api.GetSlices(slice_filter = \
144 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
146 slice_filter_type = 'slice_hrn')
149 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
150 logger.debug("IOTLABDRIVER \tfill_record_info \
152 logger.debug("SLABDRIVER \tfill_record_info \
153 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
154 TYPE SLICE RECUSER record['hrn'] %s ecord['oar_job_id']\
155 %s " %(record['hrn'], record['oar_job_id']))
156 del record['reg_researchers']
158 for rec in recslice_list:
159 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
160 logger.debug("IOTLABDRIVER\r\n \t \
161 fill_record_info oar_job_id %s " \
162 %(rec['oar_job_id']))
164 record['node_ids'] = [ self.iotlab_api.root_auth + \
166 logger.debug("SLABDRIVER\r\n \t \
167 fill_record_info oar_job_id %s " \
168 %(rec['oar_job_id']))
170 record['node_ids'] = [ self.slab_api.root_auth + \
171 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
172 hostname for hostname in rec['node_ids']]
177 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
178 logger.debug( "IOTLABDRIVER.PY \t fill_record_info SLICE \
180 logger.debug( "SLABDRIVER.PY \t fill_record_info SLICE \
181 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
182 recslice_list %s \r\n \t RECORD %s \r\n \
183 \r\n" %(recslice_list, record))
185 if str(record['type']) == 'user':
186 #The record is a SFA user record.
187 #Get the information about his slice from Iotlab's DB
188 #and add it to the user record.
189 recslice_list = self.iotlab_api.GetSlices(\
190 slice_filter = record['record_id'],\
191 slice_filter_type = 'record_id_user')
193 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
194 logger.debug( "IOTLABDRIVER.PY \t fill_record_info TYPE USER \
196 logger.debug( "SLABDRIVER.PY \t fill_record_info TYPE USER \
197 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
198 recslice_list %s \r\n \t RECORD %s \r\n" \
199 %(recslice_list , record))
200 #Append slice record in records list,
201 #therefore fetches user and slice info again(one more loop)
202 #Will update PIs and researcher for the slice
204 recuser = recslice_list[0]['reg_researchers']
205 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
206 logger.debug( "IOTLABDRIVER.PY \t fill_record_info USER \
208 logger.debug( "SLABDRIVER.PY \t fill_record_info USER \
209 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
210 recuser %s \r\n \r\n" %(recuser))
212 recslice = recslice_list[0]
213 recslice.update({'PI':[recuser['hrn']],
214 'researcher': [recuser['hrn']],
215 'name':record['hrn'],
218 'person_ids':[recuser['record_id']]})
220 for rec in recslice_list:
221 recslice['oar_job_id'].append(rec['oar_job_id'])
225 recslice.update({'type':'slice', \
226 'hrn':recslice_list[0]['hrn']})
229 #GetPersons takes [] as filters
230 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
231 user_iotlab = self.iotlab_api.GetPersons([record])
234 record.update(user_iotlab[0])
236 user_slab = self.slab_api.GetPersons([record])
239 record.update(user_slab[0])
240 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
241 #For client_helper.py compatibility
242 record.update( { 'geni_urn':'',
245 record_list.append(recslice)
247 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
248 logger.debug("IOTLABDRIVER.PY \tfill_record_info ADDING SLICE\
250 logger.debug("SLABDRIVER.PY \tfill_record_info ADDING SLICE\
251 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
252 INFO TO USER records %s" %(record_list))
255 except TypeError, error:
256 logger.log_exc("IOTLABDRIVER \t fill_record_info EXCEPTION %s"\
262 def sliver_status(self, slice_urn, slice_hrn):
264 Receive a status request for slice named urn/hrn
265 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
266 urn:publicid:IDN+iotlab+nturro_slice hrn iotlab.nturro_slice
268 urn:publicid:IDN+senslab+nturro_slice hrn senslab.nturro_slice
269 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
270 shall return a structure as described in
271 http://groups.geni.net/geni/wiki/GAPI_AM_API_V2#SliverStatus
272 NT : not sure if we should implement this or not, but used by sface.
274 :param slice_urn: slice urn
275 :type slice_urn: string
276 :param slice_hrn: slice hrn
277 :type slice_hrn: string
282 #First get the slice with the slice hrn
283 slice_list = self.iotlab_api.GetSlices(slice_filter = slice_hrn, \
284 slice_filter_type = 'slice_hrn')
286 if len(slice_list) is 0:
287 raise SliverDoesNotExist("%s slice_hrn" % (slice_hrn))
289 #Used for fetching the user info witch comes along the slice info
290 one_slice = slice_list[0]
293 #Make a list of all the nodes hostnames in use for this slice
294 slice_nodes_list = []
295 #for single_slice in slice_list:
296 #for node in single_slice['node_ids']:
297 #slice_nodes_list.append(node['hostname'])
298 #for node in one_slice:
299 #slice_nodes_list.append(node['hostname'])
300 slice_nodes_list = one_slice['node_ids']
301 #Get all the corresponding nodes details
302 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
303 nodes_all = self.iotlab_api.GetNodes({'hostname':slice_nodes_list},
305 nodes_all = self.slab_api.GetNodes({'hostname':slice_nodes_list},
306 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
307 ['node_id', 'hostname','site','boot_state'])
308 nodeall_byhostname = dict([(one_node['hostname'], one_node) \
309 for one_node in nodes_all])
313 for single_slice in slice_list:
316 top_level_status = 'empty'
319 ['geni_urn','geni_error', 'pl_login','geni_status','geni_resources'], None)
320 result['pl_login'] = one_slice['reg_researchers'][0].hrn
321 logger.debug("Slabdriver - sliver_status Sliver status \
322 urn %s hrn %s single_slice %s \r\n " \
323 %(slice_urn, slice_hrn, single_slice))
325 if 'node_ids' not in single_slice:
327 result['geni_status'] = top_level_status
328 result['geni_resources'] = []
330 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
333 top_level_status = 'ready'
334 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
336 top_level_status = 'ready'
338 #A job is running on Iotlab for this slice
339 # report about the local nodes that are in the slice only
341 result['geni_urn'] = slice_urn
344 for node_hostname in single_slice['node_ids']:
346 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
347 res['iotlab_hostname'] = node_hostname
348 res['iotlab_boot_state'] = nodeall_byhostname[node_hostname]['boot_state']
350 res['slab_hostname'] = node_hostname
351 res['slab_boot_state'] = nodeall_byhostname[node_hostname]['boot_state']
352 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
354 #res['pl_hostname'] = node['hostname']
355 #res['pl_boot_state'] = \
356 #nodeall_byhostname[node['hostname']]['boot_state']
357 #res['pl_last_contact'] = strftime(self.time_format, \
358 #gmtime(float(timestamp)))
359 sliver_id = Xrn(slice_urn, type='slice', \
360 id=nodeall_byhostname[node_hostname]['node_id'], \
361 authority=self.hrn).urn
363 res['geni_urn'] = sliver_id
364 #node_name = node['hostname']
365 if nodeall_byhostname[node_hostname]['boot_state'] == 'Alive':
367 res['geni_status'] = 'ready'
369 res['geni_status'] = 'failed'
370 top_level_status = 'failed'
372 res['geni_error'] = ''
374 resources.append(res)
376 result['geni_status'] = top_level_status
377 result['geni_resources'] = resources
378 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
379 logger.debug("IOTLABDRIVER \tsliver_statusresources %s res %s "\
381 logger.debug("SLABDRIVER \tsliver_statusresources %s res %s "\
382 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
387 def get_user_record(hrn):
389 Returns the user record based on the hrn from the SFA DB .
391 :param hrn: user's hrn
393 :return : user record from SFA database
397 return dbsession.query(RegRecord).filter_by(hrn = hrn).first()
400 def testbed_name (self):
402 Returns testbed's name.
408 # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
409 def aggregate_version (self):
412 Returns the testbed's supported rspec advertisement and
417 version_manager = VersionManager()
418 ad_rspec_versions = []
419 request_rspec_versions = []
420 for rspec_version in version_manager.versions:
421 if rspec_version.content_type in ['*', 'ad']:
422 ad_rspec_versions.append(rspec_version.to_dict())
423 if rspec_version.content_type in ['*', 'request']:
424 request_rspec_versions.append(rspec_version.to_dict())
426 'testbed':self.testbed_name(),
427 'geni_request_rspec_versions': request_rspec_versions,
428 'geni_ad_rspec_versions': ad_rspec_versions,
433 def _get_requested_leases_list(self, rspec):
435 Process leases in rspec depending on the rspec version (format)
436 type. Find the lease requests in the rspec and creates
437 a lease request list with the mandatory information ( nodes,
438 start time and duration) of the valid leases (duration above or equal
439 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
440 to the iotlab experiment minimum duration).
442 to the senslab experiment minimum duration).
443 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
445 :param rspec: rspec request received.
447 :return: list of lease requests found in the rspec
450 requested_lease_list = []
451 for lease in rspec.version.get_leases():
452 single_requested_lease = {}
453 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
454 logger.debug("IOTLABDRIVER.PY \t_get_requested_leases_list lease %s " %(lease))
456 logger.debug("SLABDRIVER.PY \t_get_requested_leases_list lease %s " %(lease))
457 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
459 if not lease.get('lease_id'):
460 if get_authority(lease['component_id']) == \
461 self.iotlab_api.root_auth:
462 single_requested_lease['hostname'] = \
463 iotlab_xrn_to_hostname(\
464 lease.get('component_id').strip())
465 single_requested_lease['start_time'] = \
466 lease.get('start_time')
467 single_requested_lease['duration'] = lease.get('duration')
468 #Check the experiment's duration is valid before adding
469 #the lease to the requested leases list
470 duration_in_seconds = \
471 int(single_requested_lease['duration'])
472 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
473 if duration_in_seconds >= self.iotlab_api.GetMinExperimentDurationInSec() :
475 if duration_in_seconds >= self.slab_api.GetMinExperimentDurationInSec() :
476 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
477 requested_lease_list.append(single_requested_lease)
479 return requested_lease_list
482 def _group_leases_by_start_time(requested_lease_list):
484 Create dict of leases by start_time, regrouping nodes reserved
485 at the same time, for the same amount of time so as to
486 define one job on OAR.
488 :param requested_lease_list: list of leases
489 :type requested_lease_list: list
490 :return: Dictionary with key = start time, value = list of leases
491 with the same start time.
495 requested_job_dict = {}
496 for lease in requested_lease_list:
498 #In case it is an asap experiment start_time is empty
499 if lease['start_time'] == '':
500 lease['start_time'] = '0'
502 if lease['start_time'] not in requested_job_dict:
503 if isinstance(lease['hostname'], str):
504 lease['hostname'] = [lease['hostname']]
507 requested_job_dict[lease['start_time']] = lease
510 job_lease = requested_job_dict[lease['start_time']]
511 if lease['duration'] == job_lease['duration'] :
512 job_lease['hostname'].append(lease['hostname'])
514 return requested_job_dict
516 def _process_requested_jobs(self, rspec):
518 Turns the requested leases and information into a dictionary
519 of requested jobs, grouped by starting time.
521 :param rspec: RSpec received
525 requested_lease_list = self._get_requested_leases_list(rspec)
526 logger.debug("IOTLABDRIVER _process_requested_jobs requested_lease_list \
527 %s"%(requested_lease_list))
528 job_dict = self._group_leases_by_start_time(requested_lease_list)
529 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
530 logger.debug("IOTLABDRIVER _process_requested_jobs job_dict\
532 logger.debug("SLABDRIVER _process_requested_jobs job_dict\
533 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
538 def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, \
541 Answer to CreateSliver.
542 Creates the leases and slivers for the users from the information
543 found in the rspec string.
544 Launch experiment on OAR if the requested leases is valid. Delete
545 no longer requested leases.
548 :param creds: user's credentials
550 :param users: user record list
555 :return: a valid Rspec for the slice which has just been
561 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
562 aggregate = IotlabAggregate(self)
564 slices = IotlabSlices(self)
566 aggregate = SlabAggregate(self)
568 slices = SlabSlices(self)
569 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
570 peer = slices.get_peer(slice_hrn)
571 sfa_peer = slices.get_sfa_peer(slice_hrn)
574 if not isinstance(creds, list):
578 slice_record = users[0].get('slice_record', {})
579 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
580 logger.debug("IOTLABDRIVER.PY \t ===============create_sliver \t\
582 logger.debug("SLABDRIVER.PY \t ===============create_sliver \t\
583 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
584 creds %s \r\n \r\n users %s" \
586 slice_record['user'] = {'keys':users[0]['keys'], \
587 'email':users[0]['email'], \
588 'hrn':slice_record['reg-researchers'][0]}
590 rspec = RSpec(rspec_string)
591 logger.debug("IOTLABDRIVER.PY \t create_sliver \trspec.version \
592 %s slice_record %s users %s" \
593 %(rspec.version,slice_record, users))
596 # ensure site record exists?
597 # ensure slice record exists
598 #Removed options to verify_slice SA 14/08/12
599 sfa_slice = slices.verify_slice(slice_hrn, slice_record, peer, \
602 # ensure person records exists
603 #verify_persons returns added persons but since the return value
605 slices.verify_persons(slice_hrn, sfa_slice, users, peer, \
606 sfa_peer, options=options)
607 #requested_attributes returned by rspec.version.get_slice_attributes()
608 #unused, removed SA 13/08/12
609 #rspec.version.get_slice_attributes()
611 logger.debug("IOTLABDRIVER.PY create_sliver slice %s " %(sfa_slice))
613 # add/remove slice from nodes
615 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
617 # add/remove slice from nodes
619 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
620 #requested_slivers = [node.get('component_id') \
621 #for node in rspec.version.get_nodes_with_slivers()\
622 #if node.get('authority_id') is self.iotlab_api.root_auth]
623 #l = [ node for node in rspec.version.get_nodes_with_slivers() ]
624 #logger.debug("SLADRIVER \tcreate_sliver requested_slivers \
625 #requested_slivers %s listnodes %s" \
626 #%(requested_slivers,l))
627 #verify_slice_nodes returns nodes, but unused here. Removed SA 13/08/12.
628 #slices.verify_slice_nodes(sfa_slice, requested_slivers, peer)
631 requested_job_dict = self._process_requested_jobs(rspec)
634 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
635 logger.debug("IOTLABDRIVER.PY \tcreate_sliver requested_job_dict %s "\
637 logger.debug("SLABDRIVER.PY \tcreate_sliver requested_job_dict %s "\
638 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
639 %(requested_job_dict))
640 #verify_slice_leases returns the leases , but the return value is unused
641 #here. Removed SA 13/08/12
642 slices.verify_slice_leases(sfa_slice, \
643 requested_job_dict, peer)
645 return aggregate.get_rspec(slice_xrn=slice_urn, \
646 login=sfa_slice['login'], version=rspec.version)
649 def delete_sliver (self, slice_urn, slice_hrn, creds, options):
651 Deletes the lease associated with the slice hrn and the credentials
652 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
653 if the slice belongs to iotlab. Answer to DeleteSliver.
655 :return: 1 if the slice to delete was not found on iotlab,
656 True if the deletion was successful, False otherwise otherwise.
658 .. note:: Should really be named delete_leases because iotlab does
660 if the slice belongs to senslab. Answer to DeleteSliver.
662 :return: 1 if the slice to delete was not found on senslab,
663 True if the deletion was successful, False otherwise otherwise.
665 .. note:: Should really be named delete_leases because senslab does
666 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
667 not have any slivers, but only deals with leases. However, SFA api only
668 have delete_sliver define so far. SA 13.05/2013
671 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
672 sfa_slice_list = self.iotlab_api.GetSlices(slice_filter = slice_hrn, \
674 sfa_slice_list = self.slab_api.GetSlices(slice_filter = slice_hrn, \
675 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
676 slice_filter_type = 'slice_hrn')
678 if not sfa_slice_list:
681 #Delete all leases in the slice
682 for sfa_slice in sfa_slice_list:
685 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
686 logger.debug("IOTLABDRIVER.PY delete_sliver slice %s" %(sfa_slice))
687 slices = IotlabSlices(self)
688 # determine if this is a peer slice
690 logger.debug("SLABDRIVER.PY delete_sliver slice %s" %(sfa_slice))
691 slices = SlabSlices(self)
692 # determine if this is a peer slice
694 peer = slices.get_peer(slice_hrn)
695 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
697 peer = slices.get_peer(slice_hrn)
699 logger.debug("IOTLABDRIVER.PY delete_sliver peer %s \
700 \r\n \t sfa_slice %s " %(peer, sfa_slice))
703 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
704 self.iotlab_api.DeleteSliceFromNodes(sfa_slice)
706 self.slab_api.DeleteSliceFromNodes(sfa_slice)
707 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
713 def list_resources (self, slice_urn, slice_hrn, creds, options):
715 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
716 List resources from the iotlab aggregate and returns a Rspec
718 List resources from the senslab aggregate and returns a Rspec
719 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
720 advertisement with resources found when slice_urn and slice_hrn are None
721 (in case of resource discovery).
722 If a slice hrn and urn are provided, list experiment's slice
723 nodes in a rspec format. Answer to ListResources.
725 :param options: options used when listing resources (list_leases, info,
727 :return: rspec string in xml
731 #cached_requested = options.get('cached', True)
733 version_manager = VersionManager()
734 # get the rspec's return format from options
736 version_manager.get_version(options.get('geni_rspec_version'))
737 version_string = "rspec_%s" % (rspec_version)
739 #panos adding the info option to the caching key (can be improved)
740 if options.get('info'):
741 version_string = version_string + "_" + \
742 options.get('info', 'default')
744 # Adding the list_leases option to the caching key
745 if options.get('list_leases'):
746 version_string = version_string + "_" + \
747 options.get('list_leases', 'default')
749 # Adding geni_available to caching key
750 if options.get('geni_available'):
751 version_string = version_string + "_" + \
752 str(options.get('geni_available'))
754 # look in cache first
755 #if cached_requested and self.cache and not slice_hrn:
756 #rspec = self.cache.get(version_string)
758 #logger.debug("IotlabDriver.ListResources: \
759 #returning cached advertisement")
762 #panos: passing user-defined options
763 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
764 aggregate = IotlabAggregate(self)
766 aggregate = SlabAggregate(self)
767 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
769 rspec = aggregate.get_rspec(slice_xrn=slice_urn, \
770 version=rspec_version, options=options)
773 #if self.cache and not slice_hrn:
774 #logger.debug("Slab.ListResources: stores advertisement in cache")
775 #self.cache.add(version_string, rspec)
780 def list_slices (self, creds, options):
782 Answer to ListSlices.
783 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
784 List slices belonging to iotlab, returns slice urns list.
786 List slices belonging to senslab, returns slice urns list.
787 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
788 No caching used. Options unused but are defined in the SFA method
791 :return: slice urns list
795 # look in cache first
797 #slices = self.cache.get('slices')
799 #logger.debug("PlDriver.list_slices returns from cache")
804 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
805 slices = self.iotlab_api.GetSlices()
806 logger.debug("IOTLABDRIVER.PY \tlist_slices hrn %s \r\n \r\n" %(slices))
807 slice_hrns = [iotlab_slice['hrn'] for iotlab_slice in slices]
809 slices = self.slab_api.GetSlices()
810 logger.debug("SLABDRIVER.PY \tlist_slices hrn %s \r\n \r\n" %(slices))
811 slice_hrns = [slab_slice['hrn'] for slab_slice in slices]
812 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
814 slice_urns = [hrn_to_urn(slice_hrn, 'slice') \
815 for slice_hrn in slice_hrns]
819 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
820 #logger.debug ("IotlabDriver.list_slices stores value in cache")
822 #logger.debug ("SlabDriver.list_slices stores value in cache")
823 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
824 #self.cache.add('slices', slice_urns)
829 def register (self, sfa_record, hrn, pub_key):
831 Adding new user, slice, node or site should not be handled
834 ..warnings:: should not be used. Different components are in charge of
835 doing this task. Adding nodes = OAR
836 Adding users = LDAP Iotlab
837 Adding slice = Import from LDAP users
840 :param sfa_record: record provided by the client of the
842 :type sfa_record: dict
847 def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
848 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
849 """No site or node record update allowed in Iotlab.
851 """No site or node record update allowed in Senslab.
852 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
853 The only modifications authorized here are key deletion/addition
854 on an existing user and password change.
855 On an existing user, CAN NOT BE MODIFIED:
856 'first_name', 'last_name', 'email'
857 DOES NOT EXIST IN SENSLAB:
858 'phone', 'url', 'bio','title', 'accepted_aup',
859 A slice is bound to its user, so modifying the user's ssh key should
860 modify the slice's GID after an import procedure.
862 :param old_sfa_record: what is in the db for this hrn
863 :param new_sfa_record: what was passed to the Update call
865 ..seealso:: update in driver.py.
868 pointer = old_sfa_record['pointer']
869 old_sfa_record_type = old_sfa_record['type']
871 # new_key implemented for users only
872 if new_key and old_sfa_record_type not in [ 'user' ]:
873 raise UnknownSfaType(old_sfa_record_type)
876 if old_sfa_record_type == "user":
878 all_fields = new_sfa_record
879 for key in all_fields.keys():
880 if key in ['key', 'password']:
881 update_fields[key] = all_fields[key]
885 # must check this key against the previous one if it exists
886 persons = self.iotlab_api.GetPersons([old_sfa_record])
888 keys = [person['pkey']]
889 #Get all the person's keys
890 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
891 keys_dict = self.iotlab_api.GetKeys(keys)
893 keys_dict = self.slab_api.GetKeys(keys)
894 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
896 # Delete all stale keys, meaning the user has only one key
898 #TODO: do we really want to delete all the other keys?
899 #Is this a problem with the GID generation to have multiple
905 #remove all the other keys
906 for key in keys_dict:
907 self.iotlab_api.DeleteKey(person, key)
908 self.iotlab_api.AddPersonKey(person, \
909 {'sshPublicKey': person['pkey']},{'sshPublicKey': new_key} )
910 #self.iotlab_api.AddPersonKey(person, {'key_type': 'ssh', \
915 def remove (self, sfa_record):
917 Removes users only. Mark the user as disabled in
918 LDAP. The user and his slice are then deleted from the db by running an
919 import on the registry.
923 :param sfa_record: record is the existing sfa record in the db
924 :type sfa_record: dict
926 ..warning::As fas as the slice is concerned, here only the leases are
927 removed from the slice. The slice is record itself is not removed from
929 TODO : REMOVE SLICE FROM THE DB AS WELL? SA 14/05/2013,
931 TODO: return boolean for the slice part
933 sfa_record_type = sfa_record['type']
934 hrn = sfa_record['hrn']
935 if sfa_record_type == 'user':
937 <<<<<<< HEAD:sfa/iotlab/iotlabdriver.py
938 #get user from iotlab ldap
939 person = self.iotlab_api.GetPersons(sfa_record)
940 #No registering at a given site in Iotlab.
941 #Once registered to the LDAP, all iotlab sites are
943 #get user from senslab ldap
944 person = self.slab_api.GetPersons(sfa_record)
945 #No registering at a given site in Senslab.
946 #Once registered to the LDAP, all senslab sites are
947 >>>>>>> 3fe7429... SA:sfa/senslab/slabdriver.py
950 #Mark account as disabled in ldap
951 return self.iotlab_api.DeletePerson(sfa_record)
953 elif sfa_record_type == 'slice':
954 if self.iotlab_api.GetSlices(slice_filter = hrn, \
955 slice_filter_type = 'slice_hrn'):
956 ret = self.iotlab_api.DeleteSlice(sfa_record)