swift 2.23.2__py3-none-any.whl → 2.35.0__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 (208) hide show
  1. swift/__init__.py +29 -50
  2. swift/account/auditor.py +21 -118
  3. swift/account/backend.py +33 -28
  4. swift/account/reaper.py +37 -28
  5. swift/account/replicator.py +22 -0
  6. swift/account/server.py +60 -26
  7. swift/account/utils.py +28 -11
  8. swift-2.23.2.data/scripts/swift-account-audit → swift/cli/account_audit.py +23 -13
  9. swift-2.23.2.data/scripts/swift-config → swift/cli/config.py +2 -2
  10. swift/cli/container_deleter.py +5 -11
  11. swift-2.23.2.data/scripts/swift-dispersion-populate → swift/cli/dispersion_populate.py +8 -7
  12. swift/cli/dispersion_report.py +10 -9
  13. swift-2.23.2.data/scripts/swift-drive-audit → swift/cli/drive_audit.py +63 -21
  14. swift/cli/form_signature.py +3 -7
  15. swift-2.23.2.data/scripts/swift-get-nodes → swift/cli/get_nodes.py +8 -2
  16. swift/cli/info.py +183 -29
  17. swift/cli/manage_shard_ranges.py +708 -37
  18. swift-2.23.2.data/scripts/swift-oldies → swift/cli/oldies.py +25 -14
  19. swift-2.23.2.data/scripts/swift-orphans → swift/cli/orphans.py +7 -3
  20. swift/cli/recon.py +196 -67
  21. swift-2.23.2.data/scripts/swift-recon-cron → swift/cli/recon_cron.py +17 -20
  22. swift-2.23.2.data/scripts/swift-reconciler-enqueue → swift/cli/reconciler_enqueue.py +2 -3
  23. swift/cli/relinker.py +807 -126
  24. swift/cli/reload.py +135 -0
  25. swift/cli/ringbuilder.py +217 -20
  26. swift/cli/ringcomposer.py +0 -1
  27. swift/cli/shard-info.py +4 -3
  28. swift/common/base_storage_server.py +9 -20
  29. swift/common/bufferedhttp.py +48 -74
  30. swift/common/constraints.py +20 -15
  31. swift/common/container_sync_realms.py +9 -11
  32. swift/common/daemon.py +25 -8
  33. swift/common/db.py +198 -127
  34. swift/common/db_auditor.py +168 -0
  35. swift/common/db_replicator.py +95 -55
  36. swift/common/digest.py +141 -0
  37. swift/common/direct_client.py +144 -33
  38. swift/common/error_limiter.py +93 -0
  39. swift/common/exceptions.py +25 -1
  40. swift/common/header_key_dict.py +2 -9
  41. swift/common/http_protocol.py +373 -0
  42. swift/common/internal_client.py +129 -59
  43. swift/common/linkat.py +3 -4
  44. swift/common/manager.py +284 -67
  45. swift/common/memcached.py +396 -147
  46. swift/common/middleware/__init__.py +4 -0
  47. swift/common/middleware/account_quotas.py +211 -46
  48. swift/common/middleware/acl.py +3 -8
  49. swift/common/middleware/backend_ratelimit.py +230 -0
  50. swift/common/middleware/bulk.py +22 -34
  51. swift/common/middleware/catch_errors.py +1 -3
  52. swift/common/middleware/cname_lookup.py +6 -11
  53. swift/common/middleware/container_quotas.py +1 -1
  54. swift/common/middleware/container_sync.py +39 -17
  55. swift/common/middleware/copy.py +12 -0
  56. swift/common/middleware/crossdomain.py +22 -9
  57. swift/common/middleware/crypto/__init__.py +2 -1
  58. swift/common/middleware/crypto/crypto_utils.py +11 -15
  59. swift/common/middleware/crypto/decrypter.py +28 -11
  60. swift/common/middleware/crypto/encrypter.py +12 -17
  61. swift/common/middleware/crypto/keymaster.py +8 -15
  62. swift/common/middleware/crypto/kms_keymaster.py +2 -1
  63. swift/common/middleware/dlo.py +15 -11
  64. swift/common/middleware/domain_remap.py +5 -4
  65. swift/common/middleware/etag_quoter.py +128 -0
  66. swift/common/middleware/formpost.py +73 -70
  67. swift/common/middleware/gatekeeper.py +8 -1
  68. swift/common/middleware/keystoneauth.py +33 -3
  69. swift/common/middleware/list_endpoints.py +4 -4
  70. swift/common/middleware/listing_formats.py +85 -49
  71. swift/common/middleware/memcache.py +4 -81
  72. swift/common/middleware/name_check.py +3 -2
  73. swift/common/middleware/proxy_logging.py +160 -92
  74. swift/common/middleware/ratelimit.py +17 -10
  75. swift/common/middleware/read_only.py +6 -4
  76. swift/common/middleware/recon.py +59 -22
  77. swift/common/middleware/s3api/acl_handlers.py +25 -3
  78. swift/common/middleware/s3api/acl_utils.py +6 -1
  79. swift/common/middleware/s3api/controllers/__init__.py +6 -0
  80. swift/common/middleware/s3api/controllers/acl.py +3 -2
  81. swift/common/middleware/s3api/controllers/bucket.py +242 -137
  82. swift/common/middleware/s3api/controllers/logging.py +2 -2
  83. swift/common/middleware/s3api/controllers/multi_delete.py +43 -20
  84. swift/common/middleware/s3api/controllers/multi_upload.py +219 -133
  85. swift/common/middleware/s3api/controllers/obj.py +112 -8
  86. swift/common/middleware/s3api/controllers/object_lock.py +44 -0
  87. swift/common/middleware/s3api/controllers/s3_acl.py +2 -2
  88. swift/common/middleware/s3api/controllers/tagging.py +57 -0
  89. swift/common/middleware/s3api/controllers/versioning.py +36 -7
  90. swift/common/middleware/s3api/etree.py +22 -9
  91. swift/common/middleware/s3api/exception.py +0 -4
  92. swift/common/middleware/s3api/s3api.py +113 -41
  93. swift/common/middleware/s3api/s3request.py +384 -218
  94. swift/common/middleware/s3api/s3response.py +126 -23
  95. swift/common/middleware/s3api/s3token.py +16 -17
  96. swift/common/middleware/s3api/schema/delete.rng +1 -1
  97. swift/common/middleware/s3api/subresource.py +7 -10
  98. swift/common/middleware/s3api/utils.py +27 -10
  99. swift/common/middleware/slo.py +665 -358
  100. swift/common/middleware/staticweb.py +64 -37
  101. swift/common/middleware/symlink.py +52 -19
  102. swift/common/middleware/tempauth.py +76 -58
  103. swift/common/middleware/tempurl.py +192 -174
  104. swift/common/middleware/versioned_writes/__init__.py +51 -0
  105. swift/common/middleware/{versioned_writes.py → versioned_writes/legacy.py} +27 -26
  106. swift/common/middleware/versioned_writes/object_versioning.py +1482 -0
  107. swift/common/middleware/x_profile/exceptions.py +1 -4
  108. swift/common/middleware/x_profile/html_viewer.py +18 -19
  109. swift/common/middleware/x_profile/profile_model.py +1 -2
  110. swift/common/middleware/xprofile.py +10 -10
  111. swift-2.23.2.data/scripts/swift-container-server → swift/common/recon.py +13 -8
  112. swift/common/registry.py +147 -0
  113. swift/common/request_helpers.py +324 -57
  114. swift/common/ring/builder.py +67 -25
  115. swift/common/ring/composite_builder.py +1 -1
  116. swift/common/ring/ring.py +177 -51
  117. swift/common/ring/utils.py +1 -1
  118. swift/common/splice.py +10 -6
  119. swift/common/statsd_client.py +205 -0
  120. swift/common/storage_policy.py +49 -44
  121. swift/common/swob.py +86 -102
  122. swift/common/{utils.py → utils/__init__.py} +2191 -2762
  123. swift/common/utils/base.py +131 -0
  124. swift/common/utils/config.py +433 -0
  125. swift/common/utils/ipaddrs.py +256 -0
  126. swift/common/utils/libc.py +345 -0
  127. swift/common/utils/logs.py +859 -0
  128. swift/common/utils/timestamp.py +412 -0
  129. swift/common/wsgi.py +555 -536
  130. swift/container/auditor.py +14 -100
  131. swift/container/backend.py +552 -227
  132. swift/container/reconciler.py +126 -37
  133. swift/container/replicator.py +96 -22
  134. swift/container/server.py +397 -176
  135. swift/container/sharder.py +1580 -639
  136. swift/container/sync.py +94 -88
  137. swift/container/updater.py +53 -32
  138. swift/obj/auditor.py +153 -35
  139. swift/obj/diskfile.py +466 -217
  140. swift/obj/expirer.py +406 -124
  141. swift/obj/mem_diskfile.py +7 -4
  142. swift/obj/mem_server.py +1 -0
  143. swift/obj/reconstructor.py +523 -262
  144. swift/obj/replicator.py +249 -188
  145. swift/obj/server.py +213 -122
  146. swift/obj/ssync_receiver.py +145 -85
  147. swift/obj/ssync_sender.py +113 -54
  148. swift/obj/updater.py +653 -139
  149. swift/obj/watchers/__init__.py +0 -0
  150. swift/obj/watchers/dark_data.py +213 -0
  151. swift/proxy/controllers/account.py +11 -11
  152. swift/proxy/controllers/base.py +848 -604
  153. swift/proxy/controllers/container.py +452 -86
  154. swift/proxy/controllers/info.py +3 -2
  155. swift/proxy/controllers/obj.py +1009 -490
  156. swift/proxy/server.py +185 -112
  157. swift-2.35.0.dist-info/AUTHORS +501 -0
  158. swift-2.35.0.dist-info/LICENSE +202 -0
  159. {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/METADATA +52 -61
  160. swift-2.35.0.dist-info/RECORD +201 -0
  161. {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/WHEEL +1 -1
  162. {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/entry_points.txt +43 -0
  163. swift-2.35.0.dist-info/pbr.json +1 -0
  164. swift/locale/de/LC_MESSAGES/swift.po +0 -1216
  165. swift/locale/en_GB/LC_MESSAGES/swift.po +0 -1207
  166. swift/locale/es/LC_MESSAGES/swift.po +0 -1085
  167. swift/locale/fr/LC_MESSAGES/swift.po +0 -909
  168. swift/locale/it/LC_MESSAGES/swift.po +0 -894
  169. swift/locale/ja/LC_MESSAGES/swift.po +0 -965
  170. swift/locale/ko_KR/LC_MESSAGES/swift.po +0 -964
  171. swift/locale/pt_BR/LC_MESSAGES/swift.po +0 -881
  172. swift/locale/ru/LC_MESSAGES/swift.po +0 -891
  173. swift/locale/tr_TR/LC_MESSAGES/swift.po +0 -832
  174. swift/locale/zh_CN/LC_MESSAGES/swift.po +0 -833
  175. swift/locale/zh_TW/LC_MESSAGES/swift.po +0 -838
  176. swift-2.23.2.data/scripts/swift-account-auditor +0 -23
  177. swift-2.23.2.data/scripts/swift-account-info +0 -51
  178. swift-2.23.2.data/scripts/swift-account-reaper +0 -23
  179. swift-2.23.2.data/scripts/swift-account-replicator +0 -34
  180. swift-2.23.2.data/scripts/swift-account-server +0 -23
  181. swift-2.23.2.data/scripts/swift-container-auditor +0 -23
  182. swift-2.23.2.data/scripts/swift-container-info +0 -51
  183. swift-2.23.2.data/scripts/swift-container-reconciler +0 -21
  184. swift-2.23.2.data/scripts/swift-container-replicator +0 -34
  185. swift-2.23.2.data/scripts/swift-container-sharder +0 -33
  186. swift-2.23.2.data/scripts/swift-container-sync +0 -23
  187. swift-2.23.2.data/scripts/swift-container-updater +0 -23
  188. swift-2.23.2.data/scripts/swift-dispersion-report +0 -24
  189. swift-2.23.2.data/scripts/swift-form-signature +0 -20
  190. swift-2.23.2.data/scripts/swift-init +0 -119
  191. swift-2.23.2.data/scripts/swift-object-auditor +0 -29
  192. swift-2.23.2.data/scripts/swift-object-expirer +0 -33
  193. swift-2.23.2.data/scripts/swift-object-info +0 -60
  194. swift-2.23.2.data/scripts/swift-object-reconstructor +0 -33
  195. swift-2.23.2.data/scripts/swift-object-relinker +0 -41
  196. swift-2.23.2.data/scripts/swift-object-replicator +0 -37
  197. swift-2.23.2.data/scripts/swift-object-server +0 -27
  198. swift-2.23.2.data/scripts/swift-object-updater +0 -23
  199. swift-2.23.2.data/scripts/swift-proxy-server +0 -23
  200. swift-2.23.2.data/scripts/swift-recon +0 -24
  201. swift-2.23.2.data/scripts/swift-ring-builder +0 -24
  202. swift-2.23.2.data/scripts/swift-ring-builder-analyzer +0 -22
  203. swift-2.23.2.data/scripts/swift-ring-composer +0 -22
  204. swift-2.23.2.dist-info/DESCRIPTION.rst +0 -166
  205. swift-2.23.2.dist-info/RECORD +0 -220
  206. swift-2.23.2.dist-info/metadata.json +0 -1
  207. swift-2.23.2.dist-info/pbr.json +0 -1
  208. {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- #!python
1
+ #!/usr/bin/env python
2
2
  # Licensed under the Apache License, Version 2.0 (the "License");
3
3
  # you may not use this file except in compliance with the License.
4
4
  # You may obtain a copy of the License at
@@ -12,13 +12,12 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from __future__ import print_function
16
15
  import optparse
17
16
  import subprocess
18
17
  import sys
19
18
 
20
19
 
21
- if __name__ == '__main__':
20
+ def main():
22
21
  parser = optparse.OptionParser(usage='''%prog [options]
23
22
 
24
23
  Lists old Swift processes.
@@ -26,6 +25,9 @@ Lists old Swift processes.
26
25
  parser.add_option('-a', '--age', dest='hours', type='int', default=720,
27
26
  help='look for processes at least HOURS old; '
28
27
  'default: 720 (30 days)')
28
+ parser.add_option('-p', '--pids', action='store_true',
29
+ help='only print the pids found; for example, to pipe '
30
+ 'to xargs kill')
29
31
  (options, args) = parser.parse_args()
30
32
 
31
33
  listing = []
@@ -68,15 +70,24 @@ Lists old Swift processes.
68
70
  if not listing:
69
71
  sys.exit()
70
72
 
71
- hours_len = len('Hours')
72
- pid_len = len('PID')
73
- args_len = len('Command')
74
- for hours, pid, args in listing:
75
- hours_len = max(hours_len, len(hours))
76
- pid_len = max(pid_len, len(pid))
77
- args_len = max(args_len, len(args))
78
- args_len = min(args_len, 78 - hours_len - pid_len)
73
+ if options.pids:
74
+ for hours, pid, args in listing:
75
+ print(pid)
76
+ else:
77
+ hours_len = len('Hours')
78
+ pid_len = len('PID')
79
+ args_len = len('Command')
80
+ for hours, pid, args in listing:
81
+ hours_len = max(hours_len, len(hours))
82
+ pid_len = max(pid_len, len(pid))
83
+ args_len = max(args_len, len(args))
84
+ args_len = min(args_len, 78 - hours_len - pid_len)
85
+
86
+ print('%*s %*s %s' % (hours_len, 'Hours', pid_len, 'PID', 'Command'))
87
+ for hours, pid, args in listing:
88
+ print('%*s %*s %s' % (hours_len, hours, pid_len,
89
+ pid, args[:args_len]))
79
90
 
80
- print('%*s %*s %s' % (hours_len, 'Hours', pid_len, 'PID', 'Command'))
81
- for hours, pid, args in listing:
82
- print('%*s %*s %s' % (hours_len, hours, pid_len, pid, args[:args_len]))
91
+
92
+ if __name__ == '__main__':
93
+ main()
@@ -1,4 +1,4 @@
1
- #!python
1
+ #!/usr/bin/env python
2
2
  # Licensed under the Apache License, Version 2.0 (the "License");
3
3
  # you may not use this file except in compliance with the License.
4
4
  # You may obtain a copy of the License at
@@ -12,7 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from __future__ import print_function
16
15
  import optparse
17
16
  import os
18
17
  import re
@@ -22,7 +21,8 @@ import sys
22
21
 
23
22
  from swift.common.manager import RUN_DIR
24
23
 
25
- if __name__ == '__main__':
24
+
25
+ def main():
26
26
  parser = optparse.OptionParser(usage='''%prog [options]
27
27
 
28
28
  Lists and optionally kills orphaned Swift processes. This is done by scanning
@@ -130,3 +130,7 @@ Example (sends SIGTERM to all orphaned Swift processes older than two hours):
130
130
  for hours, pid, args in listing:
131
131
  os.kill(int(pid), signum)
132
132
  print('Done.')
133
+
134
+
135
+ if __name__ == '__main__':
136
+ main()
swift/cli/recon.py CHANGED
@@ -15,11 +15,9 @@
15
15
  cmdline utility to perform cluster reconnaissance
16
16
  """
17
17
 
18
- from __future__ import print_function
19
18
 
20
19
  from eventlet.green import socket
21
- from six import string_types
22
- from six.moves.urllib.parse import urlparse
20
+ from urllib.parse import urlparse
23
21
 
24
22
  from swift.common.utils import (
25
23
  SWIFT_CONF_FILE, md5_hash_for_file, set_swift_dir)
@@ -30,13 +28,9 @@ import json
30
28
  import optparse
31
29
  import time
32
30
  import sys
33
- import six
34
31
  import os
35
32
 
36
- if six.PY3:
37
- from eventlet.green.urllib import request as urllib2
38
- else:
39
- from eventlet.green import urllib2
33
+ from eventlet.green.urllib import request as urllib_request
40
34
 
41
35
 
42
36
  def seconds2timeunit(seconds):
@@ -86,19 +80,19 @@ class Scout(object):
86
80
  """
87
81
  url = base_url + recon_type
88
82
  try:
89
- body = urllib2.urlopen(url, timeout=self.timeout).read()
90
- if six.PY3 and isinstance(body, six.binary_type):
83
+ body = urllib_request.urlopen(url, timeout=self.timeout).read()
84
+ if isinstance(body, bytes):
91
85
  body = body.decode('utf8')
92
86
  content = json.loads(body)
93
87
  if self.verbose:
94
88
  print("-> %s: %s" % (url, content))
95
89
  status = 200
96
- except urllib2.HTTPError as err:
90
+ except urllib_request.HTTPError as err:
97
91
  if not self.suppress_errors or self.verbose:
98
92
  print("-> %s: %s" % (url, err))
99
93
  content = err
100
94
  status = err.code
101
- except (urllib2.URLError, socket.timeout) as err:
95
+ except (urllib_request.URLError, socket.timeout) as err:
102
96
  if not self.suppress_errors or self.verbose:
103
97
  print("-> %s: %s" % (url, err))
104
98
  content = err
@@ -128,19 +122,19 @@ class Scout(object):
128
122
  """
129
123
  try:
130
124
  url = "http://%s:%s/" % (host[0], host[1])
131
- req = urllib2.Request(url)
125
+ req = urllib_request.Request(url)
132
126
  req.get_method = lambda: 'OPTIONS'
133
- conn = urllib2.urlopen(req)
127
+ conn = urllib_request.urlopen(req)
134
128
  header = conn.info().get('Server')
135
129
  server_header = header.split('/')
136
130
  content = server_header[0]
137
131
  status = 200
138
- except urllib2.HTTPError as err:
132
+ except urllib_request.HTTPError as err:
139
133
  if not self.suppress_errors or self.verbose:
140
134
  print("-> %s: %s" % (url, err))
141
135
  content = err
142
136
  status = err.code
143
- except (urllib2.URLError, socket.timeout) as err:
137
+ except (urllib_request.URLError, socket.timeout) as err:
144
138
  if not self.suppress_errors or self.verbose:
145
139
  print("-> %s: %s" % (url, err))
146
140
  content = err
@@ -221,7 +215,7 @@ class SwiftRecon(object):
221
215
  Compare ring md5sum's with those on remote host
222
216
 
223
217
  :param hosts: set of hosts to check. in the format of:
224
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
218
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
225
219
  :param swift_dir: The local directory with the ring files.
226
220
  """
227
221
  matches = 0
@@ -275,7 +269,7 @@ class SwiftRecon(object):
275
269
  Compare swift.conf md5sum with that on remote hosts
276
270
 
277
271
  :param hosts: set of hosts to check. in the format of:
278
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
272
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
279
273
  :param printfn: function to print text; defaults to print()
280
274
  """
281
275
  matches = 0
@@ -307,7 +301,7 @@ class SwiftRecon(object):
307
301
  Obtain and print async pending statistics
308
302
 
309
303
  :param hosts: set of hosts to check. in the format of:
310
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
304
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
311
305
  """
312
306
  scan = {}
313
307
  recon = Scout("async", self.verbose, self.suppress_errors,
@@ -329,7 +323,7 @@ class SwiftRecon(object):
329
323
  Obtain and print drive audit error statistics
330
324
 
331
325
  :param hosts: set of hosts to check. in the format of:
332
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)]
326
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)]
333
327
  """
334
328
  scan = {}
335
329
  recon = Scout("driveaudit", self.verbose, self.suppress_errors,
@@ -351,7 +345,7 @@ class SwiftRecon(object):
351
345
  Check for and print unmounted drives
352
346
 
353
347
  :param hosts: set of hosts to check. in the format of:
354
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
348
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
355
349
  """
356
350
  unmounted = {}
357
351
  errors = {}
@@ -384,7 +378,7 @@ class SwiftRecon(object):
384
378
  Check for server types on the ring
385
379
 
386
380
  :param hosts: set of hosts to check. in the format of:
387
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
381
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
388
382
  """
389
383
  errors = {}
390
384
  recon = Scout("server_type_check", self.verbose, self.suppress_errors,
@@ -407,7 +401,7 @@ class SwiftRecon(object):
407
401
  Obtain and print expirer statistics
408
402
 
409
403
  :param hosts: set of hosts to check. in the format of:
410
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
404
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
411
405
  """
412
406
  stats = {'object_expiration_pass': [], 'expired_last_pass': []}
413
407
  recon = Scout("expirer/%s" % self.server_type, self.verbose,
@@ -431,22 +425,91 @@ class SwiftRecon(object):
431
425
  print("[%s] - No hosts returned valid data." % k)
432
426
  print("=" * 79)
433
427
 
428
+ def _calculate_least_and_most_recent(self, url_time_data):
429
+ """calulate and print the least and most recent urls
430
+
431
+ Given a list of url and time tuples calulate the most and least
432
+ recent timings and print it out.
433
+ :param url_time_data: list of url and time tuples: [(url, time_), ..]
434
+ """
435
+ least_recent_time = 9999999999
436
+ least_recent_url = None
437
+ most_recent_time = 0
438
+ most_recent_url = None
439
+
440
+ for url, last in url_time_data:
441
+ if last is None:
442
+ continue
443
+ if last < least_recent_time:
444
+ least_recent_time = last
445
+ least_recent_url = url
446
+ if last > most_recent_time:
447
+ most_recent_time = last
448
+ most_recent_url = url
449
+
450
+ if least_recent_url is not None:
451
+ host = urlparse(least_recent_url).netloc
452
+ if not least_recent_time:
453
+ print('Oldest completion was NEVER by %s.' % host)
454
+ else:
455
+ elapsed = time.time() - least_recent_time
456
+ elapsed, elapsed_unit = seconds2timeunit(elapsed)
457
+ print('Oldest completion was %s (%d %s ago) by %s.' % (
458
+ self._ptime(least_recent_time),
459
+ elapsed, elapsed_unit, host))
460
+ if most_recent_url is not None:
461
+ host = urlparse(most_recent_url).netloc
462
+ elapsed = time.time() - most_recent_time
463
+ elapsed, elapsed_unit = seconds2timeunit(elapsed)
464
+ print('Most recent completion was %s (%d %s ago) by %s.' % (
465
+ self._ptime(most_recent_time),
466
+ elapsed, elapsed_unit, host))
467
+
468
+ def reconstruction_check(self, hosts):
469
+ """
470
+ Obtain and print reconstructon statistics
471
+
472
+ :param hosts: set of hosts to check. in the format of:
473
+ set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
474
+ """
475
+ stats = []
476
+ last_stats = []
477
+ recon = Scout("reconstruction/%s" % self.server_type, self.verbose,
478
+ self.suppress_errors, self.timeout)
479
+ print("[%s] Checking on reconstructors" % self._ptime())
480
+ for url, response, status, ts_start, ts_end in self.pool.imap(
481
+ recon.scout, hosts):
482
+ if status == 200:
483
+ stats.append(response.get('object_reconstruction_time'))
484
+ last = response.get('object_reconstruction_last', 0)
485
+ last_stats.append((url, last))
486
+ if stats:
487
+ computed = self._gen_stats(stats,
488
+ name='object_reconstruction_time')
489
+ if computed['reported'] > 0:
490
+ self._print_stats(computed)
491
+ else:
492
+ print("[object_reconstruction_time] - No hosts returned "
493
+ "valid data.")
494
+ else:
495
+ print("[object_reconstruction_time] - No hosts returned "
496
+ "valid data.")
497
+ self._calculate_least_and_most_recent(last_stats)
498
+ print("=" * 79)
499
+
434
500
  def replication_check(self, hosts):
435
501
  """
436
502
  Obtain and print replication statistics
437
503
 
438
504
  :param hosts: set of hosts to check. in the format of:
439
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
505
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
440
506
  """
441
507
  stats = {'replication_time': [], 'failure': [], 'success': [],
442
508
  'attempted': []}
509
+ last_stats = []
443
510
  recon = Scout("replication/%s" % self.server_type, self.verbose,
444
511
  self.suppress_errors, self.timeout)
445
512
  print("[%s] Checking on replication" % self._ptime())
446
- least_recent_time = 9999999999
447
- least_recent_url = None
448
- most_recent_time = 0
449
- most_recent_url = None
450
513
  for url, response, status, ts_start, ts_end in self.pool.imap(
451
514
  recon.scout, hosts):
452
515
  if status == 200:
@@ -459,14 +522,7 @@ class SwiftRecon(object):
459
522
  stats[stat_key].append(repl_stats.get(stat_key))
460
523
  last = response.get('replication_last',
461
524
  response.get('object_replication_last', 0))
462
- if last is None:
463
- continue
464
- if last < least_recent_time:
465
- least_recent_time = last
466
- least_recent_url = url
467
- if last > most_recent_time:
468
- most_recent_time = last
469
- most_recent_url = url
525
+ last_stats.append((url, last))
470
526
  for k in stats:
471
527
  if stats[k]:
472
528
  if k != 'replication_time':
@@ -480,23 +536,7 @@ class SwiftRecon(object):
480
536
  print("[%s] - No hosts returned valid data." % k)
481
537
  else:
482
538
  print("[%s] - No hosts returned valid data." % k)
483
- if least_recent_url is not None:
484
- host = urlparse(least_recent_url).netloc
485
- if not least_recent_time:
486
- print('Oldest completion was NEVER by %s.' % host)
487
- else:
488
- elapsed = time.time() - least_recent_time
489
- elapsed, elapsed_unit = seconds2timeunit(elapsed)
490
- print('Oldest completion was %s (%d %s ago) by %s.' % (
491
- self._ptime(least_recent_time),
492
- elapsed, elapsed_unit, host))
493
- if most_recent_url is not None:
494
- host = urlparse(most_recent_url).netloc
495
- elapsed = time.time() - most_recent_time
496
- elapsed, elapsed_unit = seconds2timeunit(elapsed)
497
- print('Most recent completion was %s (%d %s ago) by %s.' % (
498
- self._ptime(most_recent_time),
499
- elapsed, elapsed_unit, host))
539
+ self._calculate_least_and_most_recent(last_stats)
500
540
  print("=" * 79)
501
541
 
502
542
  def updater_check(self, hosts):
@@ -504,7 +544,7 @@ class SwiftRecon(object):
504
544
  Obtain and print updater statistics
505
545
 
506
546
  :param hosts: set of hosts to check. in the format of:
507
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
547
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
508
548
  """
509
549
  stats = []
510
550
  recon = Scout("updater/%s" % self.server_type, self.verbose,
@@ -531,7 +571,7 @@ class SwiftRecon(object):
531
571
  Obtain and print obj auditor statistics
532
572
 
533
573
  :param hosts: set of hosts to check. in the format of:
534
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
574
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
535
575
  """
536
576
  scan = {}
537
577
  adone = '%s_auditor_pass_completed' % self.server_type
@@ -603,7 +643,7 @@ class SwiftRecon(object):
603
643
  Obtain and print obj auditor statistics
604
644
 
605
645
  :param hosts: set of hosts to check. in the format of:
606
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
646
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
607
647
  """
608
648
  all_scan = {}
609
649
  zbf_scan = {}
@@ -674,12 +714,75 @@ class SwiftRecon(object):
674
714
  print("[ZBF_auditor] - No hosts returned valid data.")
675
715
  print("=" * 79)
676
716
 
717
+ def sharding_check(self, hosts):
718
+ """
719
+ Obtain and print sharding statistics
720
+
721
+ :param hosts: set of hosts to check. in the format of:
722
+ set([('127.0.0.1', 6221), ('127.0.0.2', 6231)])
723
+ """
724
+ stats = {'sharding_time': [],
725
+ 'attempted': [], 'failure': [], 'success': []}
726
+ recon = Scout("sharding", self.verbose,
727
+ self.suppress_errors, self.timeout)
728
+ print("[%s] Checking on sharders" % self._ptime())
729
+ least_recent_time = 9999999999
730
+ least_recent_url = None
731
+ most_recent_time = 0
732
+ most_recent_url = None
733
+ for url, response, status, ts_start, ts_end in self.pool.imap(
734
+ recon.scout, hosts):
735
+ if status == 200:
736
+ stats['sharding_time'].append(response.get('sharding_time', 0))
737
+ shard_stats = response.get('sharding_stats')
738
+ if shard_stats:
739
+ # Sharding has a ton more stats, like "no_change".
740
+ # Not sure if we need them at all, or maybe for -v.
741
+ for stat_key in ['attempted', 'failure', 'success']:
742
+ stats[stat_key].append(shard_stats.get(stat_key))
743
+ last = response.get('sharding_last', 0)
744
+ if last is None:
745
+ continue
746
+ if last < least_recent_time:
747
+ least_recent_time = last
748
+ least_recent_url = url
749
+ if last > most_recent_time:
750
+ most_recent_time = last
751
+ most_recent_url = url
752
+ for k in stats:
753
+ if stats[k]:
754
+ computed = self._gen_stats(stats[k], name=k)
755
+ if computed['reported'] > 0:
756
+ self._print_stats(computed)
757
+ else:
758
+ print("[%s] - No hosts returned valid data." % k)
759
+ else:
760
+ print("[%s] - No hosts returned valid data." % k)
761
+ if least_recent_url is not None:
762
+ host = urlparse(least_recent_url).netloc
763
+ if not least_recent_time:
764
+ print('Oldest completion was NEVER by %s.' % host)
765
+ else:
766
+ elapsed = time.time() - least_recent_time
767
+ elapsed, elapsed_unit = seconds2timeunit(elapsed)
768
+ print('Oldest completion was %s (%d %s ago) by %s.' % (
769
+ self._ptime(least_recent_time),
770
+ elapsed, elapsed_unit, host))
771
+ if most_recent_url is not None:
772
+ host = urlparse(most_recent_url).netloc
773
+ elapsed = time.time() - most_recent_time
774
+ elapsed, elapsed_unit = seconds2timeunit(elapsed)
775
+ print('Most recent completion was %s (%d %s ago) by %s.' % (
776
+ self._ptime(most_recent_time),
777
+ elapsed, elapsed_unit, host))
778
+ print("=" * 79)
779
+
677
780
  def load_check(self, hosts):
678
781
  """
679
782
  Obtain and print load average statistics
680
783
 
681
784
  :param hosts: set of hosts to check. in the format of:
682
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
785
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
683
786
  """
684
787
  load1 = {}
685
788
  load5 = {}
@@ -708,7 +811,7 @@ class SwiftRecon(object):
708
811
  Obtain and print quarantine statistics
709
812
 
710
813
  :param hosts: set of hosts to check. in the format of:
711
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
814
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
712
815
  """
713
816
  objq = {}
714
817
  conq = {}
@@ -742,7 +845,7 @@ class SwiftRecon(object):
742
845
  Obtain and print /proc/net/sockstat statistics
743
846
 
744
847
  :param hosts: set of hosts to check. in the format of:
745
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
848
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
746
849
  """
747
850
  inuse4 = {}
748
851
  mem = {}
@@ -776,7 +879,7 @@ class SwiftRecon(object):
776
879
  Obtain and print disk usage statistics
777
880
 
778
881
  :param hosts: set of hosts to check. in the format of:
779
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
882
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
780
883
  """
781
884
  stats = {}
782
885
  highs = []
@@ -788,9 +891,15 @@ class SwiftRecon(object):
788
891
  low_percents = [(None, 100)] * lowest
789
892
  recon = Scout("diskusage", self.verbose, self.suppress_errors,
790
893
  self.timeout)
894
+ # We want to only query each host once, but we don't care
895
+ # which of the available ports we use. So we filter hosts by
896
+ # constructing a host->port dictionary, since the dict
897
+ # constructor ensures each key is unique, thus each host
898
+ # appears only once in filtered_hosts.
899
+ filtered_hosts = set(dict(hosts).items())
791
900
  print("[%s] Checking disk usage now" % self._ptime())
792
901
  for url, response, status, ts_start, ts_end in self.pool.imap(
793
- recon.scout, hosts):
902
+ recon.scout, filtered_hosts):
794
903
  if status == 200:
795
904
  hostusage = []
796
905
  for entry in response:
@@ -875,7 +984,7 @@ class SwiftRecon(object):
875
984
  Check a time synchronization of hosts with current time
876
985
 
877
986
  :param hosts: set of hosts to check. in the format of:
878
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
987
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
879
988
  :param jitter: Maximal allowed time jitter
880
989
  """
881
990
 
@@ -914,7 +1023,7 @@ class SwiftRecon(object):
914
1023
  Check OS Swift version of hosts. Inform if differs.
915
1024
 
916
1025
  :param hosts: set of hosts to check. in the format of:
917
- set([('127.0.0.1', 6020), ('127.0.0.2', 6030)])
1026
+ set([('127.0.0.1', 6220), ('127.0.0.2', 6230)])
918
1027
  """
919
1028
  versions = set()
920
1029
  errors = 0
@@ -959,7 +1068,7 @@ class SwiftRecon(object):
959
1068
  ring_names = [p.ring_name for p in POLICIES if (
960
1069
  p.name == policy or not policy or (
961
1070
  policy.isdigit() and int(policy) == int(p) or
962
- (isinstance(policy, string_types)
1071
+ (isinstance(policy, str)
963
1072
  and policy in p.aliases)))]
964
1073
  else:
965
1074
  ring_names = [self.server_type]
@@ -973,7 +1082,7 @@ class SwiftRecon(object):
973
1082
  print("=" * 79)
974
1083
  usage = '''
975
1084
  usage: %prog <server_type> [<server_type> [<server_type>]]
976
- [-v] [--suppress] [-a] [-r] [-u] [-d]
1085
+ [-v] [--suppress] [-a] [-r] [-u] [-d] [-R]
977
1086
  [-l] [-T] [--md5] [--auditor] [--updater] [--expirer] [--sockstat]
978
1087
  [--human-readable]
979
1088
 
@@ -992,12 +1101,16 @@ class SwiftRecon(object):
992
1101
  help="Get async stats")
993
1102
  args.add_option('--replication', '-r', action="store_true",
994
1103
  help="Get replication stats")
1104
+ args.add_option('--reconstruction', '-R', action="store_true",
1105
+ help="Get reconstruction stats")
995
1106
  args.add_option('--auditor', action="store_true",
996
1107
  help="Get auditor stats")
997
1108
  args.add_option('--updater', action="store_true",
998
1109
  help="Get updater stats")
999
1110
  args.add_option('--expirer', action="store_true",
1000
1111
  help="Get expirer stats")
1112
+ args.add_option('--sharding', action="store_true",
1113
+ help="Get sharding stats")
1001
1114
  args.add_option('--unmounted', '-u', action="store_true",
1002
1115
  help="Check cluster for unmounted devices")
1003
1116
  args.add_option('--diskusage', '-d', action="store_true",
@@ -1029,7 +1142,7 @@ class SwiftRecon(object):
1029
1142
  help='Also show the lowest COUNT entries in rank \
1030
1143
  order.')
1031
1144
  args.add_option('--all', action="store_true",
1032
- help="Perform all checks. Equal to \t\t\t-arudlqT "
1145
+ help="Perform all checks. Equal to \t\t\t-arRudlqT "
1033
1146
  "--md5 --sockstat --auditor --updater --expirer "
1034
1147
  "--driveaudit --validate-servers --swift-versions")
1035
1148
  args.add_option('--region', type="int",
@@ -1087,9 +1200,11 @@ class SwiftRecon(object):
1087
1200
  self.object_auditor_check(hosts)
1088
1201
  self.updater_check(hosts)
1089
1202
  self.expirer_check(hosts)
1203
+ self.reconstruction_check(hosts)
1090
1204
  elif self.server_type == 'container':
1091
1205
  self.auditor_check(hosts)
1092
1206
  self.updater_check(hosts)
1207
+ self.sharding_check(hosts)
1093
1208
  elif self.server_type == 'account':
1094
1209
  self.auditor_check(hosts)
1095
1210
  self.replication_check(hosts)
@@ -1133,9 +1248,23 @@ class SwiftRecon(object):
1133
1248
  if self.server_type == 'object':
1134
1249
  self.expirer_check(hosts)
1135
1250
  else:
1136
- print("Error: Can't check expired on non object "
1251
+ print("Error: Can't check expirer on non object "
1137
1252
  "servers.")
1138
1253
  print("=" * 79)
1254
+ if options.sharding:
1255
+ if self.server_type == 'container':
1256
+ self.sharding_check(hosts)
1257
+ else:
1258
+ print("Error: Can't check sharding on non container "
1259
+ "servers.")
1260
+ print("=" * 79)
1261
+ if options.reconstruction:
1262
+ if self.server_type == 'object':
1263
+ self.reconstruction_check(hosts)
1264
+ else:
1265
+ print("Error: Can't check reconstruction stats on "
1266
+ "non object servers.")
1267
+ print("=" * 79)
1139
1268
  if options.validate_servers:
1140
1269
  self.server_type_check(hosts)
1141
1270
  if options.loadstats: