2503 Commits

Author SHA1 Message Date
Jenkins
e283718ed0 Merge "Add test to verify staticweb uses auth'd subrequests" 2015-10-22 10:40:19 +00:00
Jenkins
76c83cd501 Merge "Add backend subrequest tests for staticweb" 2015-10-22 10:40:11 +00:00
Jenkins
a148a00cdb Merge "Do not use pre-authenticated requests in staticweb" 2015-10-22 10:38:19 +00:00
Jenkins
e0e8d8a255 Merge "Port swift.common.utils.backward() to Python 3" 2015-10-21 01:25:25 +00:00
Jenkins
2c35859142 Merge "Make db_replicator usync smaller containers" 2015-10-19 16:56:35 +00:00
Victor Stinner
71e573f4ba Port swift.common.utils.backward() to Python 3
backward() is written to handle binary files:

* Replace literal native strings to literal byte strings: add b'...'
  prefix
* Update unit tests: use byte strings
* TemporaryFile(): use the default mode 'w+b', instead of using 'r+w'
  ('r+w' mode creates a Unicode file on Python 3).

Change-Id: Ic91f7e6c605db0b888763080d49f0f501029837f
2015-10-19 17:57:01 +02:00
Matthew Oliver
4a13dcc4a8 Make db_replicator usync smaller containers
The current rule inside the db_replicator is to rsync+merge
containers during replication if the difference between rowids
differ by more than 50%:

  # if the difference in rowids between the two differs by
  # more than 50%, rsync then do a remote merge.
  if rinfo['max_row'] / float(info['max_row']) < 0.5:

This mean on smaller containers, that only have few rows, and differ
by a small number still rsync+merge rather then copying rows.

This change adds a new condition, the difference in the rowids must
be greater than the defined per_diff otherwise usync will be used:

  # if the difference in rowids between the two differs by
  # more than 50% and the difference is greater than per_diff,
  # rsync then do a remote merge.
  # NOTE: difference > per_diff stops us from dropping to rsync
  # on smaller containers, who have only a few rows to sync.
  if rinfo['max_row'] / float(info['max_row']) < 0.5 and \
          info['max_row'] - rinfo['max_row'] > self.per_diff:

Change-Id: I9e779f71bf37714919a525404565dd075762b0d4
Closes-bug: #1019712
2015-10-19 15:26:12 +01:00
Jenkins
c49f71585b Merge "Close ECAppIter's sub-generators before propagating GeneratorExit" 2015-10-19 11:47:50 +00:00
Kota Tsuyuzaki
43cdc29669 Add backend subrequest tests for staticweb
This is an followup for
https://review.openstack.org/#/c/227204

Above patch changes staticweb to use just make_env instead of
pre authed env. The tests included in this patch assert
"backend requests generated by staticweb *NEVER* include pre
authed information (i.e. authorize_override=True)".

Change-Id: Ifbbc43d3b5ac114bc3d5e4fcab9cacdf9a3f1a5c
2015-10-15 10:59:42 +01:00
Jenkins
ca2ec2769c Merge "Improve SLO PUT error checking" 2015-10-14 18:39:10 +00:00
Alistair Coles
9993c1f124 Add test to verify staticweb uses auth'd subrequests
Follow on for change Icf159d7e567ac5481e710c5910db686bdcba6336

Related-Bug: 1489749

Change-Id: I96920645d50322c5232bbcd6bb38b0f26795b92d
2015-10-14 16:06:26 +01:00
Jenkins
fdc8828e85 Merge "py3: Replace basestring with six.string_types" 2015-10-13 10:56:05 +00:00
Christian Schwede
a7af802497 Do not use pre-authenticated requests in staticweb
staticweb middleware uses make_pre_authed_env, this makes it possible to
anonymously list containers without any read acl set if the metadata
"web-listings: true" is set on a container. Using make_env enforces correct
read_acl validation; however it is now also required to add ".rlistings" to the
read acl.

Also, if the staticweb middleware is put in the proxy pipeline before an
authentication middleware, it broke authenticated GET and HEAD requests. This
has some side effects in clients, because a html response is sent that might be
parsed wrongly by the client. In case of python-swiftclient this was shown as an
empty container without any ACL or web-listings:true meta set. This might lead
to information leaks, because a user trusts the output from python-swiftclient
and assumes an empty, private container even if the container contains public
readable data. staticweb now checks if "swift.authorize" is included in the
environ and skips itself if not.

