From 5f46fe88424d0fc37705fb2a59d67a93a2993279 Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Wed, 18 Jul 2018 17:55:50 -0500 Subject: [PATCH] Add flag for disabling object checksum generation Checksums are calculated and added to the object's metadata as a way to prevent double-uploading identical copies of large data. For some use cases, such as uploading log files, there is no risk of that and there is no point to paying the calculation cost. Change-Id: I7b3c94b72e99f9abd3c961bd811da6fd563144bb --- openstack/cloud/openstackcloud.py | 12 +++- openstack/tests/unit/cloud/test_object.py | 55 +++++++++++++++++++ ...-checksum-generation-ea1c1e47d2290054.yaml | 4 ++ 3 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/object-checksum-generation-ea1c1e47d2290054.yaml diff --git a/openstack/cloud/openstackcloud.py b/openstack/cloud/openstackcloud.py index 53abde1fc..5d8773803 100755 --- a/openstack/cloud/openstackcloud.py +++ b/openstack/cloud/openstackcloud.py @@ -7421,6 +7421,7 @@ class OpenStackCloud(_normalize.Normalizer): self, container, name, filename=None, md5=None, sha256=None, segment_size=None, use_slo=True, metadata=None, + generate_checksums=True, **headers): """Create a file object. @@ -7445,6 +7446,9 @@ class OpenStackCloud(_normalize.Normalizer): Object, use a static rather than dynamic object. Static Objects will delete segment objects when the manifest object is deleted. (optional, defaults to True) + :param generate_checksums: Whether to generate checksums on the client + side that get added to headers for later prevention of double + uploads of identical data. (optional, defaults to True) :param metadata: This dict will get changed into headers that set metadata of the object @@ -7463,10 +7467,12 @@ class OpenStackCloud(_normalize.Normalizer): segment_size = self.get_object_segment_size(segment_size) file_size = os.path.getsize(filename) - if not (md5 or sha256): + if generate_checksums and (md5 is None or sha256 is None): (md5, sha256) = self._get_file_hashes(filename) - headers[OBJECT_MD5_KEY] = md5 or '' - headers[OBJECT_SHA256_KEY] = sha256 or '' + if md5: + headers[OBJECT_MD5_KEY] = md5 or '' + if sha256: + headers[OBJECT_SHA256_KEY] = sha256 or '' for (k, v) in metadata.items(): headers['x-object-meta-' + k] = v diff --git a/openstack/tests/unit/cloud/test_object.py b/openstack/tests/unit/cloud/test_object.py index 7bb8506f9..b13d81446 100644 --- a/openstack/tests/unit/cloud/test_object.py +++ b/openstack/tests/unit/cloud/test_object.py @@ -895,3 +895,58 @@ class TestObjectUploads(BaseTestObject): 'etag': 'etag3', }, ], self.adapter.request_history[-1].json()) + + def test_create_object_skip_checksum(self): + + self.register_uris([ + dict(method='GET', + uri='https://object-store.example.com/info', + json=dict( + swift={'max_file_size': 1000}, + slo={'min_segment_size': 500})), + dict(method='HEAD', + uri='{endpoint}/{container}'.format( + endpoint=self.endpoint, + container=self.container), + status_code=404), + dict(method='PUT', + uri='{endpoint}/{container}'.format( + endpoint=self.endpoint, container=self.container), + status_code=201, + headers={ + 'Date': 'Fri, 16 Dec 2016 18:21:20 GMT', + 'Content-Length': '0', + 'Content-Type': 'text/html; charset=UTF-8', + }), + dict(method='HEAD', + uri='{endpoint}/{container}'.format( + endpoint=self.endpoint, container=self.container), + headers={ + 'Content-Length': '0', + 'X-Container-Object-Count': '0', + 'Accept-Ranges': 'bytes', + 'X-Storage-Policy': 'Policy-0', + 'Date': 'Fri, 16 Dec 2016 18:29:05 GMT', + 'X-Timestamp': '1481912480.41664', + 'X-Trans-Id': 'tx60ec128d9dbf44b9add68-0058543271dfw1', + 'X-Container-Bytes-Used': '0', + 'Content-Type': 'text/plain; charset=utf-8'}), + dict(method='HEAD', + uri='{endpoint}/{container}/{object}'.format( + endpoint=self.endpoint, container=self.container, + object=self.object), + status_code=200), + dict(method='PUT', + uri='{endpoint}/{container}/{object}'.format( + endpoint=self.endpoint, + container=self.container, object=self.object), + status_code=201, + validate=dict(headers={})), + ]) + + self.cloud.create_object( + container=self.container, name=self.object, + filename=self.object_file.name, + generate_checksums=False) + + self.assert_calls() diff --git a/releasenotes/notes/object-checksum-generation-ea1c1e47d2290054.yaml b/releasenotes/notes/object-checksum-generation-ea1c1e47d2290054.yaml new file mode 100644 index 000000000..e27a87396 --- /dev/null +++ b/releasenotes/notes/object-checksum-generation-ea1c1e47d2290054.yaml @@ -0,0 +1,4 @@ +--- +features: + - Add flag for disabling object checksum generation +