+
+ def get_slivers(self, urns, options={}):
+ """Get slivers of the given slice urns. Slivers contains slice, node and
+ user information.
+
+ For Iotlab, returns the leases with sliver ids and their allocation
+ status.
+
+ :param urns: list of slice urns.
+ :type urns: list of strings
+ :param options: unused
+ :type options: unused
+
+ .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns
+ """
+
+
+ slice_ids = set()
+ node_ids = []
+ for urn in urns:
+ xrn = IotlabXrn(xrn=urn)
+ if xrn.type == 'sliver':
+ # id: slice_id-node_id
+ try:
+ sliver_id_parts = xrn.get_sliver_id_parts()
+ slice_id = int(sliver_id_parts[0])
+ node_id = int(sliver_id_parts[1])
+ slice_ids.add(slice_id)
+ node_ids.append(node_id)
+ except ValueError:
+ pass
+ else:
+ slice_names = set()
+ slice_names.add(xrn.hrn)
+
+
+ logger.debug("IotlabAggregate \t get_slivers urns %s slice_ids %s \
+ node_ids %s\r\n" % (urns, slice_ids, node_ids))
+ logger.debug("IotlabAggregate \t get_slivers xrn %s slice_names %s \
+ \r\n" % (xrn, slice_names))
+ filter_sliver = {}
+ if slice_names:
+ filter_sliver['slice_hrn'] = list(slice_names)
+ slice_hrn = filter_sliver['slice_hrn'][0]
+
+ slice_filter_type = 'slice_hrn'
+
+ # if slice_ids:
+ # filter['slice_id'] = list(slice_ids)
+ # # get slices
+ if slice_hrn:
+ slices = self.driver.GetSlices(slice_hrn,
+ slice_filter_type)
+ leases = self.driver.GetLeases({'slice_hrn':slice_hrn})
+ logger.debug("IotlabAggregate \t get_slivers \
+ slices %s leases %s\r\n" % (slices, leases ))
+ if not slices:
+ return []
+
+ single_slice = slices[0]
+ # get sliver users
+ user = single_slice['reg_researchers'][0].__dict__
+ logger.debug("IotlabAggregate \t get_slivers user %s \
+ \r\n" % (user))
+
+ # construct user key info
+ person = self.driver.testbed_shell.ldap.LdapFindUser(record=user)
+ logger.debug("IotlabAggregate \t get_slivers person %s \
+ \r\n" % (person))
+ # name = person['last_name']
+ user['login'] = person['uid']
+ user['user_urn'] = hrn_to_urn(user['hrn'], 'user')
+ user['keys'] = person['pkey']
+
+
+ try:
+ node_ids = single_slice['node_ids']
+ node_list = self.driver.testbed_shell.GetNodes(
+ {'hostname':single_slice['node_ids']})
+ node_by_hostname = dict([(node['hostname'], node)
+ for node in node_list])
+ except KeyError:
+ logger.warning("\t get_slivers No slivers in slice")
+ # slice['node_ids'] = node_ids
+ # nodes_dict = self.get_slice_nodes(slice, options)
+
+ slivers = []
+ for current_lease in leases:
+ for hostname in current_lease['reserved_nodes']:
+ node = {}
+ node['slice_id'] = current_lease['slice_id']
+ node['slice_hrn'] = current_lease['slice_hrn']
+ slice_name = current_lease['slice_hrn'].split(".")[1]
+ node['slice_name'] = slice_name
+ index = current_lease['reserved_nodes'].index(hostname)
+ node_id = current_lease['resource_ids'][index]
+ # node['slice_name'] = user['login']
+ # node.update(single_slice)
+ more_info = node_by_hostname[hostname]
+ node.update(more_info)
+ # oar_job_id is the slice_id (lease_id)
+ sliver_hrn = '%s.%s-%s' % (self.driver.hrn,
+ current_lease['lease_id'], node_id)
+ node['node_id'] = node_id
+ node['expires'] = current_lease['t_until']
+ node['sliver_id'] = Xrn(sliver_hrn, type='sliver').urn
+ node['urn'] = node['sliver_id']
+ node['services_user'] = [user]
+
+ slivers.append(node)
+ return slivers
+
+ def list_resources(self, version = None, options={}):
+ """
+ Returns an advertisement Rspec of available resources at this
+ aggregate. This Rspec contains a resource listing along with their
+ description, providing sufficient information for clients to be able to
+ select among available resources.
+
+ :param options: various options. The valid options are: {boolean
+ geni_compressed <optional>; struct geni_rspec_version { string type;
+ #case insensitive , string version; # case insensitive}} . The only
+ mandatory options if options is specified is geni_rspec_version.
+ :type options: dictionary
+
+ :returns: On success, the value field of the return struct will contain
+ a geni.rspec advertisment RSpec
+ :rtype: Rspec advertisement in xml.
+
+ .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#RSpecdatatype
+ .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#ListResources
+ """
+
+ version_manager = VersionManager()
+ version = version_manager.get_version(version)
+ rspec_version = version_manager._get_version(version.type,
+ version.version, 'ad')
+ rspec = RSpec(version=rspec_version, user_options=options)
+ # variable ldap_username to be compliant with get_all_leases
+ # prototype. Now unused in geni-v3 since we are getting all the leases
+ # here
+ ldap_username = None
+ if not options.get('list_leases') or options['list_leases'] != 'leases':
+ # get nodes
+ nodes_dict = self.get_nodes(options)
+
+ # no interfaces on iotlab nodes
+ # convert nodes to rspec nodes
+ rspec_nodes = []
+ for node_id in nodes_dict:
+ node = nodes_dict[node_id]
+ rspec_node = self.node_to_rspec_node(node)
+ rspec_nodes.append(rspec_node)
+ rspec.version.add_nodes(rspec_nodes)
+
+ # add links
+ # links = self.get_links(sites, nodes_dict, interfaces)
+ # rspec.version.add_links(links)
+
+ if not options.get('list_leases') or options.get('list_leases') \
+ and options['list_leases'] != 'resources':
+ leases = self.get_all_leases(ldap_username)
+ rspec.version.add_leases(leases)
+
+ return rspec.toxml()
+
+
+ def describe(self, urns, version=None, options={}):
+ """
+ Retrieve a manifest RSpec describing the resources contained by the
+ named entities, e.g. a single slice or a set of the slivers in a slice.
+ This listing and description should be sufficiently descriptive to allow
+ experimenters to use the resources.
+
+ :param urns: If a slice urn is supplied and there are no slivers in the
+ given slice at this aggregate, then geni_rspec shall be a valid
+ manifest RSpec, containing no node elements - no resources.
+ :type urns: list or strings
+ :param options: various options. the valid options are: {boolean
+ geni_compressed <optional>; struct geni_rspec_version { string type;
+ #case insensitive , string version; # case insensitive}}
+ :type options: dictionary
+
+ :returns: On success returns the following dictionary {geni_rspec:
+ <geni.rspec, a Manifest RSpec>, geni_urn: <string slice urn of the
+ containing slice>, geni_slivers:{ geni_sliver_urn:
+ <string sliver urn>, geni_expires: <dateTime.rfc3339 allocation
+ expiration string, as in geni_expires from SliversStatus>,
+ geni_allocation_status: <string sliver state - e.g. geni_allocated
+ or geni_provisioned >, geni_operational_status:
+ <string sliver operational state>, geni_error: <optional string.
+ The field may be omitted entirely but may not be null/None,
+ explaining any failure for a sliver.>}
+
+ .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3#Describe
+ .. seealso:: http://groups.geni.net/geni/wiki/GAPI_AM_API_V3/CommonConcepts#urns
+ """
+ version_manager = VersionManager()
+ version = version_manager.get_version(version)
+ rspec_version = version_manager._get_version(
+ version.type, version.version, 'manifest')
+ rspec = RSpec(version=rspec_version, user_options=options)
+
+ # get slivers
+ geni_slivers = []
+ slivers = self.get_slivers(urns, options)
+ if slivers:
+ rspec_expires = datetime_to_string(utcparse(slivers[0]['expires']))
+ else:
+ rspec_expires = datetime_to_string(utcparse(time.time()))
+ rspec.xml.set('expires', rspec_expires)
+
+ # lookup the sliver allocations
+ geni_urn = urns[0]
+ sliver_ids = [sliver['sliver_id'] for sliver in slivers]
+ logger.debug(" IOTLAB_API.PY \tDescribe sliver_ids %s "
+ % (sliver_ids))
+ constraint = SliverAllocation.sliver_id.in_(sliver_ids)
+ query = self.driver.api.dbsession().query(SliverAllocation)
+ sliver_allocations = query.filter((constraint)).all()
+ logger.debug(" IOTLAB_API.PY \tDescribe sliver_allocations %s "
+ % (sliver_allocations))
+ sliver_allocation_dict = {}
+ for sliver_allocation in sliver_allocations:
+ geni_urn = sliver_allocation.slice_urn
+ sliver_allocation_dict[sliver_allocation.sliver_id] = \
+ sliver_allocation
+
+ # add slivers
+ nodes_dict = {}
+ for sliver in slivers:
+ nodes_dict[sliver['node_id']] = sliver
+ rspec_nodes = []
+ for sliver in slivers:
+ rspec_node = self.sliver_to_rspec_node(sliver,
+ sliver_allocation_dict)
+ rspec_nodes.append(rspec_node)
+ logger.debug(" IOTLAB_API.PY \tDescribe sliver_allocation_dict %s "
+ % (sliver_allocation_dict))
+ geni_sliver = self.rspec_node_to_geni_sliver(rspec_node,
+ sliver_allocation_dict)
+ geni_slivers.append(geni_sliver)
+
+ logger.debug(" IOTLAB_API.PY \tDescribe rspec_nodes %s\
+ rspec %s "
+ % (rspec_nodes, rspec))
+ rspec.version.add_nodes(rspec_nodes)
+
+ return {'geni_urn': geni_urn,
+ 'geni_rspec': rspec.toxml(),
+ 'geni_slivers': geni_slivers}
\ No newline at end of file