added spawn_instances()
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Mon, 11 Mar 2013 14:53:49 +0000 (10:53 -0400)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Mon, 11 Mar 2013 14:53:49 +0000 (10:53 -0400)
PLC/Slices.py

index 66d529b..cf1dc86 100644 (file)
@@ -2,6 +2,7 @@ from types import StringTypes
 import time
 import re
 from datetime import datetime, timedelta
+from collections import defaultdict
 
 from PLC.Faults import *
 from PLC.Parameter import Parameter, Mixed
@@ -117,6 +118,60 @@ class Slice(AlchemyObj):
             slice_node = SliceNode(self.api, {'slice_id': self['slice_id'],
                                               'node_id': node['node_id']})
             slice_node.sync()
+
+    def spawn_instance(self, nodes, caller):
+        # defaults
+        default_image = self.api.config.nova_defualt_image
+        defualt_flavor = self.api.config.nova_default_flavor
+
+        # use the caller's nova keypair
+        keypairs = self.api.client_shell.nova.keypairs.list()
+        if not keypairs:
+            raise PLCInvalidArgument("caller has no nova key")
+        key_name = keypairs[0].name
+
+        # get all public keys
+        from PLC.Persons import Persons
+        from PLC.Keys import Keys
+        persons = Persons(self.api, self['person_ids'])
+        key_ids = []
+        for person in persons:
+            key_ids.extend(person['key_ids'])
+        keys = Keys(self.api, key_ids)
+        pubkeys = [k['key'] for k in keys]
+        authorized_keys = "\n".join(pubkeys)
+        files = {'/root/.ssh/authorized_keys': authorized_keys}
+  
+        # sort slice tags by node (sliver)
+        slice_tags = SliceTags(self.api, {'slice_id': self['slice_id']})
+        sliver_tags = defaultdict(dict)
+        for slice_tag in slice_tags:
+            node_id = slice_tag['node_id']
+            sliver_tags[node_id][slice_tag['tagname']] = slice_tag 
+
+        def get_image(node):
+            if sliver_tags[node['node_id']].get('image'):
+                image = sliver_tags[node['node_id']].get('image')
+            else:
+                image = default_image
+
+        def get_flavor(node):
+            if sliver_tags[node['node_id']].get('flavor'):
+                flavor = sliver_tags[node['node_id']].get('flavor')
+            else:
+                flavor = default_image            
+
+        for node in node:
+            if self['slice_id'] not in node['slice_ids']:
+                image = get_image(node)
+                flavor = get_flavor(node)
+                flavor_id = api.client_shell.nova.flavors.find(name=flavor)
+                image_id = api.client_shell.glance.get_image(name=image)
+                api.client_shell.nova.servers.create(flavor=flavor_id,
+                                                     image=image_id,
+                                                     key_name = key_name,
+                                                     files=files,
+                                                     name=self['name'])              
  
     def remove_node(self, node_filter, commit=True):
         from PLC.Nodes import Nodes 
@@ -237,7 +292,7 @@ class Slices(list):
                 slice = Slice(api, {'name': tenant.name,
                                     'tenant_id': tenant.id,
                                     'enabled': tenant.enabled,
-                                    'description': description
+                                    'description': description,
                                     'is_public': True})
                 try:
                     slice.sync()