diff --git a/releasenotes/notes/nova-old-microversion-5e4b8e239ba44096.yaml b/releasenotes/notes/nova-old-microversion-5e4b8e239ba44096.yaml new file mode 100644 index 000000000..013ed82fa --- /dev/null +++ b/releasenotes/notes/nova-old-microversion-5e4b8e239ba44096.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - Nova microversion is being requested. Since shade is not yet + actively microversion aware, but has been dealing with the 2.0 structures + anyway, this should not affect anyone. diff --git a/shade/openstackcloud.py b/shade/openstackcloud.py index 78124749f..b42481e21 100644 --- a/shade/openstackcloud.py +++ b/shade/openstackcloud.py @@ -545,7 +545,7 @@ class OpenStackCloud(_normalize.Normalizer): def nova_client(self): if self._nova_client is None: self._nova_client = self._get_client( - 'compute', novaclient.client.Client) + 'compute', novaclient.client.Client, version='2.0') return self._nova_client @property diff --git a/shade/tests/base.py b/shade/tests/base.py index 8915e2b08..73d1e86bb 100644 --- a/shade/tests/base.py +++ b/shade/tests/base.py @@ -18,6 +18,7 @@ import os import fixtures import logging import munch +import pprint from six import StringIO import testtools import testtools.content @@ -75,6 +76,12 @@ class TestCase(testtools.TestCase): logger.addHandler(handler) logger.propagate = False + # Enable HTTP level tracing + logger = logging.getLogger('novaclient') + logger.setLevel(logging.DEBUG) + logger.addHandler(handler) + logger.propagate = False + def assertEqual(self, first, second, *args, **kwargs): '''Munch aware wrapper''' if isinstance(first, munch.Munch): @@ -101,3 +108,9 @@ class TestCase(testtools.TestCase): testtools.content_type.UTF8_TEXT, False) self.addDetail('logging', content) + + def add_info_on_exception(self, name, text): + def add_content(unused): + self.addDetail(name, testtools.content.text_content( + pprint.pformat(text))) + self.addOnException(add_content) diff --git a/shade/tests/functional/base.py b/shade/tests/functional/base.py index 6d64cb527..919a8ef03 100644 --- a/shade/tests/functional/base.py +++ b/shade/tests/functional/base.py @@ -37,3 +37,30 @@ class BaseFunctionalTestCase(base.TestCase): self.identity_version = \ self.operator_cloud.cloud_config.get_api_version('identity') + + def pick_image(self): + images = self.user_cloud.list_images() + self.add_info_on_exception('images', images) + + image_name = os.environ.get('SHADE_IMAGE') + if image_name: + for image in images: + if image.name == image_name: + return image + self.assertFalse( + "Cloud does not have {image}".format(image=image_name)) + + for image in images: + if image.name.startswith('cirros') and image.name.endswith('-uec'): + return image + for image in images: + if (image.name.startswith('cirros') + and image.disk_format == 'qcow2'): + return image + for image in images: + if image.name.lower().startswith('ubuntu'): + return image + for image in images: + if image.name.lower().startswith('centos'): + return image + self.assertFalse('no sensible image available') diff --git a/shade/tests/functional/test_compute.py b/shade/tests/functional/test_compute.py index b0a33794b..06322f6a2 100644 --- a/shade/tests/functional/test_compute.py +++ b/shade/tests/functional/test_compute.py @@ -21,7 +21,7 @@ import six from shade import exc from shade.tests.functional import base -from shade.tests.functional.util import pick_flavor, pick_image +from shade.tests.functional.util import pick_flavor from shade import _utils @@ -31,9 +31,7 @@ class TestCompute(base.BaseFunctionalTestCase): self.flavor = pick_flavor(self.user_cloud.list_flavors()) if self.flavor is None: self.assertFalse('no sensible flavor available') - self.image = pick_image(self.user_cloud.list_images()) - if self.image is None: - self.assertFalse('no sensible image available') + self.image = self.pick_image() self.server_name = self.getUniqueString() def _cleanup_servers_and_volumes(self, server_name): diff --git a/shade/tests/functional/test_floating_ip.py b/shade/tests/functional/test_floating_ip.py index 7bd8f2685..24ab87d1e 100644 --- a/shade/tests/functional/test_floating_ip.py +++ b/shade/tests/functional/test_floating_ip.py @@ -28,7 +28,7 @@ from shade import _utils from shade import meta from shade.exc import OpenStackCloudException from shade.tests.functional import base -from shade.tests.functional.util import pick_flavor, pick_image +from shade.tests.functional.util import pick_flavor class TestFloatingIP(base.BaseFunctionalTestCase): @@ -42,9 +42,7 @@ class TestFloatingIP(base.BaseFunctionalTestCase): self.flavor = pick_flavor(self.nova.flavors.list()) if self.flavor is None: self.assertFalse('no sensible flavor available') - self.image = pick_image(self.nova.images.list()) - if self.image is None: - self.assertFalse('no sensible image available') + self.image = self.pick_image() # Generate a random name for these tests self.new_item_name = self.getUniqueString() diff --git a/shade/tests/functional/test_image.py b/shade/tests/functional/test_image.py index f890b0567..7280bd36d 100644 --- a/shade/tests/functional/test_image.py +++ b/shade/tests/functional/test_image.py @@ -22,13 +22,12 @@ import os import tempfile from shade.tests.functional import base -from shade.tests.functional.util import pick_image class TestImage(base.BaseFunctionalTestCase): def setUp(self): super(TestImage, self).setUp() - self.image = pick_image(self.user_cloud.nova_client.images.list()) + self.image = self.pick_image() def test_create_image(self): test_image = tempfile.NamedTemporaryFile(delete=False) diff --git a/shade/tests/functional/test_inventory.py b/shade/tests/functional/test_inventory.py index 877051526..2fd0e38e0 100644 --- a/shade/tests/functional/test_inventory.py +++ b/shade/tests/functional/test_inventory.py @@ -22,7 +22,7 @@ Functional tests for `shade` inventory methods. from shade import inventory from shade.tests.functional import base -from shade.tests.functional.util import pick_flavor, pick_image +from shade.tests.functional.util import pick_flavor class TestInventory(base.BaseFunctionalTestCase): @@ -36,9 +36,7 @@ class TestInventory(base.BaseFunctionalTestCase): self.flavor = pick_flavor(self.nova.flavors.list()) if self.flavor is None: self.assertTrue(False, 'no sensible flavor available') - self.image = pick_image(self.nova.images.list()) - if self.image is None: - self.assertTrue(False, 'no sensible image available') + self.image = self.pick_image() self.addCleanup(self._cleanup_servers) self.operator_cloud.create_server( name=self.server_name, image=self.image, flavor=self.flavor, diff --git a/shade/tests/functional/test_usage.py b/shade/tests/functional/test_usage.py index e175c1711..35d15b0c9 100644 --- a/shade/tests/functional/test_usage.py +++ b/shade/tests/functional/test_usage.py @@ -30,5 +30,6 @@ class TestUsage(base.BaseFunctionalTestCase): usage = self.operator_cloud.get_compute_usage('demo', datetime.datetime.now(), datetime.datetime.now()) + self.add_info_on_exception('usage', usage) self.assertIsNotNone(usage) self.assertTrue(hasattr(usage, 'total_hours')) diff --git a/shade/tests/functional/util.py b/shade/tests/functional/util.py index a88e47de9..180f08f76 100644 --- a/shade/tests/functional/util.py +++ b/shade/tests/functional/util.py @@ -40,22 +40,3 @@ def pick_flavor(flavors): flavors, key=operator.attrgetter('ram')): return flavor - - -def pick_image(images): - image_name = os.environ.get('SHADE_IMAGE') - if image_name: - for image in images: - if image.name == image_name: - return image - return None - - for image in images: - if image.name.startswith('cirros') and image.name.endswith('-uec'): - return image - for image in images: - if image.name.lower().startswith('ubuntu'): - return image - for image in images: - if image.name.lower().startswith('centos'): - return image