Closes-Bug: 1489749
Change-Id: Icf159d7e567ac5481e710c5910db686bdcba6336
Depends-On: Ie24bb995023c377e49796910ad80a256b00daa03
2015-10-13 07:16:13 +00:00
Jenkins
70a52e6149 Merge "swift-recon fails with socket.timeout exception" 2015-10-13 07:11:53 +00:00
Jenkins
8cfe1b701a Merge "Fix 'swift-ring-builder write_builder' after you remove a device" 2015-10-13 00:04:25 +00:00
Samuel Merritt
c0866ceaac Improve SLO PUT error checking
This commit tries to give the user a reason that their SLO manifest
was invalid instead of just saying "Invalid SLO Manifest File". It
doesn't get every error condition, but it's better than before.

Examples of things that now have real error messages include:
 * bad keys in manifest (e.g. using "name" instead of "path")
 * bogus range (e.g. "bytes=123-taco")
 * multiple ranges (e.g. "bytes=10-20,30-40")
 * bad JSON structure (i.e. not a list of objects)
 * non-integer size_bytes

Also fixed an annoyance with unspecified-size segments that are too
small. Previously, if you uploaded a segment reference with
'{"size_bytes": null, ...}' in it and the referenced segment was less
than 1 MiB, you'd get a response that looked like this:

    HTTP/1.1 400 Bad Request
    Content-Length: 62
    Content-Type: text/html; charset=UTF-8
    X-Trans-Id: txd9ee3b25896642098e4d9-0055dd095a
    Date: Wed, 26 Aug 2015 00:33:30 GMT

    Each segment, except the last, must be at least 1048576 bytes.

This is true, but not particularly helpful, since it doesn't tell you
which of your segments violated the rule.

Now you get something more like this:

    HTTP/1.1 400 Bad Request
    Content-Length: 49
    Content-Type: text/plain
    X-Trans-Id: tx586e52580bac4956ad8e2-0055dd09c2
    Date: Wed, 26 Aug 2015 00:35:14 GMT

    Errors:
    /segs/small, Too Small; each segment, except the last...

It's not exactly a tutorial on SLO manifests, but at least it names
the problematic segment.

This also changes the status code for a self-referential manifest from
409 to 400. The rest of the error machinery was using 400, and
special-casing self-reference would be really annoying. Besides, now
that we're showing more than one error message at a time, what would
the right status code be for a manifest with a self-referential
segment *and* a segment with a bad range? 400? 409? 404.5? It's much
more consistent to just say invalid manifest --> 400.

Change-Id: I2275683230b36bc273319254e37c16b9e9b9d69c
2015-10-12 16:31:26 -07:00
Jenkins
cc46ab0b8f Merge "py3: Replace gen.next() with next(gen)" 2015-10-12 19:45:29 +00:00
Emile Snyder
92767f28d6 Fix 'swift-ring-builder write_builder' after you remove a device
clayg already posted the code fix in the bug, but noted it needs a test.

Closes-Bug: #1487280
Change-Id: I07317754afac7165baac4e696f07daeba2e72adc
2015-10-12 08:17:49 -07:00
Lisak, Peter
a486490029 swift-recon fails with socket.timeout exception
If some server is overloaded or timeout set too low, swift-recon fails with
raised socket.timeout exception.

This error should be processed the same way as HTTPError/URLError.

Change-Id: Ide8843977ab224fa866097d0f0b765d6899c66b8
2015-10-12 14:42:01 +02:00
janonymous
1882801be1 pep8 fix: assertNotEquals -> assertNotEqual
assertNotEquals is deprecated in py3

Change-Id: Ib611351987bed1199fb8f73a750955a61d022d0a
2015-10-12 07:40:07 +00: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
Jenkins
6b854bd908 Merge "py3: Replace urllib imports with six.moves.urllib" 2015-10-10 07:20:26 +00:00
Victor Stinner
84f0a54445 py3: Replace basestring with six.string_types
The builtin basestring type was removed in Python 3. Replace it with
six.string_types which works on Python 2 and Python 3.

Change-Id: Ib92a729682322cc65b41050ae169167be2899e2c
2015-10-09 22:20:03 +02:00
Jenkins
e15be1e6ec Merge "swift-ring-builder can't select id=0" 2015-10-09 09:58:22 +00:00
Lisak, Peter
a5d2faab90 swift-ring-builder can't select id=0
Currently, it is not possible to change weight of device with id=0
by swift-ring-builder cli. Instead of change the help is shown.
Example:
$ swift-ring-builder object.builder set_weight --id 0 1.00

But id=0 is generated by swift for the first device if not provided.
Also --weight, --zone and --region cause the same bug.

