Replace unicode() for six.text_type

To support Python3, unicode() calls has been replaced by
six.text_type.
Added utils.exception_to_str(): is the proper way to convert
an exception to string, since it manages logic related to
encoding.

Change-Id: I27101390e4f95e5c7690b1b445b7e75b8bcb9a08
Closes-Bug: #1284677
This commit is contained in:
Leandro I. Costantino 2014-03-26 09:35:25 -03:00
parent ed816a214b
commit 627d5fbc13
29 changed files with 156 additions and 137 deletions

View File

@ -96,7 +96,7 @@ class CacheFilter(wsgi.Middleware):
try:
self.policy.enforce(req.context, action, {})
except exception.Forbidden as e:
raise webob.exc.HTTPForbidden(explanation=unicode(e), request=req)
raise webob.exc.HTTPForbidden(explanation=e.msg, request=req)
def process_request(self, request):
"""

View File

@ -949,7 +949,7 @@ class Controller(controller.BaseController):
request=req,
content_type="text/plain")
except (exception.Conflict, exception.Duplicate) as e:
LOG.info(unicode(e))
LOG.info(utils.exception_to_str(e))
raise HTTPConflict(body='Image operation conflicts',
request=req,
content_type='text/plain')
@ -1071,7 +1071,7 @@ class ImageDeserializer(wsgi.JSONRequestDeserializer):
try:
result['image_meta'] = utils.get_image_meta_from_headers(request)
except exception.InvalidParameterValue as e:
msg = unicode(e)
msg = utils.exception_to_str(e)
LOG.warn(msg, exc_info=True)
raise HTTPBadRequest(explanation=e.msg, request=request)

View File

@ -15,7 +15,6 @@
# under the License.
from oslo.config import cfg
import six
import webob.exc
from glance.api import policy
@ -95,10 +94,10 @@ class Controller(controller.BaseController):
registry.delete_member(req.context, image_id, id)
self._update_store_acls(req, image_id)
except exception.NotFound as e:
LOG.debug(six.text_type(e))
LOG.debug(utils.exception_to_str(e))
raise webob.exc.HTTPNotFound(explanation=e.msg)
except exception.Forbidden as e:
LOG.debug(six.text_type(e))
LOG.debug(utils.exception_to_str(e))
raise webob.exc.HTTPNotFound(explanation=e.msg)
return webob.exc.HTTPNoContent()
@ -151,13 +150,13 @@ class Controller(controller.BaseController):
registry.add_member(req.context, image_id, id, can_share)
self._update_store_acls(req, image_id)
except exception.Invalid as e:
LOG.debug(six.text_type(e))
LOG.debug(utils.exception_to_str(e))
raise webob.exc.HTTPBadRequest(explanation=e.msg)
except exception.NotFound as e:
LOG.debug(six.text_type(e))
LOG.debug(utils.exception_to_str(e))
raise webob.exc.HTTPNotFound(explanation=e.msg)
except exception.Forbidden as e:
LOG.debug(six.text_type(e))
LOG.debug(utils.exception_to_str(e))
raise webob.exc.HTTPNotFound(explanation=e.msg)
return webob.exc.HTTPNoContent()
@ -186,13 +185,13 @@ class Controller(controller.BaseController):
registry.replace_members(req.context, image_id, body)
self._update_store_acls(req, image_id)
except exception.Invalid as e:
LOG.debug(six.text_type(e))
LOG.debug(utils.exception_to_str(e))
raise webob.exc.HTTPBadRequest(explanation=e.msg)
except exception.NotFound as e:
LOG.debug(six.text_type(e))
LOG.debug(utils.exception_to_str(e))
raise webob.exc.HTTPNotFound(explanation=e.msg)
except exception.Forbidden as e:
LOG.debug(six.text_type(e))
LOG.debug(utils.exception_to_str(e))
raise webob.exc.HTTPNotFound(explanation=e.msg)
return webob.exc.HTTPNoContent()
@ -213,10 +212,10 @@ class Controller(controller.BaseController):
try:
members = registry.get_member_images(req.context, id)
except exception.NotFound as e:
LOG.debug(six.text_type(e))
LOG.debug(utils.exception_to_str(e))
raise webob.exc.HTTPNotFound(explanation=e.msg)
except exception.Forbidden as e:
LOG.debug(six.text_type(e))
LOG.debug(utils.exception_to_str(e))
raise webob.exc.HTTPForbidden(explanation=e.msg)
return dict(shared_images=members)

View File

@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
import webob.exc
import glance.api.policy
@ -56,7 +55,7 @@ class ImageDataController(object):
image_repo.save(image)
except Exception as e:
msg = _("Unable to restore image %(image_id)s: %(e)s") % \
{'image_id': image.image_id, 'e': unicode(e)}
{'image_id': image.image_id, 'e': utils.exception_to_str(e)}
LOG.exception(msg)
@utils.mutating
@ -88,12 +87,13 @@ class ImageDataController(object):
except ValueError as e:
LOG.debug(_("Cannot save data for image %(id)s: %(e)s"),
{'id': image_id, 'e': six.text_type(e)})
{'id': image_id, 'e': utils.exception_to_str(e)})
self._restore(image_repo, image)
raise webob.exc.HTTPBadRequest(explanation=unicode(e))
raise webob.exc.HTTPBadRequest(explanation=
utils.exception_to_str(e))
except exception.InvalidImageStatusTransition as e:
msg = unicode(e)
msg = utils.exception_to_str(e)
LOG.debug(msg)
raise webob.exc.HTTPConflict(explanation=e.msg, request=req)

View File

@ -14,6 +14,7 @@
# under the License.
import copy
import six
import webob
from glance.api import policy
@ -104,7 +105,8 @@ class ImageMembersController(object):
except exception.Forbidden as e:
raise webob.exc.HTTPForbidden(explanation=e.msg)
except ValueError as e:
raise webob.exc.HTTPBadRequest(explanation=unicode(e))
raise webob.exc.HTTPBadRequest(explanation=
utils.exception_to_str(e))
def index(self, req, image_id):
"""
@ -233,13 +235,13 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
def create(self, response, image_member):
image_member_view = self._format_image_member(image_member)
body = jsonutils.dumps(image_member_view, ensure_ascii=False)
response.unicode_body = unicode(body)
response.unicode_body = six.text_type(body)
response.content_type = 'application/json'
def update(self, response, image_member):
image_member_view = self._format_image_member(image_member)
body = jsonutils.dumps(image_member_view, ensure_ascii=False)
response.unicode_body = unicode(body)
response.unicode_body = six.text_type(body)
response.content_type = 'application/json'
def index(self, response, image_members):
@ -251,13 +253,13 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
totalview = dict(members=image_members_view)
totalview['schema'] = '/v2/schemas/members'
body = jsonutils.dumps(totalview, ensure_ascii=False)
response.unicode_body = unicode(body)
response.unicode_body = six.text_type(body)
response.content_type = 'application/json'
def show(self, response, image_member):
image_member_view = self._format_image_member(image_member)
body = jsonutils.dumps(image_member_view, ensure_ascii=False)
response.unicode_body = unicode(body)
response.unicode_body = six.text_type(body)
response.content_type = 'application/json'

