Exemplo n.º 1
0
    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
Exemplo n.º 2
0
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})
Exemplo n.º 3
0
 def test_non_unicode_error_msg(self):
     exc = exception.GlanceException(str('test'))
     self.assertIsInstance(encodeutils.exception_to_unicode(exc),
                           six.text_type)
Exemplo n.º 4
0
 def test_specified_error_msg_with_kwargs(self):
     msg = exception.GlanceException('test: %(code)s', code=500)
     self.assertIn('test: 500', encodeutils.exception_to_unicode(msg))
Exemplo n.º 5
0
 def test_specified_error_msg(self):
     msg = exception.GlanceException('test')
     self.assertIn('test', encodeutils.exception_to_unicode(msg))
Exemplo n.º 6
0
 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
Exemplo n.º 7
0
 def data_iterator():
     self.notifier.log = []
     yield 'abcde'
     raise exception.GlanceException('Failed')