Functional v3 version of Iotlab.
authorSandrine Avakian <sandrine.avakian@inria.fr>
Fri, 13 Dec 2013 14:39:21 +0000 (15:39 +0100)
committerSandrine Avakian <sandrine.avakian@inria.fr>
Fri, 13 Dec 2013 14:39:21 +0000 (15:39 +0100)
sfa/importer/iotlabimporter.py
sfa/iotlab/iotlabaggregate.py
sfa/iotlab/iotlabdriver.py
sfa/iotlab/iotlabshell.py
testbeds/iotlab/tests/driver_tests.py
testbeds/iotlab/tests/sfi_client_tests.py

index d98d308..87cb0cd 100644 (file)
@@ -4,6 +4,7 @@ Also creates the iotlab specific databse and table to keep track
 of which slice hrn contains which job.
 """
 from sfa.util.config import Config
+from sfa.generic import Generic
 from sfa.util.xrn import Xrn, get_authority, hrn_to_urn
 from sfa.iotlab.iotlabshell import IotlabShell
 # from sfa.iotlab.iotlabdriver import IotlabDriver
@@ -333,6 +334,8 @@ class IotlabImporter:
         :param testbed_shell: IotlabDriver object, used to have access to
             testbed_shell attributes.
         :type testbed_shell: IotlabDriver
+
+        .. warning:: does not support multiple keys per user
         """
         ldap_person_listdict = testbed_shell.GetPersons()
         self.logger.info("IOTLABIMPORT \t ldap_person_listdict %s \r\n"
@@ -507,7 +510,7 @@ class IotlabImporter:
 
     def run(self, options):
         """
-        Create the special iotlab table, testbed_xp, in the iotlab database.
+        Create the special iotlab table, lease_table, in the iotlab database.
         Import everything (users, slices, nodes and sites from OAR
         and LDAP) into the SFA database.
         Delete stale records that are no longer in OAR or LDAP.
@@ -518,14 +521,14 @@ class IotlabImporter:
         config = Config ()
         interface_hrn = config.SFA_INTERFACE_HRN
         root_auth = config.SFA_REGISTRY_ROOT_AUTH
-
-        testbed_shell = IotlabShell(config)
+        api = Generic.the_flavour().make_api(interface='registry')
+        testbed_shell = IotlabShell(api)
         leases_db = TestbedAdditionalSfaDB(config)
         #Create special slice table for iotlab
 
-        if not leases_db.exists('testbed_xp'):
+        if not leases_db.exists('lease_table'):
             leases_db.createtable()
-            self.logger.info("IotlabImporter.run:  testbed_xp table created ")
+            self.logger.info("IotlabImporter.run:  lease_table table created ")
 
         # import site and node records in site into the SFA db.
         self.import_sites_and_nodes(testbed_shell)
index d57943e..85f6a75 100644 (file)
@@ -4,13 +4,13 @@ Contains methods to get information on slice, slivers, nodes and leases,
 formatting them and turn it into a RSpec.
 """
 from sfa.util.sfatime import utcparse, datetime_to_string
-from sfa.util.xrn import Xrn, hrn_to_urn, urn_to_hrn, get_authority
+from sfa.util.xrn import Xrn, hrn_to_urn, urn_to_hrn
 from sfa.iotlab.iotlabxrn import IotlabXrn
 from sfa.rspecs.rspec import RSpec
 #from sfa.rspecs.elements.location import Location
 from sfa.rspecs.elements.hardware_type import HardwareType
 from sfa.rspecs.elements.login import Login
-from sfa.rspecs.elements.services import ServicesElement
+from sfa.rspecs.elements.services import ServicesElement
 from sfa.rspecs.elements.sliver import Sliver
 from sfa.rspecs.elements.lease import Lease
 from sfa.rspecs.elements.granularity import Granularity
@@ -68,12 +68,12 @@ class IotlabAggregate:
             return (sfa_slice, slivers)
         slice_urn = hrn_to_urn(slice_xrn, 'slice')
         slice_hrn, _ = urn_to_hrn(slice_xrn)
-        slice_name = slice_hrn
 
         # GetSlices always returns a list, even if there is only one element
-        slices = self.driver.testbed_shell.GetSlices(slice_filter=str(slice_name),
-                                                  slice_filter_type='slice_hrn',
-                                                  login=login)
+        slices = self.driver.testbed_shell.GetSlices(
+                                                slice_filter=str(slice_hrn),
+                                                slice_filter_type='slice_hrn',
+                                                login=login)
 
         logger.debug("IotlabAggregate api \tget_slice_and_slivers \
                       slice_hrn %s \r\n slices %s self.driver.hrn %s"
@@ -106,7 +106,8 @@ class IotlabAggregate:
 
         #Add default sliver attribute :
         #connection information for iotlab
-        # if get_authority(sfa_slice['hrn']) == self.driver.testbed_shell.root_auth:
+        # if get_authority(sfa_slice['hrn']) == \
+            # self.driver.testbed_shell.root_auth:
         #     tmp = sfa_slice['hrn'].split('.')
         #     ldap_username = tmp[1].split('_')[0]
         #     ssh_access = None
@@ -126,6 +127,17 @@ class IotlabAggregate:
         return (slices, slivers)
 
     def find_ldap_username_from_slice(self, sfa_slice):
+        """
+        Gets the ldap username of the user based on the information contained
+        in ist sfa_slice record.
+
+        :param sfa_slice: the user's slice record. Must contain the
+            reg_researchers key.
+        :type sfa_slice: dictionary
+        :returns: ldap_username, the ldap user's login.
+        :rtype: string
+
+        """
         researchers = [sfa_slice['reg_researchers'][0].__dict__]
         # look in ldap:
         ldap_username = None
@@ -137,7 +149,7 @@ class IotlabAggregate:
 
 
 
-    def get_nodes(self, slices=None, slivers=[], options=None):
+    def get_nodes(self, options=None):
     # def node_to_rspec_node(self, node, sites, node_tags,
     #     grain=None, options={}):
         """Returns the nodes in the slice using the rspec format, with all the
@@ -148,10 +160,6 @@ class IotlabAggregate:
         it. If the slice does not have any job running or scheduled, that is
         it has no reserved nodes, then returns an empty list.
 
-        :param slices: list of slices (record dictionaries)
-        :param slivers: the list of slivers in all the slices
-        :type slices: list of dicts
-        :type slivers: list of Sliver object (dictionaries)
         :returns: An empty list if the slice has no reserved nodes, a rspec
             list with all the nodes and their properties (a dict per node)
             otherwise.
@@ -178,17 +186,18 @@ class IotlabAggregate:
         #     for one_slice in slices:
         #         try:
         #             slice_nodes_list = one_slice['node_ids']
-        #              # if we are dealing with a slice that has no node just
-        #              # return an empty list. In iotlab a slice can have multiple
-        #              # jobs scheduled, so it either has at least one lease or
-        #              # not at all.
+    #              # if we are dealing with a slice that has no node just
+    #              # return an empty list. In iotlab a slice can have multiple
+    #              # jobs scheduled, so it either has at least one lease or
+    #              # not at all.
         #         except KeyError:
         #             return []
 
         # get the granularity in second for the reservation system
         # grain = self.driver.testbed_shell.GetLeaseGranularity()
 
-        nodes = self.driver.testbed_shell.GetNodes()
+        nodes = self.driver.testbed_shell.GetNodes(node_filter_dict =
+                                                    filter_nodes)
 
         nodes_dict = {}
 
@@ -205,82 +214,25 @@ class IotlabAggregate:
                      # % (slice_nodes_list))
         for node in nodes:
             nodes_dict[node['node_id']] = node
-            # if slice_nodes_list == [] or node['hostname'] in slice_nodes_list:
-
-            #     rspec_node = IotlabNode()
-            #     # xxx how to retrieve site['login_base']
-            #     #site_id=node['site_id']
-            #     #site=sites_dict[site_id]
-
-            #     rspec_node['mobile'] = node['mobile']
-            #     rspec_node['archi'] = node['archi']
-            #     rspec_node['radio'] = node['radio']
-
-            #     iotlab_xrn = xrn_object(self.driver.testbed_shell.root_auth,
-            #                                    node['hostname'])
-            #     rspec_node['component_id'] = iotlab_xrn.urn
-            #     rspec_node['component_name'] = node['hostname']
-            #     rspec_node['component_manager_id'] = \
-            #                     hrn_to_urn(self.driver.testbed_shell.root_auth,
-            #                     'authority+sa')
-
-            #     # Iotlab's nodes are federated : there is only one authority
-            #     # for all Iotlab sites, registered in SFA.
-            #     # Removing the part including the site
-            #     # in authority_id SA 27/07/12
-            #     rspec_node['authority_id'] = rspec_node['component_manager_id']
-
-            #     # do not include boot state (<available> element)
-            #     #in the manifest rspec
-
-
-            #     rspec_node['boot_state'] = node['boot_state']
-            #     if node['hostname'] in reserved_nodes:
-            #         rspec_node['boot_state'] = "Reserved"
-            #     rspec_node['exclusive'] = 'true'
-            #     rspec_node['hardware_types'] = [HardwareType({'name': \
-            #                                     'iotlab-node'})]
-
-
-            #     location = IotlabLocation({'country':'France', 'site': \
-            #                                 node['site']})
-            #     rspec_node['location'] = location
-
-
-            #     position = IotlabPosition()
-            #     for field in position :
-            #         try:
-            #             position[field] = node[field]
-            #         except KeyError, error :
-            #             logger.log_exc("IOTLABAGGREGATE\t get_nodes \
-            #                                             position %s "% (error))
-
-            #     rspec_node['position'] = position
-            #     #rspec_node['interfaces'] = []
-
-            #     # Granularity
-            #     granularity = Granularity({'grain': grain})
-            #     rspec_node['granularity'] = granularity
-            #     rspec_node['tags'] = []
-            #     if node['hostname'] in slivers:
-            #         # add sliver info
-            #         sliver = slivers[node['hostname']]
-            #         rspec_node['sliver_id'] = sliver['sliver_id']
-            #         rspec_node['client_id'] = node['hostname']
-            #         rspec_node['slivers'] = [sliver]
-
-            #         # slivers always provide the ssh service
-            #         login = Login({'authentication': 'ssh-keys', \
-            #                 'hostname': node['hostname'], 'port':'22', \
-            #                 'username': sliver['name']})
-            #         service = Services({'login': login})
-            #         rspec_node['services'] = [service]
-            #     rspec_nodes.append(rspec_node)
-
-        # return (rspec_nodes)
+
         return nodes_dict
 
     def node_to_rspec_node(self, node):
+        """ Creates a rspec node structure with the appropriate information
+        based on the node information that can be found in the node dictionary.
+
+        :param node: node data. this dict contains information about the node
+            and must have the following keys : mobile, radio, archi, hostname,
+            boot_state, site, x, y ,z (position).
+        :type node: dictionary.
+
+        :returns: node dictionary containing the following keys : mobile, archi,
+            radio, component_id, component_name, component_manager_id,
+            authority_id, boot_state, exclusive, hardware_types, location,
+            position, granularity, tags.
+        :rtype: dict
+
+        """
 
         grain = self.driver.testbed_shell.GetLeaseGranularity()
 
@@ -356,6 +308,25 @@ class IotlabAggregate:
 
 
     def rspec_node_to_geni_sliver(self, rspec_node, sliver_allocations = {}):
+        """Makes a geni sliver structure from all the nodes allocated
+        to slivers in the sliver_allocations dictionary. Returns the states
+        of the sliver.
+
+        :param rspec_node: Node information contained in a rspec data structure
+            fashion.
+        :type rspec_node: dictionary
+        :param sliver_allocations:
+        :type sliver_allocations: dictionary
+
+        :returns: Dictionary with the following keys: geni_sliver_urn,
+            geni_expires, geni_allocation_status, geni_operational_status,
+            geni_error.
+
+        :rtype: dictionary
+
+        .. seealso:: node_to_rspec_node
+
+        """
         if rspec_node['sliver_id'] in sliver_allocations:
             # set sliver allocation and operational status
             sliver_allocation = sliver_allocations[rspec_node['sliver_id']]
@@ -383,20 +354,40 @@ class IotlabAggregate:
 
 
     def sliver_to_rspec_node(self, sliver, sliver_allocations):
+        """Used by describe to format node information into a rspec compliant
+        structure.
+
+        Creates a node rspec compliant structure by calling node_to_rspec_node.
+        Adds slivers, if any, to rspec node structure. Returns the updated
+        rspec node struct.
+
+        :param sliver: sliver dictionary. Contains keys: urn, slice_id, hostname
+            and slice_name.
+        :type sliver: dictionary
+        :param sliver_allocations: dictionary of slivers
+        :type sliver_allocations: dict
+
+        :returns: Node dictionary with all necessary data. .
+        .. seealso:: node_to_rspec_node
+        """
         rspec_node = self.node_to_rspec_node(sliver)
         rspec_node['expires'] = datetime_to_string(utcparse(sliver['expires']))
         # add sliver info
-        logger.debug("IOTLABAGGREGATE api \t  sliver_to_rspec_node sliverr  %s \r\nsliver_allocations %s"
-                      % (sliver, sliver_allocations))
+        logger.debug("IOTLABAGGREGATE api \t  sliver_to_rspec_node sliver \
+                        %s \r\nsliver_allocations %s" % (sliver,
+                            sliver_allocations))
         rspec_sliver = Sliver({'sliver_id': sliver['urn'],
                          'name': sliver['slice_id'],
                          'type': 'iotlab-exclusive',
                          'tags': []})
         rspec_node['sliver_id'] = rspec_sliver['sliver_id']
+
         if sliver['urn'] in sliver_allocations:
-            rspec_node['client_id'] = sliver_allocations[sliver['urn']].client_id
+            rspec_node['client_id'] = sliver_allocations[
+                                                    sliver['urn']].client_id
             if sliver_allocations[sliver['urn']].component_id:
-                rspec_node['component_id'] = sliver_allocations[sliver['urn']].component_id
+                rspec_node['component_id'] = sliver_allocations[
+                                                    sliver['urn']].component_id
         rspec_node['slivers'] = [rspec_sliver]
 
         # slivers always provide the ssh service
@@ -411,16 +402,18 @@ class IotlabAggregate:
 
     def get_all_leases(self, ldap_username):
         """
-
         Get list of lease dictionaries which all have the mandatory keys
         ('lease_id', 'hostname', 'site_id', 'name', 'start_time', 'duration').
         All the leases running or scheduled are returned.
 
         :param ldap_username: if ldap uid is not None, looks for the leases
-        belonging to this user.
+            belonging to this user.
         :type ldap_username: string
         :returns: rspec lease dictionary with keys lease_id, component_id,
-            slice_id, start_time, duration.
+            slice_id, start_time, duration where the lease_id is the oar job id,
+            component_id is the node's urn, slice_id is the slice urn,
+            start_time is the timestamp starting time and duration is expressed
+            in terms of the testbed's granularity.
         :rtype: dict
 
         .. note::There is no filtering of leases within a given time frame.
@@ -430,19 +423,11 @@ class IotlabAggregate:
 
         """
 
-        #now = int(time.time())
-        #lease_filter = {'clip': now }
-
-        #if slice_record:
-            #lease_filter.update({'name': slice_record['name']})
-
-        #leases = self.driver.testbed_shell.GetLeases(lease_filter)
-
         logger.debug("IOTLABAGGREGATE  get_all_leases ldap_username %s "
                      % (ldap_username))
         leases = self.driver.testbed_shell.GetLeases(login=ldap_username)
         grain = self.driver.testbed_shell.GetLeaseGranularity()
-        # site_ids = []
+
         rspec_leases = []
         for lease in leases:
             #as many leases as there are nodes in the job
@@ -492,7 +477,7 @@ class IotlabAggregate:
 
         """
 
-        ldap_username= None
+        ldap_username = None
         rspec = None
         version_manager = VersionManager()
         version = version_manager.get_version(version)
@@ -539,7 +524,7 @@ class IotlabAggregate:
         if lease_option in ['all', 'resources']:
         #if not options.get('list_leases') or options.get('list_leases')
         #and options['list_leases'] != 'leases':
-            nodes = self.get_nodes(slices, slivers)
+            nodes = self.get_nodes()
             logger.debug("\r\n")
             logger.debug("IotlabAggregate \t lease_option %s \
                           get rspec  ******* nodes %s"
@@ -582,8 +567,18 @@ class IotlabAggregate:
         return rspec.toxml()
 
     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
         """
 
 
@@ -610,14 +605,13 @@ class IotlabAggregate:
                        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 = {}
+        filter_sliver = {}
         if slice_names:
-            filter['slice_hrn'] = list(slice_names)
-            slice_hrn = filter['slice_hrn'][0]
+            filter_sliver['slice_hrn'] = list(slice_names)
+            slice_hrn = filter_sliver['slice_hrn'][0]
 
             slice_filter_type = 'slice_hrn'
-            logger.debug("IotlabAggregate \t get_slivers  slice_hrn%s \
-                       \r\n" % (slice_hrn ))
+
         # if slice_ids:
         #     filter['slice_id'] = list(slice_ids)
         # # get slices
@@ -630,50 +624,34 @@ class IotlabAggregate:
                        slices %s leases %s\r\n" % (slices, leases ))
         if not slices:
             return []
-        # slice = slices[0]
-        # slice['hrn'] = DummyXrn(auth=self.driver.hrn, slicename=slice['slice_name']).hrn
+
         single_slice = slices[0]
         # get sliver users
-        # users = []
-        # user_ids = []
-        # for slice in slices:
-        #     user_ids.extend(slice['user_ids'])
-        # if user_ids:
-        #     users = self.driver.shell.GetUsers({'user_ids': user_ids})
-
         user = single_slice['reg_researchers'][0].__dict__
         logger.debug("IotlabAggregate \t get_slivers user %s \
                        \r\n" % (user))
 
         # construct user key info
-        # users_list = []
-        # for user in users:
         person = self.driver.testbed_shell.ldap.LdapFindUser(record=user)
         logger.debug("IotlabAggregate \t get_slivers person %s \
                        \r\n" % (person))
-        name = person['last_name']
+        name = person['last_name']
         user['login'] = person['uid']
         user['user_urn'] = hrn_to_urn(user['hrn'], 'user')
         user['keys'] = person['pkey']
-            # name = user['email'][0:user['email'].index('@')]
-            # user = {
-            #     'login': slice['slice_name'],
-            #     'user_urn': Xrn('%s.%s' % (self.driver.hrn, name), type='user').urn,
-            #     'keys': user['keys']
-            # }
-            # users_list.append(user)
+
 
         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])
+            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)
-        logger.debug("IotlabAggregate \t get_slivers  node_by_hostname%s \
-                       \r\n" % (node_by_hostname))
+
         slivers = []
         for current_lease in leases:
             for hostname in current_lease['reserved_nodes']:
@@ -696,42 +674,49 @@ class IotlabAggregate:
                 node['sliver_id'] = Xrn(sliver_hrn, type='sliver').urn
                 node['urn'] = node['sliver_id']
                 node['services_user'] = [user]
-                logger.debug("IotlabAggregate \t get_slivers node %s current_lease %s\
-                       \r\n more_info %s" % (node, current_lease, more_info))
+
                 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_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 the get_all_leases
+        # 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)
-            # site_ids = []
-            # interface_ids = []
-            # tag_ids = []
-            # nodes_dict = {}
-            # for node in nodes:
-            #     site_ids.append(node['site_id'])
-            #     interface_ids.extend(node['interface_ids'])
-            #     tag_ids.extend(node['node_tag_ids'])
-            #     nodes_dict[node['node_id']] = node
-            # sites = self.get_sites({'site_id': site_ids})
-            # interfaces = self.get_interfaces({'interface_id':interface_ids})
-            # node_tags = self.get_node_tags({'node_tag_id': tag_ids})
-            # pl_initscripts = self.get_pl_initscripts()
+
+            # 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, sites, interfaces, node_tags, pl_initscripts)
                 rspec_node = self.node_to_rspec_node(node)
                 rspec_nodes.append(rspec_node)
             rspec.version.add_nodes(rspec_nodes)
@@ -755,25 +740,28 @@ class IotlabAggregate:
         This listing and description should be sufficiently descriptive to allow
         experimenters to use the resources.
 
-        returns: On success returns the following struct:
-        {
-           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.>
-                       },
-                 ]}
+        :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)
@@ -796,15 +784,15 @@ class IotlabAggregate:
         logger.debug(" IOTLAB_API.PY \tDescribe  sliver_ids %s "
                      % (sliver_ids))
         constraint = SliverAllocation.sliver_id.in_(sliver_ids)
-        logger.debug(" IOTLAB_API.PY \tDescribe  constraint %s "
-                     % (constraint))
-        sliver_allocations = self.driver.api.dbsession().query(SliverAllocation).filter((constraint)).all()
+        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
+            sliver_allocation_dict[sliver_allocation.sliver_id] = \
+                                                            sliver_allocation
 
         # add slivers
         nodes_dict = {}
@@ -812,11 +800,13 @@ class IotlabAggregate:
             nodes_dict[sliver['node_id']] = sliver
         rspec_nodes = []
         for sliver in slivers:
-            rspec_node = self.sliver_to_rspec_node(sliver, sliver_allocation_dict)
+            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_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\
index 699e111..1e7fb76 100644 (file)
@@ -1,7 +1,7 @@
 """
 Implements what a driver should provide for SFA to work.
 """
-from sfa.util.faults import SliverDoesNotExist, UnknownSfaType
+from sfa.util.faults import SliverDoesNotExist, Forbidden
 from sfa.util.sfalogging import logger
 from sfa.storage.model import RegRecord
 from sfa.util.sfatime import utcparse, datetime_to_string
@@ -10,14 +10,15 @@ from sfa.managers.driver import Driver
 from sfa.rspecs.version_manager import VersionManager
 from sfa.rspecs.rspec import RSpec
 
-from sfa.iotlab.iotlabxrn import xrn_object
+from sfa.iotlab.iotlabxrn import IotlabXrn, xrn_object
 from sfa.util.xrn import Xrn, hrn_to_urn, get_authority, urn_to_hrn
-
 from sfa.iotlab.iotlabaggregate import IotlabAggregate
 from sfa.iotlab.iotlabxrn import xrn_to_hostname
 from sfa.iotlab.iotlabslices import IotlabSlices
 
+from sfa.trust.credential import Credential
 from sfa.storage.model import SliverAllocation
+
 from sfa.iotlab.iotlabshell import IotlabShell
 
 
@@ -42,7 +43,7 @@ class IotlabDriver(Driver):
         """
         Driver.__init__(self, api)
         self.api = api
-        config = api.config
+        config = api.config
         self.testbed_shell = IotlabShell(api)
         self.cache = None
 
@@ -323,28 +324,6 @@ class IotlabDriver(Driver):
         """
         return self.hrn
 
-    # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
-    def aggregate_version(self):
-        """
-
-        Returns the testbed's supported rspec advertisement and request
-        versions.
-        :returns: rspec versions supported ad a dictionary.
-        :rtype: dict
-
-        """
-        version_manager = VersionManager()
-        ad_rspec_versions = []
-        request_rspec_versions = []
-        for rspec_version in version_manager.versions:
-            if rspec_version.content_type in ['*', 'ad']:
-                ad_rspec_versions.append(rspec_version.to_dict())
-            if rspec_version.content_type in ['*', 'request']:
-                request_rspec_versions.append(rspec_version.to_dict())
-        return {
-            'testbed': self.testbed_name(),
-            'geni_request_rspec_versions': request_rspec_versions,
-            'geni_ad_rspec_versions': ad_rspec_versions}
 
     def _get_requested_leases_list(self, rspec):
         """
@@ -438,96 +417,8 @@ class IotlabDriver(Driver):
         return xp_dict
 
 
-    def create_sliver(self, slice_urn, slice_hrn, creds, rspec_string,
-                      users, options):
-        """Answer to CreateSliver.
-
-        Creates the leases and slivers for the users from the information
-            found in the rspec string.
-            Launch experiment on OAR if the requested leases is valid. Delete
-            no longer requested leases.
-
 
-        :param creds: user's credentials
-        :type creds: string
-        :param users: user record list
-        :type users: list
-        :param options:
-        :type options:
-
-        :returns: a valid Rspec for the slice which has just been
-            modified.
-        :rtype: RSpec
-
-
-        """
-        aggregate = IotlabAggregate(self)
-
-        slices = IotlabSlices(self)
-        peer = slices.get_peer(slice_hrn)
-        sfa_peer = slices.get_sfa_peer(slice_hrn)
-        slice_record = None
-
-        if not isinstance(creds, list):
-            creds = [creds]
-
-        if users:
-            slice_record = users[0].get('slice_record', {})
-            logger.debug("IOTLABDRIVER.PY \t ===============create_sliver \t\
-                            creds %s \r\n \r\n users %s"
-                         % (creds, users))
-            slice_record['user'] = {'keys': users[0]['keys'],
-                                    'email': users[0]['email'],
-                                    'hrn': slice_record['reg-researchers'][0]}
-        # parse rspec
-        rspec = RSpec(rspec_string)
-        logger.debug("IOTLABDRIVER.PY \t create_sliver \trspec.version \
-                     %s slice_record %s users %s"
-                     % (rspec.version, slice_record, users))
-
-        # ensure site record exists?
-        # ensure slice record exists
-        #Removed options in verify_slice SA 14/08/12
-        #Removed peer record in  verify_slice SA 18/07/13
-        sfa_slice = slices.verify_slice(slice_hrn, slice_record, sfa_peer)
-
-        # ensure person records exists
-        #verify_persons returns added persons but the return value
-        #is not used
-        #Removed peer record and sfa_peer in  verify_persons SA 18/07/13
-        slices.verify_persons(slice_hrn, sfa_slice, users, options=options)
-        #requested_attributes returned by rspec.version.get_slice_attributes()
-        #unused, removed SA 13/08/12
-        #rspec.version.get_slice_attributes()
-
-        logger.debug("IOTLABDRIVER.PY create_sliver slice %s " % (sfa_slice))
-
-        # add/remove slice from nodes
-
-        #requested_slivers = [node.get('component_id') \
-                    #for node in rspec.version.get_nodes_with_slivers()\
-                    #if node.get('authority_id') is self.testbed_shell.root_auth]
-        #l = [ node for node in rspec.version.get_nodes_with_slivers() ]
-        #logger.debug("SLADRIVER \tcreate_sliver requested_slivers \
-                                    #requested_slivers %s  listnodes %s" \
-                                    #%(requested_slivers,l))
-        #verify_slice_nodes returns nodes, but unused here. Removed SA 13/08/12.
-        #slices.verify_slice_nodes(sfa_slice, requested_slivers, peer)
-
-        requested_xp_dict = self._process_requested_xp_dict(rspec)
-
-        logger.debug("IOTLABDRIVER.PY \tcreate_sliver  requested_xp_dict %s "
-                     % (requested_xp_dict))
-        #verify_slice_leases returns the leases , but the return value is unused
-        #here. Removed SA 13/08/12
-        slices.verify_slice_leases(sfa_slice,
-                                   requested_xp_dict, peer)
-
-        return aggregate.get_rspec(slice_xrn=slice_urn,
-                                   login=sfa_slice['login'],
-                                   version=rspec.version)
-
-    def delete(self, slice_urns, options):
+    def delete(self, slice_urns, options={}):
         """
         Deletes the lease associated with the slice hrn and the credentials
             if the slice belongs to iotlab. Answer to DeleteSliver.
@@ -550,12 +441,15 @@ class IotlabDriver(Driver):
         aggregate = IotlabAggregate(self)
         slivers = aggregate.get_slivers(slice_urns)
         if slivers:
-            slice_id = slivers[0]['slice_id']
+            slice_id = slivers[0]['slice_id']
             node_ids = []
             sliver_ids = []
+            sliver_jobs_dict = {}
             for sliver in slivers:
                 node_ids.append(sliver['node_id'])
                 sliver_ids.append(sliver['sliver_id'])
+                job_id = sliver['sliver_id'].split('+')[-1].split('-')[0]
+                sliver_jobs_dict[job_id] = sliver['sliver_id']
         logger.debug("IOTLABDRIVER.PY delete_sliver slivers %s slice_urns %s"
             % (slivers, slice_urns))
         slice_hrn = urn_to_hrn(slice_urns[0])[0]
@@ -577,11 +471,20 @@ class IotlabDriver(Driver):
 
             logger.debug("IOTLABDRIVER.PY delete_sliver peer %s \
                 \r\n \t sfa_slice %s " % (peer, sfa_slice))
+            oar_bool_ans = self.testbed_shell.DeleteSliceFromNodes(
+                                                                    sfa_slice)
+            for job_id in oar_bool_ans:
+                # if the job has not been successfully deleted
+                # don't delete the associated sliver
+                # remove it from the sliver list
+                if oar_bool_ans[job_id] is False:
+                    sliver = sliver_jobs_dict[job_id]
+                    sliver_ids.remove(sliver)
             try:
-                self.testbed_shell.DeleteSliceFromNodes(sfa_slice)
+
                 dbsession = self.api.dbsession()
-                SliverAllocation.delete_allocations(sliver_ids,dbsession)
-            except:
+                SliverAllocation.delete_allocations(sliver_ids, dbsession)
+            except :
                 logger.log_exc("IOTLABDRIVER.PY delete error ")
 
         # prepare return struct
@@ -593,73 +496,73 @@ 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_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):
@@ -672,7 +575,7 @@ class IotlabDriver(Driver):
         :returns: slice urns list
         :rtype: list
 
-        .. note:: creds are unused
+        .. note:: creds and options are unused - SA 12/12/13
         """
         # look in cache first
         #if self.cache:
@@ -741,46 +644,49 @@ class IotlabDriver(Driver):
         :type hrn: string
 
         TODO: needs review
-        .. seealso:: update in driver.py.
-
-        """
-        pointer = old_sfa_record['pointer']
-        old_sfa_record_type = old_sfa_record['type']
-
-        # new_key implemented for users only
-        if new_key and old_sfa_record_type not in ['user']:
-            raise UnknownSfaType(old_sfa_record_type)
-
-        if old_sfa_record_type == "user":
-            update_fields = {}
-            all_fields = new_sfa_record
-            for key in all_fields.keys():
-                if key in ['key', 'password']:
-                    update_fields[key] = all_fields[key]
-
-            if new_key:
-                # must check this key against the previous one if it exists
-                persons = self.testbed_shell.GetPersons([old_sfa_record])
-                person = persons[0]
-                keys = [person['pkey']]
-                #Get all the person's keys
-                keys_dict = self.testbed_shell.GetKeys(keys)
-
-                # Delete all stale keys, meaning the user has only one key
-                #at a time
-                #TODO: do we really want to delete all the other keys?
-                #Is this a problem with the GID generation to have multiple
-                #keys? SA 30/05/13
-                key_exists = False
-                if key in keys_dict:
-                    key_exists = True
-                else:
-                    #remove all the other keys
-                    for key in keys_dict:
-                        self.testbed_shell.DeleteKey(person, key)
-                    self.testbed_shell.AddPersonKey(
-                        person, {'sshPublicKey': person['pkey']},
-                        {'sshPublicKey': new_key})
+        .. warning:: SA 12/12/13 - Removed. should be done in iotlabimporter
+            since users, keys and slice are managed by the LDAP.
+
+        """
+        # pointer = old_sfa_record['pointer']
+        # old_sfa_record_type = old_sfa_record['type']
+
+        # # new_key implemented for users only
+        # if new_key and old_sfa_record_type not in ['user']:
+        #     raise UnknownSfaType(old_sfa_record_type)
+
+        # if old_sfa_record_type == "user":
+        #     update_fields = {}
+        #     all_fields = new_sfa_record
+        #     for key in all_fields.keys():
+        #         if key in ['key', 'password']:
+        #             update_fields[key] = all_fields[key]
+
+        #     if new_key:
+        #         # must check this key against the previous one if it exists
+        #         persons = self.testbed_shell.GetPersons([old_sfa_record])
+        #         person = persons[0]
+        #         keys = [person['pkey']]
+        #         #Get all the person's keys
+        #         keys_dict = self.testbed_shell.GetKeys(keys)
+
+        #         # Delete all stale keys, meaning the user has only one key
+        #         #at a time
+        #         #TODO: do we really want to delete all the other keys?
+        #         #Is this a problem with the GID generation to have multiple
+        #         #keys? SA 30/05/13
+        #         key_exists = False
+        #         if key in keys_dict:
+        #             key_exists = True
+        #         else:
+        #             #remove all the other keys
+        #             for key in keys_dict:
+        #                 self.testbed_shell.DeleteKey(person, key)
+        #             self.testbed_shell.AddPersonKey(
+        #                 person, {'sshPublicKey': person['pkey']},
+        #                 {'sshPublicKey': new_key})
+        logger.warning ("UNDEFINED - Update should be done by the \
+            iotlabimporter")
         return True
 
     def remove(self, sfa_record):
@@ -822,13 +728,21 @@ class IotlabDriver(Driver):
             return True
 
     def check_sliver_credentials(self, creds, urns):
+        """Check that the sliver urns belongs to the slice specified in the
+        credentials.
+
+        :param urns: list of sliver urns.
+        :type urns: list.
+        :param creds: slice credentials.
+        :type creds: Credential object.
+
+
+        """
         # build list of cred object hrns
         slice_cred_names = []
         for cred in creds:
             slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn()
-            slicename = Xrn(xrn=slice_cred_hrn).iotlab_slicename()
-            logger.debug("IOTLABDRIVER.PY \t check_sliver_credentials slicename %s \r\n \r\n"
-                     % (slicename))
+            slicename = IotlabXrn(xrn=slice_cred_hrn).iotlab_slicename()
             slice_cred_names.append(slicename)
 
         # look up slice name of slivers listed in urns arg
@@ -842,12 +756,12 @@ class IotlabDriver(Driver):
                 pass
 
         if not slice_ids:
-             raise Forbidden("sliver urn not provided")
+            raise Forbidden("sliver urn not provided")
 
         slices = self.testbed_shell.GetSlices(slice_ids)
         sliver_names = [single_slice['name'] for single_slice in slices]
 
-        # make sure we have a credential for every specified sliver ierd
+        # make sure we have a credential for every specified sliver
         for sliver_name in sliver_names:
             if sliver_name not in slice_cred_names:
                 msg = "Valid credential not found for target: %s" % sliver_name
@@ -857,11 +771,28 @@ class IotlabDriver(Driver):
     ########## aggregate oriented
     ########################################
 
+    # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
+    def aggregate_version(self):
+        """
 
-    def testbed_name (self): return "iotlab"
+        Returns the testbed's supported rspec advertisement and request
+        versions.
+        :returns: rspec versions supported ad a dictionary.
+        :rtype: dict
 
-    def aggregate_version (self):
-        return {}
+        """
+        version_manager = VersionManager()
+        ad_rspec_versions = []
+        request_rspec_versions = []
+        for rspec_version in version_manager.versions:
+            if rspec_version.content_type in ['*', 'ad']:
+                ad_rspec_versions.append(rspec_version.to_dict())
+            if rspec_version.content_type in ['*', 'request']:
+                request_rspec_versions.append(rspec_version.to_dict())
+        return {
+            'testbed': self.testbed_name(),
+            'geni_request_rspec_versions': request_rspec_versions,
+            'geni_ad_rspec_versions': ad_rspec_versions}
 
     # first 2 args are None in case of resource discovery
     def list_resources (self, version=None, options={}):
@@ -896,8 +827,7 @@ class IotlabDriver(Driver):
         sfa_users = options.get('sfa_users', [])
         if sfa_users:
             slice_record = sfa_users[0].get('slice_record', [])
-        logger.debug("IOTLABDRIVER.PY \t ===============allocate \t\
-                            \r\n \r\n options %s slice_record %s" % (options,slice_record))
+
         # parse rspec
         rspec = RSpec(rspec_string)
         # requested_attributes = rspec.version.get_slice_attributes()
@@ -914,9 +844,11 @@ class IotlabDriver(Driver):
         # oui c'est degueulasse, le slice_record se retrouve modifie
         # dans la methode avec les infos du user, els infos sont propagees
         # dans verify_slice_leases
-        persons = slices.verify_persons(xrn.hrn, slice_record, users, options=options)
+        persons = slices.verify_persons(xrn.hrn, slice_record, users,
+                                        options=options)
         # ensure slice attributes exists
-        # slices.verify_slice_attributes(slice, requested_attributes, options=options)
+        # slices.verify_slice_attributes(slice, requested_attributes,
+                                    # options=options)
 
         # add/remove slice from nodes
         requested_xp_dict = self._process_requested_xp_dict(rspec)
@@ -937,8 +869,9 @@ class IotlabDriver(Driver):
         # add/remove leases
         rspec_requested_leases = rspec.version.get_leases()
         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))
+        logger.debug("IOTLABDRIVER.PY \tallocate leases  %s \
+                        rspec_requested_leases %s" % (leases,
+                        rspec_requested_leases))
          # update sliver allocations
         for hostname in nodes_list:
             client_id = hostname
@@ -955,15 +888,7 @@ class IotlabDriver(Driver):
                                       component_id=component_id,
                                       slice_urn = slice_urn,
                                       allocation_state='geni_allocated')
