Commit Graph

635 Commits

Author SHA1 Message Date
Clay Gerrard 91db804e6f Start common.utils refactor
Related-Bug: #2015274
Change-Id: I6e7c1a19a39f51e4520dabfcfad65817534b42a2
2023-04-04 10:46:58 -05:00
Alistair Coles acf31a61db Rename ShardRange*Bound to Namespace*Bound
Also:

  - move some tests to test_utils.TestNamespace.
  - move ShardName class in file (no change to class)
  - move end_marker method from ShardRange to Namespace

Related-Change: If98af569f99aa1ac79b9485ce9028fdd8d22576b
Change-Id: Ibd5614d378ec5e9ba47055ba8b67a42ab7f7453c
2023-03-15 15:59:14 +00:00
Jianjian Huo 6ff90ea73e Proxy: restructure cached updating shard ranges
Restructure the shard ranges that are stored in memcache for
object updating to only persist the essential attributes of
shard ranges in memcache (lower bounds and names), so the
aggregate of memcache values is much smaller and retrieval
will be much faster too.

Co-Authored-By: Alistair Coles <alistairncoles@gmail.com>
Co-Authored-By: Tim Burke <tim.burke@gmail.com>

UpgradeImpact
=============
The cache key for updating shard ranges in memcached is renamed
from 'shard-updating/<account>/<container>' to
'shard-updating-v2/<account>/<container>', and cache data is
changed to be a list of [lower bound, name]. As a result, this
will invalid all existing updating shard ranges stored in the
memcache cluster.

Change-Id: If98af569f99aa1ac79b9485ce9028fdd8d22576b
2023-03-06 22:20:02 -08:00
indianwhocodes 9ec90d4d56 proxy-server exception logging shows replication_ip/port
Adding a "use_replication" field to the node dict, a helper function to
set use_replication dict value for a node copy by looking up the header
value for x-backend-use-replication-network

Change-Id: Ie05af464765dc10cf585be851f462033fc6bdec7
2023-02-10 09:34:59 +00:00
Tim Burke bac5d8ff7f Switch from pkg_resources to importlib
setuptools seems to be in the process of deprecating pkg_resources.

Change-Id: I64f1434a5acab99057beb4f397adca85bdcc4ab6
2023-01-31 15:41:48 -08:00
Zuul 477423f60a Merge "Clean up a bunch of deprecation warnings" 2023-01-18 21:01:11 +00:00
Jianjian Huo b4124e0cd2 Memcached: add timing stats to set/get and other public functions
Change-Id: If6af519440fb444539e2526ea4dcca0ec0636388
2023-01-06 10:02:15 -08:00
Tim Burke 20b48a6900 Clean up a bunch of deprecation warnings
pytest still complains about some 20k warnings, but the vast majority
are actually because of eventlet, and a lot of those will get cleaned up
when upper-constraints picks up v0.33.2.

Change-Id: If48cda4ae206266bb41a4065cd90c17cbac84b7f
2022-12-27 13:34:00 -08:00
Alistair Coles 2bcf3d1a8e sharder: merge shard shard_ranges from root while sharding
We've seen shards become stuck while sharding because they had
incomplete or stale deleted shard ranges. The root container had more
complete and useful shard ranges into which objects could have been
cleaved, but the shard never merged the root's shard ranges.

While the sharder is auditing shard container DBs it would previously
only merge shard ranges fetched from root into the shard DB if the
shard was shrinking or the shard ranges were known to be children of
the shard. With this patch the sharder will now merge other shard
ranges from root during sharding as well as shrinking.

Shard ranges from root are only merged if they would not result in
overlaps or gaps in the set of shard ranges in the shard DB. Shard
ranges that are known to be ancestors of the shard are never merged,
except the root shard range which may be merged into a shrinking
shard. These checks were not previously applied when merging
shard ranges into a shrinking shard.

The two substantive changes with this patch are therefore:

  - shard ranges from root are now merged during sharding,
    subject to checks.
  - shard ranges from root are still merged during shrinking,
    but are now subjected to checks.

