add information in Iot-LAB rspec node
fsaintma [Fri, 22 May 2015 08:57:20 +0000 (10:57 +0200)]
sfa/iotlab/iotlabaggregate.py
sfa/iotlab/iotlabshell.py

index 9dbeccb..2b49615 100644 (file)
@@ -9,6 +9,9 @@ from sfa.rspecs.elements.hardware_type import HardwareType
 from sfa.rspecs.elements.lease import Lease
 from sfa.rspecs.elements.granularity import Granularity
 from sfa.rspecs.version_manager import VersionManager
+from sfa.rspecs.elements.services import ServicesElement
+from sfa.rspecs.elements.login import Login
+from sfa.rspecs.elements.sliver import Sliver
 from sfa.rspecs.elements.versions.iotlabv1Node import IotlabPosition
 from sfa.rspecs.elements.versions.iotlabv1Node import IotlabNode
 from sfa.rspecs.elements.versions.iotlabv1Node import IotlabLocation
@@ -16,6 +19,7 @@ from sfa.iotlab.iotlablease import LeaseTable
 import time
 import datetime
 
+
 class IotLABAggregate(object):
     """
     SFA aggregate for Iot-LAB testbed
@@ -24,7 +28,6 @@ class IotLABAggregate(object):
     def __init__(self, driver):
         self.driver = driver
 
-
     def leases_to_rspec_leases(self, leases):
         """ Get leases attributes list"""
         rspec_leases = []
@@ -33,17 +36,17 @@ class IotLABAggregate(object):
                 rspec_lease = Lease()
                 rspec_lease['lease_id'] = lease['id']
                 iotlab_xrn = Xrn('.'.join([self.driver.root_auth,
-                              Xrn.escape(node)]),
-                              type='node')
+                                 Xrn.escape(node)]),
+                                 type='node')
                 rspec_lease['component_id'] = iotlab_xrn.urn
                 rspec_lease['start_time'] = str(lease['date'])
-                duration = int(lease['duration'])/60 # duration in minutes
+                # duration in minutes
+                duration = int(lease['duration'])/60
                 rspec_lease['duration'] = duration
                 rspec_lease['slice_id'] = lease['slice_id']
                 rspec_leases.append(rspec_lease)
         return rspec_leases
 
-
     def node_to_rspec_node(self, node):
         """ Get node attributes """
         rspec_node = IotlabNode()
@@ -51,20 +54,25 @@ class IotLABAggregate(object):
         rspec_node['archi'] = node['archi']
         rspec_node['radio'] = (node['archi'].split(':'))[1]
         iotlab_xrn = Xrn('.'.join([self.driver.root_auth,
-                              Xrn.escape(node['network_address'])]),
-                              type='node')
-        rspec_node['boot_state'] = 'true'
+                         Xrn.escape(node['network_address'])]),
+                         type='node')
+        # rspec_node['boot_state'] = 'true'
+        if node['state'] == 'Absent' or \
+           node['state'] == 'Suspected' or \
+           node['state'] == 'Busy':
+            rspec_node['available'] = 'false'
+        else:
+            rspec_node['available'] = 'true'
         rspec_node['component_id'] = iotlab_xrn.urn
         rspec_node['component_name'] = node['network_address']
-        rspec_node['component_manager_id'] = \
-                        hrn_to_urn(self.driver.root_auth,
-                        'authority+sa')
+        rspec_node['component_manager_id'] = hrn_to_urn(self.driver.root_auth,
+                                                        'authority+sa')
         rspec_node['authority_id'] = rspec_node['component_manager_id']
         rspec_node['exclusive'] = 'true'
-        rspec_node['hardware_types'] = [HardwareType({'name': \
-                                        'iotlab-node'})]
-        location = IotlabLocation({'country':'France', 'site': \
-                                    node['site']})
+        rspec_node['hardware_types'] = \
+            [HardwareType({'name': node['archi']})]
+        location = IotlabLocation({'country': 'France',
+                                   'site': node['site']})
         rspec_node['location'] = location
         position = IotlabPosition()
         for field in position:
@@ -74,27 +82,38 @@ class IotLABAggregate(object):
         rspec_node['tags'] = []
         return rspec_node
 
-
     def sliver_to_rspec_node(self, sliver):
         """ Get node and sliver attributes """
         rspec_node = self.node_to_rspec_node(sliver)
         rspec_node['expires'] = datetime_to_string(utcparse(sliver['expires']))
         rspec_node['sliver_id'] = sliver['sliver_id']
+        rspec_sliver = Sliver({'sliver_id': sliver['sliver_id'],
+                               'name': sliver['name'],
+                               'type': sliver['archi'],
+                               'tags': []})
+        rspec_node['slivers'] = [rspec_sliver]
+        # slivers always provide the ssh service
+        login = Login({'authentication': 'ssh-keys',
+                       'hostname': sliver['hostname'],
+                       'port': '22',
+                       'username': sliver['name'],
+                       'login': sliver['name']
+                       })
+        service = ServicesElement({'login': login})
+        rspec_node['services'] = [service]
         return rspec_node
 
-
     @classmethod
     def rspec_node_to_geni_sliver(cls, rspec_node):
         """ Get sliver status """
         geni_sliver = {'geni_sliver_urn': rspec_node['sliver_id'],
                        'geni_expires': rspec_node['expires'],
-                       'geni_allocation_status' : 'geni_allocated',
+                       'geni_allocation_status': 'geni_allocated',
                        'geni_operational_status': 'geni_pending_allocation',
                        'geni_error': '',
                        }
         return geni_sliver
 
-
     def list_resources(self, version=None, options=None):
         """
         list_resources method sends a RSpec with all Iot-LAB testbed nodes
