From 952c83c9dc4cef2e7c746281247883ac9d4685f3 Mon Sep 17 00:00:00 2001 From: Tony Mack Date: Tue, 12 Mar 2013 14:24:08 -0400 Subject: [PATCH] keep track of slice instances --- PLC/Methods/AddSliceToNodes.py | 1 - PLC/Nodes.py | 7 +++++-- PLC/Slices.py | 35 +++++++++++++++++++++++++++------- PLC/Storage/AlchemyObject.py | 8 ++++---- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/PLC/Methods/AddSliceToNodes.py b/PLC/Methods/AddSliceToNodes.py index 903681e4..72ffbedb 100644 --- a/PLC/Methods/AddSliceToNodes.py +++ b/PLC/Methods/AddSliceToNodes.py @@ -50,7 +50,6 @@ class AddSliceToNodes(Method): # Get specified nodes, add them to the slice nodes = Nodes(self.api, node_id_or_hostname_list, ['node_id', 'hostname', 'slice_ids', 'slice_ids_whitelist', 'site_id']) - slice.spawn_instances(nodes) for node in nodes: # check the slice whitelist on each node first diff --git a/PLC/Nodes.py b/PLC/Nodes.py index 6886b78d..f478054b 100644 --- a/PLC/Nodes.py +++ b/PLC/Nodes.py @@ -97,7 +97,7 @@ class Node(AlchemyObj): def validate_node_type(self, node_type): # Make sure node type does not alredy exist - conflicts = NodeTypes(self.api, [name]) + conflicts = NodeTypes(self.api, [node_type]) if not conflicts: raise PLCInvalidArgument, "Invalid node_type" return node_type @@ -314,7 +314,10 @@ class Nodes(list): # Separate the list into integers and strings ints = filter(lambda x: isinstance(x, (int, long)), node_filter) strs = filter(lambda x: isinstance(x, StringTypes), node_filter) - nodes = Node().select(filter={'node_id': ints, 'hostname': strs}) + node_filter = {} + if ints: node_filter['node_id'] = ints + if strs: node_filter['hostname'] = strs + nodes = Node().select(filter=node_filter) elif isinstance(node_filter, dict): nodes = Node().select(filter=node_filter) elif isinstance (node_filter, StringTypes): diff --git a/PLC/Slices.py b/PLC/Slices.py index 21a8ccf9..e5f1823b 100644 --- a/PLC/Slices.py +++ b/PLC/Slices.py @@ -12,6 +12,7 @@ from PLC.Nodes import Node from PLC.Persons import Person, Persons from PLC.SlicePersons import SlicePerson, SlicePersons from PLC.SliceNodes import SliceNode, SliceNodes +from PLC.SliceInstances import SliceInstance, SliceInstances from PLC.SliceTags import SliceTag, SliceTags from PLC.Timestamp import Timestamp from PLC.Storage.AlchemyObject import AlchemyObj @@ -39,6 +40,7 @@ class Slice(AlchemyObj): 'created': Parameter(datetime, "Date and time when slice was created, in seconds since UNIX epoch", ro = True), 'expires': Parameter(datetime, "Date and time when slice expires, in seconds since UNIX epoch"), 'node_ids': Parameter([str], "List of nodes in this slice", joined = True), + 'instance_ids': Parameter([str], "List of instances running under this slice", joined = True), 'person_ids': Parameter([str], "List of accounts that can use this slice", joined = True), 'slice_tag_ids': Parameter([int], "List of slice attributes", joined = True), 'peer_id': Parameter(int, "Peer to which this slice belongs", nullok = True), @@ -187,13 +189,17 @@ class Slice(AlchemyObj): raise PLCInvalidArgument('Image bot found') image_id = images[0]['id'] hints = {'force_hosts': node['hostname']} - self.api.client_shell.nova.servers.create(name=self['name'], + server = self.api.client_shell.nova.servers.create( + name=self['name'], flavor=flavor_id, image=image_id, key_name = key_name, security_group = security_group, files=files, - scheduler_hints=hints) + scheduler_hints=hints) + slice_instance = SliceInstance(self.api, {'slice_id': self['slice_id'], + 'instance_id': server.id}) + slice_instance.sync() def destroy_instances(self, nodes): hostnames = [n['hostname'] for n in nodes] @@ -202,8 +208,10 @@ class Slice(AlchemyObj): name = server.name hostname = server._info['OS-EXT-SRV-ATTR:host'] if self['name'] == name and hostname in hostnames: + instance_id = server.id self.api.client_shell.nova.servers.delete(server) - + AlchemyObj.delete(SliceInstance, filter={'slice_id': self['slice_id'], + 'instance_id': instance_id}) def remove_node(self, node_filter, commit=True): @@ -262,6 +270,8 @@ class Slice(AlchemyObj): slice_person.delete() for slice_node in SliceNode().select(filter={'slice_id': self['slice_id']}): slice_node.delete() + for slice_instance in SliceInstance().select(filter={'slice_id': self['slice_id']}): + slice_instance.delete() for slice_tag in SliceTag().select(filter={'slice_id': self['slice_id']}): slice_tag.delete() @@ -293,11 +303,22 @@ class Slices(list): slice = Slice(api, object=slice) if not columns or 'person_ids' in columns: slice_persons = SlicePerson().select(filter={'slice_id': slice['slice_id']}) - slice['person_ids'] = [rec.person_id for rec in slice_persons] - + slice['person_ids'] = [rec.person_id for rec in slice_persons] + + # we need to get the instance ids if node_ids is specified + if not columns or 'instance_ids' in columns or 'node_ids' in columns: + slice_instances = SliceInstance().select(filter={'slice_id': slice['slice_id']}) + slice['instance_ids'] = [rec.instance_id for rec in slice_instances] if not columns or 'node_ids' in columns: - slice_nodes = SliceNode().select(filter={'slice_id': slice['slice_id']}) - slice['node_ids'] = [rec.node_id for rec in slice_nodes] + #slice_nodes = SliceNode().select(filter={'slice_id': slice['slice_id']}) + #slice['node_ids'] = [rec.node_id for rec in slice_nodes] + # need to look up the manually look up each instance's host and query plc + # for the node ids + instances = api.client_shell.nova.servers.list() + hostnames = [s._info['OS-EXT-SRV-ATTR:host'] for s in instances \ + if s.id in slice['instance_ids']] + nodes = Node().select(filter={'hostname': hostnames}) + slice['node_ids'] = [rec.node_id for rec in nodes] if not columns or 'slice_tag_ids' in columns: slice_tags = SliceTag().select(filter={'slice_id': slice['slice_id']}) diff --git a/PLC/Storage/AlchemyObject.py b/PLC/Storage/AlchemyObject.py index c0c3974a..2f490231 100644 --- a/PLC/Storage/AlchemyObject.py +++ b/PLC/Storage/AlchemyObject.py @@ -90,10 +90,10 @@ class AlchemyObj(Record): constraints = [] for (field, value) in filter.items(): if isinstance(value, list): - if value: - column = table.columns.get(field) - if isinstance(column, Column): - constraints.append(column.in_(value)) + #if value: + column = table.columns.get(field) + if isinstance(column, Column): + constraints.append(column.in_(value)) else: constraints.append(table.columns.get(field) == value) if not constraints: -- 2.47.0