View File

@ -16,6 +16,7 @@
import re
from oslo.config import cfg
import six
import six.moves.urllib.parse as urlparse
import webob.exc
@ -66,7 +67,7 @@ class ImagesController(object):
except exception.InvalidParameterValue as e:
raise webob.exc.HTTPBadRequest(explanation=e.msg)
except exception.LimitExceeded as e:
LOG.info(unicode(e))
LOG.info(utils.exception_to_str(e))
raise webob.exc.HTTPRequestEntityTooLarge(
explanation=e.msg, request=req, content_type='text/plain')
@ -135,7 +136,7 @@ class ImagesController(object):
raise webob.exc.HTTPRequestEntityTooLarge(
explanation=msg, request=req, content_type='text/plain')
except exception.LimitExceeded as e:
LOG.info(unicode(e))
LOG.info(utils.exception_to_str(e))
raise webob.exc.HTTPRequestEntityTooLarge(
explanation=e.msg, request=req, content_type='text/plain')
@ -230,7 +231,8 @@ class ImagesController(object):
except (exception.BadStoreUri, exception.DuplicateLocation) as bse:
raise webob.exc.HTTPBadRequest(explanation=bse.msg)
except ValueError as ve: # update image status failed.
raise webob.exc.HTTPBadRequest(explanation=unicode(ve))
raise webob.exc.HTTPBadRequest(explanation=
utils.exception_to_str(ve))
def _do_add_locations(self, image, path_pos, value):
pos = self._get_locations_op_pos(path_pos,
@ -245,7 +247,8 @@ class ImagesController(object):
except (exception.BadStoreUri, exception.DuplicateLocation) as bse:
raise webob.exc.HTTPBadRequest(explanation=bse.msg)
except ValueError as ve: # update image status failed.
raise webob.exc.HTTPBadRequest(explanation=unicode(ve))
raise webob.exc.HTTPBadRequest(explanation=
utils.exception_to_str(ve))
def _do_remove_locations(self, image, path_pos):
pos = self._get_locations_op_pos(path_pos,
@ -258,7 +261,8 @@ class ImagesController(object):
# from the backend store.
image.locations.pop(pos)
except Exception as e:
raise webob.exc.HTTPInternalServerError(explanation=unicode(e))
raise webob.exc.HTTPInternalServerError(explanation=
utils.exception_to_str(e))
if (len(image.locations) == 0) and (image.status == 'active'):
image.status = 'queued'
@ -293,7 +297,8 @@ class RequestDeserializer(wsgi.JSONRequestDeserializer):
for key in cls._disallowed_properties:
if key in image:
msg = _("Attribute '%s' is read-only.") % key
raise webob.exc.HTTPForbidden(explanation=unicode(msg))
raise webob.exc.HTTPForbidden(explanation=
utils.exception_to_str(msg))
def create(self, request):
body = self._get_request_body(request)
@ -392,10 +397,10 @@ class RequestDeserializer(wsgi.JSONRequestDeserializer):
path_root = change['path'][0]
if path_root in self._readonly_properties:
msg = _("Attribute '%s' is read-only.") % path_root
raise webob.exc.HTTPForbidden(explanation=unicode(msg))
raise webob.exc.HTTPForbidden(explanation=six.text_type(msg))
if path_root in self._reserved_properties:
msg = _("Attribute '%s' is reserved.") % path_root
raise webob.exc.HTTPForbidden(explanation=unicode(msg))
raise webob.exc.HTTPForbidden(explanation=six.text_type(msg))
if change['op'] == 'delete':
return
@ -426,7 +431,7 @@ class RequestDeserializer(wsgi.JSONRequestDeserializer):
if len(path) != limits.get(op, 1):
msg = _("Invalid JSON pointer for this resource: "
"'/%s'") % '/'.join(path)
raise webob.exc.HTTPBadRequest(explanation=unicode(msg))
raise webob.exc.HTTPBadRequest(explanation=six.text_type(msg))
def _parse_json_schema_change(self, raw_change, draft_version):
if draft_version == 10:
@ -606,13 +611,13 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
def show(self, response, image):
image_view = self._format_image(image)
body = json.dumps(image_view, ensure_ascii=False)
response.unicode_body = unicode(body)
response.unicode_body = six.text_type(body)
response.content_type = 'application/json'
def update(self, response, image):
image_view = self._format_image(image)
body = json.dumps(image_view, ensure_ascii=False)
response.unicode_body = unicode(body)
response.unicode_body = six.text_type(body)
response.content_type = 'application/json'
def index(self, response, result):
@ -630,7 +635,8 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
params['marker'] = result['next_marker']
next_query = urlparse.urlencode(params)
body['next'] = '/v2/images?%s' % next_query
response.unicode_body = unicode(json.dumps(body, ensure_ascii=False))
response.unicode_body = six.text_type(json.dumps(body,
ensure_ascii=False))
response.content_type = 'application/json'
def delete(self, response, result):

View File

@ -18,6 +18,7 @@ import copy
import webob.exc
from oslo.config import cfg
import six
import six.moves.urllib.parse as urlparse
from glance.api import policy
@ -63,7 +64,7 @@ class TasksController(object):
task_repo.add(new_task)
except exception.Forbidden as e:
msg = (_("Forbidden to create task. Reason: %(reason)s")
% {'reason': unicode(e)})
% {'reason': utils.exception_to_str(e)})
LOG.info(msg)
raise webob.exc.HTTPForbidden(explanation=e.msg)
return new_task
@ -87,10 +88,10 @@ class TasksController(object):
result['next_marker'] = tasks[-1].task_id
except (exception.NotFound, exception.InvalidSortKey,
exception.InvalidFilterRangeValue) as e:
LOG.info(unicode(e))
LOG.info(utils.exception_to_str(e))
raise webob.exc.HTTPBadRequest(explanation=e.msg)
except exception.Forbidden as e:
LOG.info(unicode(e))
LOG.info(utils.exception_to_str(e))
raise webob.exc.HTTPForbidden(explanation=e.msg)
result['tasks'] = tasks
return result
@ -101,12 +102,12 @@ class TasksController(object):
task = task_repo.get(task_id)
except exception.NotFound as e:
msg = (_("Failed to find task %(task_id)s. Reason: %(reason)s") %
{'task_id': task_id, 'reason': unicode(e)})
{'task_id': task_id, 'reason': utils.exception_to_str(e)})
LOG.info(msg)
raise webob.exc.HTTPNotFound(explanation=e.msg)
except exception.Forbidden as e:
msg = (_("Forbidden to get task %(task_id)s. Reason: %(reason)s") %
{'task_id': task_id, 'reason': unicode(e)})
{'task_id': task_id, 'reason': utils.exception_to_str(e)})
LOG.info(msg)
raise webob.exc.HTTPForbidden(explanation=e.msg)
return task
@ -176,7 +177,7 @@ class RequestDeserializer(wsgi.JSONRequestDeserializer):
for param in self._required_properties:
if param not in body:
msg = _("Task '%s' is required") % param
raise webob.exc.HTTPBadRequest(explanation=unicode(msg))
raise webob.exc.HTTPBadRequest(explanation=msg)
def __init__(self, schema=None):
super(RequestDeserializer, self).__init__()
@ -272,7 +273,7 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
def get(self, response, task):
task_view = self._format_task(self.task_schema, task)
body = json.dumps(task_view, ensure_ascii=False)
response.unicode_body = unicode(body)
response.unicode_body = six.text_type(body)
response.content_type = 'application/json'
def index(self, response, result):
@ -291,7 +292,8 @@ class ResponseSerializer(wsgi.JSONResponseSerializer):
params['marker'] = result['next_marker']
next_query = urlparse.urlencode(params)
body['next'] = '/v2/tasks?%s' % next_query
response.unicode_body = unicode(json.dumps(body, ensure_ascii=False))
response.unicode_body = six.text_type(json.dumps(body,
ensure_ascii=False))
response.content_type = 'application/json'

