Store client_id in sliver_allocation table
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Tue, 11 Dec 2012 18:39:40 +0000 (13:39 -0500)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Tue, 11 Dec 2012 18:39:40 +0000 (13:39 -0500)
sfa/planetlab/plaggregate.py
sfa/planetlab/pldriver.py
sfa/planetlab/plslices.py
sfa/storage/model.py

index 48f3eb1..ecaf7b8 100644 (file)
@@ -195,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)
@@ -209,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
@@ -387,7 +388,8 @@ 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)
+                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) 
index 43ee799..db9a2dd 100644 (file)
@@ -569,7 +569,7 @@ class PlDriver (Driver):
         rspec =  aggregate.list_resources(version=version, options=options)
         return rspec
 
-    def describe(self, urns, version, options={}, allocation_status=None):
+    def describe(self, urns, version, options={}):
         aggregate = PlAggregate(self)
         return aggregate.describe(urns, version=version, options=options)
     
@@ -603,26 +603,10 @@ class PlDriver (Driver):
         persons = slices.verify_persons(xrn.hrn, slice, users, peer, sfa_peer, options=options)
         # ensure slice attributes exists
         slices.verify_slice_attributes(slice, requested_attributes, options=options)
-        
+       
         # add/remove slice from nodes
-        requested_slivers = []
-        for node in rspec.version.get_nodes_with_slivers():
-            hostname = None
-            if node.get('component_name'):
-                hostname = node.get('component_name').strip()
-            elif node.get('component_id'):
-                hostname = xrn_to_hostname(node.get('component_id').strip())
-            if hostname:
-                requested_slivers.append(hostname)
-        nodes = slices.verify_slice_nodes(slice, requested_slivers, peer)
-
-        # update all sliver allocation states setting then to geni_allocated   
-        sliver_ids = []
-        for node in nodes:
-            sliver_hrn = '%s.%s-%s' % (self.hrn, slice['slice_id'], node['node_id'])
-            sliver_id = Xrn(sliver_hrn, type='sliver').urn
-            sliver_ids.append(sliver_id)
-        SliverAllocation.set_allocations(sliver_ids, 'geni_allocated')
+        request_nodes = rspec.version.get_nodes_with_slivers()
+        nodes = slices.verify_slice_nodes(slice, request_nodes, peer)
          
         # add/remove links links 
         slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
@@ -654,8 +638,9 @@ class PlDriver (Driver):
         slivers = aggregate.get_slivers(urns)
         sliver_ids = [sliver['sliver_id'] for sliver in slivers]
         SliverAllocation.set_allocations(sliver_ids, 'geni_provisioned')
-     
-        return self.describe(urns, None, options=options)
+        version_manager = VersionManager()
+        rspec_version = version_manager.get_version(options['geni_rspec_version']) 
+        return self.describe(urns, rspec_version, options=options)
 
     def delete(self, urns, options={}):
         # collect sliver ids so we can update sliver allocation states after
index 3cfc2f6..0ee4fda 100644 (file)
@@ -8,6 +8,8 @@ from sfa.rspecs.rspec import RSpec
 from sfa.planetlab.vlink import VLink
 from sfa.planetlab.topology import Topology
 from sfa.planetlab.plxrn import PlXrn, hrn_to_pl_slicename
+from sfa.storage.model import SliverAllocation
+from sfa.storage.alchemy import dbsession
 
 MAXINT =  2L**31-1
 
@@ -178,28 +180,48 @@ class PlSlices:
         return leases
 
 
-    def verify_slice_nodes(self, slice, requested_slivers, peer):
+    def verify_slice_nodes(self, slice, rspec_nodes, peer):
+        
+        slivers = {}
+        for node in rspec_nodes:
+            hostname = None
+            client_id = node.get('client_id')    
+            if node.get('component_name'):
+                hostname = node.get('component_name').strip()
+            elif node.get('component_id'):
+                hostname = xrn_to_hostname(node.get('component_id').strip())
+            if hostname:
+                slivers[hostname] = client_id
         
         nodes = self.driver.shell.GetNodes(slice['node_ids'], ['node_id', 'hostname', 'interface_ids'])
         current_slivers = [node['hostname'] for node in nodes]
 
         # remove nodes not in rspec
-        deleted_nodes = list(set(current_slivers).difference(requested_slivers))
+        deleted_nodes = list(set(current_slivers).difference(slivers.keys()))
 
         # add nodes from rspec
-        added_nodes = list(set(requested_slivers).difference(current_slivers))        
+        added_nodes = list(set(slivers.keys()).difference(current_slivers))        
 
         try:
             if peer:
                 self.driver.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer['shortname'])
             self.driver.shell.AddSliceToNodes(slice['name'], added_nodes)
             self.driver.shell.DeleteSliceFromNodes(slice['name'], deleted_nodes)
-
+            
         except: 
             logger.log_exc('Failed to add/remove slice from nodes')
 
         slices = self.driver.shell.GetSlices(slice['name'], ['node_ids']) 
         resulting_nodes = self.driver.shell.GetNodes(slices[0]['node_ids'])
+
+        # update sliver allocations
+        for node in resulting_nodes:
+            client_id = slivers[node['hostname']]
+            logger.info(client_id)
+            sliver_hrn = '%s.%s-%s' % (self.driver.hrn, slice['slice_id'], node['node_id'])
+            sliver_id = Xrn(sliver_hrn, type='sliver').urn
+            record = SliverAllocation(sliver_id=sliver_id, client_id=client_id, allocation_state='geni_allocated')      
+            record.sync()
         return resulting_nodes
 
     def free_egre_key(self):
index 5495800..43be3e7 100644 (file)
@@ -1,6 +1,7 @@
 from types import StringTypes
 from datetime import datetime
 
+from sqlalchemy import or_, and_ 
 from sqlalchemy import Column, Integer, String, DateTime
 from sqlalchemy import Table, Column, MetaData, join, ForeignKey
 from sqlalchemy.orm import relationship, backref
@@ -314,11 +315,14 @@ class RegKey (Base):
 class SliverAllocation(Base,AlchemyObj):
     __tablename__       = 'sliver_allocation'
     sliver_id           = Column(String, primary_key=True)
+    client_id           = Column(String)
     allocation_state    = Column(String)
 
     def __init__(self, **kwds):
         if 'sliver_id' in kwds:
             self.sliver_id = kwds['sliver_id']
+        if 'sliver_id' in kwds:
+            self.client_id = kwds['client_id']
         if 'allocation_state' in kwds:
             self.allocation_state = kwds['allocation_state']
 
@@ -365,6 +369,27 @@ class SliverAllocation(Base,AlchemyObj):
         for sliver_allocation in sliver_allocations:
             dbsession.delete(sliver_allocation)
         dbsession.commit()
+    
+    def sync(self):
+        from sfa.storage.alchemy import dbsession
+        
+        constraints = [SliverAllocation.sliver_id==self.sliver_id,
+                       SliverAllocation.client_id==self.client_id,
+                       SliverAllocation.allocation_state==self.allocation_state]
+        results = dbsession.query(SliverAllocation).filter(and_(*constraints))
+        records = []
+        for result in results:
+            records.append(result) 
+        
+        if not records:
+            dbsession.add(self)
+        else:
+            record = records[0]
+            record.sliver_id = self.sliver_id
+            record.client_id  = self.client_id
+            record.allocation_state = self.allocation_state
+        dbsession.commit()    
+        
 
 ##############################
 # although the db needs of course to be reachable for the following functions