keep track of slice instances
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Tue, 12 Mar 2013 18:24:08 +0000 (14:24 -0400)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Tue, 12 Mar 2013 18:24:08 +0000 (14:24 -0400)
PLC/Methods/AddSliceToNodes.py
PLC/Nodes.py
PLC/Slices.py
PLC/Storage/AlchemyObject.py

index 903681e..72ffbed 100644 (file)
@@ -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
index 6886b78..f478054 100644 (file)
@@ -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):
index 21a8ccf..e5f1823 100644 (file)
@@ -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']})
index c0c3974..2f49023 100644 (file)
@@ -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: