Write the ring file to a temporary location first and then move it into
place. This should help prevent issues like reading a partial ring file
while a new instances is being written out.
Change-Id: I28357a2f038a51cb9d823822b92f736dff033a9e
Prior to this patch the proxy_logging middleware always prepared to
read the response and process it for access logging, where the
proxy_logging instance first to handle the response bytes marked the
request as "logged".
This meant that the proxy_logging instance immediately before the
proxy-server app (right most in the pipeline, if properly setup) would
always log the responses for all the client requests, regardless if
middleware to the left of it still had processing to do for the
response. This would break SLO, where the slo middleware passed along
the GET of the manifest, unchanged from the client, so that the right
most proxy logging middleware would log the sponse for just the
manifest, but then the slo middleware would fetch all the segments of
the manifest, feeding them out in the response to the client, the
request now marked as "logged" so that the left most proxy logging
middleware would not log it.
This patch inverts this behavior so that now the first proxy_logging
middleware instance to receive a request in the pipeline marks that
request as handling it. So now, the left most proxy_logging middleware
handles logging for all client reaquests, and the right most
proxy_logging middleware handles all other requests initiated from
within the pipeline to its left.
Closes bug: 1297438
Change-Id: Ia3561523db76c693e4e0b2c38f461544dfcee086
It seemed like some of the tests ment to exercise the proxy's timeout could
would occastionally race and the backend mock would be able to cough up a
chunk before the timeout fired in the proxy - typically resulting in a failed
assertion like " lalala" != 'lalala'.
We paramaterize the timeout value, and bump it up for those cases where we are
expecting to hit the timeout. Timing shows this change is just as fast for
passing tests. And if you want to break the node_timeout in
proxy.controller.base you can verify the tests are still just as effective -
if a bit slower to detect the failure path.
Fixes bug #1272509
Change-Id: Iaf91d9d551e94fc317a08e8c0ee02daeed331b60
This is a very simple swift tool to retrieve information
of a container that is located on the storage node.
One can call the tool with a given container db file
as it is stored on the storage node system.
It will then return several information about that container.
Change-Id: Ifebaed6c51a9ed5fbc0e7572bb43ef05d7dd254b
By moving the blocking to gatekeeper from the proxy server, we gain
the ability to pass X-Backend headers in via InternalClient while
still keeping real clients from using them.
I wanted this functionality while working on storage policies; I had
an InternalClient and wanted to tell it to use a specific policy index
instead of what the container said, and that seemed like a good time
for an X-Backend header.
Change-Id: I4089e980d3cfca660365c7df799723b1f16ba277
This makes it so test-cors.html is a real file in doc/source so it's easy for
those in the know to jump in there with a `python -m SimpleHTTPServer` and
point their webbrowser to `http://localhost:8000/test-cors.html`.
The example html and javascript still appear in the docs in their entirety
using the Sphinx literal include directive.
Change-Id: Ia0ba36df6c58795e3764fa53b7f585dcc1b3be07
The proxy.controllers.base's generate_request_headers will set an X-Timestamp
header for you if it didn't get populated by additional kwarg or the
transfer_headers method. This works fine if you only call it once per
request, but because of how proxy.controllers.obj and
proxy.controllers.container fill in the backend update header chains in
_backend_requests we need multiple independent copies and call the base
controllers generate_request_headers once of each backend request - which left
the ContainerController sending down different X-Timestamp values
(microseconds apart) for PUT and DELETE.
The ObjectController skirts the issue entirely because it always preloads a
X-Timestamp on the req used to generate backend headers, and it allows it to
be copied over via transfer_headers by including 'x-timestamp' in it's
pass_through_headers attribute.
Because the container-replicator is already does merge_timestamps the
differences would always eventaully even out and there is no consistency bug,
but this seems cleaner since they put_timestamp being stored on the three
replicas during a container PUT were all coming from the same client request.
Since both PUT and DELETE were effected, and the ContainerController doesn't
need to allow X-Timestamp to pass_through like the ObjectController does for
container-sync, it seemed cleanest to fix the issue in _backend_requests via
the additional kwarg to generate_request_headers.
There's a driveby fix for FakeLogger and update to the proxy_server's
ContainerController tests.
Change-Id: Idbdf1204da33f8fb356ae35961dbdc931b228b77
There was a path on container recreate that would sometimes allow db to get
reinitialized without updating put_timestamp. Replication would of course fix
it up, but that node would think it's database was deleted till then desipite
just ok'ing a request with a newer X-Timestamp than the deleted_timestamp on
disk.
Change-Id: I8b98afb2aac2e433b6ecb5c421ba0d778cef42fa
Closes-Bug: #1292784
If I want to fetch an object only if it is newer than the first moon
landing, I send a GET request with header:
If-Modified-Since: Sun, 20 Jul 1969 20:18:00 UTC
Since that date is older than Swift, I expect a 2xx response. However,
I get a 412, which isn't even a valid thing to do for
If-Modified-Since; it should either be 2xx or 304. This is because of
two problems:
(a) Swift treats pre-1970 dates as invalid, and
(b) Swift returns 412 when a date is invalid instead of ignoring it.
This commit makes it so any time between datetime.datetime.min and
datetime.datetime.max is an acceptable value for If-Modified-Since and
If-Unmodified-Since. Dates outside that date range are treated as
invalid headers and thus are ignored, as RFC 2616 section 14.28
requires ("If the specified date is invalid, the header is ignored").
This only works for dates that the Python standard library can parse,
which on my machine is 01 Jan 1 to 31 Dec 9999. Eliminating those
restrictions would require implementing our own date parsing and
comparison, and that's almost certainly not worth it.
Change-Id: I4cb4903c4e5e3b6b3c9506c2cabbfbda62e82f35
CORS doesn't really work with swift right now. OPTIONS calls for the most part
work but for so called "simple cross-site requests" (i.e. those that don't
require a pre-flight OPTIONS request) Swift always returns the Origin it was
given as the Access-Control-Allow-Origin in the response. This makes CORS
"work" for these requests but if you actually wanted the javascript user agent
to restrict anything for you it wouldn't be able to!
You can duplicate the issue with updated CORS test page:
http://docs.openstack.org/developer/swift/cors.html#test-cors-page
And a public container with an 'X-Container-Meta-Access-Control-Allow-Origin'
that does NOT match the webserver hosting the test-cors-page.
e.g.
with a public container that accepts cross-site requests from "example.com":
`swift post cors-container -m access-control-allow-origin:example.com -r .r:*`
You could point your browser at a copy of the test-cors-page on your
filesystem (the browser will will send 'Origin: null')
Without a token the XMLHttpRequest will not request any custom headers (i.e.
Access-Control-Request-Headers: x-auth-token) and the request will be made
with-out a preflight OPTIONS request (which Swift would have denied anyway
because the origin's don't match)
i.e. fill in "http://saio:8080/v1/AUTH_test/cors-container" for "URL" and
leave "Token" blank.
You would expect that the browser would not complete the request because
"Origin: null" does not match the configured "Access-Control-Allow-Origin:
example.com" on the container metadata, and indeed with this patch - it won't!
Also:
The way cors is set up does not play well with certain applications for swift.
If you are running a CDN on top of swift and you have the
Access-Control-Allow-Origin cors header set to * then you probably want the *
to be cached on the the CDN, not the Origin that happened to result in an
origin request.
Also:
If you were unfortunate enough to allow cors headers to be saved directly
onto objects then this allows them to supersede the headers coming from the
container.
NOTE: There is a change is behavior with this patch. Because its cors, a
spec that was created only to cause annoyance to all, I'll write out
what's being changed and hopefully someone will speak up if it breaks
there stuff.
previous behavior: When a request was made with a Origin header set the
cors_validation decorator would always add that origin as
the Access-Control-Allow-Origin header in the response-
whether the passed origin was a match with the container's
X-Container-Meta-Access-Control-Allow-Origin or not, or even
if the container did not have CORS set up at all.
new behavior: If strict_cors_mode is set to True in the proxy-server.conf
(which is the default) the cors_validation decorator will only
add the Access-Control-Allow-Origin header to the response when
the request's Origin matches the value set in
X-Container-Meta-Access-Control-Allow-Origin. NOTE- if the
container does not have CORS set up it won't just magically start
working. Furthremore, if the Origin doesn't match the
Access-Control-Allow-Origin - a successfully authorized request
(either by token or public ACL) won't be *denied* - it just
won't include the Access-Control-Allow-Origin header (it's up
to the security model in the browser to cancel the request
if the response doesn't include a matching Allow-Origin
header). On the other hand, if you want to restrict requests
with CORS, you can actually do it now.
If you are worried about breaking current functionality you
must set:
strict_cors_mode = False
in the proxy-server.conf. This will continue with returning the
passed in Origin as the Access-Control-Allow-Origin in the
response.
previous: If you had X-Container-Meta-Access-Control-Allow-Origin set to *
and you passed in Origin: http://hey.com you'd get
Access-Control-Allow-Origin: http://hey.com back. This was true for
both OPTIONS and regular reqs.
new: With X-Container-Meta-Access-Control-Allow-Origin set to * you get * back
for both OPTIONS and regular reqs.
previous: cors headers saved directly onto objects (by allowing them to be
saved via the allowed_headers config in the object-server conf)
would be overridden by whatever container cors you have set up.
new: For regular (non-OPTIONS) calls the object headers will be kept. The
container cors will only be applied to objects without the
'Access-Control-Allow-Origin' and 'Access-Control-Expose-Headers' headers.
This behavior doesn't make a whole lot of sense for OPTIONS calls so I
left that as is. I don't think that allowing cors headers to be saved
directly onto objects is a good idea and it should be discouraged.
DocImpact
Change-Id: I9b0219407e77c77a9bb1133cbcb179a4c681c4a8
If you had a partition with 1 replica on a deleted device, 1 on a
zero-weight device, and 1 on a normal device, then rebalancing would
crash. This was because the ring builder was memoizing tiers_for_dev()
for all *available* devices (i.e. weight > 0 and not deleted), but
depended on it being present for all devices with partitions still on
them.
Since the builder moved the replica from the deleted device, it left
the one on the zero-weight device alone, so you had an unavailable
device with a partition replica still on it, triggering the crash.
Now we go ahead and memoize tiers_for_dev() for *all* devices, not
just available ones, thereby fixing the crash.
Change-Id: Ie0b58b65e0353732cf785ab772e95e699f3a5b5d
In object audit "once" mode we are allowing the user to specify
a sub-set of devices to audit using the "--devices" command-line
option. The sub-set is specified as a comma-separated list. This
patch is taken from a larger patch to enable parallel processing
in the object auditor.
We've had to modify recon so that it will work properly with this
change to "once" mode. We've modified dump_recon_cache()
so that it will store nested dictionaries, in other words it will
store a recon cache entry such as {'key1': {'key2': {...}}}. When
the object auditor is run in "once" mode with "--devices" set the
object_auditor_stats_ALL and ZBF entries look like:
{'object_auditor_stats_ALL': {'disk1disk2..diskn': {...}}}. When
swift-recon is run, it hunts through the nested dicts to find the
appropriate entries. The object auditor recon cache entries are set
to {} at the beginning of each audit cycle, and individual disk
entries are cleared from cache at the end of each disk's audit cycle.
DocImpact
Change-Id: Icc53dac0a8136f1b2f61d5e08baf7b4fd87c8123