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.
Files changed (95) hide show
  1. swift/account/server.py +1 -11
  2. swift/cli/info.py +28 -1
  3. swift-2.32.1.data/scripts/swift-recon-cron → swift/cli/recon_cron.py +4 -13
  4. swift/cli/reload.py +141 -0
  5. swift/common/daemon.py +12 -2
  6. swift/common/db.py +12 -8
  7. swift/common/http_protocol.py +76 -3
  8. swift/common/manager.py +18 -5
  9. swift/common/memcached.py +18 -12
  10. swift/common/middleware/proxy_logging.py +35 -27
  11. swift/common/middleware/s3api/acl_handlers.py +1 -1
  12. swift/common/middleware/s3api/controllers/__init__.py +3 -0
  13. swift/common/middleware/s3api/controllers/acl.py +3 -2
  14. swift/common/middleware/s3api/controllers/logging.py +2 -2
  15. swift/common/middleware/s3api/controllers/multi_upload.py +30 -6
  16. swift/common/middleware/s3api/controllers/object_lock.py +44 -0
  17. swift/common/middleware/s3api/s3api.py +4 -0
  18. swift/common/middleware/s3api/s3request.py +19 -12
  19. swift/common/middleware/s3api/s3response.py +13 -2
  20. swift/common/middleware/s3api/utils.py +1 -1
  21. swift/common/middleware/slo.py +395 -298
  22. swift/common/middleware/staticweb.py +45 -14
  23. swift/common/middleware/tempurl.py +132 -91
  24. swift/common/request_helpers.py +32 -8
  25. swift/common/storage_policy.py +1 -1
  26. swift/common/swob.py +5 -2
  27. swift/common/utils/__init__.py +230 -135
  28. swift/common/utils/timestamp.py +23 -2
  29. swift/common/wsgi.py +8 -0
  30. swift/container/backend.py +126 -21
  31. swift/container/replicator.py +42 -6
  32. swift/container/server.py +264 -145
  33. swift/container/sharder.py +50 -30
  34. swift/container/updater.py +1 -0
  35. swift/obj/auditor.py +2 -1
  36. swift/obj/diskfile.py +55 -19
  37. swift/obj/expirer.py +1 -13
  38. swift/obj/mem_diskfile.py +2 -1
  39. swift/obj/mem_server.py +1 -0
  40. swift/obj/replicator.py +2 -2
  41. swift/obj/server.py +12 -23
  42. swift/obj/updater.py +1 -0
  43. swift/obj/watchers/dark_data.py +72 -34
  44. swift/proxy/controllers/account.py +3 -2
  45. swift/proxy/controllers/base.py +217 -127
  46. swift/proxy/controllers/container.py +274 -289
  47. swift/proxy/controllers/obj.py +98 -141
  48. swift/proxy/server.py +2 -12
  49. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-info +3 -0
  50. swift-2.33.1.data/scripts/swift-recon-cron +24 -0
  51. {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/AUTHORS +3 -1
  52. {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/METADATA +4 -3
  53. {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/RECORD +94 -91
  54. {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/WHEEL +1 -1
  55. {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/entry_points.txt +1 -0
  56. swift-2.33.1.dist-info/pbr.json +1 -0
  57. swift-2.32.1.dist-info/pbr.json +0 -1
  58. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-audit +0 -0
  59. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-auditor +0 -0
  60. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-info +0 -0
  61. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-reaper +0 -0
  62. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-replicator +0 -0
  63. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-account-server +0 -0
  64. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-config +0 -0
  65. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-auditor +0 -0
  66. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-reconciler +0 -0
  67. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-replicator +0 -0
  68. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-server +0 -0
  69. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-sharder +0 -0
  70. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-sync +0 -0
  71. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-container-updater +0 -0
  72. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-dispersion-populate +0 -0
  73. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-dispersion-report +0 -0
  74. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-drive-audit +0 -0
  75. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-form-signature +0 -0
  76. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-get-nodes +0 -0
  77. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-init +0 -0
  78. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-auditor +0 -0
  79. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-expirer +0 -0
  80. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-info +0 -0
  81. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-reconstructor +0 -0
  82. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-relinker +0 -0
  83. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-replicator +0 -0
  84. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-server +0 -0
  85. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-object-updater +0 -0
  86. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-oldies +0 -0
  87. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-orphans +0 -0
  88. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-proxy-server +0 -0
  89. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-recon +0 -0
  90. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-reconciler-enqueue +0 -0
  91. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-ring-builder +0 -0
  92. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-ring-builder-analyzer +0 -0
  93. {swift-2.32.1.data → swift-2.33.1.data}/scripts/swift-ring-composer +0 -0
  94. {swift-2.32.1.dist-info → swift-2.33.1.dist-info}/LICENSE +0 -0
  95. {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)
@@ -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 state(s); can be an
1713
- int or a list of ints.
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 state(s); can be a list of ints or a
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
- own_shard_range = self.get_own_shard_range()
1910
- if shard_ranges:
1911
- last_upper = shard_ranges[-1].upper
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:
@@ -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
- broker.merge_shard_ranges(json.loads(
142
- response.data.decode('ascii')))
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
- new_broker.merge_shard_ranges(
398
- existing_broker.get_all_shard_range_data())
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
- broker.merge_shard_ranges(args[0])
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):