View File

@ -25,7 +25,7 @@ import eventlet
import os
import sys
import six
from glance.common import utils
# Monkey patch socket, time, select, threads
eventlet.patcher.monkey_patch(all=False, socket=True, time=True,
@ -47,7 +47,7 @@ import glance.store
def fail(returncode, e):
sys.stderr.write("ERROR: %s\n" % six.text_type(e))
sys.stderr.write("ERROR: %s\n" % utils.exception_to_str(e))
sys.exit(returncode)

View File

@ -26,6 +26,8 @@ import os
import sys
import time
from glance.common import utils
# If ../glance/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
@ -35,7 +37,6 @@ if os.path.exists(os.path.join(possible_topdir, 'glance', '__init__.py')):
sys.path.insert(0, possible_topdir)
from glance.common import exception
from glance.common import utils
import glance.image_cache.client
from glance.openstack.common import timeutils
from glance.version import version_info as version
@ -66,7 +67,7 @@ def catch_error(action):
if options.debug:
raise
print("Failed to %s. Got error:" % action)
pieces = unicode(e).split('\n')
pieces = utils.exception_to_str(e).split('\n')
for piece in pieces:
print(piece)
return FAILURE

View File

@ -25,6 +25,7 @@ from webob import exc
from glance.common import client
from glance.common import exception
from glance.common import utils
from glance.common import wsgi
import glance.openstack.common.importutils as imp
import glance.openstack.common.log as logging
@ -178,7 +179,7 @@ class Controller(object):
if self.raise_exc:
raise
cls, val = e.__class__, six.text_type(e)
cls, val = e.__class__, utils.exception_to_str(e)
msg = (_("RPC Call Error: %(val)s\n%(tb)s") %
dict(val=val, tb=traceback.format_exc()))
LOG.error(msg)

View File

@ -40,6 +40,8 @@ from OpenSSL import crypto
from oslo.config import cfg
from webob import exc
import six
from glance.common import exception
from glance.openstack.common import excutils
import glance.openstack.common.log as logging
@ -633,3 +635,15 @@ def parse_valid_host_port(host_port):
'"[fe80::a:b:c]:9876").') % ex)
return (host, int(port))
def exception_to_str(exc):
try:
error = six.text_type(exc)
except UnicodeError:
try:
error = str(exc)
except UnicodeError:
error = ("Caught '%(exception)s' exception." %
{"exception": exc.__class__.__name__})
return strutils.safe_encode(error, errors='ignore')