@@ -139,7 +158,7 @@ class IotLABAggregate(object):
 
         nodes = self.driver.shell.get_nodes()
         reserved_nodes = self.driver.shell.get_reserved_nodes()
-        if not 'error' in nodes and not 'error' in reserved_nodes:
+        if 'error' not in nodes and 'error' not in reserved_nodes:
             # convert nodes to rspec nodes
             rspec_nodes = []
             for node in nodes:
@@ -162,7 +181,7 @@ class IotLABAggregate(object):
                 # iotlab slice = job submission from Iot-LAB
                 else:
                     reserved_nodes[lease_id]['slice_id'] = \
-                        hrn_to_urn(self.driver.root_auth+'.'+
+                        hrn_to_urn(self.driver.root_auth + '.' +
                                    reserved_nodes[lease_id]['owner']+"_slice",
                                    'slice')
                 leases.append(reserved_nodes[lease_id])
@@ -173,7 +192,6 @@ class IotLABAggregate(object):
             rspec.version.add_leases(rspec_leases)
         return rspec.toxml()
 
-
     def get_slivers(self, urns, leases, nodes):
         """ Get slivers attributes list """
         logger.warning("iotlabaggregate get_slivers")
@@ -181,18 +199,23 @@ class IotLABAggregate(object):
         slivers = []
         for lease in leases:
             for node in lease['resources']:
+                network_address = node.split(".")
                 sliver_node = nodes[node]
                 sliver_hrn = '%s.%s-%s' % (self.driver.hrn,
-                             lease['id'], node.split(".")[0])
+                                           lease['id'],
+                                           network_address[0])
                 start_time = datetime.datetime.fromtimestamp(lease['date'])
                 duration = datetime.timedelta(seconds=int(lease['duration']))
                 sliver_node['expires'] = start_time + duration
                 sliver_node['sliver_id'] = Xrn(sliver_hrn,
                                                type='sliver').urn
+                # frontend SSH hostname
+                sliver_node['hostname'] = '.'.join(network_address[1:])
+                # user login
+                sliver_node['name'] = lease['owner']
                 slivers.append(sliver_node)
         return slivers
 
-
     def _delete_db_lease(self, job_id):
         """ Delete lease table row in SFA database """
         logger.warning("iotlabdriver _delete_db_lease lease job_id : %s"
@@ -201,15 +224,14 @@ class IotLABAggregate(object):
             LeaseTable.job_id == job_id).delete()
         self.driver.api.dbsession().commit()
 
