Replace glance.client with python-glanceclient
The legacy glance client code is going to be removed soon, so
Tempest needs to stop using it. This patch updates Tempest to
use the shiny new python-glanceclient library.
This requires python-glanceclient 0.5.1+ to work.
Fixes bug 1048716
Change-Id: I6e0773644ed1e4e19448a5899a71ee2ed5d36f82
diff --git a/tempest/manager.py b/tempest/manager.py
index 0679db9..2cac25e 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -18,7 +18,7 @@
import logging
# Default client libs
-import glance.client
+import glanceclient
import keystoneclient.v2_0.client
import novaclient.client
import quantumclient.v2_0.client
@@ -131,30 +131,11 @@
no_cache=True)
def _get_image_client(self):
- host = self.config.images.host
- port = self.config.images.port
- strategy = self.config.identity.strategy
- auth_url = self.config.identity.auth_url
- username = self.config.images.username
- password = self.config.images.password
- tenant_name = self.config.images.tenant_name
-
- if None in (host, port, username, password, tenant_name):
- msg = ("Missing required credentials for image client. "
- "host:%(host)s, port: %(port)s username: %(username)s, "
- "password: %(password)s, "
- "tenant_name: %(tenant_name)s") % locals()
- raise exceptions.InvalidConfiguration(msg)
- auth_url = self.config.identity.auth_url.rstrip('tokens')
-
- creds = {'strategy': strategy,
- 'username': username,
- 'password': password,
- 'tenant': tenant_name,
- 'auth_url': auth_url}
-
- # Create our default Glance client to use in testing
- return glance.client.Client(host, port, creds=creds)
+ keystone = self._get_identity_client()
+ token = keystone.auth_token
+ endpoint = keystone.service_catalog.url_for(service_type='image',
+ endpoint_type='publicURL')
+ return glanceclient.Client('1', endpoint=endpoint, token=token)
def _get_identity_client(self):
# This identity client is not intended to check the security
diff --git a/tempest/services/image/service.py b/tempest/services/image/service.py
index 9cfe502..154b5b8 100644
--- a/tempest/services/image/service.py
+++ b/tempest/services/image/service.py
@@ -36,22 +36,25 @@
# Determine the Images API version
self.api_version = int(config.images.api_version)
+ # We load the client class specific to the API version...
if self.api_version == 1:
- # We load the client class specific to the API version...
- from glance import client
- creds = {
- 'username': config.images.username,
- 'password': config.images.password,
- 'tenant': config.images.tenant_name,
- # rstrip() is necessary here because Glance client
- # automatically adds the tokens/ part...
- 'auth_url': config.identity.auth_url.rstrip('/tokens'),
- 'strategy': config.identity.strategy
- }
- self._client = client.Client(config.images.host,
- config.images.port,
- creds=creds,
- configure_via_auth=False)
+ import glanceclient
+ import keystoneclient.v2_0.client
+
+ auth_url = self.config.identity.auth_url.rstrip('tokens')
+ keystone = keystoneclient.v2_0.client.Client(
+ username=config.images.username,
+ password=config.images.password,
+ tenant_name=config.images.tenant_name,
+ auth_url=auth_url)
+ token = keystone.auth_token
+ endpoint = keystone.service_catalog.url_for(
+ service_type='image',
+ endpoint_type='publicURL')
+
+ self._client = glanceclient.Client('1',
+ endpoint=endpoint,
+ token=token)
else:
raise NotImplementedError
diff --git a/tempest/tests/image/test_images.py b/tempest/tests/image/test_images.py
index 0e515dc..c6b903b 100644
--- a/tempest/tests/image/test_images.py
+++ b/tempest/tests/image/test_images.py
@@ -25,8 +25,7 @@
GLANCE_INSTALLED = False
try:
- from glance import client
- from glance.common import exception
+ import glanceclient
GLANCE_INSTALLED = True
except ImportError:
pass
@@ -51,7 +50,7 @@
@classmethod
def tearDownClass(cls):
for image_id in cls.created_images:
- cls.client.delete_image(image_id)
+ cls.client.images.delete(image_id)
@attr(type='image')
def test_register_with_invalid_data(self):
@@ -70,11 +69,10 @@
]
for meta in metas:
try:
- results = self.client.add_image(meta)
- except exception.Invalid:
+ self.client.images.create(**meta)
+ except glanceclient.exc.HTTPBadRequest:
continue
- self.fail("Did not raise Invalid for meta %s. Got results: %s" %
- (meta, results))
+ self.fail("Did not raise Invalid for meta %s." % meta)
@attr(type='image')
def test_register_then_upload(self):
@@ -86,27 +84,27 @@
'container_format': 'bare',
'properties': {'prop1': 'val1'}
}
- results = self.client.add_image(meta)
- self.assertTrue('id' in results)
- image_id = results['id']
+ results = self.client.images.create(**meta)
+ self.assertTrue(hasattr(results, 'id'))
+ image_id = results.id
self.created_images.append(image_id)
- self.assertTrue('name' in results)
- self.assertEqual(meta['name'], results['name'])
- self.assertTrue('is_public' in results)
- self.assertEqual(meta['is_public'], results['is_public'])
- self.assertTrue('status' in results)
- self.assertEqual('queued', results['status'])
- self.assertTrue('properties' in results)
+ self.assertTrue(hasattr(results, 'name'))
+ self.assertEqual(meta['name'], results.name)
+ self.assertTrue(hasattr(results, 'is_public'))
+ self.assertEqual(meta['is_public'], results.is_public)
+ self.assertTrue(hasattr(results, 'status'))
+ self.assertEqual('queued', results.status)
+ self.assertTrue(hasattr(results, 'properties'))
for key, val in meta['properties'].items():
- self.assertEqual(val, results['properties'][key])
+ self.assertEqual(val, results.properties[key])
# Now try uploading an image file
image_file = StringIO.StringIO('*' * 1024)
- results = self.client.update_image(image_id, image_data=image_file)
- self.assertTrue('status' in results)
- self.assertEqual('active', results['status'])
- self.assertTrue('size' in results)
- self.assertEqual(1024, results['size'])
+ results = self.client.images.update(image_id, data=image_file)
+ self.assertTrue(hasattr(results, 'status'))
+ self.assertEqual('active', results.status)
+ self.assertTrue(hasattr(results, 'size'))
+ self.assertEqual(1024, results.size)
@attr(type='image')
def test_register_remote_image(self):
@@ -118,16 +116,16 @@
'container_format': 'bare',
'location': 'http://example.com/someimage.iso'
}
- results = self.client.add_image(meta)
- self.assertTrue('id' in results)
- image_id = results['id']
+ results = self.client.images.create(**meta)
+ self.assertTrue(hasattr(results, 'id'))
+ image_id = results.id
self.created_images.append(image_id)
- self.assertTrue('name' in results)
- self.assertEqual(meta['name'], results['name'])
- self.assertTrue('is_public' in results)
- self.assertEqual(meta['is_public'], results['is_public'])
- self.assertTrue('status' in results)
- self.assertEqual('active', results['status'])
+ self.assertTrue(hasattr(results, 'name'))
+ self.assertEqual(meta['name'], results.name)
+ self.assertTrue(hasattr(results, 'is_public'))
+ self.assertEqual(meta['is_public'], results.is_public)
+ self.assertTrue(hasattr(results, 'status'))
+ self.assertEqual('active', results.status)
class ListImagesTest(unittest.TestCase):
@@ -143,7 +141,7 @@
cls.os = openstack.ServiceManager()
cls.client = cls.os.images.get_client()
cls.created_images = []
- cls.original_images = cls.client.get_images()
+ cls.original_images = list(cls.client.images.list())
# We add a few images here to test the listing functionality of
# the images API
@@ -157,7 +155,7 @@
@classmethod
def tearDownClass(cls):
for image_id in cls.created_images:
- cls.client.delete_image(image_id)
+ cls.client.images.delete(image_id)
@classmethod
def _create_remote_image(cls, x):
@@ -172,8 +170,8 @@
'container_format': 'bare',
'location': 'http://example.com/someimage_%s.iso' % x
}
- results = cls.client.add_image(meta)
- image_id = results['id']
+ results = cls.client.images.create(**meta)
+ image_id = results.id
return image_id
@classmethod
@@ -183,15 +181,16 @@
image. Note that the size of the new image is a random number between
1024 and 4096
"""
+ image_file = StringIO.StringIO('*' * random.randint(1024, 4096))
meta = {
'name': 'New Standard Image %s' % x,
'is_public': True,
'disk_format': 'raw',
- 'container_format': 'bare'
+ 'container_format': 'bare',
+ 'data': image_file,
}
- image_file = StringIO.StringIO('*' * random.randint(1024, 4096))
- results = cls.client.add_image(meta, image_file)
- image_id = results['id']
+ results = cls.client.images.create(**meta)
+ image_id = results.id
return image_id
@attr(type='image')
@@ -199,5 +198,5 @@
"""
Simple test to see all fixture images returned
"""
- images = self.client.get_images()
+ images = list(self.client.images.list())
self.assertEqual(10, len(images) - len(self.original_images))