View File

@ -17,6 +17,7 @@ import six.moves.urllib.parse as urlparse
import sqlalchemy
from glance.common import exception
from glance.common import utils
import glance.openstack.common.log as logging
LOG = logging.getLogger(__name__)
@ -55,9 +56,10 @@ def migrate_location_credentials(migrate_engine, to_quoted):
.where(images_table.c.id == image['id'])\
.values(location=fixed_uri).execute()
except exception.BadStoreUri as e:
reason = utils.exception_to_str(e)
err_msg = _("Invalid store uri for image: %(image_id)s. "
"Details: %(reason)s") % {'image_id': image.id,
'reason': unicode(e)}
'reason': reason}
LOG.exception(err_msg)
raise

View File

@ -34,6 +34,7 @@ import sqlalchemy
from glance.common import crypt
from glance.common import exception
from glance.common import utils
import glance.openstack.common.log as logging
import glance.store.swift # noqa
@ -85,9 +86,10 @@ def migrate_location_credentials(migrate_engine, to_quoted):
msg = _("Failed to decrypt location value for image %(image_id)s")
LOG.warn(msg % {'image_id': image['id']})
except exception.BadStoreUri as e:
reason = utils.exception_to_str(e)
err_msg = _("Invalid store uri for image: %(image_id)s. "
"Details: %(reason)s") % {'image_id': image.id,
'reason': unicode(e)}
'reason': reason}
LOG.exception(err_msg)
raise