-
     def describe(self, urns, version=None, options=None):
         """
         describe method returns slice slivers (allocated resources) and leases
         (OAR job submission). We search in lease table of SFA database all OAR
-        jobs id for this slice and match OAR jobs with state Waiting or Running.
-        If OAR job id doesn't exist the experiment is terminated and we delete
-        the database table entry. Otherwise we add slivers and leases in the
-        response
+        jobs id for this slice and match OAR jobs with state Waiting or
+        Running. If OAR job id doesn't exist the experiment is terminated and
+        we delete the database table entry. Otherwise we add slivers and leases
+        in the response
 
         :returns:
             geni_slivers : a list of allocated slivers with information about
@@ -258,7 +280,7 @@ class IotLABAggregate(object):
 
         nodes = self.driver.shell.get_nodes()
         reserved_nodes = self.driver.shell.get_reserved_nodes()
-        if not 'error' in nodes and not 'error' in reserved_nodes:
+        if 'error' not in nodes and 'error' not in reserved_nodes:
             # find OAR jobs id for one slice in SFA database
             db_leases = [(lease.job_id, lease.slice_hrn)
                          for lease in self.driver.api.dbsession()
@@ -268,7 +290,7 @@ class IotLABAggregate(object):
             leases = []
             for job_id, slice_hrn in db_leases:
                 # OAR job terminated, we delete entry in database
-                if not job_id in reserved_nodes:
+                if job_id not in reserved_nodes:
                     self._delete_db_lease(job_id)
                 else:
                     # onelab slice = job submission from OneLAB
@@ -304,4 +326,3 @@ class IotLABAggregate(object):
         return {'geni_urn': urns[0],
                 'geni_rspec': rspec.toxml(),
                 'geni_slivers': geni_slivers}
-
index 558593a..f1fb1db 100644 (file)
@@ -18,7 +18,6 @@ class IotLABShell(object):
         user, passwd = auth.get_user_credentials()
         self.api = rest.Api(user, passwd)
 
-
     def get_nodes(self):
         """
         Get all OAR nodes
@@ -48,12 +47,11 @@ class IotLABShell(object):
             nodes = experiment.info_experiment(self.api)
         except HTTPError as err:
             logger.warning("iotlashell get_nodes error %s" % err.reason)
-            return {'error' : err.reason}
+            return {'error': err.reason}
         for node in nodes['items']:
             nodes_dict[node['network_address']] = node
         return nodes_dict
 
-
     def get_users(self):
         """
         Get all LDAP users
@@ -84,12 +82,11 @@ class IotLABShell(object):
             users = self.api.method('admin/users')
         except HTTPError as err:
             logger.warning("iotlashell get_users error %s" % err.reason)
-            return {'error' : err.reason}
+            return {'error': err.reason}
         for user in users:
             users_dict[user['email']] = user
         return users_dict
 
-
     def reserve_nodes(self, login, exp_name,
                       nodes_list, start_time, duration):
         """
@@ -108,8 +105,7 @@ class IotLABShell(object):
                                    files=exp_file)
         except HTTPError as err:
             logger.warning("iotlashell reserve_nodes error %s" % err.reason)
-            return {'error' : err.reason}
-
+            return {'error': err.reason}
 
     def get_reserved_nodes(self):
         """
@@ -138,7 +134,7 @@ class IotLABShell(object):
         except HTTPError as err:
             logger.warning("iotlashell get_reserved_nodes error %s" %
                            err.reason)
-            return {'error' : err.reason}
+            return {'error': err.reason}
         for exp in experiments['items']:
             # BUG IN OAR REST API : job with reservation didn't return
             # resources attribute list
@@ -148,17 +144,17 @@ class IotLABShell(object):
             reserved_nodes_dict[exp['id']] = exp
         return reserved_nodes_dict
 
-
     def add_user(self, slice_user):
         """
         Add LDAP user
         """
         # pylint:disable=E1123
         logger.warning("iotlashell add_user")
-        user = {"type" : "SA", # single account creation
-                "city" : "To be defined",
-                "country" : "To be defined",
-                "motivations" : "SFA federation"}
+        # single account creation
+        user = {"type": "SA",
+                "city": "To be defined",
+                "country": "To be defined",
+                "motivations": "SFA federation"}
         email = slice_user['email']
         user['email'] = email
         user['sshPublicKey'] = slice_user['keys'][0]
@@ -172,7 +168,6 @@ class IotLABShell(object):
             user['lastName'] = email.split('.')[0]
         try:
             self.api.method('admin/users', 'post',
-                        json=user)
+                            json=user)
         except HTTPError as err:
             logger.warning("iotlashell add_user error %s" % err.reason)
-    
\ No newline at end of file