2 from sfa.util.xrn import hrn_to_urn, urn_to_hrn, get_authority
4 from sfa.rspecs.rspec import RSpec
5 #from sfa.rspecs.elements.location import Location
6 from sfa.rspecs.elements.hardware_type import HardwareType
7 from sfa.rspecs.elements.login import Login
8 from sfa.rspecs.elements.services import ServicesElement
9 from sfa.rspecs.elements.sliver import Sliver
10 from sfa.rspecs.elements.lease import Lease
11 from sfa.rspecs.elements.granularity import Granularity
12 from sfa.rspecs.version_manager import VersionManager
15 from sfa.rspecs.elements.versions.iotlabv1Node import IotlabPosition, IotlabNode, \
17 from sfa.util.sfalogging import logger
19 from sfa.util.xrn import Xrn
21 def iotlab_xrn_to_hostname(xrn):
22 return Xrn.unescape(Xrn(xrn=xrn, type='node').get_leaf())
24 def iotlab_xrn_object(root_auth, hostname):
25 """Attributes are urn and hrn.
26 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
27 Get the hostname using iotlab_xrn_to_hostname on the urn.
29 :return: the iotlab node's xrn
31 Get the hostname using slab_xrn_to_hostname on the urn.
33 :return: the senslab node's xrn
34 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
37 return Xrn('.'.join( [root_auth, Xrn.escape(hostname)]), type='node')
39 class IotlabAggregate:
52 def __init__(self, driver):
55 def get_slice_and_slivers(self, slice_xrn, login=None):
57 Get the slices and the associated leases if any from the iotlab
58 testbed. For each slice, get the nodes in the associated lease
59 and create a sliver with the necessary info and insertinto the sliver
60 dictionary, keyed on the node hostnames.
61 Returns a dict of slivers based on the sliver's node_id.
65 :param slice_xrn: xrn of the slice
66 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
67 :param login: user's login on iotlab ldap
69 :param login: user's login on senslab ldap
70 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
72 :type slice_xrn: string
74 :reutnr : a list of slices dict and a dictionary of Sliver object
77 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
78 ..note: There is no slivers in iotlab, only leases.
80 ..note: There is no slivers in senslab, only leases.
81 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
87 return (sfa_slice, slivers)
88 slice_urn = hrn_to_urn(slice_xrn, 'slice')
89 slice_hrn, _ = urn_to_hrn(slice_xrn)
90 slice_name = slice_hrn
92 slices = self.driver.iotlab_api.GetSlices(slice_filter= str(slice_name), \
93 slice_filter_type = 'slice_hrn', \
96 logger.debug("Slabaggregate api \tget_slice_and_slivers \
97 sfa_slice %s \r\n slices %s self.driver.hrn %s" \
98 %(sfa_slice, slices, self.driver.hrn))
100 return (sfa_slice, slivers)
103 # sort slivers by node id , if there is a job
104 #and therefore, node allocated to this slice
105 for sfa_slice in slices:
107 node_ids_list = sfa_slice['node_ids']
109 logger.log_exc("SLABAGGREGATE \t \
110 get_slice_and_slivers No nodes in the slice - KeyError ")
113 for node in node_ids_list:
114 sliver_xrn = Xrn(slice_urn, type='sliver', id=node)
115 sliver_xrn.set_authority(self.driver.hrn)
116 sliver = Sliver({'sliver_id':sliver_xrn.urn,
117 'name': sfa_slice['hrn'],
118 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
119 'type': 'iotlab-node',
122 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
125 slivers[node] = sliver
128 #Add default sliver attribute :
129 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
130 #connection information for iotlab
131 if get_authority (sfa_slice['hrn']) == self.driver.iotlab_api.root_auth:
133 #connection information for senslab
134 if get_authority (sfa_slice['hrn']) == self.driver.slab_api.root_auth:
135 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
136 tmp = sfa_slice['hrn'].split('.')
137 ldap_username = tmp[1].split('_')[0]
139 slivers['default_sliver'] = {'ssh': ssh_access , \
140 'login': ldap_username}
142 #TODO get_slice_and_slivers Find the login of the external user
144 logger.debug("SLABAGGREGATE api get_slice_and_slivers slivers %s "\
146 return (slices, slivers)
150 def get_nodes(self, slices=None, slivers=[], options=None):
151 # NT: the semantic of this function is not clear to me :
152 # if slice is not defined, then all the nodes should be returned
153 # if slice is defined, we should return only the nodes that
154 # are part of this slice
155 # but what is the role of the slivers parameter ?
156 # So i assume that slice['node_ids'] will be the same as slivers for us
159 #if not slices or not slices['node_ids']:
163 # get the granularity in second for the reservation system
164 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
165 grain = self.driver.iotlab_api.GetLeaseGranularity()
168 nodes = self.driver.iotlab_api.GetNodes()
170 grain = self.driver.slab_api.GetLeaseGranularity()
173 nodes = self.driver.slab_api.GetNodes()
174 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
175 #geni_available = options.get('geni_available')
177 #filter['boot_state'] = 'boot'
179 #filter.update({'peer_id': None})
180 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
181 #nodes = self.driver.iotlab_api.GetNodes(filter['hostname'])
183 #nodes = self.driver.slab_api.GetNodes(filter['hostname'])
184 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
193 #nodes_dict[node['node_id']] = node
194 #logger.debug("SLABAGGREGATE api get_nodes nodes %s "\
197 #sites_dict = self.get_sites({'site_id': site_ids})
199 #interfaces = self.get_interfaces({'interface_id':interface_ids})
201 #node_tags = self.get_node_tags(tags_filter)
203 #if slices, this means we got to list all the nodes given to this slice
204 # Make a list of all the nodes in the slice before getting their
207 slice_nodes_list = []
208 logger.debug("SLABAGGREGATE api get_nodes slice_nodes_list %s "\
210 if slices is not None:
211 for one_slice in slices:
213 slice_nodes_list = one_slice['node_ids']
216 #for node in one_slice['node_ids']:
217 #slice_nodes_list.append(node)
219 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
220 reserved_nodes = self.driver.iotlab_api.GetNodesCurrentlyInUse()
222 reserved_nodes = self.driver.slab_api.GetNodesCurrentlyInUse()
223 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
224 logger.debug("SLABAGGREGATE api get_nodes slice_nodes_list %s "\
227 nodes_dict[node['node_id']] = node
228 if slice_nodes_list == [] or node['hostname'] in slice_nodes_list:
230 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
231 rspec_node = IotlabNode()
233 rspec_node = SlabNode()
234 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
235 # xxx how to retrieve site['login_base']
236 #site_id=node['site_id']
237 #site=sites_dict[site_id]
239 rspec_node['mobile'] = node['mobile']
240 rspec_node['archi'] = node['archi']
241 rspec_node['radio'] = node['radio']
243 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
244 iotlab_xrn = iotlab_xrn_object(self.driver.iotlab_api.root_auth, \
246 rspec_node['component_id'] = iotlab_xrn.urn
248 slab_xrn = slab_xrn_object(self.driver.slab_api.root_auth, \
250 rspec_node['component_id'] = slab_xrn.urn
251 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
252 rspec_node['component_name'] = node['hostname']
253 rspec_node['component_manager_id'] = \
254 hrn_to_urn(self.driver.iotlab_api.root_auth, \
257 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
258 # Iotlab's nodes are federated : there is only one authority
259 # for all Iotlab sites, registered in SFA.
261 # Senslab's nodes are federated : there is only one authority
262 # for all Senslab sites, registered in SFA.
263 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
264 # Removing the part including the site
265 # in authority_id SA 27/07/12
266 rspec_node['authority_id'] = rspec_node['component_manager_id']
268 # do not include boot state (<available> element)
269 #in the manifest rspec
272 rspec_node['boot_state'] = node['boot_state']
273 if node['hostname'] in reserved_nodes:
274 rspec_node['boot_state'] = "Reserved"
275 rspec_node['exclusive'] = 'true'
276 rspec_node['hardware_types'] = [HardwareType({'name': \
280 location = IotlabLocation({'country':'France', 'site': \
282 rspec_node['location'] = location
285 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
286 position = IotlabPosition()
288 position = SlabPosition()
289 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
290 for field in position :
292 position[field] = node[field]
293 except KeyError, error :
294 logger.log_exc("SLABAGGREGATE\t get_nodes \
295 position %s "%(error))
297 rspec_node['position'] = position
298 #rspec_node['interfaces'] = []
301 granularity = Granularity({'grain': grain})
302 rspec_node['granularity'] = granularity
303 rspec_node['tags'] = []
304 if node['hostname'] in slivers:
306 sliver = slivers[node['hostname']]
307 rspec_node['sliver_id'] = sliver['sliver_id']
308 rspec_node['client_id'] = node['hostname']
309 rspec_node['slivers'] = [sliver]
311 # slivers always provide the ssh service
312 login = Login({'authentication': 'ssh-keys', \
313 'hostname': node['hostname'], 'port':'22', \
314 'username': sliver['name']})
315 service = Services({'login': login})
316 rspec_node['services'] = [service]
317 rspec_nodes.append(rspec_node)
320 #def get_all_leases(self, slice_record = None):
321 def get_all_leases(self):
323 Get list of lease dictionaries which all have the mandatory keys
324 ('lease_id', 'hostname', 'site_id', 'name', 'start_time', 'duration').
325 All the leases running or scheduled are returned.
328 ..note::There is no filtering of leases within a given time frame.
329 All the running or scheduled leases are returned. options
330 removed SA 15/05/2013
335 #now = int(time.time())
336 #lease_filter = {'clip': now }
339 #lease_filter.update({'name': slice_record['name']})
341 #leases = self.driver.iotlab_api.GetLeases(lease_filter)
342 leases = self.driver.iotlab_api.GetLeases()
343 grain = self.driver.iotlab_api.GetLeaseGranularity()
347 #as many leases as there are nodes in the job
348 for node in lease['reserved_nodes']:
349 rspec_lease = Lease()
350 rspec_lease['lease_id'] = lease['lease_id']
351 #site = node['site_id']
352 iotlab_xrn = iotlab_xrn_object(self.driver.iotlab_api.root_auth, node)
353 rspec_lease['component_id'] = iotlab_xrn.urn
354 #rspec_lease['component_id'] = hostname_to_urn(self.driver.hrn,\
355 #site, node['hostname'])
357 rspec_lease['slice_id'] = lease['slice_id']
359 #No info on the slice used in iotlab_xp table
361 rspec_lease['start_time'] = lease['t_from']
362 rspec_lease['duration'] = (lease['t_until'] - lease['t_from']) \
364 rspec_leases.append(rspec_lease)
369 #from plc/aggregate.py
370 def get_rspec(self, slice_xrn=None, login=None, version = None, \
374 version_manager = VersionManager()
375 version = version_manager.get_version(version)
376 logger.debug("IotlabAggregate \t get_rspec ***version %s \
377 version.type %s version.version %s options %s \r\n" \
378 %(version,version.type,version.version,options))
380 if slice_xrn is None:
381 rspec_version = version_manager._get_version(version.type, \
382 version.version, 'ad')
385 rspec_version = version_manager._get_version(version.type, \
386 version.version, 'manifest')
388 slices, slivers = self.get_slice_and_slivers(slice_xrn, login)
389 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
390 #at this point sliver may be empty if no iotlab job
392 #at this point sliver may be empty if no senslab job
393 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
394 #is running for this user/slice.
395 rspec = RSpec(version=rspec_version, user_options=options)
398 #if slice and 'expires' in slice:
399 #rspec.xml.set('expires',\
400 #datetime_to_string(utcparse(slice['expires']))
401 # add sliver defaults
402 #nodes, links = self.get_nodes(slice, slivers)
403 logger.debug("\r\n \r\n IotlabAggregate \tget_rspec *** \
404 slice_xrn %s slices %s\r\n \r\n"\
405 %(slice_xrn, slices))
407 if options is not None:
408 lease_option = options['list_leases']
410 #If no options are specified, at least print the resources
413 #lease_option = 'all'
416 if lease_option in ['all', 'resources']:
417 #if not options.get('list_leases') or options.get('list_leases')
418 #and options['list_leases'] != 'leases':
419 nodes = self.get_nodes(slices, slivers)
420 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
421 logger.debug("\r\n \r\n IotlabAggregate \ lease_option %s \
423 logger.debug("\r\n \r\n SlabAggregate \ lease_option %s \
424 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py
425 get rspec ******* nodes %s"\
426 %(lease_option, nodes[0]))
428 sites_set = set([node['location']['site'] for node in nodes] )
430 #In case creating a job, slice_xrn is not set to None
431 rspec.version.add_nodes(nodes)
433 #Get user associated with this slice
434 #user = dbsession.query(RegRecord).filter_by(record_id = \
435 #slices['record_id_user']).first()
437 #ldap_username = (user.hrn).split('.')[1]
440 #for one_slice in slices :
441 ldap_username = slices[0]['hrn']
442 tmp = ldap_username.split('.')
443 ldap_username = tmp[1].split('_')[0]
445 if version.type == "Slab":
446 rspec.version.add_connection_information(ldap_username, \
449 default_sliver = slivers.get('default_sliver', [])
451 #default_sliver_attribs = default_sliver.get('tags', [])
452 logger.debug("IotlabAggregate \tget_rspec **** \
453 default_sliver%s \r\n" %(default_sliver))
454 for attrib in default_sliver:
455 rspec.version.add_default_sliver_attribute(attrib, \
456 default_sliver[attrib])
457 if lease_option in ['all','leases']:
458 #leases = self.get_all_leases(slices)
459 leases = self.get_all_leases()
460 rspec.version.add_leases(leases)
462 <<<<<<< HEAD:sfa/iotlab/iotlabaggregate.py
463 #logger.debug("IotlabAggregate \tget_rspec ******* rspec_toxml %s \r\n"\
465 #logger.debug("SlabAggregate \tget_rspec ******* rspec_toxml %s \r\n"\
466 >>>>>>> 3fe7429... SA:sfa/senslab/slabaggregate.py