swift 2.32.1__py2.py3-none-any.whl → 2.33.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- swift/account/server.py +1 -11
- swift/cli/info.py +28 -1
- swift-2.32.1.data/scripts/swift-recon-cron → swift/cli/recon_cron.py +4 -13
- swift/cli/reload.py +141 -0
- swift/common/daemon.py +12 -2
- swift/common/db.py +12 -8
- swift/common/http_protocol.py +76 -3
- swift/common/manager.py +18 -5
- swift/common/memcached.py +18 -12
- swift/common/middleware/proxy_logging.py +35 -27
- swift/common/middleware/s3api/acl_handlers.py +1 -1
- swift/common/middleware/s3api/controllers/__init__.py +3 -0
- swift/common/middleware/s3api/controllers/acl.py +3 -2
- swift/common/middleware/s3api/controllers/logging.py +2 -2
- swift/common/middleware/s3api/controllers/multi_upload.py +30 -6
- swift/common/middleware/s3api/controllers/object_lock.py +44 -0
- swift/common/middleware/s3api/s3api.py +4 -0
- swift/common/middleware/s3api/s3request.py +19 -12
- swift/common/middleware/s3api/s3response.py +13 -2
- swift/common/middleware/s3api/utils.py +1 -1
- swift/common/middleware/slo.py +395 -298
- swift/common/middleware/staticweb.py +45 -14
- swift/common/middleware/tempurl.py +132 -91
- swift/common/request_helpers.py +32 -8
- swift/common/storage_policy.py +1 -1
- swift/common/swob.py +5 -2
- swift/common/utils/__init__.py +230 -135
- swift/common/utils/timestamp.py +23 -2
- swift/common/wsgi.py +8 -0
- swift/container/backend.py +126 -21
- swift/container/replicator.py +42 -6
- swift/container/server.py +264 -145
- swift/container/sharder.py +50 -30
- swift/container/updater.py +1 -0
- swift/obj/auditor.py +2 -1
- swift/obj/diskfile.py +55 -19
- swift/obj/expirer.py +1 -13
- swift/obj/mem_diskfile.py +2 -1
- swift/obj/mem_server.py +1 -0
- swift/obj/replicator.py +2 -2
- swift/obj/server.py +12 -23
- swift/obj/updater.py +1 -0
- swift/obj/watchers/dark_data.py +72 -34
- swift/proxy/controllers/account.py +3 -2
- swift/proxy/controllers/base.py +217 -127
- swift/proxy/controllers/container.py +274 -289
- swift/proxy/controllers/obj.py +98 -141
- swift/proxy/server.py +2 -12
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-info +3 -0
- swift-2.33.1.data/scripts/swift-recon-cron +24 -0
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/AUTHORS +3 -1
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/METADATA +4 -3
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/RECORD +94 -91
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/WHEEL +1 -1
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/entry_points.txt +1 -0
- swift-2.33.1.dist-info/pbr.json +1 -0
- swift-2.32.1.dist-info/pbr.json +0 -1
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-audit +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-auditor +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-info +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-reaper +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-replicator +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-server +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-config +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-auditor +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-reconciler +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-replicator +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-server +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-sharder +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-sync +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-updater +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-dispersion-populate +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-dispersion-report +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-drive-audit +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-form-signature +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-get-nodes +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-init +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-auditor +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-expirer +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-info +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-reconstructor +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-relinker +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-replicator +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-server +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-updater +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-oldies +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-orphans +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-proxy-server +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-recon +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-reconciler-enqueue +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-ring-builder +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-ring-builder-analyzer +0 -0
- {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-ring-composer +0 -0
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/LICENSE +0 -0
- {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/top_level.txt +0 -0
swift/common/wsgi.py
CHANGED
@@ -487,6 +487,8 @@ class StrategyBase(object):
|
|
487
487
|
capture_stdio(self.logger)
|
488
488
|
drop_privileges(self.conf.get('user', 'swift'))
|
489
489
|
del self.tracking_data # children don't need to track siblings
|
490
|
+
# only MAINPID should be sending systemd notifications
|
491
|
+
os.environ.pop('NOTIFY_SOCKET', None)
|
490
492
|
|
491
493
|
def shutdown_sockets(self):
|
492
494
|
"""
|
@@ -888,6 +890,7 @@ def run_wsgi(conf_path, app_section, *args, **kwargs):
|
|
888
890
|
run_server(conf, logger, no_fork_sock, global_conf=global_conf,
|
889
891
|
ready_callback=strategy.signal_ready,
|
890
892
|
allow_modify_pipeline=allow_modify_pipeline)
|
893
|
+
systemd_notify(logger, "STOPPING=1")
|
891
894
|
return 0
|
892
895
|
|
893
896
|
def stop_with_signal(signum, *args):
|
@@ -981,8 +984,10 @@ def run_wsgi(conf_path, app_section, *args, **kwargs):
|
|
981
984
|
else:
|
982
985
|
logger.notice('%s received (%s)', signame, os.getpid())
|
983
986
|
if running_context[1] == signal.SIGTERM:
|
987
|
+
systemd_notify(logger, "STOPPING=1")
|
984
988
|
os.killpg(0, signal.SIGTERM)
|
985
989
|
elif running_context[1] == signal.SIGUSR1:
|
990
|
+
systemd_notify(logger, "RELOADING=1")
|
986
991
|
# set up a pipe, fork off a child to handle cleanup later,
|
987
992
|
# and rexec ourselves with an environment variable set which will
|
988
993
|
# indicate which fd (one of the pipe ends) to write a byte to
|
@@ -1041,6 +1046,9 @@ def run_wsgi(conf_path, app_section, *args, **kwargs):
|
|
1041
1046
|
os.close(read_fd)
|
1042
1047
|
except Exception:
|
1043
1048
|
pass
|
1049
|
+
else:
|
1050
|
+
# SIGHUP or, less likely, run in "once" mode
|
1051
|
+
systemd_notify(logger, "STOPPING=1")
|
1044
1052
|
|
1045
1053
|
strategy.shutdown_sockets()
|
1046
1054
|
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
swift/container/backend.py
CHANGED
@@ -1685,6 +1685,125 @@ class ContainerBroker(DatabaseBroker):
|
|
1685
1685
|
if ('no such table: %s' % SHARD_RANGE_TABLE) not in str(err):
|
1686
1686
|
raise
|
1687
1687
|
|
1688
|
+
def _make_filler_shard_range(self, namespaces, marker, end_marker):
|
1689
|
+
if namespaces and namespaces[-1].upper == Namespace.MAX:
|
1690
|
+
return None
|
1691
|
+
|
1692
|
+
# Insert a modified copy of own shard range to fill any gap between the
|
1693
|
+
# end of any found and the upper bound of own shard range. Gaps
|
1694
|
+
# enclosed within the found shard ranges are not filled.
|
1695
|
+
own_shard_range = self.get_own_shard_range()
|
1696
|
+
if namespaces:
|
1697
|
+
last_upper = namespaces[-1].upper
|
1698
|
+
else:
|
1699
|
+
last_upper = max(marker or own_shard_range.lower,
|
1700
|
+
own_shard_range.lower)
|
1701
|
+
required_upper = min(end_marker or own_shard_range.upper,
|
1702
|
+
own_shard_range.upper)
|
1703
|
+
if required_upper > last_upper:
|
1704
|
+
filler_sr = own_shard_range
|
1705
|
+
filler_sr.lower = last_upper
|
1706
|
+
filler_sr.upper = required_upper
|
1707
|
+
return filler_sr
|
1708
|
+
else:
|
1709
|
+
return None
|
1710
|
+
|
1711
|
+
def get_namespaces(self, marker=None, end_marker=None, includes=None,
|
1712
|
+
reverse=False, states=None, fill_gaps=False):
|
1713
|
+
"""
|
1714
|
+
Returns a list of persisted namespaces per input parameters.
|
1715
|
+
|
1716
|
+
:param marker: restricts the returned list to shard ranges whose
|
1717
|
+
namespace includes or is greater than the marker value. If
|
1718
|
+
``reverse=True`` then ``marker`` is treated as ``end_marker``.
|
1719
|
+
``marker`` is ignored if ``includes`` is specified.
|
1720
|
+
:param end_marker: restricts the returned list to shard ranges whose
|
1721
|
+
namespace includes or is less than the end_marker value. If
|
1722
|
+
``reverse=True`` then ``end_marker`` is treated as ``marker``.
|
1723
|
+
``end_marker`` is ignored if ``includes`` is specified.
|
1724
|
+
:param includes: restricts the returned list to the shard range that
|
1725
|
+
includes the given value; if ``includes`` is specified then
|
1726
|
+
``fill_gaps``, ``marker`` and ``end_marker`` are ignored.
|
1727
|
+
:param reverse: reverse the result order.
|
1728
|
+
:param states: if specified, restricts the returned list to namespaces
|
1729
|
+
that have one of the given states; should be a list of ints.
|
1730
|
+
:param fill_gaps: if True, insert a modified copy of own shard range to
|
1731
|
+
fill any gap between the end of any found shard ranges and the
|
1732
|
+
upper bound of own shard range. Gaps enclosed within the found
|
1733
|
+
shard ranges are not filled.
|
1734
|
+
:return: a list of Namespace objects.
|
1735
|
+
"""
|
1736
|
+
if includes is None and (marker == Namespace.MAX
|
1737
|
+
or end_marker == Namespace.MIN):
|
1738
|
+
return []
|
1739
|
+
|
1740
|
+
if reverse:
|
1741
|
+
marker, end_marker = end_marker, marker
|
1742
|
+
if marker and end_marker and marker >= end_marker:
|
1743
|
+
return []
|
1744
|
+
|
1745
|
+
included_states = set(states) if states else None
|
1746
|
+
with self.get() as conn:
|
1747
|
+
# Namespace only needs 'name', 'lower' and 'upper', but the query
|
1748
|
+
# also need to include 'state' to be used when subesequently
|
1749
|
+
# sorting the rows. And the sorting can't be done within SQLite
|
1750
|
+
# since the value for maximum upper bound is an empty string.
|
1751
|
+
|
1752
|
+
conditions = ['deleted = 0', 'name != ?']
|
1753
|
+
params = [self.path]
|
1754
|
+
if included_states:
|
1755
|
+
conditions.append('state in (%s)' % ','.join(
|
1756
|
+
'?' * len(included_states)))
|
1757
|
+
params.extend(included_states)
|
1758
|
+
if includes is None:
|
1759
|
+
if end_marker:
|
1760
|
+
conditions.append('lower < ?')
|
1761
|
+
params.append(end_marker)
|
1762
|
+
if marker:
|
1763
|
+
conditions.append("(upper = '' OR upper > ?)")
|
1764
|
+
params.append(marker)
|
1765
|
+
else:
|
1766
|
+
conditions.extend(('lower < ?', "(upper = '' OR upper >= ?)"))
|
1767
|
+
params.extend((includes, includes))
|
1768
|
+
condition = ' WHERE ' + ' AND '.join(conditions)
|
1769
|
+
sql = '''
|
1770
|
+
SELECT name, lower, upper, state FROM %s%s
|
1771
|
+
''' % (SHARD_RANGE_TABLE, condition)
|
1772
|
+
try:
|
1773
|
+
data = conn.execute(sql, params)
|
1774
|
+
data.row_factory = None
|
1775
|
+
namespaces = [row for row in data]
|
1776
|
+
except sqlite3.OperationalError as err:
|
1777
|
+
if ('no such table: %s' % SHARD_RANGE_TABLE) in str(err):
|
1778
|
+
return []
|
1779
|
+
else:
|
1780
|
+
raise
|
1781
|
+
|
1782
|
+
# Sort those namespaces in order, note that each namespace record also
|
1783
|
+
# include additional attribute 'state'.
|
1784
|
+
def sort_key(namespace):
|
1785
|
+
return ShardRange.sort_key_order(name=namespace[0],
|
1786
|
+
lower=namespace[1],
|
1787
|
+
upper=namespace[2],
|
1788
|
+
state=namespace[3])
|
1789
|
+
namespaces.sort(key=sort_key)
|
1790
|
+
# Convert the record tuples to Namespace objects.
|
1791
|
+
namespaces = [Namespace(row[0], row[1], row[2]) for row in namespaces]
|
1792
|
+
if includes:
|
1793
|
+
return namespaces[:1] if namespaces else []
|
1794
|
+
|
1795
|
+
if fill_gaps:
|
1796
|
+
filler_sr = self._make_filler_shard_range(
|
1797
|
+
namespaces, marker, end_marker)
|
1798
|
+
if filler_sr:
|
1799
|
+
namespaces.append(Namespace(filler_sr.name,
|
1800
|
+
filler_sr.lower,
|
1801
|
+
filler_sr.upper))
|
1802
|
+
if reverse:
|
1803
|
+
namespaces.reverse()
|
1804
|
+
|
1805
|
+
return namespaces
|
1806
|
+
|
1688
1807
|
def _get_shard_range_rows(self, connection=None, marker=None,
|
1689
1808
|
end_marker=None, includes=None,
|
1690
1809
|
include_deleted=False, states=None,
|
@@ -1709,8 +1828,8 @@ class ContainerBroker(DatabaseBroker):
|
|
1709
1828
|
``marker`` and ``end_marker`` are ignored, but other constraints
|
1710
1829
|
are applied (e.g. ``exclude_others`` and ``include_deleted``).
|
1711
1830
|
:param include_deleted: include rows marked as deleted.
|
1712
|
-
:param states: include only rows matching the given
|
1713
|
-
|
1831
|
+
:param states: include only rows matching the given states; should be
|
1832
|
+
a list of ints.
|
1714
1833
|
:param include_own: boolean that governs whether the row whose name
|
1715
1834
|
matches the broker's path is included in the returned list. If
|
1716
1835
|
True, that row is included unless it is excluded by other
|
@@ -1734,11 +1853,7 @@ class ContainerBroker(DatabaseBroker):
|
|
1734
1853
|
if exclude_others and not include_own:
|
1735
1854
|
return []
|
1736
1855
|
|
1737
|
-
included_states = set()
|
1738
|
-
if isinstance(states, (list, tuple, set)):
|
1739
|
-
included_states.update(states)
|
1740
|
-
elif states is not None:
|
1741
|
-
included_states.add(states)
|
1856
|
+
included_states = set(states) if states else None
|
1742
1857
|
|
1743
1858
|
# defaults to be used when legacy db's are missing columns
|
1744
1859
|
default_values = {'reported': 0,
|
@@ -1868,8 +1983,7 @@ class ContainerBroker(DatabaseBroker):
|
|
1868
1983
|
:param reverse: reverse the result order.
|
1869
1984
|
:param include_deleted: include items that have the delete marker set.
|
1870
1985
|
:param states: if specified, restricts the returned list to shard
|
1871
|
-
ranges that have the given
|
1872
|
-
single int.
|
1986
|
+
ranges that have one of the given states; should be a list of ints.
|
1873
1987
|
:param include_own: boolean that governs whether the row whose name
|
1874
1988
|
matches the broker's path is included in the returned list. If
|
1875
1989
|
True, that row is included unless it is excluded by other
|
@@ -1906,18 +2020,9 @@ class ContainerBroker(DatabaseBroker):
|
|
1906
2020
|
return shard_ranges[:1] if shard_ranges else []
|
1907
2021
|
|
1908
2022
|
if fill_gaps:
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
else:
|
1913
|
-
last_upper = max(marker or own_shard_range.lower,
|
1914
|
-
own_shard_range.lower)
|
1915
|
-
required_upper = min(end_marker or own_shard_range.upper,
|
1916
|
-
own_shard_range.upper)
|
1917
|
-
if required_upper > last_upper:
|
1918
|
-
filler_sr = own_shard_range
|
1919
|
-
filler_sr.lower = last_upper
|
1920
|
-
filler_sr.upper = required_upper
|
2023
|
+
filler_sr = self._make_filler_shard_range(
|
2024
|
+
shard_ranges, marker, end_marker)
|
2025
|
+
if filler_sr:
|
1921
2026
|
shard_ranges.append(filler_sr)
|
1922
2027
|
|
1923
2028
|
if reverse:
|
swift/container/replicator.py
CHANGED
@@ -20,7 +20,8 @@ from eventlet import Timeout
|
|
20
20
|
from random import choice
|
21
21
|
|
22
22
|
from swift.container.sync_store import ContainerSyncStore
|
23
|
-
from swift.container.backend import ContainerBroker, DATADIR, SHARDED
|
23
|
+
from swift.container.backend import ContainerBroker, DATADIR, SHARDED, \
|
24
|
+
merge_shards
|
24
25
|
from swift.container.reconciler import (
|
25
26
|
MISPLACED_OBJECTS_ACCOUNT, incorrect_policy_index,
|
26
27
|
get_reconciler_container_name, get_row_to_q_entry_translator)
|
@@ -31,6 +32,35 @@ from swift.common.http import is_success
|
|
31
32
|
from swift.common.utils import Timestamp, majority_size, get_db_files
|
32
33
|
|
33
34
|
|
35
|
+
def check_merge_own_shard_range(shards, broker, logger, source):
|
36
|
+
"""
|
37
|
+
If broker has own_shard_range *with an epoch* then filter out an
|
38
|
+
own_shard_range *without an epoch*, and log a warning about it.
|
39
|
+
|
40
|
+
:param shards: a list of candidate ShardRanges to merge
|
41
|
+
:param broker: a ContainerBroker
|
42
|
+
:param logger: a logger
|
43
|
+
:param source: string to log as source of shards
|
44
|
+
:return: a list of ShardRanges to actually merge
|
45
|
+
"""
|
46
|
+
# work-around for https://bugs.launchpad.net/swift/+bug/1980451
|
47
|
+
own_sr = broker.get_own_shard_range()
|
48
|
+
if own_sr.epoch is None:
|
49
|
+
return shards
|
50
|
+
to_merge = []
|
51
|
+
for shard in shards:
|
52
|
+
if shard['name'] == own_sr.name and not shard['epoch']:
|
53
|
+
shard_copy = dict(shard)
|
54
|
+
new_content = merge_shards(shard_copy, dict(own_sr))
|
55
|
+
if new_content and shard_copy['epoch'] is None:
|
56
|
+
logger.warning(
|
57
|
+
'Ignoring remote osr w/o epoch, own_sr: %r, remote_sr: %r,'
|
58
|
+
' source: %s', dict(own_sr), shard, source)
|
59
|
+
continue
|
60
|
+
to_merge.append(shard)
|
61
|
+
return to_merge
|
62
|
+
|
63
|
+
|
34
64
|
class ContainerReplicator(db_replicator.Replicator):
|
35
65
|
server_type = 'container'
|
36
66
|
brokerclass = ContainerBroker
|
@@ -138,8 +168,10 @@ class ContainerReplicator(db_replicator.Replicator):
|
|
138
168
|
with Timeout(self.node_timeout):
|
139
169
|
response = http.replicate('get_shard_ranges')
|
140
170
|
if response and is_success(response.status):
|
141
|
-
|
142
|
-
|
171
|
+
shards = json.loads(response.data.decode('ascii'))
|
172
|
+
shards = check_merge_own_shard_range(
|
173
|
+
shards, broker, self.logger, '%s%s' % (http.host, http.path))
|
174
|
+
broker.merge_shard_ranges(shards)
|
143
175
|
|
144
176
|
def find_local_handoff_for_part(self, part):
|
145
177
|
"""
|
@@ -394,11 +426,15 @@ class ContainerReplicatorRpc(db_replicator.ReplicatorRpc):
|
|
394
426
|
def _post_rsync_then_merge_hook(self, existing_broker, new_broker):
|
395
427
|
# Note the following hook will need to change to using a pointer and
|
396
428
|
# limit in the future.
|
397
|
-
|
398
|
-
|
429
|
+
shards = existing_broker.get_all_shard_range_data()
|
430
|
+
shards = check_merge_own_shard_range(
|
431
|
+
shards, new_broker, self.logger, 'rsync')
|
432
|
+
new_broker.merge_shard_ranges(shards)
|
399
433
|
|
400
434
|
def merge_shard_ranges(self, broker, args):
|
401
|
-
|
435
|
+
shards = check_merge_own_shard_range(
|
436
|
+
args[0], broker, self.logger, 'repl_req')
|
437
|
+
broker.merge_shard_ranges(shards)
|
402
438
|
return HTTPAccepted()
|
403
439
|
|
404
440
|
def get_shard_ranges(self, broker, args):
|