diff options
author | Alfredo Moralejo <amoralej@redhat.com> | 2019-04-09 19:27:29 +0200 |
---|---|---|
committer | Alfredo Moralejo <amoralej@redhat.com> | 2019-04-17 12:38:22 +0200 |
commit | ed356fc6b46e133899e1bf1c54df239536ea78b9 (patch) | |
tree | 25c1bf5d8c0378c32fd4ec440c66e50e448e9dc2 | |
parent | ba6b5cf2ae0afb69bf31ab1e2b30edaeba388946 (diff) | |
download | glance_store-ed356fc6b46e133899e1bf1c54df239536ea78b9.tar.gz |
Do not include ETag when puting manifest in chunked uploads
While testing glance with Ceph Rados Gateway using latest Ceph release
(Nautilus), i've found that glance fails to upload the manifest using
dynamic large objects mode because of the value used in ETag request.
This issue has been reported to Ceph as it seems related to some recent
change in radosgw code [1].
However, checking at the upload workflow used by glance and comparing
to Swift documentation [2], I wonder if adding the etag is actually
providing any value. In the Swift the ETag header is used to validate
integrity when uploading chunks, not the manifest while glance is doing
exactly the oposite, not sending the etag in the chunks (I guess to
avoid checksuming big images, which makes sense to me) and sending it
when puting the manifest.
This patch is removing the etag header when sending the PUT request for
the manifest in chunked uploads.
[1] https://tracker.ceph.com/issues/39160
[2] https://docs.openstack.org/swift/latest/api/large_objects.html#dynamic-large-objects
Closes-bug: #1824533
Change-Id: I0b563dfcdc30026669fb089c82db8c3df7edc808
-rw-r--r-- | glance_store/_drivers/swift/store.py | 9 | ||||
-rw-r--r-- | glance_store/tests/unit/test_swift_store.py | 3 | ||||
-rw-r--r-- | glance_store/tests/unit/test_swift_store_multibackend.py | 3 |
3 files changed, 9 insertions, 6 deletions
diff --git a/glance_store/_drivers/swift/store.py b/glance_store/_drivers/swift/store.py index 5de7e6c..706d352 100644 --- a/glance_store/_drivers/swift/store.py +++ b/glance_store/_drivers/swift/store.py @@ -1030,11 +1030,12 @@ class BaseStore(driver.Store): if image_size == 0: image_size = combined_chunks_size - # Now we write the object manifest and return the - # manifest's etag... + # Now we write the object manifest in X-Object-Manifest + # header as defined for Dynamic Large Objects (DLO) Mode. + # This request does not include ETag as PUT request has not + # actual content that we need to verify. manifest = "%s/%s-" % (location.container, location.obj) - headers = {'ETag': hashlib.md5(b"").hexdigest(), - 'X-Object-Manifest': manifest} + headers = {'X-Object-Manifest': manifest} # The ETag returned for the manifest is actually the # MD5 hash of the concatenated checksums of the strings diff --git a/glance_store/tests/unit/test_swift_store.py b/glance_store/tests/unit/test_swift_store.py index 287097c..400fff6 100644 --- a/glance_store/tests/unit/test_swift_store.py +++ b/glance_store/tests/unit/test_swift_store.py @@ -118,8 +118,9 @@ class SwiftTests(object): fixture_key = "%s/%s" % (container, name) if fixture_key not in fixture_headers: if kwargs.get('headers'): - etag = kwargs['headers']['ETag'] manifest = kwargs.get('headers').get('X-Object-Manifest') + etag = kwargs.get('headers') \ + .get('ETag', hashlib.md5(b'').hexdigest()) fixture_headers[fixture_key] = { 'manifest': True, 'etag': etag, diff --git a/glance_store/tests/unit/test_swift_store_multibackend.py b/glance_store/tests/unit/test_swift_store_multibackend.py index fa26301..07c44d9 100644 --- a/glance_store/tests/unit/test_swift_store_multibackend.py +++ b/glance_store/tests/unit/test_swift_store_multibackend.py @@ -109,8 +109,9 @@ class SwiftTests(object): fixture_key = "%s/%s" % (container, name) if fixture_key not in fixture_headers: if kwargs.get('headers'): - etag = kwargs['headers']['ETag'] manifest = kwargs.get('headers').get('X-Object-Manifest') + etag = kwargs.get('headers') \ + .get('ETag', hashlib.md5(b'').hexdigest()) fixture_headers[fixture_key] = { 'manifest': True, 'etag': etag, |