Store client_id in sliver_allocation table
[sfa.git] / sfa / planetlab / plaggregate.py
index 5bf0950..ecaf7b8 100644 (file)
@@ -3,7 +3,7 @@ from collections import defaultdict
 from sfa.util.xrn import Xrn, hrn_to_urn, urn_to_hrn
 from sfa.util.sfatime import utcparse, datetime_to_string
 from sfa.util.sfalogging import logger
-
+from sfa.util.faults import SliverDoesNotExist
 from sfa.rspecs.rspec import RSpec
 from sfa.rspecs.elements.hardware_type import HardwareType
 from sfa.rspecs.elements.node import Node
@@ -21,6 +21,9 @@ from sfa.rspecs.version_manager import VersionManager
 from sfa.planetlab.plxrn import PlXrn, hostname_to_urn, hrn_to_pl_slicename, slicename_to_hrn
 from sfa.planetlab.vlink import get_tc_rate
 from sfa.planetlab.topology import Topology
+from sfa.storage.alchemy import dbsession
+from sfa.storage.model import SliverAllocation
+
 
 import time
 
@@ -109,7 +112,7 @@ class PlAggregate:
             pl_initscripts[initscript['initscript_id']] = initscript
         return pl_initscripts
 
-    def get_slivers(self, urns, options):
+    def get_slivers(self, urns, options={}):
         names = set()
         slice_ids = set()
         node_ids = []
@@ -129,8 +132,10 @@ class PlAggregate:
         if names:
             filter['name'] = list(names)
         if slice_ids:
-            filter['slice_id'] = list(slice_ids) 
+            filter['slice_id'] = list(slice_ids)
         slices = self.driver.shell.GetSlices(filter)
+        if not slices:
+            return []
         slice = slices[0]
         if node_ids:
             slice['node_ids'] = node_ids
@@ -141,7 +146,8 @@ class PlAggregate:
             node.update(slices[0]) 
             node['tags'] = tags_dict[node['node_id']]
             sliver_hrn = '%s.%s-%s' % (self.driver.hrn, slice['slice_id'], node['node_id'])
-            node['urn'] = PlXrn(xrn=sliver_hrn, type='sliver').get_urn() 
+            node['sliver_id'] = Xrn(sliver_hrn, type='sliver').urn
+            node['urn'] = node['sliver_id'] 
             slivers.append(node)
         return slivers
 
@@ -155,6 +161,10 @@ class PlAggregate:
         rspec_node['authority_id'] = hrn_to_urn(PlXrn.site_hrn(self.driver.hrn, site['login_base']), 'authority+sa')
         # do not include boot state (<available> element) in the manifest rspec
         rspec_node['boot_state'] = node['boot_state']
+        if node['boot_state'] == 'boot': 
+            rspec_node['available'] = 'true'
+        else:
+            rspec_node['available'] = 'false'
         rspec_node['exclusive'] = 'false'
         rspec_node['hardware_types'] = [HardwareType({'name': 'plab-pc'}),
                                         HardwareType({'name': 'pc'})]
@@ -185,7 +195,8 @@ class PlAggregate:
         rspec_node['tags'] = tags
         return rspec_node
 
-    def sliver_to_rspec_node(self, sliver, sites, interfaces, node_tags, pl_initscripts):
+    def sliver_to_rspec_node(self, sliver, sites, interfaces, node_tags, \
+                             pl_initscripts, sliver_allocations):
         # get the granularity in second for the reservation system
         grain = self.driver.shell.GetLeaseGranularity()
         rspec_node = self.node_to_rspec_node(sliver, sites, interfaces, node_tags, pl_initscripts, grain)
@@ -199,7 +210,7 @@ class PlAggregate:
                          'type': 'plab-vserver',
                          'tags': []})
         rspec_node['sliver_id'] = rspec_sliver['sliver_id']
-        rspec_node['client_id'] = sliver['hostname']
+        rspec_node['client_id'] = sliver_allocations[sliver['urn']].client_id
         rspec_node['slivers'] = [rspec_sliver]
 
         # slivers always provide the ssh service
@@ -236,18 +247,27 @@ class PlAggregate:
             nodes_dict[node['node_id']] = node
         return nodes_dict
 
