Add an option: disable etag check on downloads
This patch is to add an option of disable etag check on downloads. Change-Id: I9ad389dd691942dea6db470ca3f0543eb6e9703e Closes-bug: #1581147
This commit is contained in:
parent
f9d0657e70
commit
69bf4634b9
doc
swiftclient
tests/unit
@ -86,6 +86,7 @@ container, or a list of objects depending on the args given. For a single
|
|||||||
object download, you may use the \-o [\-\-output] <filename> option to
|
object download, you may use the \-o [\-\-output] <filename> option to
|
||||||
redirect the output to a specific file or if "-" then just redirect to stdout or
|
redirect the output to a specific file or if "-" then just redirect to stdout or
|
||||||
with \-\-no-download actually not to write anything to disk.
|
with \-\-no-download actually not to write anything to disk.
|
||||||
|
The \-\-ignore-checksum is an option that turn off checksum validation.
|
||||||
You can specify optional headers with the repeatable cURL-like option
|
You can specify optional headers with the repeatable cURL-like option
|
||||||
\-H [\-\-header]. For more details and options see swift download \-\-help.
|
\-H [\-\-header]. For more details and options see swift download \-\-help.
|
||||||
.RE
|
.RE
|
||||||
|
@ -186,7 +186,8 @@ Download
|
|||||||
container, or a list of objects depending on the arguments given. For a
|
container, or a list of objects depending on the arguments given. For a
|
||||||
single object download, you may use the ``-o <filename>`` or ``--output <filename>``
|
single object download, you may use the ``-o <filename>`` or ``--output <filename>``
|
||||||
option to redirect the output to a specific file or ``-`` to
|
option to redirect the output to a specific file or ``-`` to
|
||||||
redirect to stdout. You can specify optional headers with the repeatable
|
redirect to stdout. The ``--ignore-checksum`` is an option that turn off
|
||||||
|
checksum validation. You can specify optional headers with the repeatable
|
||||||
cURL-like option ``-H [--header <name:value>]``.
|
cURL-like option ``-H [--header <name:value>]``.
|
||||||
|
|
||||||
Delete
|
Delete
|
||||||
|
@ -207,6 +207,9 @@ Options
|
|||||||
Affects uploads, and allows empty 'pseudofolder' objects to be created
|
Affects uploads, and allows empty 'pseudofolder' objects to be created
|
||||||
when the source of an upload is ``None``.
|
when the source of an upload is ``None``.
|
||||||
|
|
||||||
|
``checksum``: ``True``
|
||||||
|
Affects uploads and downloads, and means if check md5 for downloads/uploads.
|
||||||
|
|
||||||
``shuffle``: ``False``
|
``shuffle``: ``False``
|
||||||
When downloading objects, the default behaviour of the CLI is to shuffle
|
When downloading objects, the default behaviour of the CLI is to shuffle
|
||||||
lists of objects in order to spread the load on storage drives when multiple
|
lists of objects in order to spread the load on storage drives when multiple
|
||||||
|
@ -336,7 +336,7 @@ class _SwiftReader(object):
|
|||||||
errors on failures caused by either invalid md5sum or size of the
|
errors on failures caused by either invalid md5sum or size of the
|
||||||
data read.
|
data read.
|
||||||
"""
|
"""
|
||||||
def __init__(self, path, body, headers):
|
def __init__(self, path, body, headers, checksum=True):
|
||||||
self._path = path
|
self._path = path
|
||||||
self._body = body
|
self._body = body
|
||||||
self._actual_read = 0
|
self._actual_read = 0
|
||||||
@ -345,7 +345,7 @@ class _SwiftReader(object):
|
|||||||
self._expected_etag = headers.get('etag')
|
self._expected_etag = headers.get('etag')
|
||||||
|
|
||||||
if ('x-object-manifest' not in headers
|
if ('x-object-manifest' not in headers
|
||||||
and 'x-static-large-object' not in headers):
|
and 'x-static-large-object' not in headers and checksum):
|
||||||
self._actual_md5 = md5()
|
self._actual_md5 = md5()
|
||||||
|
|
||||||
if 'content-length' in headers:
|
if 'content-length' in headers:
|
||||||
@ -980,6 +980,7 @@ class SwiftService(object):
|
|||||||
'header': [],
|
'header': [],
|
||||||
'skip_identical': False,
|
'skip_identical': False,
|
||||||
'out_directory': None,
|
'out_directory': None,
|
||||||
|
'checksum': True,
|
||||||
'out_file': None,
|
'out_file': None,
|
||||||
'remove_prefix': False,
|
'remove_prefix': False,
|
||||||
'shuffle' : False
|
'shuffle' : False
|
||||||
@ -1135,7 +1136,8 @@ class SwiftService(object):
|
|||||||
|
|
||||||
headers_receipt = time()
|
headers_receipt = time()
|
||||||
|
|
||||||
obj_body = _SwiftReader(path, body, headers)
|
obj_body = _SwiftReader(path, body, headers,
|
||||||
|
options.get('checksum', True))
|
||||||
|
|
||||||
no_file = options['no_download']
|
no_file = options['no_download']
|
||||||
if out_file == "-" and not no_file:
|
if out_file == "-" and not no_file:
|
||||||
|
@ -204,7 +204,7 @@ def st_delete(parser, args, output_manager):
|
|||||||
|
|
||||||
st_download_options = '''[--all] [--marker <marker>] [--prefix <prefix>]
|
st_download_options = '''[--all] [--marker <marker>] [--prefix <prefix>]
|
||||||
[--output <out_file>] [--output-dir <out_directory>]
|
[--output <out_file>] [--output-dir <out_directory>]
|
||||||
[--object-threads <threads>]
|
[--object-threads <threads>] [--ignore-checksum]
|
||||||
[--container-threads <threads>] [--no-download]
|
[--container-threads <threads>] [--no-download]
|
||||||
[--skip-identical] [--remove-prefix]
|
[--skip-identical] [--remove-prefix]
|
||||||
[--header <header:value>] [--no-shuffle]
|
[--header <header:value>] [--no-shuffle]
|
||||||
@ -251,6 +251,7 @@ Optional arguments:
|
|||||||
Example --header "content-type:text/plain"
|
Example --header "content-type:text/plain"
|
||||||
--skip-identical Skip downloading files that are identical on both
|
--skip-identical Skip downloading files that are identical on both
|
||||||
sides.
|
sides.
|
||||||
|
--ignore-checksum Turn off checksum validation for downloads.
|
||||||
--no-shuffle By default, when downloading a complete account or
|
--no-shuffle By default, when downloading a complete account or
|
||||||
container, download order is randomised in order to
|
container, download order is randomised in order to
|
||||||
reduce the load on individual drives when multiple
|
reduce the load on individual drives when multiple
|
||||||
@ -308,6 +309,9 @@ def st_download(parser, args, output_manager):
|
|||||||
'--skip-identical', action='store_true', dest='skip_identical',
|
'--skip-identical', action='store_true', dest='skip_identical',
|
||||||
default=False, help='Skip downloading files that are identical on '
|
default=False, help='Skip downloading files that are identical on '
|
||||||
'both sides.')
|
'both sides.')
|
||||||
|
parser.add_argument(
|
||||||
|
'--ignore-checksum', action='store_false', dest='checksum',
|
||||||
|
default=True, help='Turn off checksum validation for downloads.')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--no-shuffle', action='store_false', dest='shuffle',
|
'--no-shuffle', action='store_false', dest='shuffle',
|
||||||
default=True, help='By default, download order is randomised in order '
|
default=True, help='By default, download order is randomised in order '
|
||||||
|
@ -103,6 +103,15 @@ class TestSwiftReader(unittest.TestCase):
|
|||||||
self.assertEqual(sr._expected_etag, None)
|
self.assertEqual(sr._expected_etag, None)
|
||||||
self.assertEqual(sr._actual_md5, None)
|
self.assertEqual(sr._actual_md5, None)
|
||||||
|
|
||||||
|
def test_create_with_ignore_checksum(self):
|
||||||
|
# md5 should not be initialized if checksum is False
|
||||||
|
sr = self.sr('path', 'body', {}, False)
|
||||||
|
self.assertEqual(sr._path, 'path')
|
||||||
|
self.assertEqual(sr._body, 'body')
|
||||||
|
self.assertEqual(sr._content_length, None)
|
||||||
|
self.assertEqual(sr._expected_etag, None)
|
||||||
|
self.assertEqual(sr._actual_md5, None)
|
||||||
|
|
||||||
def test_create_with_content_length(self):
|
def test_create_with_content_length(self):
|
||||||
sr = self.sr('path', 'body', {'content-length': 5})
|
sr = self.sr('path', 'body', {'content-length': 5})
|
||||||
|
|
||||||
|
@ -367,6 +367,24 @@ class TestShell(unittest.TestCase):
|
|||||||
mock_open.assert_called_with('object', 'wb')
|
mock_open.assert_called_with('object', 'wb')
|
||||||
self.assertEqual([], makedirs.mock_calls)
|
self.assertEqual([], makedirs.mock_calls)
|
||||||
|
|
||||||
|
# Test downloading without md5 checks
|
||||||
|
objcontent = six.BytesIO(b'objcontent')
|
||||||
|
connection.return_value.get_object.side_effect = [
|
||||||
|
({'content-type': 'text/plain',
|
||||||
|
'etag': '2cbbfe139a744d6abbe695e17f3c1991'},
|
||||||
|
objcontent)
|
||||||
|
]
|
||||||
|
with mock.patch(BUILTIN_OPEN) as mock_open, mock.patch(
|
||||||
|
'swiftclient.service._SwiftReader') as sr:
|
||||||
|
argv = ["", "download", "container", "object", "--ignore-check"]
|
||||||
|
swiftclient.shell.main(argv)
|
||||||
|
connection.return_value.get_object.assert_called_with(
|
||||||
|
'container', 'object', headers={}, resp_chunk_size=65536,
|
||||||
|
response_dict={})
|
||||||
|
mock_open.assert_called_with('object', 'wb')
|
||||||
|
sr.assert_called_once_with('object', mock.ANY, mock.ANY, False)
|
||||||
|
self.assertEqual([], makedirs.mock_calls)
|
||||||
|
|
||||||
# Test downloading single object to stdout
|
# Test downloading single object to stdout
|
||||||
objcontent = six.BytesIO(b'objcontent')
|
objcontent = six.BytesIO(b'objcontent')
|
||||||
connection.return_value.get_object.side_effect = [
|
connection.return_value.get_object.side_effect = [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user