43 Commits

Author SHA1 Message Date
Zuul
b0cd86676d Merge "Fix bulk heartbeating when emitting XML" 2018-01-27 01:37:04 +00:00
Tim Burke
29e9ae1cc5 Make xml responses less insane
Looking at bulk extractions:

   $ tar c *.py | curl http://saio:8090/v1/AUTH_test/c?extract-archive=tar \
      -H accept:application/xml -T -
   <?xml version="1.0" encoding="UTF-8"?>
   <delete>
   <number_files_created>2</number_files_created>
   <response_body></response_body>
   <response_status>201 Created</response_status>
   <errors>
   </errors>
   </delete>

Or SLO upload failures:

   $ curl http://saio:8090/v1/AUTH_test/c/slo?multipart-manifest=put -X PUT \
      -d '[{"path": "not/found"}]' -H accept:application/xml
   <delete>
   <errors>
   <object><name>not/found</name><status>404 Not Found</status></object></errors>
   </delete>

Why <delete>? Makes no sense.

Drive-by: stop being so quadratic.

Change-Id: I46b233864ba2815ac632d856b9f3c40cc9d0001a
2017-11-01 03:50:26 +00:00
Tim Burke
88c9ba4396 Fix bulk heartbeating when emitting XML
Previously, we would set eventlet.minimum_write_chunk_size *after* we
emit the XML declaration. As a result, eventlet thinks it should buffer
the entire response, rendering our attempts at heartbeating useless.

Change-Id: Idb58c6cc982cc221fed5fc837afd06aa958d9ad4
2017-10-10 00:35:42 +00:00
lingyongxu
ee9458a250 Using assertIsNone() instead of assertEqual(None)
Following OpenStack Style Guidelines:
[1] http://docs.openstack.org/developer/hacking/#unit-tests-and-assertraises
[H203] Unit test assertions tend to give better messages for more specific
assertions. As a result, assertIsNone(...) is preferred over
assertEqual(None, ...) and assertIs(..., None)

Change-Id: If4db8872c4f5705c1fff017c4891626e9ce4d1e4
2017-06-07 14:05:53 +08:00
Tim Burke
6970099a76 Fix intermittent bulk delete unit test failures
Change-Id: I0822b14d7b1ddae5fe0cc567c7cbaf544cb081ee
Closes-Bug: 1588414
2016-06-29 14:30:39 -07:00
Tim Burke
e09c4ee780 Allow concurrent bulk deletes
Before, server-side deletes of static large objects could take a long
time to complete since the proxy would wait for a response to each
segment DELETE before starting the next DELETE request.

Now, operators can configure a concurrency factor for the slo and bulk
middlewares to allow up to N concurrent DELETE requests. By default, two
DELETE requests will be allowed at a time.

Note that objects and containers are now deleted in separate passes, to
reduce the likelihood of 409 Conflict responses when deleting
containers.

Upgrade Consideration
=====================
If operators have enabled the bulk or slo middlewares and would like to
preserve the prior (single-threaded) DELETE behavior, they must add the
following line to their [filter:slo] and [filter:bulk] proxy config
sections:

   delete_concurrency = 1

This may be done prior to upgrading Swift.

UpgradeImpact
Closes-Bug: 1524454
Change-Id: I128374d74a4cef7a479b221fd15eec785cc4694a
2016-05-23 21:38:45 -07:00
Samuel Merritt
9430f4c9f5 Move HeaderKeyDict to avoid an inline import
There was a function in swift.common.utils that was importing
swob.HeaderKeyDict at call time. It couldn't import it at compilation
time since utils can't import from swob or else it blows up with a
circular import error.

This commit just moves HeaderKeyDict into swift.common.header_key_dict
so that we can remove the inline import.

Change-Id: I656fde8cc2e125327c26c589cf1045cb81ffc7e5
2016-03-07 12:26:48 -08:00
janonymous
f5f9d791b0 pep8 fix: assertEquals -> assertEqual
assertEquals is deprecated in py3, replacing it.