View File

@ -59,10 +59,10 @@ import stat
import time
from oslo.config import cfg
import six
import xattr
from glance.common import exception
from glance.common import utils
from glance.image_cache.drivers import base
from glance.openstack.common import excutils
import glance.openstack.common.log as logging
@ -283,13 +283,13 @@ class Driver(base.Driver):
os.unlink(self.get_image_filepath(image_id, 'queue'))
def rollback(e):
set_attr('error', six.text_type(e))
set_attr('error', utils.exception_to_str(e))
invalid_path = self.get_image_filepath(image_id, 'invalid')
LOG.debug(_("Fetch of cache file failed (%(e)s), rolling back by "
"moving '%(incomplete_path)s' to "
"'%(invalid_path)s'"),
{'e': six.text_type(e),
{'e': utils.exception_to_str(e),
'incomplete_path': incomplete_path,
'invalid_path': invalid_path})
os.rename(incomplete_path, invalid_path)

View File

@ -19,6 +19,7 @@ from oslo import messaging
import webob
from glance.common import exception
from glance.common import utils
import glance.domain.proxy
from glance.openstack.common import excutils
import glance.openstack.common.log as logging
@ -260,7 +261,8 @@ class ImageProxy(glance.domain.proxy.Image):
{'image_id': self.image.image_id,
'error': e})
self.notifier.error('image.upload', msg)
raise webob.exc.HTTPBadRequest(explanation=unicode(e))
raise webob.exc.HTTPBadRequest(explanation=
utils.exception_to_str(e))
except exception.Duplicate as e:
msg = (_("Unable to upload duplicate image data for image"
"%(image_id)s: %(error)s") %
@ -280,7 +282,7 @@ class ImageProxy(glance.domain.proxy.Image):
" %(error)s") % {'image_id': self.image.image_id,
'error': e})
self.notifier.error('image.upload', msg)
raise webob.exc.HTTPNotFound(explanation=unicode(e))
raise webob.exc.HTTPNotFound(explanation=utils.exception_to_str(e))
except webob.exc.HTTPError as e:
with excutils.save_and_reraise_exception():
msg = (_("Failed to upload image data for image %(image_id)s"

View File

@ -18,6 +18,7 @@ Reference implementation registry server WSGI controller
"""
from oslo.config import cfg
import six
from webob import exc
from glance.common import exception
@ -481,7 +482,7 @@ class Controller(object):
request=req,
content_type='text/plain')
except exception.Conflict as e:
LOG.info(unicode(e))
LOG.info(six.text_type(e))
raise exc.HTTPConflict(body='Image operation conflicts',
request=req,
content_type='text/plain')

View File

@ -14,9 +14,9 @@
# under the License.
import jsonschema
import six
from glance.common import exception
from glance.common import utils
class Schema(object):
@ -33,7 +33,7 @@ class Schema(object):
jsonschema.validate(obj, self.raw())
except jsonschema.ValidationError as e:
raise exception.InvalidObject(schema=self.name,
reason=six.text_type(e))
reason=utils.exception_to_str(e))
def filter(self, obj):
filtered = {}

View File

@ -20,6 +20,7 @@ import os
import time
from oslo.config import cfg
import six
from glance.common import crypt
from glance.common import exception
@ -386,11 +387,11 @@ class Daemon(object):
class Scrubber(object):
def __init__(self, store_api):
LOG.info(_("Initializing scrubber with configuration: %s") %
unicode({'scrubber_datadir': CONF.scrubber_datadir,
'cleanup': CONF.cleanup_scrubber,
'cleanup_time': CONF.cleanup_scrubber_time,
'registry_host': CONF.registry_host,
'registry_port': CONF.registry_port}))
six.text_type({'scrubber_datadir': CONF.scrubber_datadir,
'cleanup': CONF.cleanup_scrubber,
'cleanup_time': CONF.cleanup_scrubber_time,
'registry_host': CONF.registry_host,
'registry_port': CONF.registry_port}))
utils.safe_mkdirs(CONF.scrubber_datadir)
@ -473,13 +474,13 @@ class Scrubber(object):
"""
try:
if not os.path.exists(file_path):
msg = _("%s file is not exists.") % unicode(file_path)
msg = _("%s file is not exists.") % six.text_type(file_path)
raise Exception(msg)
atime = int(os.path.getatime(file_path))
mtime = int(os.path.getmtime(file_path))
if atime != mtime:
msg = _("%s file contains conflicting cleanup "
"timestamp.") % unicode(file_path)
"timestamp.") % six.text_type(file_path)
raise Exception(msg)
return atime
except Exception as e:
@ -497,7 +498,8 @@ class Scrubber(object):
os.chmod(file_path, 0o600)
os.utime(file_path, (cleanup_time, cleanup_time))
except Exception:
LOG.error(_("%s file can not be created.") % unicode(file_path))
LOG.error(_("%s file can not be created.") %
six.text_type(file_path))
def _cleanup(self, pool):
now = time.time()

View File

@ -191,7 +191,8 @@ def create_stores():
store_instance = store_cls()
except exception.BadStoreConfiguration as e:
if store_entry in CONF.known_stores:
LOG.warn(_("%s Skipping store driver.") % unicode(e))
LOG.warn(_("%s Skipping store driver.") %
utils.exception_to_str(e))
continue
finally:
# NOTE(flaper87): To be removed in Juno
@ -322,7 +323,7 @@ def safe_delete_from_backend(context, uri, image_id, **kwargs):
msg = _('Failed to delete image %s in store from URI')
LOG.warn(msg % image_id)
except exception.StoreDeleteNotSupported as e:
LOG.warn(six.text_type(e))
LOG.warn(utils.exception_to_str(e))
except UnsupportedBackend:
exc_type = sys.exc_info()[0].__name__
msg = (_('Failed to delete image %(image_id)s from store '
@ -359,7 +360,7 @@ def check_location_metadata(val, key=''):
for v in val:
check_location_metadata(v, key='%s[%d]' % (key, ndx))
ndx = ndx + 1
elif not isinstance(val, unicode):
elif not isinstance(val, six.text_type):
raise BackendException(_("The image metadata key %(key)s has an "
"invalid type of %(val)s. Only dict, list, "
"and unicode are supported.") %
@ -397,7 +398,7 @@ def store_add_to_backend(image_id, data, size, store):
"%(store)s storage driver: %(metadata)s. %(error)s.") %
{'store': six.text_type(store),
'metadata': six.text_type(metadata),
'error': six.text_type(e)})
'error': utils.exception_to_str(e)})
LOG.error(e_msg)
raise BackendException(e_msg)
return (location, size, checksum, metadata)
@ -747,7 +748,7 @@ class ImageProxy(glance.domain.proxy.Image):
except Exception as e:
LOG.warn(_('Get image %(id)s data failed: '
'%(err)s.') % {'id': self.image.image_id,
'err': six.text_type(e)})
'err': utils.exception_to_str(e)})
err = e
# tried all locations
LOG.error(_('Glance tried all locations to get data for image %s '

View File

@ -17,26 +17,14 @@
"""Base class for all storage backends"""
from glance.common import exception
from glance.common import utils
from glance.openstack.common import importutils
import glance.openstack.common.log as logging
from glance.openstack.common import strutils
from glance.openstack.common import units
LOG = logging.getLogger(__name__)
def _exception_to_unicode(exc):
try:
return unicode(exc)
except UnicodeError:
try:
return strutils.safe_decode(str(exc), errors='ignore')
except UnicodeError:
msg = (_("Caught '%(exception)s' exception.") %
{"exception": exc.__class__.__name__})
return strutils.safe_decode(msg, errors='ignore')
class Store(object):
CHUNKSIZE = 16 * units.Mi # 16M
@ -54,7 +42,7 @@ class Store(object):
except exception.BadStoreConfiguration as e:
self.add = self.add_disabled
msg = (_(u"Failed to configure store correctly: %s "
"Disabling add method.") % _exception_to_unicode(e))
"Disabling add method.") % utils.exception_to_str(e))
LOG.warn(msg)
def configure(self):