There is problem to detect new command format in validate_args
function if zero is as valid value for some args.

Change-Id: I4ee379c242f090d116cd2504e21d0e1904cdc2fc
2015-10-08 15:57:01 +02:00
Victor Stinner
8f85427939 py3: Replace gen.next() with next(gen)
The next() method of Python 2 generators was renamed to __next__().
Call the builtin next() function instead which works on Python 2 and
Python 3.

The patch was generated by the next operation of the sixer tool.

Change-Id: Id12bc16cba7d9b8a283af0d392188a185abe439d
2015-10-08 15:40:06 +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
647e97e63b Merge "Python 3 using builtins instead of __builtin__, rename raw_input() to input() from six.moves" 2015-10-08 08:41:30 +00:00
Jenkins
2b521dfbaa Merge "Port swob to Python 3" 2015-10-08 06:05:17 +00:00
Jenkins
6ff6bb272e Merge "Fix replicator intersection exception when sync data to remote regions." 2015-10-08 05:09:09 +00:00
Christian Schwede
c30ceec6f1 Fix ring device checks in probetests
If a device has been removed from one of the rings, it actually is set as None
within the ring. In that case the length of the devices is not True without
filtering the None devices. However, if the length matched the condition but
included a removed device the probetests would fail with a TypeError.

This fix could be done also in swift/common/ring/ring.py, but it seems it only
affects probetests right now, thus fixing it there and not changing the current
behavior.

Change-Id: I8ccf9b32a51957e040dd370bc9f711d4328d17b1
2015-10-07 19:59:15 +00:00
Charles Hsu
d01cd42509 Fix replicator intersection exception when sync data to remote regions.
This patch fixed the exception (AttributeError: 'list' object has no
attribute 'intersection') when replicator try to sync data from
handoff to primary partition in more than one remote region.

Change-Id: I565c45dda8c99d36e24dbf1145f2d2527d593ac0
Closes-Bug: 1503152
2015-10-07 12:18:35 -07:00
Jenkins
ce52187375 Merge "replace use of deprecated rfc822.Message with a helper utility" 2015-10-07 12:45:48 +00:00
Jenkins
84687ee324 Merge "Change POST container semantics" 2015-10-06 19:10:15 +00:00
Jenkins
bcd17c550d Merge "Fix slorange on-disk format when including whole object" 2015-10-06 17:16:01 +00:00
Clay Gerrard
752ceb266b Close ECAppIter's sub-generators before propagating GeneratorExit
... which ensures no Timeouts remain pending after the parent generator
is closed when a client disconnects before being able to read the entire
body.

Also tighten up a few tests that may have left some open ECAppIter
generators lying about after the tests themselves had finished.  This
has the side effect of preventing the extraneous printing of the Timeout
errors being raised by the eventlet hub in the background while our
unittests are running.

Change-Id: I156d873c72c19623bcfbf39bf120c98800b3cada
2015-10-05 13:31:09 -07:00
Zack M. Davis
06bede8942 replace use of deprecated rfc822.Message with a helper utility
The rfc822 module has been deprecated since Python 2.3, and in
particular is absent from the Python 3 standard library. However, Swift
uses instances of rfc822.Message in a number of places, relying on its
behavior of immediately parsing the headers of a file-like object
without consuming the body, leaving the position of the file at the
start of the body. Python 3's http.client has an undocumented
parse_headers function with the same behavior, which inspired the new
parse_mime_headers utility introduced here. (The HeaderKeyDict returned
by parse_mime_headers doesn't have a `.getheader(key)` method like
rfc822.Message did; the dictionary-like `[key]` or `.get(key)` interface
should be used exclusively.)

The implementation in this commit won't actually work with Python 3, the
email.parser.Parser().parsestr of which expects a Unicode string, but it
is believed that this can be addressed in followup work.

Change-Id: Ia5ee2ead67e36e8c6416183667f64ae255887736
2015-10-05 12:22:24 -07:00
Jenkins
ab78b2409a Merge "Make sure we have enough .durable's for GETs" 2015-10-03 02:04:23 +00:00
Jenkins
c799d4de52 Merge "Validate against duplicate device part replica assignment" 2015-10-03 01:35:12 +00:00
Clay Gerrard
5070869ac0 Validate against duplicate device part replica assignment
We should never assign multiple replicas of the same partition to the
same device - our on-disk layout can only support a single replica of a
given part on a single device.  We should not do this, so we validate
against it and raise a loud warning if this terrible state is ever
observed after a rebalance.

