def cache_tee_iter(self, image_id, image_iter, image_checksum): try: current_checksum = hashlib.md5() with self.driver.open_for_write(image_id) as cache_file: for chunk in image_iter: try: cache_file.write(chunk) finally: current_checksum.update(chunk) yield chunk cache_file.flush() if (image_checksum and image_checksum != current_checksum.hexdigest()): msg = _("Checksum verification failed. Aborted " "caching of image '%s'.") % image_id raise exception.GlanceException(msg) except exception.GlanceException as e: with excutils.save_and_reraise_exception(): # image_iter has given us bad, (size_checked_iter has found a # bad length), or corrupt data (checksum is wrong). LOG.exception(encodeutils.exception_to_unicode(e)) except Exception as e: LOG.exception(_LE("Exception encountered while tee'ing " "image '%(image_id)s' into cache: %(error)s. " "Continuing with response.") % {'image_id': image_id, 'error': encodeutils.exception_to_unicode(e)}) # If no checksum provided continue responding even if # caching failed. for chunk in image_iter: yield chunk
def size_checked_iter(response, image_meta, expected_size, image_iter, notifier): image_id = image_meta['id'] bytes_written = 0 def notify_image_sent_hook(env): image_send_notification(bytes_written, expected_size, image_meta, response.request, notifier) # Add hook to process after response is fully sent if 'eventlet.posthooks' in response.request.environ: response.request.environ['eventlet.posthooks'].append( (notify_image_sent_hook, (), {})) try: for chunk in image_iter: yield chunk bytes_written += len(chunk) except Exception as err: with excutils.save_and_reraise_exception(): msg = (_LE("An error occurred reading from backend storage for " "image %(image_id)s: %(err)s") % {'image_id': image_id, 'err': err}) LOG.error(msg) if expected_size != bytes_written: msg = (_LE("Backend storage for image %(image_id)s " "disconnected after writing only %(bytes_written)d " "bytes") % {'image_id': image_id, 'bytes_written': bytes_written}) LOG.error(msg) raise exception.GlanceException(_("Corrupt image download for " "image %(image_id)s") % {'image_id': image_id})
def tee_iter(image_id): try: current_checksum = hashlib.md5() with self.driver.open_for_write(image_id) as cache_file: for chunk in image_iter: try: cache_file.write(chunk) finally: current_checksum.update(chunk) yield chunk cache_file.flush() if image_checksum and \ image_checksum != current_checksum.hexdigest(): msg = _("Checksum verification failed. Aborted caching " "of image %s." % image_id) raise exception.GlanceException(msg) except Exception: LOG.exception( _("Exception encountered while tee'ing " "image '%s' into cache. Continuing " "with response.") % image_id) # NOTE(markwash): continue responding even if caching failed for chunk in image_iter: yield chunk
def tee_iter(image_id): try: current_checksum = hashlib.md5() with self.driver.open_for_write(image_id) as cache_file: for chunk in image_iter: try: cache_file.write(chunk) finally: current_checksum.update(chunk) yield chunk cache_file.flush() if (image_checksum and image_checksum != current_checksum.hexdigest()): msg = _("Checksum verification failed. Aborted " "caching of image '%s'." % image_id) raise exception.GlanceException(msg) except exception.GlanceException as e: # image_iter has given us bad, (size_checked_iter has found a # bad length), or corrupt data (checksum is wrong). LOG.exception(e) raise except Exception as e: LOG.exception( _("Exception encountered while tee'ing " "image '%s' into cache: %s. Continuing " "with response.") % (image_id, e)) # NOTE(markwash): continue responding even if caching failed for chunk in image_iter: yield chunk
def staging_store_path(): """Return the local path to the staging store. :raises: GlanceException if staging store is not configured to be a file:// URI """ if CONF.enabled_backends: separator, staging_dir = store_utils.get_dir_separator() else: staging_dir = CONF.node_staging_uri expected_prefix = 'file://' if not staging_dir.startswith(expected_prefix): raise exception.GlanceException('Unexpected scheme in staging store; ' 'unable to scan for residue') return staging_dir[len(expected_prefix):]
def __get_backend(self): if not self.__backend: if self.__config_group is None: backend_name = CONF[self.__pivot] else: backend_name = CONF[self.__config_group][self.__pivot] if backend_name not in self.__backends: msg = _('Invalid backend: %s') % backend_name raise exception.GlanceException(msg) backend = self.__backends[backend_name] if isinstance(backend, tuple): name = backend[0] fromlist = backend[1] else: name = backend fromlist = backend self.__backend = __import__(name, None, None, fromlist) return self.__backend
def _sync(self, version): """ Place an existing database under migration control and upgrade it. """ alembic_migrations.place_database_under_alembic_control() a_config = alembic_migrations.get_alembic_config() alembic_command.upgrade(a_config, version) heads = alembic_migrations.get_current_alembic_heads() if heads is None: raise exception.GlanceException("Database sync failed") revs = ", ".join(heads) if version == 'heads': print(_("Upgraded database, current revision(s):"), revs) else: print( _('Upgraded database to: %(v)s, current revision(s): %(r)s') % { 'v': version, 'r': revs })
def _get_sock_from_parent(self): # This is supposed to be called exactly once in the child process. # We're passing a copy of the socket through a pipe. pipe_handle = int(getattr(CONF, 'pipe_handle', 0)) if not pipe_handle: err_msg = _("Did not receive a pipe handle, which is used when " "communicating with the parent process.") raise exception.GlanceException(err_msg) # Get the length of the data to be received. buff = self._ioutils.get_buffer(4) self._ioutils.read_file(pipe_handle, buff, 4) socket_buff_sz = struct.unpack('<I', buff)[0] # Get the serialized socket object. socket_buff = self._ioutils.get_buffer(socket_buff_sz) self._ioutils.read_file(pipe_handle, socket_buff, socket_buff_sz) self._ioutils.close_handle(pipe_handle) # Recreate the socket object. This will only work with # Python 3.6 or later. return socket.fromshare(bytes(socket_buff[:]))
def test_specified_error_msg_with_kwargs(self): self.assertTrue('test: 500' in unicode( exception.GlanceException('test: %(code)s', code=500)))
def test_specified_error_msg(self): self.assertTrue('test' in unicode(exception.GlanceException('test')))
def faulty_backend(): data = [b'a', b'b', b'c', b'Fail', b'd', b'e', b'f'] for d in data: if d == b'Fail': raise exception.GlanceException('Backend failure') yield d
def test_specified_error_msg(self): msg = exception.GlanceException('test') self.assertIn('test', encodeutils.exception_to_unicode(msg))
def test_non_unicode_error_msg(self): exc = exception.GlanceException(str('test')) self.assertIsInstance(six.text_type(exc), six.text_type)
def data_iterator(): self.notifier.log = [] yield 'abcde' raise exception.GlanceException('Failed')
for chunk in image_iter: yield chunk bytes_written += len(chunk) except Exception, err: msg = _("An error occurred reading from backend storage " "for image %(image_id)s: %(err)s") % locals() LOG.error(msg) raise if expected_size != bytes_written: msg = _("Backend storage for image %(image_id)s " "disconnected after writing only %(bytes_written)d " "bytes") % locals() LOG.error(msg) raise exception.GlanceException( _("Corrupt image download for " "image %(image_id)s") % locals()) def image_send_notification(bytes_written, expected_size, image_meta, request, notifier): """Send an image.send message to the notifier.""" try: context = request.context payload = { 'bytes_sent': bytes_written, 'image_id': image_meta['id'], 'owner_id': image_meta['owner'], 'receiver_tenant_id': context.tenant, 'receiver_user_id': context.user, 'destination_ip': request.remote_addr,
def test_non_unicode_error_msg(self): exc = exception.GlanceException(str('test')) self.assertIsInstance(utils.exception_to_str(exc), str)
def test_specified_error_msg_with_kwargs(self): msg = exception.GlanceException('test: %(code)s', code=500) self.assertIn('test: 500', utils.exception_to_str(msg))
def test_specified_error_msg(self): msg = exception.GlanceException('test') self.assertIn('test', utils.exception_to_str(msg))
def test_specified_error_msg_with_kwargs(self): msg = exception.GlanceException('test: %(code)s', code=int(http.INTERNAL_SERVER_ERROR)) self.assertIn('test: 500', encodeutils.exception_to_unicode(msg))