View File

@ -22,7 +22,6 @@ import hashlib
import os
from oslo.config import cfg
import six
import six.moves.urllib.parse as urlparse
from glance.common import exception
@ -281,19 +280,20 @@ class Store(glance.store.base.Store):
'used: %(error)s An empty dictionary will be '
'returned to the client.') %
{'file': CONF.filesystem_store_metadata_file,
'error': six.text_type(bee)})
'error': utils.exception_to_str(bee)})
return {}
except IOError as ioe:
LOG.error(_('The path for the metadata file %(file)s could not be '
'opened: %(error)s An empty dictionary will be '
'returned to the client.') %
{'file': CONF.filesystem_store_metadata_file,
'error': six.text_type(ioe)})
'error': utils.exception_to_str(ioe)})
return {}
except Exception as ex:
LOG.exception(_('An error occurred processing the storage systems '
'meta data file: %s. An empty dictionary will be '
'returned to the client.') % six.text_type(ex))
'returned to the client.') %
utils.exception_to_str(ex))
return {}
def get(self, location):

View File

@ -133,7 +133,7 @@ class TestRBDStore(store_tests.BaseTestCase, testtools.TestCase):
# and uri to ascii before passing it to librbd.
store = self.get_store()
image_id = unicode(str(uuid.uuid4()))
image_id = six.text_type(str(uuid.uuid4()))
image_size = 300
image_data = six.StringIO('X' * image_size)
image_checksum = '41757066eaff7c4c6c965556b4d3c6c5'
@ -141,7 +141,7 @@ class TestRBDStore(store_tests.BaseTestCase, testtools.TestCase):
uri, add_size, add_checksum = store.add(image_id,
image_data,
image_size)
uri = unicode(uri)
uri = six.text_type(uri)
self.assertEqual(image_size, add_size)
self.assertEqual(image_checksum, add_checksum)

