Support PUTs to container server with json serialized ShardRanges in
body. Shard range PUTs may autocreate containers.
Support GET of shard ranges from container server.Shard range GETs
support X-Backend-Include-Deleted to include deleted shard ranges in
list and X-Backend-Override-Delete to get shard ranges when container
has been marked as deleted.
The X-Backend-Record-Type = ['object'|'shard'|'auto'] is introduced
to differentiate container server requests for object versus shard
ranges. When 'auto' is used with a GET request the container server
will return whichever record type is appropriate for fetchng object
listings, depending on whether the container is sharded or not.
Support container PUTs with body in direct_client .py
Co-Authored-By: Matthew Oliver <matt@oliver.net.au>
Co-Authored-By: Tim Burke <tim.burke@gmail.com>
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>
Change-Id: I029782ae348f38c5fb76d2759609f67a06c883ef
Because the direct_client module uses the buffered_http module it's
requests are already robust to receiving either unicode or utf-8 paths.
The DirectClientException message however encodes the given path with
the device key from a ring node - which having come from a json
de-serialized ring will be a unicode type. Despite the device key
almost always being only ascii characters; python string interpolation
with any unicode type will always force all binary strings to be
converted to unicode - which will raise an error if any byte strings
includes non-ascii characters.
To maintain robustness in DirectClientException, when the provided path
is not already unicode we decode the bytes as utf-8 before mixing them
with the other unicode strings and then normalize everything back to a
quoted utf-8 byte string.
Change-Id: I162d2e093a3110856d6e1d513de3c7919079c9e7
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
Often, we want the current timestamp. May as well improve the ergonomics
a bit and provide a class method for it.
Change-Id: I3581c635c094a8c4339e9b770331a03eab704074
It defines self.node information in setUp(), it is unnecessary to
define node in test_direct_delete_account. Because although self.node
includes replication_ip and replication_port, direct_delete_account
doesn't use both and uses ip,port and device. Therefore, I think self.node
can instead of node.
Change-Id: I6df7081280d2b540f984e4e688620931f5d4ac88
Make the tests for direct_get_container and direct_get_account
verify all combinations of request parameters.
Change-Id: I3b929ca83b37c32927b9bf619f445d698b9bdab9
Related-Change: I846fc70ff3abdb1674152a8d9e0521c709f254c4
Currently the direct_get_container and direct_get_account methods
of the direct client don't support passing in the 'end_marker' and
'reverse' params.
This change adds support for these params in direct client.
Change-Id: I846fc70ff3abdb1674152a8d9e0521c709f254c4
Changing the recommended ports for Swift services
from ports 6000-6002 to unused ports 6200-6202;
so they do not conflict with X-Windows or other services.
Updated SAIO docs.
DocImpact
Closes-Bug: #1521339
Change-Id: Ie1c778b159792c8e259e2a54cb86051686ac9d18
When direct_client.direct_get_suffix_hashes raises a
DirectClientException the exception message and variables
should report the replication_ip and replication_port, as
opposed to the ip and port values reported for all other
case when the exception is raised.
Add option to override ip and port reported in
DirectClientException.
Also adds unit tests to verify both cases.
Related-Bug: 1566395
Change-Id: If3d952847c7199f4e9f6164858085367266386d2
direct_client.direct_get_suffix_hashes doesn't use replication ip and
port for REPLICATE request. Since we have an option of doing
replication in separate network, we can add replication_ip and port
while creating rings if not it will get filled in with the regular
node's ip.
Change-Id: I34067df27042fc3146b795191ab8043ee1aed3ce
Closes-Bug:1566395
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
Add tests for direct_delete_account, direct_get_object, retry
Tests to validate possible argument calls of direct_put_object
Extend FakeConn to support chunks in response
Change-Id: I00cbc6c535ed8b3fb29bc07fdc51fdbb1220ff10
Signed-off-by: Ganesh Maharaj Mahalingam <ganesh.mahalingam@intel.com>
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
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
* 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
Since we're dropping Python 2.6 support, we can rely on stdlib's json
and get rid of our dependency on simplejson.
This commit just takes simplejson out of the unit and functional
tests. They still pass.
Change-Id: I96f17df81fa5d265395a938b19213d2638682106
The account reaper is using a unique timestamp when deleting
replicas of the same resource. This will result in unnecessary
replication traffic after reaping.
This patch makes the reaper use a single timestamp per resource.
Probe test is modified to check that delete times are equal
across replicas before replicators run.
test_direct_client.py is modified to check that it uses explicit
timestamp when passed to direct_delete_[object|container]
methods.
Drive-by bug fixes in the probe test e.g. it was not sending
X-Backend-Storage-Policy-Index when doing a direct GET to check
object state, so the 404s being verified could in fact be due
to diskfile not existing rather than diskfile being deleted.
Closes-Bug: 1442879
Change-Id: I8bab22d66308bb9d3294e1e0def017c784228423
The call to _get_direct_account_container in direct_get_account
has several of its args =None instead of set to the value passed
to direct_get_account.
The same applies to _get_direct_account_container in
direct_get_container.
The direct_get_container is only called by the account-reaper
and this bug will have limited impact on it. The marker,
maintained in reap_container, is ignored by direct_get_container.
This is not as bad as it sounds, if the account-reaper successfully
deletes the first 10K objects, assuming the container has > 10K
objects, the next call to direct_get_container will in fact return
the next 10K objects even though it sets marker=None (assuming the
first 10K objects were successfully deleted).
This patch also updates test_direct_get_account and
test_direct_get_container to ensure the appropriate
args are included in the connection query_string.
Closes-Bug: #1369558
Change-Id: If1c8aa1240d38354ebc9b1ebca92dc1c8c36cb5f
Replaced throughout code base & tox'd. Functional as well
as probe tests pass with and without policies defined.
POLICY --> 'X-Storage-Policy'
POLICY_INDEX --> 'X-Backend-Storage-Policy-Index'
Change-Id: Iea3d06de80210e9e504e296d4572583d7ffabeac
The normalized form of the X-Timestamp header looks like a float with a fixed
width to ensure stable string sorting - normalized timestamps look like
"1402464677.04188"
To support overwrites of existing data without modifying the original
timestamp but still maintain consistency a second internal offset
vector is append to the normalized timestamp form which compares and
sorts greater than the fixed width float format but less than a newer
timestamp. The internalized format of timestamps looks like
"1402464677.04188_0000000000000000" - the portion after the underscore
is the offset and is a formatted hexadecimal integer.
The internalized form is not exposed to clients in responses from Swift.
Normal client operations will not create a timestamp with an offset.
The Timestamp class in common.utils supports internalized and normalized
formatting of timestamps and also comparison of timestamp values. When the
offset value of a Timestamp is 0 - it's considered insignificant and need not
be represented in the string format; to support backwards compatibility during
a Swift upgrade the internalized and normalized form of a Timestamp with an
insignificant offset are identical. When a timestamp includes an offset it
will always be represented in the internalized form, but is still excluded
from the normalized form. Timestamps with an equivalent timestamp portion
(the float part) will compare and order by their offset. Timestamps with a
greater timestamp portion will always compare and order greater than a
Timestamp with a lesser timestamp regardless of it's offset. String
comparison and ordering is guaranteed for the internalized string format, and
is backwards compatible for normalized timestamps which do not include an
offset.
The reconciler currently uses a offset bump to ensure that objects can move to
the wrong storage policy and be moved back. This use-case is valid because
the content represented by the user-facing timestamp is not modified in way.
Future consumers of the offset vector of timestamps should be mindful of HTTP
semantics of If-Modified and take care to avoid deviation in the response from
the object server without an accompanying change to the user facing timestamp.
DocImpact
Implements: blueprint storage-policies
Change-Id: Id85c960b126ec919a481dc62469bf172b7fb8549
Rework header handling and add some methods needed by the reconciler.
* response headers are case insensitive HeaderKeyDicts
* add direct client container obj put and delete
* add headers param to direct head object
* add headers to DirectClientException
DirectClientException is a subclass of ClientException with a convience
constructor. ClientException now supports an http_headers kwarg.
Exceptions raised from direct_client will include headers.
DocImpact
Implements: blueprint storage-policies
Change-Id: Ia484d569619df0bf85f973e4e916de2ac6401d5e
Unit tests in test/unit only have one dependency
to swiftclient in test_direct_client.py. This one
can be easily avoided and this patch removes it.
Change-Id: Ic1c78bc7f7fe426e8f7d8209a783342a0c4f071f
Enhance internally logged messages to report referer and user-agent.
Pass the referering URL and METHOD between internal servers (when
known), and set the user-agent to be the server type (obj-server,
container-server, proxy-server, obj-updater, obj-replicator,
container-updater, direct-client, etc.) with the process PID. In
conjunction with the transaction ID, it helps to track down which PID
from a given system was responsible for initiating the request and
what that server was working on to make this request.
This has been helpful in tracking down interactions between object,
container and account servers.
We also take things a bit further performaing a bit of refactoring to
consolidate calls to transfer_headers() now that we have a helper
method for constructing them.
Finally we performed further changes to avoid header key duplication
due to string literal header key values and the various objects
representing headers for requests and responses. See below for more
details.
====
Header Keys
There seems to be a bit of a problem with the case of the various
string literals used for header keys and the interchangable way
standard Python dictionaries, HeaderKeyDict() and HeaderEnvironProxy()
objects are used.
If one is not careful, a header object of some sort (one that does not
normalize its keys, and that is not necessarily a dictionary) can be
constructed containing header keys which differ only by the case of
their string literals. E.g.:
{ 'x-trans-id': '1234', 'X-Trans-Id': '5678' }
Such an object, when passed to http_connect() will result in an
on-the-wire header where the key values are merged together, comma
separated, that looks something like:
HTTP_X_TRANS_ID: 1234,5678
For some headers in some contexts, this is behavior is desirable. For
example, one can also use a list of tuples which enumerate the multiple
values a single header should have.
However, in almost all of the contexts used in the code base, this is
not desirable.
This behavior arises from a combination of factors:
1. Header strings are not constants and different lower-case and
title-case header strings values are used interchangably in the
code at times
It might be worth the effort to make a pass through the code to
stop using string literals and use constants instead, but there
are plusses and minuses to doing that, so this was not attempted
in this effort
2. HeaderEnvironProxy() objects report their keys in ".title()"
case, but normalize all other key references to the form
expected by the Request class's environ field
swob.Request.headers fields are HeaderEnvironProxy() objects.
3. HeaderKeyDict() objects report their keys in ".lower()" case,
and normalize all other key references to ".lower()" case
swob.Response.headers fields are HeaderKeyDict() objects.
Depending on which object is used and how it is used, one can end up
with such a mismatch.
This commit takes the following steps as a (PROPOSED) solution:
1. Change HeaderKeyDict() to normalize using ".title()" case to
match HeaderEnvironProxy()
2. Replace standard python dictionary objects with HeaderKeyDict()
objects where possible
This gives us an object that normalizes key references to avoid
fixing the code to normalize the string literals.
3. Fix up a few places to use title case string literals to match
the new defaults
Change-Id: Ied56a1df83ffac793ee85e796424d7d20f18f469
Signed-off-by: Peter Portante <peter.portante@redhat.com>