-    def rspec_node_to_geni_sliver(self, rspec_node):
-        op_status = "geni_unknown"
-        state = rspec_node['boot_state'].lower()
-        if state == 'boot':
-            op_status = 'geni_ready'
-        else:
-            op_status =' geni_failed'
-
+    def rspec_node_to_geni_sliver(self, rspec_node, sliver_allocations = {}):
+        if rspec_node['sliver_id'] in sliver_allocations:
+            # set sliver allocation and operational status
+            sliver_allocation = sliver_allocations[rspec_node['sliver_id']]
+            if sliver_allocation:
+                allocation_status = sliver_allocation.allocation_state
+                if allocation_status == 'geni_allocated':
+                    op_status =  'geni_pending_allocation'
+                elif allocation_status == 'geni_provisioned':
+                    if rspec_node['boot_state'] == 'boot':
+                        op_status = 'geni_ready'
+                    else:
+                        op_status = 'geni_failed'
+                else:
+                    op_status = 'geni_unknown'
+            else:
+                allocation_status = 'geni_unallocated'    
         # required fields
         geni_sliver = {'geni_sliver_urn': rspec_node['sliver_id'],
                        'geni_expires': rspec_node['expires'],
-                       'geni_allocation_status': 'geni_provisioned',
+                       'geni_allocation_status' : allocation_status,
                        'geni_operational_status': op_status,
                        'geni_error': None,
                        }
@@ -330,14 +350,24 @@ class PlAggregate:
         version_manager = VersionManager()
         version = version_manager.get_version(version)
         rspec_version = version_manager._get_version(version.type, version.version, 'manifest')
-        rspec = RSpec(version=version, user_options=options)
+        rspec = RSpec(version=rspec_version, user_options=options)
 
         # get slivers
         geni_slivers = []
-        slivers = self.get_slivers(urns, options) 
-        if len(slivers) == 0:
-            raise SliverDoesNotExist("You have not allocated any slivers here")
-        rspec.xml.set('expires',  datetime_to_string(utcparse(slivers[0]['expires'])))
+        slivers = self.get_slivers(urns, options)
+        if slivers:
+            rspec_expires = datetime_to_string(utcparse(slivers[0]['expires']))
+        else:
+            rspec_expires = datetime_to_string(utcparse(time.time()))      
+        rspec.xml.set('expires',  rspec_expires)
+
+        # lookup the sliver allocations
+        sliver_ids = [sliver['sliver_id'] for sliver in slivers]
+        constraint = SliverAllocation.sliver_id.in_(sliver_ids)
+        sliver_allocations = dbsession.query(SliverAllocation).filter(constraint)
+        sliver_allocation_dict = {}
+        for sliver_allocation in sliver_allocations:
+            sliver_allocation_dict[sliver_allocation.sliver_id] = sliver_allocation
       
         if not options.get('list_leases') or options['list_leases'] != 'leases':
             # add slivers
@@ -358,9 +388,12 @@ class PlAggregate:
             for sliver in slivers:
                 if sliver['slice_ids_whitelist'] and sliver['slice_id'] not in sliver['slice_ids_whitelist']:
                     continue
-                rspec_node = self.sliver_to_rspec_node(sliver, sites, interfaces, node_tags, pl_initscripts)
-                geni_sliver = self.rspec_node_to_geni_sliver(rspec_node)
+                rspec_node = self.sliver_to_rspec_node(sliver, sites, interfaces, node_tags, 
+                                                       pl_initscripts, sliver_allocation_dict)
+                # manifest node element shouldn't contain available attribute
+                rspec_node.pop('available')
                 rspec_nodes.append(rspec_node) 
+                geni_sliver = self.rspec_node_to_geni_sliver(rspec_node, sliver_allocation_dict)
                 geni_slivers.append(geni_sliver)
             rspec.version.add_nodes(rspec_nodes)
 
@@ -376,8 +409,9 @@ class PlAggregate:
             rspec.version.add_links(links)
 
         if not options.get('list_leases') or options['list_leases'] != 'resources':
-            leases = self.get_leases(slivers[0])
-            rspec.version.add_leases(leases)
+            if slivers:
+                leases = self.get_leases(slivers[0])
+                rspec.version.add_leases(leases)
 
                
         return {'geni_urn': urns[0],