View File

@ -13,9 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
from glance.common import exception
from glance.common import utils
from glance.tests import utils as test_utils
@ -26,23 +25,23 @@ class GlanceExceptionTestCase(test_utils.BaseTestCase):
message = "default message"
exc = FakeGlanceException()
self.assertEqual(unicode(exc), 'default message')
self.assertEqual(utils.exception_to_str(exc), 'default message')
def test_specified_error_msg(self):
self.assertIn('test', unicode(exception.GlanceException('test')))
msg = exception.GlanceException('test')
self.assertIn('test', utils.exception_to_str(msg))
def test_default_error_msg_with_kwargs(self):
class FakeGlanceException(exception.GlanceException):
message = "default message: %(code)s"
exc = FakeGlanceException(code=500)
self.assertEqual(unicode(exc), "default message: 500")
self.assertEqual(utils.exception_to_str(exc), "default message: 500")
def test_specified_error_msg_with_kwargs(self):
self.assertIn('test: 500',
unicode(exception.GlanceException('test: %(code)s',
code=500)))
msg = exception.GlanceException('test: %(code)s', code=500)
self.assertIn('test: 500', utils.exception_to_str(msg))
def test_non_unicode_error_msg(self):
exc = exception.GlanceException(str('test'))
self.assertIsInstance(six.text_type(exc), six.text_type)
self.assertIsInstance(utils.exception_to_str(exc), str)

View File

@ -363,6 +363,21 @@ class TestUtils(test_utils.BaseTestCase):
utils.parse_valid_host_port,
pair)
def test_exception_to_str(self):
class FakeException(Exception):
def __str__(self):
raise UnicodeError()
ret = utils.exception_to_str(Exception('error message'))
self.assertEqual(ret, 'error message')
ret = utils.exception_to_str(Exception('\xa5 error message'))
self.assertEqual(ret, ' error message')
ret = utils.exception_to_str(FakeException('\xa5 error message'))
self.assertEqual(ret, "Caught '%(exception)s' exception." %
{'exception': 'FakeException'})
class UUIDTestCase(test_utils.BaseTestCase):

View File

@ -21,6 +21,7 @@ from oslo.config import cfg
from glance.common import crypt
from glance.common import exception
from glance.common import utils
import glance.context
import glance.db
import glance.tests.unit.utils as unit_test_utils
@ -188,7 +189,7 @@ class TestImageRepo(test_utils.BaseTestCase):
fake_uuid = str(uuid.uuid4())
exc = self.assertRaises(exception.NotFound, self.image_repo.get,
fake_uuid)
self.assertIn(fake_uuid, unicode(exc))
self.assertIn(fake_uuid, utils.exception_to_str(exc))
def test_get_forbidden(self):
self.assertRaises(exception.NotFound, self.image_repo.get, UUID4)
@ -329,7 +330,7 @@ class TestImageRepo(test_utils.BaseTestCase):
image.image_id = fake_uuid
exc = self.assertRaises(exception.NotFound, self.image_repo.save,
image)
self.assertIn(fake_uuid, unicode(exc))
self.assertIn(fake_uuid, utils.exception_to_str(exc))
def test_remove_image(self):
image = self.image_repo.get(UUID1)
@ -344,7 +345,7 @@ class TestImageRepo(test_utils.BaseTestCase):
image.image_id = fake_uuid
exc = self.assertRaises(exception.NotFound, self.image_repo.remove,
image)
self.assertIn(fake_uuid, unicode(exc))
self.assertIn(fake_uuid, utils.exception_to_str(exc))
class TestEncryptedLocations(test_utils.BaseTestCase):
@ -536,7 +537,7 @@ class TestImageMemberRepo(test_utils.BaseTestCase):
exc = self.assertRaises(exception.NotFound,
self.image_member_repo.remove,
fake_member)
self.assertIn(fake_uuid, unicode(exc))
self.assertIn(fake_uuid, utils.exception_to_str(exc))
class TestTaskRepo(test_utils.BaseTestCase):