Change-Id: I066cfbd9062c43cd9638710882ae9bd85a5b4c37
2022-11-16 16:12:32 +00:00
Zuul 61cc0573e3 Merge "Stop locking in our SysLogHandler" 2022-10-27 19:52:38 +00:00
Tim Burke a7af17394b Clean up some replication error messages
Lines like `Invalid response 500 from ::1` aren't terribly useful in an
all-in-one, while lines like

   Error syncing with node: {'device': 'd5', 'id': 3, 'ip': '::1',
   'meta': '', 'port': 6200, 'region': 1, 'replication_ip': '::1',
   'replication_port': 6200, 'weight': 8000.0, 'zone': 1, 'index': 0}:
   Timeout (60s)

are needlessly verbose.

While we're at it, introduce a node_to_string() helper, and use it in a
bunch of places.

Change-Id: I62b12f69e9ac44ce27ffaed320c0a3563673a018
2022-10-23 15:24:23 -07:00
Tim Burke e09d4bcf42 Stop locking in our SysLogHandler
It shouldn't be necessary since we only allow it to use UDS or UDP.

Leave an escape hatch in case operators suspect an issue with it; they
can set the environment variable

    SWIFT_NOOP_LOGGING_MUTEX=false

to return to prior behavior. Future releases of Swift may remove this
option based on operator feedback.

Change-Id: I33007868e6d8a6a19eebdf14d5cfe18028424759
Related-Change: https://review.opendev.org/c/openstack/swift/+/493636
2022-10-11 13:43:14 -07:00
Alistair Coles f15b92084f sharder: always get ranges from root while shrinking
While auditing a shard container that is in a shrinking state, the
sharder will merge any shard ranges fetched from the root that cover
the shard's namespace. Previously this was conditional upon the
sharder also fetching the shard's *own* shard range from the
root. However, in extreme circumstances, the shard's own shard range
could become deleted and reclaimed from the root while the shard DB
still needs to shrink to its acceptor ranges. This patch therefore
allows the shard to be updated with potential acceptor ranges from the
root even when its own shard range is not fetched from the root.

Also change the log level from debug to info when logging an update to
a shard's own shard range from root.

Change-Id: I17957cf0ef4936f91e69c6d9ae21551972f0df31
2022-09-30 08:46:57 +01:00
Zuul 8ab6af27c5 Merge "proxy: Add a chance to skip memcache for get_*_info calls" 2022-09-26 19:08:11 +00:00
Zuul fc08c23326 Merge "swift-manage-shard-ranges repair: check for parent-child overlaps." 2022-09-10 00:48:17 +00:00
Jianjian Huo a53270a15a swift-manage-shard-ranges repair: check for parent-child overlaps.
Stuck shard ranges have been seen in the production, root cause has been
traced back to that s-m-s-r failed to detect parent-child relationship
in overlaps and it either shrinked child shard ranges into parents or
the other way around. A patch has been added to check minimum age before
s-m-s-r performs repair, which will most likely prevent this from
happening again, but we also need to check for parent-child relationship
in overlaps explicitly during repairs. This patch will do that and
remove parent or child shard ranges from doners, and prevent s-m-s-r
from shrinking them into acceptor shard ranges.

Drive-by 1: fixup gap repair probe test.
The probe test is no longer appropriate because we're no longer
allowed to repair parent-child overlaps, so replace the test with a
manually created gap.

Drive-by 2: address probe test TODOs.
The commented assertion would fail because the node filtering
comparison failed to account for the same node having different indexes
when generated for the root versus the shard. Adding a new iterable
function filter_nodes makes the node filtering behave as expected.

Co-Authored-By: Alistair Coles <alistairncoles@gmail.com>
Co-Authored-By: Clay Gerrard <clay.gerrard@gmail.com>

Change-Id: Iaa89e94a2746ba939fb62449e24bdab9666d7bab
2022-09-09 11:04:43 -07:00
Clay Gerrard 032d7aa054 ShardName: add test and clarify docstrings
Change-Id: Iebc9802ec06b39e55094972bab5822eae6431094
2022-09-09 10:04:37 +01:00
Alistair Coles 73bce63312 ShardRange: add is_child_of method
Adds an is_child_of method that infers the parent-child relationship
of two shard ranges from their names. This new method is limited to
use only under the same account.