-
-            logger.debug("\r\n \
-                ===============================IOTLABDRIVER.PY \tallocate  sliver_id %s slice_urn %s \r\n"
-                     % (sliver_id,slice_urn))
             record.sync(self.api.dbsession())
-        # add/remove links links
-        # slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
-
-
 
         return aggregate.describe([xrn.get_urn()], version=rspec.version)
 
@@ -981,8 +906,10 @@ class IotlabDriver(Driver):
         # slices.handle_peer(None, None, persons, peer)
         # update sliver allocation states and set them to geni_provisioned
         sliver_ids = [sliver['sliver_id'] for sliver in slivers]
-        dbsession =self.api.dbsession()
-        SliverAllocation.set_allocations(sliver_ids, 'geni_provisioned',dbsession)
+        dbsession = self.api.dbsession()
+        SliverAllocation.set_allocations(sliver_ids, 'geni_provisioned',
+                                                                dbsession)
         version_manager = VersionManager()
-        rspec_version = version_manager.get_version(options['geni_rspec_version'])
+        rspec_version = version_manager.get_version(options[
+                                                        'geni_rspec_version'])
         return self.describe(urns, rspec_version, options=options)
index e546943..650c458 100644 (file)
@@ -2,6 +2,8 @@
 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
@@ -235,9 +237,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
@@ -245,7 +248,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"
@@ -266,33 +270,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.
@@ -317,7 +294,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):
@@ -531,15 +507,15 @@ class IotlabShell():
         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.