View File

@ -30,27 +30,6 @@ class TestStoreBase(test_base.StoreClearingUnitTest):
self.config(default_store='file')
super(TestStoreBase, self).setUp()
def test_exception_to_unicode(self):
class FakeException(Exception):
def __str__(self):
raise UnicodeError()
exc = Exception('error message')
ret = store_base._exception_to_unicode(exc)
self.assertIsInstance(ret, unicode)
self.assertEqual(ret, 'error message')
exc = Exception('\xa5 error message')
ret = store_base._exception_to_unicode(exc)
self.assertIsInstance(ret, unicode)
self.assertEqual(ret, ' error message')
exc = FakeException('\xa5 error message')
ret = store_base._exception_to_unicode(exc)
self.assertIsInstance(ret, unicode)
self.assertEqual(ret, _("Caught '%(exception)s' exception.") %
{'exception': 'FakeException'})
def test_create_store_exclude_unconfigurable_drivers(self):
self.config(known_stores=[
"glance.tests.unit.test_store_base.FakeUnconfigurableStoreDriver",

View File

@ -29,6 +29,7 @@ import swiftclient
import glance.common.auth
from glance.common import exception
from glance.common import utils
from glance.openstack.common import units
from glance.store import BackendException
@ -424,7 +425,7 @@ class SwiftTests(object):
except BackendException as e:
exception_caught = True
self.assertIn("container noexist does not exist "
"in Swift", six.text_type(e))
"in Swift", utils.exception_to_str(e))
self.assertTrue(exception_caught)
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 0)

View File

@ -3054,7 +3054,7 @@ class TestImageSerializer(base.IsolatedUnitTest):
# want to output utf-8.
FIXTURE = {
'image_meta': {
'id': unicode(UUID2),
'id': six.text_type(UUID2),
'name': u'fake image #2 with utf-8 éàè',
'status': u'active',
'disk_format': u'vhd',
@ -3066,7 +3066,7 @@ class TestImageSerializer(base.IsolatedUnitTest):
'deleted': False,
'checksum': u'06ff575a2856444fbe93100157ed74ab92eb7eff',
'size': 19,
'owner': unicode(_gen_uuid()),
'owner': six.text_type(_gen_uuid()),
'location': u"file:///tmp/glance-tests/2",
'properties': {
u'prop_éé': u'ça marche',

View File

@ -17,6 +17,7 @@ import datetime
import uuid
from oslo.config import cfg
import six
import testtools
import webob
@ -2805,8 +2806,8 @@ class TestImagesSerializerWithUnicode(test_utils.BaseTestCase):
u'disk_format': u'ami',
u'min_ram': 128,
u'min_disk': 10,
u'created_at': unicode(ISOTIME),
u'updated_at': unicode(ISOTIME),
u'created_at': six.text_type(ISOTIME),
u'updated_at': six.text_type(ISOTIME),
u'self': u'/v2/images/%s' % UUID1,
u'file': u'/v2/images/%s/file' % UUID1,
u'schema': u'/v2/schemas/image',
@ -2840,8 +2841,8 @@ class TestImagesSerializerWithUnicode(test_utils.BaseTestCase):
u'disk_format': u'ami',
u'min_ram': 128,
u'min_disk': 10,
u'created_at': unicode(ISOTIME),
u'updated_at': unicode(ISOTIME),
u'created_at': six.text_type(ISOTIME),
u'updated_at': six.text_type(ISOTIME),
u'self': u'/v2/images/%s' % UUID1,
u'file': u'/v2/images/%s/file' % UUID1,
u'schema': u'/v2/schemas/image',
@ -2871,8 +2872,8 @@ class TestImagesSerializerWithUnicode(test_utils.BaseTestCase):
u'disk_format': u'ami',
u'min_ram': 128,
u'min_disk': 10,
u'created_at': unicode(ISOTIME),
u'updated_at': unicode(ISOTIME),
u'created_at': six.text_type(ISOTIME),
u'updated_at': six.text_type(ISOTIME),
u'self': u'/v2/images/%s' % UUID1,
u'file': u'/v2/images/%s/file' % UUID1,
u'schema': u'/v2/schemas/image',
@ -2902,8 +2903,8 @@ class TestImagesSerializerWithUnicode(test_utils.BaseTestCase):
u'disk_format': u'ami',
u'min_ram': 128,
u'min_disk': 10,
u'created_at': unicode(ISOTIME),
u'updated_at': unicode(ISOTIME),
u'created_at': six.text_type(ISOTIME),
u'updated_at': six.text_type(ISOTIME),
u'self': u'/v2/images/%s' % UUID1,
u'file': u'/v2/images/%s/file' % UUID1,
u'schema': u'/v2/schemas/image',