Merge "Add ability to pass data to create_object"
This commit is contained in:
@@ -7429,7 +7429,7 @@ class OpenStackCloud(_normalize.Normalizer):
|
|||||||
self, container, name, filename=None,
|
self, container, name, filename=None,
|
||||||
md5=None, sha256=None, segment_size=None,
|
md5=None, sha256=None, segment_size=None,
|
||||||
use_slo=True, metadata=None,
|
use_slo=True, metadata=None,
|
||||||
generate_checksums=True,
|
generate_checksums=None, data=None,
|
||||||
**headers):
|
**headers):
|
||||||
"""Create a file object.
|
"""Create a file object.
|
||||||
|
|
||||||
@@ -7439,7 +7439,9 @@ class OpenStackCloud(_normalize.Normalizer):
|
|||||||
This container will be created if it does not exist already.
|
This container will be created if it does not exist already.
|
||||||
:param name: Name for the object within the container.
|
:param name: Name for the object within the container.
|
||||||
:param filename: The path to the local file whose contents will be
|
:param filename: The path to the local file whose contents will be
|
||||||
uploaded.
|
uploaded. Mutually exclusive with data.
|
||||||
|
:param data: The content to upload to the object. Mutually exclusive
|
||||||
|
with filename.
|
||||||
:param md5: A hexadecimal md5 of the file. (Optional), if it is known
|
:param md5: A hexadecimal md5 of the file. (Optional), if it is known
|
||||||
and can be passed here, it will save repeating the expensive md5
|
and can be passed here, it will save repeating the expensive md5
|
||||||
process. It is assumed to be accurate.
|
process. It is assumed to be accurate.
|
||||||
@@ -7462,10 +7464,25 @@ class OpenStackCloud(_normalize.Normalizer):
|
|||||||
|
|
||||||
:raises: ``OpenStackCloudException`` on operation error.
|
:raises: ``OpenStackCloudException`` on operation error.
|
||||||
"""
|
"""
|
||||||
|
if data is not None and filename:
|
||||||
|
raise ValueError(
|
||||||
|
"Both filename and data given. Please choose one.")
|
||||||
|
if data is not None and not name:
|
||||||
|
raise ValueError(
|
||||||
|
"name is a required parameter when data is given")
|
||||||
|
if data is not None and generate_checksums:
|
||||||
|
raise ValueError(
|
||||||
|
"checksums cannot be generated with data parameter")
|
||||||
|
if generate_checksums is None:
|
||||||
|
if data is not None:
|
||||||
|
generate_checksums = False
|
||||||
|
else:
|
||||||
|
generate_checksums = True
|
||||||
|
|
||||||
if not metadata:
|
if not metadata:
|
||||||
metadata = {}
|
metadata = {}
|
||||||
|
|
||||||
if not filename:
|
if not filename and data is None:
|
||||||
filename = name
|
filename = name
|
||||||
|
|
||||||
# segment_size gets used as a step value in a range call, so needs
|
# segment_size gets used as a step value in a range call, so needs
|
||||||
@@ -7473,7 +7490,10 @@ class OpenStackCloud(_normalize.Normalizer):
|
|||||||
if segment_size:
|
if segment_size:
|
||||||
segment_size = int(segment_size)
|
segment_size = int(segment_size)
|
||||||
segment_size = self.get_object_segment_size(segment_size)
|
segment_size = self.get_object_segment_size(segment_size)
|
||||||
|
if filename:
|
||||||
file_size = os.path.getsize(filename)
|
file_size = os.path.getsize(filename)
|
||||||
|
else:
|
||||||
|
file_size = len(data)
|
||||||
|
|
||||||
if generate_checksums and (md5 is None or sha256 is None):
|
if generate_checksums and (md5 is None or sha256 is None):
|
||||||
(md5, sha256) = self._get_file_hashes(filename)
|
(md5, sha256) = self._get_file_hashes(filename)
|
||||||
@@ -7487,10 +7507,17 @@ class OpenStackCloud(_normalize.Normalizer):
|
|||||||
# On some clouds this is not necessary. On others it is. I'm confused.
|
# On some clouds this is not necessary. On others it is. I'm confused.
|
||||||
self.create_container(container)
|
self.create_container(container)
|
||||||
|
|
||||||
|
endpoint = '{container}/{name}'.format(container=container, name=name)
|
||||||
|
|
||||||
|
if data is not None:
|
||||||
|
self.log.debug(
|
||||||
|
"swift uploading data to %(endpoint)s",
|
||||||
|
{'endpoint': endpoint})
|
||||||
|
|
||||||
|
return self._upload_object_data(endpoint, data, headers)
|
||||||
|
|
||||||
if self.is_object_stale(container, name, filename, md5, sha256):
|
if self.is_object_stale(container, name, filename, md5, sha256):
|
||||||
|
|
||||||
endpoint = '{container}/{name}'.format(
|
|
||||||
container=container, name=name)
|
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
"swift uploading %(filename)s to %(endpoint)s",
|
"swift uploading %(filename)s to %(endpoint)s",
|
||||||
{'filename': filename, 'endpoint': endpoint})
|
{'filename': filename, 'endpoint': endpoint})
|
||||||
@@ -7502,6 +7529,10 @@ class OpenStackCloud(_normalize.Normalizer):
|
|||||||
endpoint, filename, headers,
|
endpoint, filename, headers,
|
||||||
file_size, segment_size, use_slo)
|
file_size, segment_size, use_slo)
|
||||||
|
|
||||||
|
def _upload_object_data(self, endpoint, data, headers):
|
||||||
|
return self._object_store_client.put(
|
||||||
|
endpoint, headers=headers, data=data)
|
||||||
|
|
||||||
def _upload_object(self, endpoint, filename, headers):
|
def _upload_object(self, endpoint, filename, headers):
|
||||||
return self._object_store_client.put(
|
return self._object_store_client.put(
|
||||||
endpoint, headers=headers, data=open(filename, 'r'))
|
endpoint, headers=headers, data=open(filename, 'r'))
|
||||||
|
|||||||
@@ -594,7 +594,7 @@ class TestCase(base.TestCase):
|
|||||||
key = '{method}|{uri}|{params}'.format(
|
key = '{method}|{uri}|{params}'.format(
|
||||||
method=method, uri=uri, params=kw_params)
|
method=method, uri=uri, params=kw_params)
|
||||||
validate = to_mock.pop('validate', {})
|
validate = to_mock.pop('validate', {})
|
||||||
valid_keys = set(['json', 'headers', 'params'])
|
valid_keys = set(['json', 'headers', 'params', 'data'])
|
||||||
invalid_keys = set(validate.keys()) - valid_keys
|
invalid_keys = set(validate.keys()) - valid_keys
|
||||||
if invalid_keys:
|
if invalid_keys:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
|
|||||||
@@ -950,3 +950,55 @@ class TestObjectUploads(BaseTestObject):
|
|||||||
generate_checksums=False)
|
generate_checksums=False)
|
||||||
|
|
||||||
self.assert_calls()
|
self.assert_calls()
|
||||||
|
|
||||||
|
def test_create_object_data(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='PUT',
|
||||||
|
uri='{endpoint}/{container}/{object}'.format(
|
||||||
|
endpoint=self.endpoint,
|
||||||
|
container=self.container, object=self.object),
|
||||||
|
status_code=201,
|
||||||
|
validate=dict(
|
||||||
|
headers={},
|
||||||
|
data=self.content,
|
||||||
|
)),
|
||||||
|
])
|
||||||
|
|
||||||
|
self.cloud.create_object(
|
||||||
|
container=self.container, name=self.object,
|
||||||
|
data=self.content)
|
||||||
|
|
||||||
|
self.assert_calls()
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add a data parameter to ``openstack.connection.Connection.create_object``
|
||||||
|
so that data can be passed in directly instead of through a file.
|
||||||
Reference in New Issue
Block a user