Change-Id: Ida206abbb13c320095bb9e3b25a2b66cc31bfba8
Co-Authored-By: Ondřej Nový <ondrej.novy@firma.seznam.cz>
2015-10-11 12:57:25 +02:00
Victor Stinner
c0af385173 py3: Replace urllib imports with six.moves.urllib
The urllib, urllib2 and urlparse modules of Python 2 were reorganized
into a new urllib namespace on Python 3. Replace urllib, urllib2 and
urlparse imports with six.moves.urllib to make the modified code
compatible with Python 2 and Python 3.

The initial patch was generated by the urllib operation of the sixer
tool on: bin/* swift/ test/.

Change-Id: I61a8c7fb7972eabc7da8dad3b3d34bceee5c5d93
2015-10-08 15:24:13 +02:00
Victor Stinner
f2cac20d17 py3: Replace unicode with six.text_type
The unicode type was renamed to str in Python 3. Use six.text_type to
make the modified code compatible with Python 2 and Python 3.

The initial patch was generated by the unicode operation of the sixer
tool on: bin/* swift/ test/.

Change-Id: I9e13748ccde36ee8110756202d55d3ae945d4860
2015-10-08 13:16:43 +02:00
Jenkins
187cea5445 Merge "Replace StringIO with BytesIO for WSGI input" 2015-07-24 06:52:40 +00:00
Jenkins
260e976e50 Merge "Get StringIO and cStringIO from six.moves" 2015-07-24 06:52:36 +00:00
janonymous
cd7b2db550 unit tests: Replace "self.assert_" by "self.assertTrue"
The assert_() method is deprecated and can be safely replaced by assertTrue().
This patch makes sure that running the tests does not create undesired
warnings.

Change-Id: I0602ba39ef93263386644ee68088d5f65fcb4a71
2015-07-21 19:23:00 +05:30
Victor Stinner
8753e452b0 Replace StringIO with BytesIO for WSGI input
wsgi.input is a binary stream (bytes), not a text stream (unicode).

* Replace StringIO with BytesIO for WSGI input
* Replace StringIO('') with StringIO() and replace WsgiStringIO('') with
  WsgiStringIO(): an empty string is already the default value

Change-Id: I09c9527be2265a6847189aeeb74a17261ddc781a
2015-07-15 16:56:33 +02:00
Victor Stinner
6e70f3fa32 Get StringIO and cStringIO from six.moves
* replace "from cStringIO import StringIO"
  with "from six.moves import cStringIO as StringIO"
* replace "from StringIO import StringIO"
  with "from six import StringIO"
* replace "import cStringIO" and "cStringIO.StringIO()"
  with "from six import moves" and "moves.cStringIO()"
* replace "import StringIO" and "StringIO.StringIO()"
  with "import six" and "six.StringIO()"

This patch was generated by the stringio operation of the sixer tool:
https://pypi.python.org/pypi/sixer

Change-Id: Iacba77fec3045f96773d1090c0bd48613729a561
2015-07-15 16:56:33 +02:00
Jenkins
b2e79357bb Merge "Replace dict.iteritems() with dict.items()" 2015-07-09 18:36:05 +00:00
Victor Stinner
e70b66586e Replace dict.iteritems() with dict.items()
The iteritems() of Python 2 dictionaries has been renamed to items() on
Python 3. According to a discussion on the openstack-dev mailing list,
the overhead of creating a temporary list using dict.items() on Python 2
is very low because most dictionaries are small:

http://lists.openstack.org/pipermail/openstack-dev/2015-June/066391.html

Patch generated by the following command:

    sed -i 's,iteritems,items,g' \
      $(find swift -name "*.py") \
      $(find test -name "*.py")

Change-Id: I6070bb6c684be76e8e77222a7d280ec6edd43496
2015-06-24 09:39:55 +02:00
Victor Stinner
e5c962a28c Replace xrange() with six.moves.range()
Patch generated by the xrange operation of the sixer tool:
https://pypi.python.org/pypi/sixer

Manual changes:

* Fix indentation for pep8 checks
* Fix TestGreenthreadSafeIterator.test_access_is_serialized of
  test.unit.common.test_utils:
  replace range(1, 11) with list(range(1, 11))
* Fix UnsafeXrange docstring, revert change

Change-Id: Icb7e26135c5e57b5302b8bfe066b33cafe69fe4d
2015-06-23 07:29:15 +00:00
Samuel Merritt
215cd551df Bulk upload: treat user xattrs as object metadata
Currently, if you PUT a single object, then you can also associate
metadata with it by putting it in the request headers, prefixed with
"X-Object-Meta". However, if you're bulk-uploading objects, then you
have no way to assign any metadata.

The tar file format* allows for arbitrary UTF-8 key/value pairs to be
associated with each file in an archive (as well as with the archive
itself, but we don't care about that here). If a file has extended
attributes, then tar will store those as key/value pairs.

This commit makes bulk upload read those extended attributes, if
present, and convert those to Swift object metadata. Attributes
starting with "user.meta" are converted to object metadata, and
"user.mime_type"** is converted to Content-Type.

For example, if you have a file "setup.py":

    $ setfattr -n user.mime_type -v "application/python-setup" setup.py
    $ setfattr -n user.meta.lunch -v "burger and fries" setup.py
    $ setfattr -n user.meta.dinner -v "baked ziti" setup.py
    $ setfattr -n user.stuff -v "whee" setup.py

This will get translated to headers:

    Content-Type: application/python-setup
    X-Object-Meta-Lunch: burger and fries
    X-Object-Meta-Dinner: baked ziti

Swift will handle xattrs stored by both GNU and BSD tar***. Only
xattrs user.mime_type and user.meta.* are processed; others are
ignored.

This brings bulk upload much closer to feature-parity with non-bulk upload.

* The POSIX 1003.1-2001 (pax) format, at least. There are a few
  different, mutually-incompatible tar formats out there, because of
  course there are. This is the default format on GNU tar 1.27.1 or
  later.

** http://standards.freedesktop.org/shared-mime-info-spec/latest/ar01s02.html#idm140622087713936

*** Even with pax-format tarballs, different encoders store xattrs
    slightly differently; for example, GNU tar stores the xattr
    "user.rubberducky" as pax header "SCHILY.xattr.user.rubberducky",
    while BSD tar (which uses libarchive) stores it as
    "LIBARCHIVE.xattr.user.rubberducky". One might wonder if this is
    some programmer's attempt at job security.

Change-Id: I5e3ce87d31054f5239e86d47c45adbde2bb93640
2015-04-21 18:42:32 -07:00
Peter Portante
07fcf50c3a Rework use of constraints to ease testing
Prior to this patch both mainline code and testing modules imported
and used constraints directly into their own namespace, or relied on
the namespace of other modules that were not the constraints
module. This meant that if a unit test wanted to change a constraint
for its operation, it had to know how that module was using the
constraint, instead of referencing the constraint module itself.

This patch unifies the use of constraints so that all constraints are
referenced via the constraints module. In turn, this allows a test to
leverage the re-loadable nature of the constraints in the constraints
module.

It addition, a number of functional tests where using the default
values for constraints, instead of the configured value discovered in
a test.conf or in an existing swift.conf. This patch removes those
direct references in favor of the load_constraint() method from the
test/functional/tests.py module.

Change-Id: Ia5313d653c667dd9ca800786de59b59334c34eaa
2014-04-02 23:48:01 -04:00
Jenkins
13563e3d87 Merge "Make POST for bulk delete actually work" 2014-01-12 07:15:11 +00:00
Samuel Merritt
aae254df55 Make POST for bulk delete actually work
Change-Id: I568e7e31df3dcbeac20dba6d543a13c0409de00e
Closes-Bug: 1232787
2013-12-21 11:32:34 -08:00
Cristian A Sanchez
96c9ff56fa Adds a retry mechanism when deleting containers
Bulk middleware now has a mechanism to retry a delete when the
HTTP response code is 409. This happens when the container still
has objects. It can be useful in a bulk delete where you delete
all the objects in a container and then try to delete the container.
It is very likely that at the end it will fail because the replica
objects have not been deleted by the time the middleware got a
successful response.

Change-Id: I1614fcb5cc511be26a9dda90753dd08ec9546a3c
Closes-Bug: #1253478
2013-12-09 19:16:35 -08:00
Samuel Merritt
0d45e99ff0 Expose bulk-operation limits in /info.
These will allow clients to perform the minimal number of requests
required to accomplish some bulk tasks. For example, a client with
many objects to delete can learn that the cluster's limit on
deletes-per-request is, say, 128, and then batch up their deletes in
groups of 128. Without this, the client has to either discover the
limit out-of-band somehow (and get notified if it changes), or do some
sort of binary search to figure out the limit.

Similar reasoning applies to the containers-per-request value.

The errors-per-request values are included so that clients may size
their requests such that everything is attempted regardless of
failure.

I split the 'bulk' entry into 'bulk_delete' and 'bulk_upload' because,
from a client's standpoint, they're separate operations. It so happens
that Swift implements both in one piece of middleware, but clients
don't care.

Bonus fix: documented a missing config setting for the bulk middleware.

Change-Id: Ic3549aef79682fd5b798145c3545c1609aa1592b
2013-11-30 11:09:34 -08:00
Jenkins
62b693d133 Merge "Use POST in bulk-delete" 2013-11-22 09:11:05 +00:00
Kun Huang
94090e8760 Use POST in bulk-delete
The DELETE verb applies to a single resource, and doesn't define any
semantics for the body.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7

The swift Bulk Delete command affects multiple resources specified in a
DELETE body.

http://docs.openstack.org/developer/swift/misc.html#module-swift.common.middleware.bulk

While Bulk Delete is a welcome operation, its usage of DELETE is
unusual: affecting multiple resources and relying on reading content.

More typically, such an operation employs POST (or PUT), which folks
including api-craft usually agree is the best "catch-all" verb for
behaviors such as those affecting multiple resources. That's the TL;DR;
of the thread below.

https://groups.google.com/forum/#!searchin/api-craft/Regarding$20Bulk$20actions/api-craft/wY-W1NdZDRs/7YDwMhCR608J

Note that this topic isn't nasal or abstract. The current behavior is
unsupported using the built-in java http client. Even if third-party
libraries can work around this behavior, it is probably best to not be a
snowflake wrt http verb semantics where possible!

http://stackoverflow.com/questions/9100776/http-delete-with-request-body-issues

DocImpact

Closes-Bug: #1232787
Change-Id: I0fc74c85618fe4dd7ff5e7f9756c7f6f67aa0465
2013-11-20 11:28:14 +08:00
David Goetz
d6c65c34aa catch decompression errors
Change-Id: Ica380edc2364a5e18cefc26f70710e18ea329cfa
2013-10-25 19:56:19 +00:00
Jenkins
0b594bc3af Merge "Change OpenStack LLC to Foundation" 2013-10-07 16:09:37 +00:00
David Goetz
df39602c41 bulk delete bug with trailing whitespace
Change-Id: Ia48224a1a187a8ed6b0c9a3c72cac06f084a6fc8
2013-09-26 11:17:18 -07:00
Brian D. Burns
3e6f9293b8 update SLO delete error handling
* ensure all responses are 200 OK
* report missing sub-SLO manifests or other error messages in bulk
  delete response

Change-Id: Iaf88c94bc7114ff3c9751f9f31f8f748de911f8a
2013-09-22 16:26:15 -04:00
ZhiQiang Fan
f72704fc82 Change OpenStack LLC to Foundation
Change-Id: I7c3df47c31759dbeb3105f8883e2688ada848d58
Closes-bug: #1214176
2013-09-20 01:02:31 +08:00
David Goetz
4893aacc67 Allow users to extract tars to containers with ACLs set
This fixes bug: https://bugs.launchpad.net/swift/+bug/1203182 (well
it should :) I don't have keystone installed but the same issue
existed with tempauth).

Change-Id: I6f4045f484b27c0153a9244e0dbf2641cbc9e84e
2013-08-30 14:36:26 -07:00
Kun Huang
4ef993735b clean temp dir in /tmp
In unit tests, many test class use tempfile.mkdtemp in SetUp and
shutil.rmtree in tearDown.

A common wrong case is putting test data in `testdir = os.join(mkdtemp() +
'some_class')` and `rmmtree(testdir)`. As a result, /tmp/xxx/some_class
was deleted, but /tmp/xxx is still leaved in system. So a proper fix is
`rmtree(os.path.dirname(testdir), ignore_errors=1)`

fixes bug #1212583

Change-Id: Iafbe3e11f16b51bdf49abce9e68eb01f25bc5df2
2013-08-16 00:17:08 +08:00
Samuel Merritt
f2c3e1af9c Fix bulk's unit tests on Mac OS.
Turns out if your $TMPDIR is really long
(e.g. /var/folders/vq/n32yszdn4s76z6l8dxklmwdh0000gn/T/, which is 50
characters), then the test that drops stuff into $TMPDIR and adds it
to a tarball and uploads it will fail due to every added file's name
being too long.

Change-Id: I8fcab2d95091f72b831b906bfc87a36d8be12631
2013-07-23 15:30:11 -07:00
Brian D. Burns
6768d5b4be Use object name from request in bulk Errors
This will allow users to more easily match the failed objects in Errors
for bulk delete requests to the object names they provided in the request.
For extract Errors, it reports the failed path from the tar archive.

DocImpact

Change-Id: I084057810fc4fb7fdac05494cc6fec2cbf81bb9d
2013-06-24 16:44:32 -04:00
David Goetz
ad24cde120 bulk response Content-Type does not match request Accept header
Change-Id: Ieceed3837466c45bc2790b09cd56ae95f43dba2e
2013-06-19 07:45:46 -07:00
David Goetz
af2607c457 Refactor Bulk middleware to handle long running requests
Change-Id: I8ea0ff86518d453597faae44ec3918298e2d5147
2013-05-08 10:00:21 -07:00
Greg Lange
44f00a23c1 fixed some minor things in tests that pyflakes complained about
Change-Id: Ifeab56a964630bcf941e932fcbe39e6572e62975
2013-03-26 20:42:26 +00:00
David Goetz
92e877ae51 Fix bugs in bulk and slo and small doc change.
Added 411 responses in bulk and slo when needed.

Make X-Static-Large-Object an illegal header with slo installed- somehow
that got lost with some refactor I did.

Change-Id: I986c1656658f874172860469624118cc63bff9bc
2013-03-21 09:56:54 -07:00
David Goetz
1b150749f7 fix stupid bug with bulk delete max items
Change-Id: I52160b5e7480112d536c45dd4b0b10a808adcdcd
2013-03-19 11:48:14 -07:00
David Goetz
5d73da158b Static Large Object Support
DocImpact

Change-Id: I7edaa5e44208ab451f7f7566b64bb571b8eea1f9
2013-03-01 16:46:10 -08:00
David Goetz
08c017418b Change the flag set to specify bulk delete and expand archives from a HTTP
header to a query parameter.

This is needed because query parameters show up in proxy logs and headers do
not. With this change it will be easy to determine from any log line that gets
created from the original request (of which there is currently none) that the
request was a bulk action.

Note: This is not backwards compatible with the previous method of setting a
header. Because the bulk middleware has not been included in an openstack swift
release this should be fine.

Change-Id: I0297fa2de9e491bf0b8c430c0781e2e12316ed4b
2013-02-07 11:11:32 -08:00
David Goetz
2f663ff9a0 Bulk Requests: auto extract archive and bulk delete middleware.
Fix small problem in ratelimiting middleware.

DocImpact

Change-Id: Ide3e0b9f4887626c30cae0b97eb7e2237b1df3ed
2013-01-24 12:34:56 -08:00