+        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 = \
-        self.api.dbsession().query(RegUser).filter_by(email = user_dict['email']).first()
+        query = self.api.dbsession().query(RegUser)
+        check_if_exists = query.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 \
@@ -837,22 +813,23 @@ class IotlabShell():
 
 
             logger.debug("IOTLAB_API \r\n \r\n \t AddLeases TURN ON LOGGING SQL \
-                            %s %s %s "%(slice_record['hrn'], job_id, end_time))
+                        %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)
+            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))
+            logger.debug("IOTLAB_API \t AddLeases hostname_list start_time %s "
+                        %(start_time))
 
         return job_id
 
@@ -883,8 +860,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
 
@@ -909,8 +886,8 @@ class IotlabShell():
                 reservation['slice_hrn'] != filter_value:
                 filtered_reservation_list.remove(reservation)
 
-        logger.debug("IOTLAB_API \t filter_lease_name filtered_reservation_list %s" \
-                        % (filtered_reservation_list))
+        logger.debug("IOTLAB_API \t filter_lease_name filtered_reservation_list\
+                     %s" % (filtered_reservation_list))
         return filtered_reservation_list
 
     @staticmethod
@@ -954,7 +931,6 @@ class IotlabShell():
         #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])
@@ -1155,6 +1131,7 @@ class IotlabShell():
         :rtype: Boolean
 
         """
+
         all_user_keys = user_record['keys']
         all_user_keys.remove(key_string)
         new_attributes = {'sshPublicKey':all_user_keys}
index 3823224..6236bab 100644 (file)
@@ -20,7 +20,7 @@ from sfa.iotlab.OARrestapi import OARrestapi
 from sfa.iotlab.iotlabdriver import IotlabDriver
 from sfa.util.config import Config
 
-
+from sfa.generic import Generic
 import os
 import sys
 
@@ -75,7 +75,7 @@ def TestLdap(job_id = None):
     print "\r\n TEST ldap_server.LdapSearch ids = avakian", ret
 
 
-    password = ldap_server.generate_password()
+    password = ldap_server.login_pwd.generate_password()
     print "\r\n TEST generate_password ", password
 
     maxi = ldap_server.find_max_uidNumber()
@@ -94,7 +94,7 @@ def TestLdap(job_id = None):
     record['mail'] = "robin@arkham.fr"
 
 
-    login = ldap_server.generate_login(data)
+    login = ldap_server.LdapGenerateUniqueLogin(data)
     print "\r\n Robin \tgenerate_login  ", ret, login
 
     ret = ldap_server.LdapAddUser(data)
@@ -105,7 +105,7 @@ def TestLdap(job_id = None):
     print "\r\n Robin \tldap_server.LdapSearch ids = %s %s" % (login, ret)
 
     password = "Thridrobin"
-    enc = ldap_server.encrypt_password(password)
+    enc = ldap_server.login_pwd.encrypt_password(password)
     print "\r\n Robin \tencrypt_password ", enc
 
     ret = ldap_server.LdapModifyUser(record, {'userPassword':enc})
@@ -134,8 +134,8 @@ def TestLdap(job_id = None):
     #ret = ldap_server.LdapSearch('(uid=grayson)', [])
     #print "\r\n Nightwing \tldap_server.LdapSearch ids = %s %s" %('grayson',ret )
 
-    #ret = ldap_server.LdapAddUser(datanight)
-    #print "\r\n Nightwing \tLdapAddUser ", ret
+    ret = ldap_server.LdapAddUser(datanight)
+    print "\r\n Nightwing \tLdapAddUser ", ret
 
     #ret = ldap_server.LdapResetPassword(record_night)
     #print "\r\n Nightwing  \tLdapResetPassword de %s : %s" % (record_night, ret)
@@ -228,7 +228,7 @@ def TestOAR(job_id = None):
 
     uri = '/oarapi/jobs/' + job_id + '/resources.json'
     raw_json = get_stuff(oar, uri)
-    print "\r\n OAR  ", uri, raw_json, "\r\n KKK \t", raw_json.keys()
+    print "\r\n OAR  ", uri, raw_json, "\r\n resources.json \t", raw_json.keys()
 
     time_format = "%Y-%m-%d %H:%M:%S"
 
@@ -248,7 +248,8 @@ def TestOAR(job_id = None):
 
 
 def TestImporter(arg=None):
-    iotlabdriver = IotlabDriver(Config())
+    api = Generic.the_flavour().make_api(interface='registry')
+    iotlabdriver = IotlabDriver(api)
 
     nodes_listdict = iotlabdriver.testbed_shell.GetNodes()
     sites_listdict = iotlabdriver.testbed_shell.GetSites()
@@ -263,19 +264,21 @@ def TestIotlabDriver(job_id = None):
 
     if isinstance(job_id, list) and len(job_id) == 1:
         job_id = job_id[0]
-    iotlabdriver = IotlabDriver(Config())
 
+    api = Generic.the_flavour().make_api(interface='registry')
+    iotlabdriver = IotlabDriver(api)
     #nodes = iotlabdriver.testbed_shell.GetReservedNodes()
     #print " \r\n \r\n GetReservedNodes", nodes
 
-    sl = iotlabdriver.testbed_shell.GetSlices(slice_filter='iotlab.avakian_slice', slice_filter_type='slice_hrn')
+    sl = iotlabdriver.testbed_shell.GetSlices(
+            slice_filter='iotlab.avakian_slice', slice_filter_type='slice_hrn')
     print "\r\n \r\nGetSlices", sl[0]
 
     #sl = iotlabdriver.testbed_shell.GetSlices(slice_filter='20', slice_filter_type='record_id_user')
     #print "\r\n \r\nGetSlices", sl
 
-    #sl = iotlabdriver.testbed_shell.GetSlices()
-    #print "\r\n \r\nGetSlices", sl
+    sl = iotlabdriver.testbed_shell.GetSlices()
+    print "\r\n \r\nGetSlices", sl
 
     persons = iotlabdriver.testbed_shell.GetPersons()
     print "\r\n \r\n  GetPersons", persons
@@ -284,11 +287,11 @@ def TestIotlabDriver(job_id = None):
     print "\r\n \r\n  GetLeases", leases
 
     leases = iotlabdriver.testbed_shell.GetLeases(lease_filter_dict={'slice_hrn':'iotlab.avakian_slice'})
-    print "\r\n \r\n  GetLeases", leases
+    print "\r\n \r\n  GetLeases slice_hrn iotlab.avakian_slice ", leases
 
 
     leases = iotlabdriver.testbed_shell.GetLeases(lease_filter_dict={'t_from':1405070000})
-    print "\r\n \r\n  GetLeases", leases
+    print "\r\n \r\n  GetLeases t_from 1405070000", leases
 def  TestSfi(filename = None):
 
     if filename is None:
@@ -343,7 +346,7 @@ def  TestSfi(filename = None):
 
 def TestSQL(arg = None):
     from sfa.storage.model import make_record, RegSlice, RegRecord
-    from sfa.storage.alchemy import dbsession
+    from sfa.storage.alchemy import global_dbsession
     from sqlalchemy.orm.collections import InstrumentedList
 
     from sqlalchemy.orm import joinedload
@@ -377,13 +380,16 @@ def TestSQL(arg = None):
         #used  to know if a given record is already known to SFA
 
     records_by_type_hrn = \
-            dict ( [ ( (record.type,record.hrn) , record ) for record in all_records ] )
+            dict ( [ ( (record.type,record.hrn) , record ) for
+                                        record in all_records ] )
     for (rec_type, rec) in records_by_type_hrn :
         if rec_type == 'user':
-            print >>sys.stderr,"\r\n IOTLABIMPORT \t keys %s rec %s \r\n" %(rec_type, rec )
+            print >>sys.stderr,"\r\n IOTLABIMPORT \t keys %s rec \
+                %s \r\n" %(rec_type, rec )
 
     users_rec_by_email = \
-            dict ( [ (record.email, record) for record in all_records if record.type == 'user' ] )
+            dict ( [ (record.email, record) for record
+                        in all_records if record.type == 'user' ] )
 
 
 def RunAll( arg ):
index 0bff16c..2dc59a6 100755 (executable)
@@ -30,39 +30,90 @@ rspec_filename_list = ['firexp_avakian_slice_iotlab.rspec',
 'test_delete_all_leases.rspec']
 
 rspec_filename_dict = {
-       ('iotlab_avakian', 'iotlab'):
-               "sfi.py create iotlab.avakian_slice " + rspec_dir + \
+       ('iotlab_avakian', 'iotlab', 'allocate' ):
+               "sfi.py allocate iotlab.avakian_slice " + rspec_dir + \
                        'iotlab_avakian_slice_iotlab.rspec',
 
-       ('iotlab_avakian', 'iotlab2'):
-               "sfi.py create iotlab.avakian_slice " + rspec_dir + \
+       ('iotlab_avakian', 'iotlab2', 'allocate'):
+               "sfi.py allocate iotlab.avakian_slice " + rspec_dir + \
                'iotlab_avakian_slice_iotlab2.rspec',
 
-       ('firexp_user','iotlab'):
-               "sfi.py create firexp.flab.iotlab_slice " + rspec_dir + \
+       ('firexp_user','iotlab', 'allocate'):
+               "sfi.py allocate firexp.flab.iotlab_slice " + rspec_dir + \
                        'firexp_iotlab_slice_iotlab.rspec',
 
-       ('firexp_user', 'all'):
-                       "sfi.py create firexp.flab.iotlab_slice "+ rspec_dir + \
+       ('firexp_user', 'all', 'allocate'):
+                       "sfi.py allocate firexp.flab.iotlab_slice "+ rspec_dir + \
                                'firexp_iotlab_slice_all.rspec',
 
-       ('iotlab_user', 'iotlab'):
-               "sfi.py create iotlab.user_slice "+ rspec_dir + \
+       ('iotlab_user', 'iotlab', 'allocate'):
+               "sfi.py allocate iotlab.user_slice "+ rspec_dir + \
                        'iotlab_user_slice_iotlab.rspec',
 
-       ('firexp_avakian','iotlab'):
-               "sfi.py create firexp.flab.avakian_slice " + rspec_dir + \
+       ('firexp_avakian','iotlab', 'allocate'):
+               "sfi.py allocate firexp.flab.avakian_slice " + rspec_dir + \
                        'firexp_avakian_slice_iotlab.rspec',
 
-       ('iotlab_avakian', 'plab') :
-                       "sfi.py create iotlab.avakian_slice " + rspec_dir + \
+       ('iotlab_avakian', 'plab', 'allocate') :
+                       "sfi.py allocate iotlab.avakian_slice " + rspec_dir + \
                                'iotlab_avakian_slice_plab.rspec',
 
-       ('iotlab_avakian', 'all') :
-        "sfi.py create iotlab.avakian_slice " + rspec_dir + \
-               'iotlab_avakian_slice_all.rspec'
+       ('iotlab_avakian', 'all', 'allocate') :
+        "sfi.py allocate iotlab.avakian_slice " + rspec_dir + \
+               'iotlab_avakian_slice_all.rspec',
 
+    ('iotlab_avakian', 'iotlab', 'provision' ):
+        "sfi.py provision iotlab.avakian_slice \
+                            iotlab_avakian_slice_iotlab.rspec",
+
+    ('iotlab_avakian', 'iotlab2', 'provision'):
+        "sfi.py provision iotlab.avakian_slice \
+                            iotlab_avakian_slice_iotlab2.rspec",
+
+    ('firexp_user','iotlab', 'provision'):
+        "sfi.py provision firexp.flab.iotlab_slice firexp_iotlab_slice_iotlab.rspec",
+
+    ('firexp_user', 'all', 'provision'):
+            "sfi.py provision firexp.flab.iotlab_slice firexp_iotlab_slice_all.rspec",
+
+    ('iotlab_user', 'iotlab', 'provision'):
+        "sfi.py provision iotlab.user_slice iotlab_user_slice_iotlab.rspec",
+
+    ('firexp_avakian','iotlab', 'provision'):
+        "sfi.py provision firexp.flab.avakian_slice firexp_avakian_slice_iotlab.rspec",
+
+    ('iotlab_avakian', 'plab', 'provision') :
+            "sfi.py provision iotlab.avakian_slice iotlab_avakian_slice_plab.rspec",
+
+    ('iotlab_avakian', 'all', 'provision') :
+     "sfi.py provision iotlab.avakian_slice iotlab_avakian_slice_all.rspec",
+
+    ('iotlab_avakian', 'iotlab', 'describe' ):
+        "sfi.py describe iotlab.avakian_slice iotlab_avakian_slice_iotlab.rspec",
+
+    ('iotlab_avakian', 'iotlab2', 'describe'):
+        "sfi.py describe iotlab.avakian_slice iotlab_avakian_slice_iotlab2.rspec",
+
+    ('firexp_user','iotlab', 'describe'):
+        "sfi.py describe firexp.flab.iotlab_slice firexp_iotlab_slice_iotlab.rspec",
+
+    ('firexp_user', 'all', 'describe'):
+            "sfi.py describe firexp.flab.iotlab_slice firexp_iotlab_slice_all.rspec",
+
+    ('iotlab_user', 'iotlab', 'describe'):
+        "sfi.py describe iotlab.user_slice iotlab_user_slice_iotlab.rspec",
+
+    ('firexp_avakian','iotlab', 'describe'):
+        "sfi.py describe firexp.flab.avakian_slice firexp_avakian_slice_iotlab.rspec",
+
+    ('iotlab_avakian', 'plab', 'describe') :
+            "sfi.py describe iotlab.avakian_slice iotlab_avakian_slice_plab.rspec",
+
+    ('iotlab_avakian', 'all', 'describe') :
+     "sfi.py describe iotlab.avakian_slice iotlab_avakian_slice_all.rspec"
        }
+
+print rspec_filename_dict
 # check if the firexp user (uid user) is already in LDAP
 # in this is the case, delete it :
 ldap_server = LDAPapi()
@@ -131,16 +182,24 @@ os.system('sfi.py show iotlab.avakian')
 print " =================    SFI.PY SHOW NODE   ============="
 os.system('sfi.py show iotlab.m3-3.devgrenoble.iot-lab.info')
 
-print " =================    SFI.PY SLICES       ============="
-raw_input("Press Enter to continue...")
-os.system('sfi.py slices')
+
 
 print " =================    SFI.PY STATUS SLICE   ============="
 os.system('sfi.py status iotlab.avakian_slice')
 
-print " =================    SFI.PY CREATE SLICE  on iotlab only  ============="
+print " =================    SFI.PY ALLOCATE SLICE  on iotlab only  ============="
+raw_input("Press Enter to continue...")
+os.system( rspec_filename_dict[('iotlab_avakian','iotlab' , 'allocate')])
+
+
+print " =================    SFI.PY PROVISION SLICE  on iotlab only  ============="
 raw_input("Press Enter to continue...")
-os.system( rspec_filename_dict[('iotlab_avakian','iotlab')])
+os.system( rspec_filename_dict[('iotlab_avakian','iotlab' , 'provision')])
+
+
+print " =================    SFI.PY DESCRIBE SLICE  on iotlab only  ============="
+raw_input("Press Enter to continue...")
+os.system( rspec_filename_dict[('iotlab_avakian','iotlab' , 'describe')])
 
 
 print " ================= SFI.PY RESOURCES -l all iotlab.avakian_slice ============="
@@ -153,9 +212,9 @@ raw_input("Press Enter to continue...")
 os.system('sfi.py delete iotlab.avakian_slice')
 
 
-print " =================    SFI.PY CREATE SLICE  on iotlab and firexp  ============="
+print " =================    SFI.PY ALLOCATE SLICE  on iotlab and firexp  ============="
 raw_input("Press Enter to continue...")
-os.system(rspec_filename_dict[('iotlab_avakian','all')])
+os.system(rspec_filename_dict[('iotlab_avakian','all', 'allocate')])
 
 
 print " ================= SFI.PY RESOURCES -l all -r iotlab iotlab.avakian_slice ============="
@@ -178,9 +237,17 @@ os.system('cp /root/.sfi/sfi_config_firexp /root/.sfi/sfi_config')
 
 
 
-print " =================    SFI.PY CREATE SLICE  on iotlab and firexp  ============="
+print " =================    SFI.PY ALLOCATE SLICE  on iotlab and firexp  ============="
+raw_input("Press Enter to continue...")
+os.system(rspec_filename_dict[('firexp_user','all', 'allocate')])
+
+print " =================    SFI.PY DESCRIBE SLICE  on iotlab and firexp  ============="
+raw_input("Press Enter to continue...")
+os.system(rspec_filename_dict[('firexp_user','all', 'describe')])
+
+print " =================    SFI.PY PROVISION SLICE  on iotlab and firexp  ============="
 raw_input("Press Enter to continue...")
-os.system(rspec_filename_dict[('firexp_user','all')])
+os.system(rspec_filename_dict[('firexp_user','all', 'provision')])
 
 
 print " =================    SFI.PY SHOW SLICE   ============="