From: Sapan Bhatia Date: Mon, 26 Aug 2013 15:05:31 +0000 (-0400) Subject: Merge branch 'master' of ssh://git.planet-lab.org/git/plstackapi X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=5fdfbbe8bf337cbe68019d9c753376b2ca6ed646;hp=78ce7694b6fb4a1decf3859f563ef1e3bbdaaa0b;p=plstackapi.git Merge branch 'master' of ssh://git.planet-lab.org/git/plstackapi --- diff --git a/planetstack/core/models/sliver.py b/planetstack/core/models/sliver.py index 44a6af1..9c00cee 100644 --- a/planetstack/core/models/sliver.py +++ b/planetstack/core/models/sliver.py @@ -26,7 +26,16 @@ class Sliver(PlCoreBase): numberCores = models.IntegerField(verbose_name="Number of Cores", help_text="Number of cores for sliver", default=0) tags = generic.GenericRelation(Tag) - def __unicode__(self): return u'%s' % (self.instance_name) + def __unicode__(self): + if self.instance_name: + return u'%s' % (self.instance_name) + elif self.id: + return u'uninstantiated-%s' % str(self.id) + elif self.slice: + return u'unsaved-sliver on %s' % self.slice.name + else: + return u'unsaved-sliver' + def save(self, *args, **kwds): if not self.name: diff --git a/planetstack/openstack/observer.py b/planetstack/openstack/observer.py index 73bb114..d8c3c61 100644 --- a/planetstack/openstack/observer.py +++ b/planetstack/openstack/observer.py @@ -37,6 +37,7 @@ class OpenStackObserver: return while True: try: + start_time=time.time() logger.info('Observer run loop') #self.sync_roles() @@ -46,6 +47,8 @@ class OpenStackObserver: except: logger.log_exc("Exception in sync_tenants") traceback.print_exc() + finish_time = time.time() + logger.info('Sync tenants took %f seconds'%(finish_time-start_time)) logger.info('Calling sync users') try: @@ -53,6 +56,8 @@ class OpenStackObserver: except: logger.log_exc("Exception in sync_users") traceback.print_exc() + finish_time = time.time() + logger.info('Sync users took %f seconds'%(finish_time-start_time)) logger.info('Calling sync tenant roles') try: @@ -67,6 +72,8 @@ class OpenStackObserver: except: logger.log_exc("Exception in sync slivers") traceback.print_exc() + finish_time = time.time() + logger.info('Sync slivers took %f seconds'%(finish_time-start_time)) logger.info('Calling sync sliver ips') try: @@ -74,6 +81,8 @@ class OpenStackObserver: except: logger.log_exc("Exception in sync_sliver_ips") traceback.print_exc() + finish_time = time.time() + logger.info('Sync sliver ips took %f seconds'%(finish_time-start_time)) logger.info('Calling sync networks') try: @@ -81,6 +90,8 @@ class OpenStackObserver: except: logger.log_exc("Exception in sync_networks") traceback.print_exc() + finish_time = time.time() + logger.info('Sync networks took %f seconds'%(finish_time-start_time)) logger.info('Calling sync network slivers') try: @@ -88,6 +99,8 @@ class OpenStackObserver: except: logger.log_exc("Exception in sync_network_slivers") traceback.print_exc() + finish_time = time.time() + logger.info('Sync network sliver ips took %f seconds'%(finish_time-start_time)) logger.info('Calling sync external routes') try: @@ -95,6 +108,8 @@ class OpenStackObserver: except: logger.log_exc("Exception in sync_external_routes") traceback.print_exc() + finish_time = time.time() + logger.info('Sync external routes took %f seconds'%(finish_time-start_time)) logger.info('Waiting for event') tBeforeWait = time.time() @@ -329,11 +344,16 @@ class OpenStackObserver: for instance in instances: if instance.uuid not in sliver_dict: try: - # lookup tenant and update context - tenant = self.manager.driver.shell.keystone.tenants.find(id=instance.project_id) - self.manager.init_admin(tenant=tenant.name) + # lookup tenant and update context + try: + tenant = self.manager.driver.shell.keystone.tenants.find(id=instance.project_id) + tenant_name = tenant.name + except: + tenant_name = None + logger.info("exception while retrieving tenant %s. Deleting instance using root tenant." % instance.project_id) + self.manager.init_admin(tenant=tenant_name) self.manager.driver.destroy_instance(instance.uuid) - logger.info("destroyed sliver: %s" % (instance)) + logger.info("destroyed sliver: %s" % (instance.uuid)) except: logger.log_exc("destroy sliver failed: %s" % instance) diff --git a/planetstack/tests/networktest.py b/planetstack/tests/networktest.py new file mode 100644 index 0000000..7f3cf70 --- /dev/null +++ b/planetstack/tests/networktest.py @@ -0,0 +1,195 @@ +""" + Network Data Model Test + + 1) Create a slice1 + 2) Create sliver1 on slice1 + 3) Verify one quantum network created for sliver1 + 4) Create a private network, network1 + 5) Connect network1 to slice1 + 6) Create sliver1_2 on slice1 + 7) Verify two quantum networks created for sliver1_2 +""" + +import os +import json +import sys +import time + +sys.path.append("/opt/planetstack") + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings") +from openstack.manager import OpenStackManager +from core.models import Slice, Sliver, ServiceClass, Reservation, Tag, Network, User, Node, Image, Deployment, Site, NetworkTemplate, NetworkSlice + +from planetstacktest import PlanetStackTest, fail_unless, fail + +class NetworkTest(PlanetStackTest): + def __init__(self): + PlanetStackTest.__init__(self) + + def wait_for_ports(self, sliver, count=1, max_time=120): + print "waiting for %d ports on %s" % (count, str(sliver)) + while max_time>0: + ports = self.manager.driver.shell.quantum.list_ports(device_id=sliver.instance_id)["ports"] + if len(ports)==count: + return ports + + fail_unless(len(ports)<=count, "too many ports") + + time.sleep(10) + max_time = max_time - 10 + + fail("timed out while waiting for port creation") + + def ports_to_networks(self, ports): + networks = [] + for port in ports: + port_networks = networks + self.manager.driver.shell.quantum.list_networks(id=port["network_id"])["networks"] + for network in port_networks: + if not (network in networks): + networks.append(network) + return networks + + def ports_to_network_names(self, ports): + network_names = [] + for network in self.ports_to_networks(ports): + network_names.append(network["name"]) + return network_names + + def verify_network_names(self, ports, network_names): + port_network_names = sorted(self.ports_to_network_names(ports)) + network_names = sorted(network_names) + fail_unless(port_network_names == network_names, "mismatched network names: %s != %s" % (str(port_network_names), str(network_names))) + print " verified network ports to", ",".join(port_network_names) + + def test_slice1(self): + slice1Name = self.make_slice_name() + slice1 = Slice(name = slice1Name, + omf_friendly=True, + site=self.testSite, + creator=self.testUser) + slice1=self.save_and_wait_for_enacted(slice1, nonempty_fields=["tenant_id"]) + + sliver1 = Sliver(image = self.testImage, + creator=self.testUser, + slice=slice1, + node=self.testNode, + deploymentNetwork=self.testDeployment) + sliver1=self.save_and_wait_for_enacted(sliver1, nonempty_fields=["instance_id", "ip"]) + + # sliver1 should have only one port, its private network + ports = self.wait_for_ports(sliver1, count=1) + self.verify_network_names(ports, [slice1.name]) + + network1 = Network(name = slice1Name + "-pvt", + template = self.get_network_template("private"), + owner = slice1) + network1=self.save_and_wait_for_enacted(network1, nonempty_fields=["network_id", "subnet_id", "router_id", "subnet"]) + + network1_slice1 = NetworkSlice(network=network1, slice=slice1) + network1_slice1.save() # does not need to be enacted + + sliver1_2 = Sliver(image = self.testImage, + creator=self.testUser, + slice=slice1, + node=self.testNode, + deploymentNetwork=self.testDeployment) + sliver1_2=self.save_and_wait_for_enacted(sliver1_2, nonempty_fields=["instance_id", "ip"]) + + ports = self.wait_for_ports(sliver1_2, count=2) + self.verify_network_names(ports, [slice1.name, network1.name]) + + self.slice1 = slice1 + self.network1 = network1 + + def test_slice2(self): + slice2Name = self.make_slice_name() + slice2 = Slice(name = slice2Name, + omf_friendly=True, + site=self.testSite, + creator=self.testUser) + slice2=self.save_and_wait_for_enacted(slice2, nonempty_fields=["tenant_id"]) + + network2 = Network(name = slice2Name + "-pvt", + template = self.get_network_template("private"), + owner = slice2) + network2=self.save_and_wait_for_enacted(network2, nonempty_fields=["network_id", "subnet_id", "router_id", "subnet"]) + + network2_slice2 = NetworkSlice(network=network2, slice=slice2) + network2_slice2.save() # does not need to be enacted + + sliver2_1 = Sliver(image = self.testImage, + creator=self.testUser, + slice=slice2, + node=self.testNode, + deploymentNetwork=self.testDeployment) + sliver2_1=self.save_and_wait_for_enacted(sliver2_1, nonempty_fields=["instance_id", "ip"]) + + ports = self.wait_for_ports(sliver2_1, count=2) + self.verify_network_names(ports, [slice2.name, network2.name]) + + self.slice2 = slice2 + self.network2 = network2 + + def test_shared_private_net(self): + # connect network2 to slice1 + self.network2.permittedSlices.add(self.slice1) + network2_slice1 = NetworkSlice(network=self.network2, slice=self.slice1) + network2_slice1.save() + + sliver1_3 = Sliver(image = self.testImage, + creator=self.testUser, + slice=self.slice1, + node=self.testNode, + deploymentNetwork=self.testDeployment) + sliver1_3=self.save_and_wait_for_enacted(sliver1_3, nonempty_fields=["instance_id", "ip"]) + + ports = self.wait_for_ports(sliver1_3, count=3) + self.verify_network_names(ports, [self.slice1.name, self.network1.name, self.network2.name]) + + def test_nat_net(self): + slice3Name = self.make_slice_name() + slice3 = Slice(name = slice3Name, + omf_friendly=True, + site=self.testSite, + creator=self.testUser) + slice3=self.save_and_wait_for_enacted(slice3, nonempty_fields=["tenant_id"]) + + network3 = Network(name = slice3Name + "-nat", + template = self.get_network_template("private-nat"), + owner = slice3) + # note that router_id will not be filled in for nat-net, since nat-net has no routers + network3=self.save_and_wait_for_enacted(network3, nonempty_fields=["network_id", "subnet_id", "subnet"]) + + network3_slice3 = NetworkSlice(network=network3, slice=slice3) + network3_slice3.save() # does not need to be enacted + + sliver3_1 = Sliver(image = self.testImage, + creator=self.testUser, + slice=slice3, + node=self.testNode, + deploymentNetwork=self.testDeployment) + sliver3_1=self.save_and_wait_for_enacted(sliver3_1, nonempty_fields=["instance_id", "ip"]) + + ports = self.wait_for_ports(sliver3_1, count=2) + self.verify_network_names(ports, [slice3.name, "nat-net"]) + + def run(self): + self.setup() + try: + self.test_slice1() + self.test_slice2() + self.test_shared_private_net() + self.test_nat_net() + print "SUCCESS" + finally: + self.cleanup() + +def main(): + NetworkTest().run() + +if __name__=="__main__": + main() + + + diff --git a/planetstack/tests/planetstacktest.py b/planetstack/tests/planetstacktest.py new file mode 100644 index 0000000..77ed95f --- /dev/null +++ b/planetstack/tests/planetstacktest.py @@ -0,0 +1,94 @@ +import os +import json +import sys +import time + +sys.path.append("/opt/planetstack") + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings") +from openstack.manager import OpenStackManager +from core.models import Slice, Sliver, ServiceClass, Reservation, Tag, Network, User, Node, Image, Deployment, Site, NetworkTemplate, NetworkSlice + +TEST_SITE_NAME = "Princeton University" +TEST_USER_EMAIL = "sbaker@planetstack.org" +TEST_IMAGE_NAME = "Fedora 16 LXC rev 1.3" +TEST_NODE_NAME = "viccidev3.cs.princeton.edu" +TEST_DEPLOYMENT_NAME = "VICCI" + +def fail(msg): + print msg + sys.exit(-1) + +def fail_unless(condition, msg): + if not condition: + fail(msg) + +class PlanetStackTest: + def __init__(self): + self.objs_saved = [] + self.counter = 0 + + def setup(self): + self.manager = OpenStackManager() + + print "getting test site" + self.testSite = Site.objects.get(name=TEST_SITE_NAME) + + print "getting test user" + self.testUser = User.objects.get(email=TEST_USER_EMAIL) + + print "getting test image" + self.testImage = Image.objects.get(name=TEST_IMAGE_NAME) + + print "getting test node" + self.testNode = Node.objects.get(name=TEST_NODE_NAME) + + print "getting test deployment" + self.testDeployment = Deployment.objects.get(name=TEST_DEPLOYMENT_NAME) + + def save_and_wait_for_enacted(self, x, nonempty_fields=[]): + print "saving", x.__class__.__name__, str(x) + x.save() + self.objs_saved.append(x) + print " waiting for", str(x), "to be enacted" + tStart = time.time() + while True: + new_x = x.__class__.objects.get(id=x.id) + if (new_x.enacted != None) and (new_x.enacted >= new_x.updated): + print " ", str(x), "has been enacted" + break + time.sleep(5) + + if nonempty_fields: + print " waiting for", ", ".join(nonempty_fields), "to be nonempty" + while True: + new_x = x.__class__.objects.get(id=x.id) + keep_waiting=False + for field in nonempty_fields: + if not getattr(new_x, field, None): + keep_waiting=True + if not keep_waiting: + break + + print " saved and enacted in %d seconds" % int(time.time() - tStart) + + return new_x + + def make_slice_name(self): + self.counter = self.counter +1 + return "test-" + str(time.time()) + "." + str(self.counter) + + def get_network_template(self,name): + template = NetworkTemplate.objects.get(name=name) + return template + + def cleanup(self): + print "cleaning up" + print "press return" + sys.stdin.readline() + for obj in self.objs_saved: + try: + print " deleting", str(obj) + obj.delete() + except: + print "failed to delete", str(obj) diff --git a/planetstack/tests/slivertest.py b/planetstack/tests/slivertest.py new file mode 100644 index 0000000..271fe5b --- /dev/null +++ b/planetstack/tests/slivertest.py @@ -0,0 +1,51 @@ +""" + Basic Sliver Test + + 1) Create a slice1 + 2) Create sliver1 on slice1 +""" + +import os +import json +import sys +import time + +sys.path.append("/opt/planetstack") + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings") +from openstack.manager import OpenStackManager +from core.models import Slice, Sliver, ServiceClass, Reservation, Tag, Network, User, Node, Image, Deployment, Site, NetworkTemplate, NetworkSlice + +from planetstacktest import PlanetStackTest, fail_unless + +class SliverTest(PlanetStackTest): + def __init__(self): + PlanetStackTest.__init__(self) + + def run_sliver1(self): + slice1Name = self.make_slice_name() + slice1 = Slice(name = slice1Name, + omf_friendly=True, + site=self.testSite, + creator=self.testUser) + slice1=self.save_and_wait_for_enacted(slice1, nonempty_fields=["tenant_id"]) + + sliver1 = Sliver(image = self.testImage, + creator=self.testUser, + slice=slice1, + node=self.testNode, + deploymentNetwork=self.testDeployment) + sliver1=self.save_and_wait_for_enacted(sliver1, nonempty_fields=["instance_id", "ip"]) + + def run(self): + self.setup() + try: + self.run_sliver1() + finally: + self.cleanup() + +def main(): + SliverTest().run() + +if __name__=="__main__": + main()