Allocate, Describe, Provision now working for iotlab.
[sfa.git] / sfa / iotlab / iotlabdriver.py
index 6aea1ce..699e111 100644 (file)
@@ -4,18 +4,20 @@ Implements what a driver should provide for SFA to work.
 from sfa.util.faults import SliverDoesNotExist, UnknownSfaType
 from sfa.util.sfalogging import logger
 from sfa.storage.model import RegRecord
 from sfa.util.faults import SliverDoesNotExist, UnknownSfaType
 from sfa.util.sfalogging import logger
 from sfa.storage.model import RegRecord
+from sfa.util.sfatime import utcparse, datetime_to_string
 
 from sfa.managers.driver import Driver
 from sfa.rspecs.version_manager import VersionManager
 from sfa.rspecs.rspec import RSpec
 
 
 from sfa.managers.driver import Driver
 from sfa.rspecs.version_manager import VersionManager
 from sfa.rspecs.rspec import RSpec
 
-from sfa.util.xrn import Xrn, hrn_to_urn, get_authority
+from sfa.iotlab.iotlabxrn import 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.iotlab.iotlabaggregate import IotlabAggregate
 from sfa.iotlab.iotlabxrn import xrn_to_hostname
 from sfa.iotlab.iotlabslices import IotlabSlices
 
-
+from sfa.storage.model import SliverAllocation
 from sfa.iotlab.iotlabshell import IotlabShell
 
 
 from sfa.iotlab.iotlabshell import IotlabShell
 
 
@@ -41,7 +43,7 @@ class IotlabDriver(Driver):
         Driver.__init__(self, api)
         self.api = api
         config = api.config
         Driver.__init__(self, api)
         self.api = api
         config = api.config
-        self.testbed_shell = IotlabShell(config)
+        self.testbed_shell = IotlabShell(api)
         self.cache = None
 
     def augment_records_with_testbed_info(self, record_list):
         self.cache = None
 
     def augment_records_with_testbed_info(self, record_list):
@@ -525,17 +527,14 @@ class IotlabDriver(Driver):
                                    login=sfa_slice['login'],
                                    version=rspec.version)
 
                                    login=sfa_slice['login'],
                                    version=rspec.version)
 