Co-Authored-By: Jianjian Huo <jhuo@nvidia.com>
Change-Id: Iac3a8ec5d8947989b64aa27f40caa3d8d1423a7c
2022-09-08 11:56:53 +01:00
Tim Burke 5c6407bf59 proxy: Add a chance to skip memcache for get_*_info calls
If you've got thousands of requests per second for objects in a single
container, you basically NEVER want that container's info to ever fall
out of memcache. If it *does*, all those clients are almost certainly
going to overload the container.

Avoid this by allowing some small fraction of requests to bypass and
refresh the cache, pushing out the TTL as long as there continue to be
requests to the container. The likelihood of skipping the cache is
configurable, similar to what we did for shard range sets.

Change-Id: If9249a42b30e2a2e7c4b0b91f947f24bf891b86f
Closes-Bug: #1883324
2022-08-30 18:49:48 +10:00
Zuul 24acc6e56b Merge "Add backend rate limiting middleware" 2022-08-30 07:18:57 +00:00
Zuul 3e86c7e46f Merge "Optimize ShardRanges a little" 2022-08-26 19:43:04 +00:00
Tim Burke 52a4fe37aa Various doc formatting cleanups
* Get rid of a bunch of accidental blockquote formatting
* Always declare a lexer to use for ``.. code::`` blocks

Change-Id: I8940e75b094843e542e815dde6b6be4740751813
2022-08-02 14:28:36 -07:00
Tim Burke 38866a3963 Optimize ShardRanges a little
We make a lot of ShardRange objects, pretty much all the time.  Try to
make it a little better:

  * Add __slots__ to improve memory consumption and attribute lookups.
  * Avoid the overhead of catch_warnings() by not tripping the warning.

Change-Id: Ib1c698be9e9f579649bc81acf3562c92feb6c8d3
2022-07-29 11:06:21 -07:00
Matthew Oliver 2d063cd61f formpost: deprecate sha1 signatures
We've known this would eventually be necessary for a while [1], and
way back in 2017 we started seeing SHA-1 collisions [2].