Unfortunately currently there's a couple not necessarily uncommon
scenarios which will trigger this observed state today:

 1. If we have less devices than replicas
 2. If a server or zones aggregate device weight make it the most
    appropriate candidate for multiple replicas and you're a bit unlucky

Fixing #1 would be easy, we should just not allow that state anymore.
Really we never did - if you have a 3 replica ring with one device - you
have one replica.  Everything that iter_nodes'd would de-dupe.  We
should just be insisting that you explicitly acknowledge your replica
count with set_replicas.

I have been lost in the abyss for days searching for a general solutions
to #2.  I'm sure it exists, but I will not have wrestled it to
submission by RC1.  In the meantime we can eliminate a great deal of the
luck required simply by refusing to place more than one replica of a
part on a device in assign_parts.

The meat of the change is a small update to the .validate method in
RingBuilder.  It basically unrolls a pre-existing (part, replica) loop
so that all the replicas of the part come out in order so that we can
build up the set of dev_id's for which all the replicas of a given part
are assigned part-by-part.

If we observe any duplicates - we raise a warning.

To clean the cobwebs out of the rest of the corner cases we're going to
delay get_required_overload from kicking in until we achive dispersion,
and a small check was added when selecting a device subtier to validate
if it's already being used - picking any other device in the tier works
out much better.  If no other devices are available in the tier - we
raise a warning.  A more elegant or optimized solution may exist.

Many unittests did not meet the criteria #1, but the fix was straight
forward after being identified by the pigeonhole check.

However, many more tests were affected by #2 - but again the fix came to
be simply adding more devices.  The fantasy that all failure domains
contain at least replica count devices is prevalent in both our ring
placement algorithm and it's tests.  These tests were trying to
demonstrate some complex characteristics of our ring placement algorithm
and I believe we just got a bit too carried away trying to find the
simplest possible example to demonstrate the desirable trait.  I think
a better example looks more like a real ring - with many devices in each
server and many servers in each zone - I think more devices makes the
tests better.  As much as possible I've tried to maintain the original
intent of the tests - when adding devices I've either spread the weight
out amongst them or added proportional weights to the other tiers.

I added an example straw man test to validate that three devices with
different weights in three different zones won't blow up.  Once we can
do that without raising warnings and assigning duplicate device part
replicas - we can add more.  And more importantly change the warnings to
errors - because we would much prefer to not do that #$%^ anymore.

Co-Authored-By: Kota Tsuyuzaki <tsuyuzaki.kota@lab.ntt.co.jp>
Related-Bug: #1452431
Change-Id: I592d5b611188670ae842fe3d030aa3b340ac36f9
2015-10-02 16:42:25 -07:00
Clay Gerrard
a31ee07bda Make sure we have enough .durable's for GETs
Increase the number of nodes from which we require a final successful
HTTP responses before we return success to the client on a write - to
the same number of nodes we'll require successful responses from to
service a client request for a read.

Change-Id: Ifd36790faa0a5d00ec79c23d1f96a332a0ca0f0b
Related-Bug: #1469094
2015-10-02 13:53:27 -07:00
Jenkins
0e3e2db913 Merge "Add POST capability to ssync for .meta files" 2015-10-02 13:54:51 +00:00
Alistair Coles
29c10db0cb Add POST capability to ssync for .meta files
ssync currently does the wrong thing when replicating object dirs
containing both a .data and a .meta file. The ssync sender uses a
single PUT to send both object content and metadata to the receiver,
using the metadata (.meta file) timestamp. This results in the object
content timestamp being advanced to the metadata timestamp,
potentially overwriting newer object data on the receiver and causing
an inconsistency with the container server record for the object.

For example, replicating an object dir with {t0.data(etag=x), t2.meta}
to a receiver with t1.data(etag=y) will result in the creation of
t2.data(etag=x) on the receiver. However, the container server will
continue to list the object as t1(etag=y).

This patch modifies ssync to replicate the content of .data and .meta
separately using a PUT request for the data (no change) and a POST
request for the metadata. In effect, ssync replication replicates the
client operations that generated the .data and .meta files so that
the result of replication is the same as if the original client requests
had persisted on all object servers.

Apart from maintaining correct timestamps across sync'd nodes, this has
the added benefit of not needing to PUT objects when only the metadata
has changed and a POST will suffice.

Taking the same example, ssync sender will no longer PUT t0.data but will
POST t2.meta resulting in the receiver having t1.data and t2.meta.

The changes are backwards compatible: an upgraded sender will only sync
data files to a legacy receiver and will not sync meta files (fixing the
erroneous behavior described above); a legacy sender will operate as
before when sync'ing to an upgraded receiver.

