From: Tony Mack Date: Tue, 11 Dec 2012 18:39:40 +0000 (-0500) Subject: Store client_id in sliver_allocation table X-Git-Tag: sfa-3.0-0~53 X-Git-Url: http://git.onelab.eu/?p=sfa.git;a=commitdiff_plain;h=de06f1f7eb8480a7894ed6a1aa8665f032365892 Store client_id in sliver_allocation table --- diff --git a/sfa/planetlab/plaggregate.py b/sfa/planetlab/plaggregate.py index 48f3eb13..ecaf7b8f 100644 --- a/sfa/planetlab/plaggregate.py +++ b/sfa/planetlab/plaggregate.py @@ -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) diff --git a/sfa/planetlab/pldriver.py b/sfa/planetlab/pldriver.py index 43ee799b..db9a2ddf 100644 --- a/sfa/planetlab/pldriver.py +++ b/sfa/planetlab/pldriver.py @@ -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 diff --git a/sfa/planetlab/plslices.py b/sfa/planetlab/plslices.py index 3cfc2f65..0ee4fdad 100644 --- a/sfa/planetlab/plslices.py +++ b/sfa/planetlab/plslices.py @@ -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): diff --git a/sfa/storage/model.py b/sfa/storage/model.py index 5495800d..43be3e7a 100644 --- a/sfa/storage/model.py +++ b/sfa/storage/model.py @@ -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