This patch follows the approach of soft deprecation of SHA1 in tempurl.
It's still a default digest, but we'll start with warning as the
middleware is loaded and exposing any deprecated digests
(if they're still allowed) in /info.

Further, because there is much shared code between formpost and tempurl, this
patch also goes and refactors shared code out into swift.common.digest.
Now that we have a digest, we also move digest related code:
 - get_hmac
 - extract_digest_and_algorithm

[1] https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html
[2] https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html

Change-Id: I581cadd6bc79e623f1dae071025e4d375254c1d9
2022-07-26 10:39:58 +10:00
Matthew Oliver ef31baf3fc formpost: Add support for sha256/512 signatures
Sha1 has known to be deprecated for a while so allow the formpost
middleware to use SHA256 and SHA512. Follow the tempurl model and
accept signatures of the form:

   <hex-encoded signature>

or

   sha1:<base64-encoded signature>
   sha256:<base64-encoded signature>
   sha512:<base64-encoded signature>

where the base64-encoding can be either standard or URL-safe, and the
trailing '=' chars may be stripped off.

As part of this, pull the signature-parsing out to a new function, and
add detection for hex-encoded sha512 signatures to tempurl.

Change-Id: Iaba3725551bd47d75067a634a7571485b9afa2de
Related-Change: Ia9dd1a91cc3c9c946f5f029cdefc9e66bcf01046
Co-Authored-By: Tim Burke <tim.burke@gmail.com>
Closes-Bug: #1794601
2022-06-16 09:52:37 -07:00
Zuul 73b2730f71 Merge "Add ring_ip option to object services" 2022-06-06 21:04:48 +00:00
Clay Gerrard 12bc79bf01 Add ring_ip option to object services
This will be used when finding their own devices in rings, defaulting to
the bind_ip.

Notably, this allows services to be containerized while servers_per_port
is enabled:

* For the object-server, the ring_ip should be set to the host ip and
  will be used to discover which ports need binding. Sockets will still
  be bound to the bind_ip (likely 0.0.0.0), with the assumption that the
  host will publish ports 1:1.

* For the replicator and reconstructor, the ring_ip will be used to
  discover which devices should be replicated. While bind_ip could
  previously be used for this, it would have required a separate config
  from the object-server.

Also rename object deamon's bind_ip attribute to ring_ip so that it's
more obvious wherever we're using the IP for ring lookups instead of
socket binding.

Co-Authored-By: Tim Burke <tim.burke@gmail.com>
Change-Id: I1c9bb8086994f7930acd8cda8f56e766938c2218
2022-06-02 16:31:29 -05:00
Zuul 5398204f22 Merge "tempurl: Deprecate sha1 signatures" 2022-06-01 15:54:25 +00:00
Alistair Coles ccaf49a00c Add backend rate limiting middleware
This is a fairly blunt tool: ratelimiting is per device and
applied independently in each worker, but this at least provides
some limit to disk IO on backend servers.

GET, HEAD, PUT, POST, DELETE, UPDATE and REPLICATE methods may be
rate-limited.

Only requests with a path starting '<device>/<partition>', where
<partition> can be cast to an integer, will be rate-limited. Other
requests, including, for example, recon requests with paths such as
'recon/version', are unconditionally forwarded to the next app in the
pipeline.

OPTIONS and SSYNC methods are not rate-limited. Note that
SSYNC sub-requests are passed directly to the object server app
and will not pass though this middleware.

Change-Id: I78b59a081698a6bff0d74cbac7525e28f7b5d7c1
2022-05-20 14:40:00 +01:00
Zuul 4ff0226707 Merge "AbstractRateLimiter: add option to burst on start-up" 2022-05-17 08:15:18 +00:00
Zuul 8e92a9aaf1 Merge "Refactor rate-limiting helper into a class" 2022-05-16 20:51:27 +00:00
Alistair Coles 2f607cd319 Round s3api listing LastModified to integer resolution
s3api bucket listing elements currently have LastModified values with
millisecond precision. This is inconsistent with the value of the
Last-Modified header returned with an object GET or HEAD response
which has second precision. This patch reduces the precision to
seconds in bucket listings and upload part listings. This is also
consistent with observation of an aws listing response.

The last modified values in the swift native listing *up* to
the nearest second to be consistent with the seconds-precision
Last-Modified time header that is returned with an object GET or HEAD.
However, we continue to include millisecond digits set to 0 in the
last-modified string, e.g.: '2014-06-10T22:47:32.000Z'.

Also, fix the last modified time returned in an object copy response
to be consistent with the last modified time of the object that was
created. Previously it was rounded down, but it should be rounded up.

Change-Id: I8c98791a920eeedfc79e8a9d83e5032c07ae86d3
2022-05-10 11:26:27 +01:00
Alistair Coles 52254bb5ca Add ceil method to utils.Timestamp
There are a few places where a last-modified value is calculated by
rounding a timestamp *up* to the nearest second. This patch refactors
to use a new Timestamp.ceil() method to do this rounding, along with a
clarifying docstring.

Change-Id: I9ef73e5183bdf21b22f5f19b8440ffef6988aec7
2022-05-06 16:19:54 +01:00
Alistair Coles 99a4b9c7e6 AbstractRateLimiter: add option to burst on start-up
The AbstractRateLimiter currently loses any accumulated rate_buffer
allowance (i.e. the capacity to burst) after it has been idle for more
than rate_buffer seconds. This patch adds an option 'burst_after_idle'
which causes any rate_bufer allowance to be preserved during idle
periods so that there is capacity for a burst immediately after the
idle period.

Note that a burst on start-up can be avoided by initialising a
AbstractRateLimiter with running_time=now.

Change-Id: I280ce2aa3efa28c92b806436e7e87ad77429b7a4
2022-05-04 11:24:06 +01:00
Alistair Coles 5227cb702b Refactor rate-limiting helper into a class
Replaces the ratelimit_sleep helper function with an
EventletRateLimiter class that encapsulates the rate-limiting state
that previously needed to be maintained by the caller of the function.

The ratelimit_sleep function is retained but deprecated, and now
forwards to the EventletRateLimiter class.

The object updater's BucketizedUpdateSkippingLimiter is refactored to
take advantage of the new EventletRateLimiter class.

The rate limiting algorithm is corrected to make the allowed request
rate more uniform: previously pairs of requests would be allowed in
rapid succession before the rate limiter would the sleep for the time
allowance consumed by those two requests; now the rate limiter will
sleep as required after each allowed request. For example, before a
max_rate of 1 per second might result in 2 requests being allowed
followed by a 2 second sleep. That is corrected to be a sleep of 1
second after each request.

Change-Id: Ibcf4dbeb4332dee7e9e233473d4ceaf75a5a85c7
2022-05-04 11:22:50 +01:00
Tim Burke 118cf2ba8a tempurl: Deprecate sha1 signatures
We've known this would eventually be necessary for a while [1], and
way back in 2017 we started seeing SHA-1 collisions [2].

[1] https://www.schneier.com/blog/archives/2012/10/when_will_we_se.html
[2] https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html

UpgradeImpact:
==============
"sha1" has been removed from the default set of `allowed_digests` in the
tempurl middleware config. If your cluster still has clients requiring
the use of SHA-1,

- explicitly configure `allowed_digests` to include "sha1" and
- encourage your clients to move to more-secure algorithms.

Depends-On: https://review.opendev.org/c/openstack/tempest/+/832771
Change-Id: I6e6fa76671c860191a2ce921cb6caddc859b1066
Related-Change: Ia9dd1a91cc3c9c946f5f029cdefc9e66bcf01046
Closes-Bug: #1733634
2022-04-22 20:43:01 +10:00
Tim Burke c4762acaaa Quiet more BadStatusLine tracebacks
Related-Change: I07192b8d2ece2d2ee04fe0d877ead6fbfc321d86
Change-Id: I01528eadf6abfc6b7daa99e718a70dcbe668f910
2022-02-10 16:53:29 -08:00
Alistair Coles eda7d5fe3c Deprecate LogAdapter.set_statsd_prefix
Previously, the set_statsd_prefix method was used to mutate a logger's
StatsdClient tail prefix after a logger was instantiated. This pattern
had led to unexpected mutations (see Related-Change). The tail_prefix
can now be passed as an argument to get_logger(), and is then
forwarded to the StatsdClient constructor, for a more explicit
assignment pattern.

The set_statsd_prefix method is left in place for backwards
compatibility. A DeprecationWarning will be raised if it is used
to mutate the StatsdClient tail prefix.

Change-Id: I7692860e3b741e1bc10626e26bb7b27399c325ab
Related-Change: I0522b1953722ca96021a0002cf93432b973ce626
2022-02-07 17:46:06 +00:00
Zuul e8cecf7fcc Merge "Move *_swift_info functions into a new registry module" 2022-02-04 07:01:15 +00:00
Zuul 8ea49a1def Merge "Fix statsd prefix mutation in proxy controllers" 2022-02-04 06:56:53 +00:00
Matthew Oliver 589ac355f3 Move *_swift_info functions into a new registry module
The *_swift_info functions use in module global dicts to provide a
registry mechanism for registering and getting swift info.

This is an abnormal pattern and doesn't quite fit into utils. Further
we looking at following this pattern for sensitive info to trim in the
future.
So this patch does some house cleaning and moves this registry to a new
module swift.common.registry. And updates all the references to it.

For backwards compat we still import the *_swift_info methods into utils
for any 3rd party tools or middleware.

Change-Id: I71fd7f50d1aafc001d6905438f42de4e58af8421
2022-02-03 14:41:13 +00:00
Alistair Coles 6942b25cc1 Fix statsd prefix mutation in proxy controllers
Swift loggers encapsulate a StatsdClient that is typically initialised
with a prefix, equal to the logger name (e.g. 'proxy_server'), that is
prepended to metrics names. The proxy server would previously mutate
its logger's prefix, using its set_statsd_prefix method, each time a
controller was instantiated, extending it with the controller type
(e.g. changing the prefix 'proxy_server.object'). As a result, when an
object request spawned container subrequests, for example, the statsd
client would be left with a 'proxy_server.container' prefix part for
subsequent object request related metrics.

The proxy server logger is now wrapped with a new
MetricsPrefixLoggerAdapter each time a controller is instantiated, and
the adapter applies the correct prefix for the controller type for the
lifetime of the controller.

Change-Id: I0522b1953722ca96021a0002cf93432b973ce626
2022-01-27 09:06:15 -08:00
Alistair Coles 876a7de6a7 De-clutter container sync sample internal client conf
Since the Related-Change, the inline default internal client config
for container-sync doesn't need to be a carbon-copy of the actual
internal-client.conf-sample, so all the comment lines are removed
because this is not the place to be maintaining documentation of the
internal client config.

Also, add clarifying comment to utils.get_logger().

Related-Change: I844381fb9e1f3462043d27eb93e3fa188b206d05
Change-Id: I623d13a2d4528f28dcfb6e64407372c504206074
2022-01-26 10:16:57 +00:00
Alistair Coles 035d91dce5 Modify log_name in internal clients' pipeline configs
Modify the 'log_name' option in the InternalClient wsgi config for the
following services: container-sharder, container-reconciler,
container-deleter, container-sync and object-expirer.

Previously the 'log_name' value for all internal client instances
sharing a single internal-client.conf file took the value configured
in the conf file, or would default to 'swift'. This resulted in no
distinction between logs from each internal client, and no association
with the service using a particular internal client.

With this change the 'log_name' value will typically be <log_route>-ic
where <log_route> is the service's conf file section name. For
example, 'container-sharder-ic'.

Note: any 'log_name' value configured in an internal client conf file
will now be ignored for these services unless the option key is
preceded by 'set'.

Note: by default, the logger's StatdsClient uses the log_name as its
tail_prefix when composing metrics' names. However, the proxy-logging
middleware overrides the tail_prefix with the hard-coded value
'proxy-server'. This change to log_name therefore does not change the
statsd metric names emitted by the internal client's proxy-logging.

This patch does not change the logging of the services themselves,
just their internal clients.

Change-Id: I844381fb9e1f3462043d27eb93e3fa188b206d05
Related-Change: Ida39ec7eb02a93cf4b2aa68fc07b7f0ae27b5439
2022-01-12 11:07:25 +00:00
Zuul 52f2af7c61 Merge "reconstructor: Delay purging reverted non-durable datafiles" 2021-07-02 19:10:04 +00:00
Alistair Coles 2934818d60 reconstructor: Delay purging reverted non-durable datafiles
The reconstructor may revert a non-durable datafile on a handoff
concurrently with an object server PUT that is about to make the
datafile durable.  This could previously lead to the reconstructor
deleting the recently written datafile before the object-server
attempts to rename it to a durable datafile, and consequently a
traceback in the object server.

The reconstructor will now only remove reverted nondurable datafiles
that are older (according to mtime) than a period set by a new
nondurable_purge_delay option (defaults to 60 seconds). More recent
nondurable datafiles may be made durable or will remain on the handoff
until a subsequent reconstructor cycle.

Change-Id: I0d519ebaaade35249fb7b17bd5f419ffdaa616c0
2021-06-24 09:33:06 +01:00
Tim Burke 0d05a8ff38 Quiet EPIPE tracebacks
Co-Authored-By: Alistair Coles <alistairncoles@gmail.com>
Change-Id: Ibf6cce2447921b58f5a0dff630ea5a0c6284119c
2021-06-21 11:25:14 -07:00
Tim Burke bead9f1ca4 relinker: Remove replication locks for empty parts
Otherwise, the rmdir will fail.

Drive-by: pull the 10s default for various locks up to a module-level
DEFAULT_LOCK_TIMEOUT that can be monkey-patched.

Change-Id: I559f40d04bf30a74b507d9428c532111a7152b28
2021-06-01 10:31:43 -07:00
Zuul 6167dbf7ba Merge "relinker: Rehash the parts actually touched when relinking" 2021-05-12 11:14:09 +00:00
Tim Burke 1db2816119 relinker: Rehash the parts actually touched when relinking
This has a few different benefits:

* When re-running the relinker, we won't try to rehash partitions
  outside the expanded range.
* When running on a small, sparse cluster (like in dev or testing) we
  won't try to rehash an empty new partition.
* If we find old files from an earlier part power increase and link them
  into the correct partition, we'll rehash the one we actually linked
  to.
* If we relink a file during cleanup that was missed during relink,
  we'll rehash it rather than waiting for the replicator to do it.

Related-Change: I9aace80088cd00d02c418fe4d782b662fb5c8bcf
Change-Id: I3c91127e19156af7a707ad84c5a89727df87f2f1
2021-05-12 10:02:35 +01:00