-    def delete_sliver(self, slice_urn, slice_hrn, creds, 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.
 
         :param slice_urn: urn of the slice
         """
         Deletes the lease associated with the slice hrn and the credentials
             if the slice belongs to iotlab. Answer to DeleteSliver.
 
         :param slice_urn: urn of the slice
-        :param slice_hrn: name of the slice
-        :param creds: slice credenials
         :type slice_urn: string
         :type slice_urn: string
-        :type slice_hrn: string
-        :type creds: ? unused
+
 
         :returns: 1 if the slice to delete was not found on iotlab,
             True if the deletion was successful, False otherwise otherwise.
 
         :returns: 1 if the slice to delete was not found on iotlab,
             True if the deletion was successful, False otherwise otherwise.
@@ -546,6 +545,20 @@ class IotlabDriver(Driver):
         .. note:: creds are unused, and are not used either in the dummy driver
              delete_sliver .
         """
         .. note:: creds are unused, and are not used either in the dummy driver
              delete_sliver .
         """
+        # collect sliver ids so we can update sliver allocation states after
+        # we remove the slivers.
+        aggregate = IotlabAggregate(self)
+        slivers = aggregate.get_slivers(slice_urns)
+        if slivers:
+            slice_id = slivers[0]['slice_id']
+            node_ids = []
+            sliver_ids = []
+            for sliver in slivers:
+                node_ids.append(sliver['node_id'])
+                sliver_ids.append(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]
 
         sfa_slice_list = self.testbed_shell.GetSlices(
             slice_filter=slice_hrn,
 
         sfa_slice_list = self.testbed_shell.GetSlices(
             slice_filter=slice_hrn,
@@ -566,9 +579,19 @@ class IotlabDriver(Driver):
                 \r\n \t sfa_slice %s " % (peer, sfa_slice))
             try:
                 self.testbed_shell.DeleteSliceFromNodes(sfa_slice)
                 \r\n \t sfa_slice %s " % (peer, sfa_slice))
             try:
                 self.testbed_shell.DeleteSliceFromNodes(sfa_slice)
-                return True
+                dbsession = self.api.dbsession()
+                SliverAllocation.delete_allocations(sliver_ids,dbsession)
             except:
             except:
-                return False
+                logger.log_exc("IOTLABDRIVER.PY delete error ")
+
+        # prepare return struct
+        geni_slivers = []
+        for sliver in slivers:
+            geni_slivers.append(
+                {'geni_sliver_urn': sliver['sliver_id'],
+                 'geni_allocation_status': 'geni_unallocated',
+                 'geni_expires': datetime_to_string(utcparse(sliver['expires']))})
+        return geni_slivers
 
     def list_resources (self, slice_urn, slice_hrn, creds, options):
         """
 
     def list_resources (self, slice_urn, slice_hrn, creds, options):
         """
@@ -869,10 +892,12 @@ class IotlabDriver(Driver):
 
         slice_record = None
         users = options.get('geni_users', [])
 
         slice_record = None
         users = options.get('geni_users', [])
-        if users:
-            slice_record = users[0].get('slice_record', {})
-            logger.debug("IOTLABDRIVER.PY \t ===============allocatte \t\
-                            \r\n \r\n users %s" % (users))
+
+        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()
         # parse rspec
         rspec = RSpec(rspec_string)
         # requested_attributes = rspec.version.get_slice_attributes()
@@ -880,30 +905,65 @@ class IotlabDriver(Driver):
         # ensure site record exists
         # site = slices.verify_site(xrn.hrn, slice_record, peer, sfa_peer, options=options)
         # ensure slice record exists
         # ensure site record exists
         # site = slices.verify_site(xrn.hrn, slice_record, peer, sfa_peer, options=options)
         # ensure slice record exists
-        current_slice = slices.verify_slice(xrn.hrn, slice_record, peer, sfa_peer, expiration=expiration, options=options)
+
+        current_slice = slices.verify_slice(xrn.hrn, slice_record, sfa_peer)
+        logger.debug("IOTLABDRIVER.PY \t ===============allocate \t\
+                            \r\n \r\n  current_slice %s" % (current_slice))
         # ensure person records exists
         # ensure person records exists
-        persons = slices.verify_persons(xrn.hrn, slice, users, peer, sfa_peer, options=options)
+
+        # 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)
         # ensure slice attributes exists
         # slices.verify_slice_attributes(slice, requested_attributes, options=options)
 
         # add/remove slice from nodes
         requested_xp_dict = self._process_requested_xp_dict(rspec)
 
         # ensure slice attributes exists
         # slices.verify_slice_attributes(slice, requested_attributes, options=options)
 
         # add/remove slice from nodes
         requested_xp_dict = self._process_requested_xp_dict(rspec)
 
-        logger.debug("IOTLABDRIVER.PY \tcreate_sliver  requested_xp_dict %s "
+        logger.debug("IOTLABDRIVER.PY \tallocate  requested_xp_dict %s "
                      % (requested_xp_dict))
                      % (requested_xp_dict))
-        # request_nodes = rspec.version.get_nodes_with_slivers()
-        # nodes = slices.verify_slice_nodes(urn, slice, request_nodes, peer)
+        request_nodes = rspec.version.get_nodes_with_slivers()
+        nodes_list = []
+        for start_time in requested_xp_dict:
+            lease = requested_xp_dict[start_time]
+            for hostname in lease['hostname']:
+                nodes_list.append(hostname)
+
+        # nodes = slices.verify_slice_nodes(slice_record,request_nodes, peer)
+        logger.debug("IOTLABDRIVER.PY \tallocate  nodes_list %s slice_record %s"
+                     % (nodes_list, slice_record))
 
 
+        # 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))
+         # update sliver allocations
+        for hostname in nodes_list:
+            client_id = hostname
+            node_urn = xrn_object(self.testbed_shell.root_auth, hostname).urn
+            component_id = node_urn
+            slice_urn = current_slice['reg-urn']
+            for lease in leases:
+                if hostname in lease['reserved_nodes']:
+                    index = lease['reserved_nodes'].index(hostname)
+                    sliver_hrn = '%s.%s-%s' % (self.hrn, lease['lease_id'],
+                                   lease['resource_ids'][index] )
+            sliver_id = Xrn(sliver_hrn, type='sliver').urn
+            record = SliverAllocation(sliver_id=sliver_id, client_id=client_id,
+                                      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)
 
         # add/remove links links
         # slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
 
-        # add/remove leases
-        # rspec_requested_leases = rspec.version.get_leases()
-        leases = slices.verify_slice_leases(current_slice, requested_xp_dict, peer)
 
 
-        # handle MyPLC peer association.
-        # only used by plc and ple.
-        slices.handle_peer(site, slice, None, peer)
 
         return aggregate.describe([xrn.get_urn()], version=rspec.version)
 
 
         return aggregate.describe([xrn.get_urn()], version=rspec.version)
 
@@ -916,12 +976,12 @@ class IotlabDriver(Driver):
         peer = slices.get_peer(current_slice['hrn'])
         sfa_peer = slices.get_sfa_peer(current_slice['hrn'])
         users = options.get('geni_users', [])
         peer = slices.get_peer(current_slice['hrn'])
         sfa_peer = slices.get_sfa_peer(current_slice['hrn'])
         users = options.get('geni_users', [])
-        persons = slices.verify_persons(current_slice['hrn'],
-            current_slice, users, peer, sfa_peer, options=options)
-        slices.handle_peer(None, None, persons, peer)
+        persons = slices.verify_persons(current_slice['hrn'],
+            current_slice, users, peer, sfa_peer, options=options)
+        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]
         # update sliver allocation states and set them to geni_provisioned
         sliver_ids = [sliver['sliver_id'] for sliver in slivers]
-        dbsession=self.api.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'])
         SliverAllocation.set_allocations(sliver_ids, 'geni_provisioned',dbsession)
         version_manager = VersionManager()
         rspec_version = version_manager.get_version(options['geni_rspec_version'])