Changes:
- diskfile API provides methods to get the data file timestamp
  as distinct from the diskfile timestamp.

- diskfile yield_hashes return tuple now passes a dict mapping data and
  meta (if any) timestamps to their respective values in the timestamp
  field.

- ssync_sender will encode data and meta timestamps in the
  (hash_path, timestamp) tuple sent to the receiver during
  missing_checks.

- ssync_receiver compares sender's data and meta timestamps to any
  local diskfile and may specify that only data or meta parts are sent
  during updates phase by appending a qualifier to the hash returned
  in its 'wanted' list.

- ssync_sender now sends POST subrequests when a meta file
  exists and its content needs to be replicated.

- ssync_sender may send *only* a POST if the receiver indicates that
  is the only part required to be sync'd.

- object server will allow PUT and DELETE with earlier timestamp than
  a POST

- Fixed TODO related to replicated objects with fast-POST and ssync

Related spec change-id: I60688efc3df692d3a39557114dca8c5490f7837e

Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>
Closes-Bug: 1501528
Change-Id: I97552d194e5cc342b0a3f4b9800de8aa6b9cb85b
2015-10-02 11:24:19 +00:00
Jenkins
fc7c8c23c9 Merge "Fix copy requests to service accounts in Keystone" 2015-10-02 03:10:18 +00:00
Tim Burke
969f1ea939 Fix slorange on-disk format when including whole object
Not that the current implementation is broken, just wasteful.

When a client specifies a range for an SLO segment that includes the
entire referenced object, we should drop the 'range' key from the
manifest that's stored on disk.

Previously, we would do this if the uploaded manifest included the
object-length for validation, but not if it didn't. Now we will
always drop the 'range' key if the entire segment is being used.

Change-Id: I69d2fff8c7c59b81e9e4777bdbefcd3c274b59a9
Related-Change: Ia21d51c2cef4e2ee5162161dd2c1d3069009b52c
2015-10-01 21:22:40 +00:00
Christian Schwede
4b8f52b153 Fix copy requests to service accounts in Keystone
In case of a COPY request the swift_owner was already set to True, and the
following PUT request was granted access no matter if a service token was used
or not.  This allowed to copy data to service accounts without any service
token.

Service token unit tests have been added to verify that when
swift_owner is set to True in a request environ, this setting is
ignored when authorizing another request based on the same
environ. Applying only this test change on master fails currently, and
only passes with the fix in this patch.

Tempauth seems to be not affected, however a small doc update has been added to
make it more clear that a service token is not needed to access a service account
when an ACL is used.

Further details with an example are available in the bug report
(https://bugs.launchpad.net/swift/+bug/1483007).

Co-Authored-By: Alistair Coles <alistair.coles@hp.com>
Co-Authored-By: Hisashi Osanai <osanai.hisashi@jp.fujitsu.com>
Co-Authored-By: Donagh McCabe <donagh.mccabe@hp.com>

Closes-Bug: 1483007
Change-Id: I1207b911f018b855362b1078f68c38615be74bbd
2015-10-01 10:01:03 +01:00
Jenkins
608bdd7245 Merge "Don't send commits for quorum *BAD* requests on EC" 2015-09-29 22:46:01 +00:00
Jenkins
4a6f0cc30b Merge "Fix inlines for test/unit/obj/test_server.py" 2015-09-29 17:29:55 +00:00
Kota Tsuyuzaki
8f1c7409e7 Don't send commits for quorum *BAD* requests on EC
In EC PUT request case, proxy-server may send commits to object-servers
it may make .durable file even though the request failed due to a lack
of quorum number.

For example:
- Considering the case that almost all object-servers fail by 422
  Unprocessable Entity
- Using ec scheme 4 + 2
- 5 (quorum size) object-server failed with 422, 1 object-servers
  succeeded as 201 created

How it works:
- Client creates a PUT request
- Proxy will open connections to backend object-servers
- Proxy will send whole encoded chunks to object-servers
- Proxy will send content-md5 as footers.
- Proxy will get responses [422, 422, 422, 422, 422, 201] (currently
  this list will be regarded as "we have quorum response")
- And then proxy will send commits to object-servers (the only
  object-server with 201 will create .durable file)
- Proxy will return 503 because the commits results in no response
  statuses from object-servers except the 201 node.

This patch fixes the quorum handling at ObjectController to check
that it has *successful* quorum responses before sending durable commits.

Closes-Bug: #1491748
Change-Id: Icc099993be76bcc687191f332db56d62856a500f
2015-09-29 05:56:12 -07:00