swift 2.23.3__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 (206) 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.3.data/scripts/swift-account-audit → swift/cli/account_audit.py +23 -13
  9. swift-2.23.3.data/scripts/swift-config → swift/cli/config.py +2 -2
  10. swift/cli/container_deleter.py +5 -11
  11. swift-2.23.3.data/scripts/swift-dispersion-populate → swift/cli/dispersion_populate.py +8 -7
  12. swift/cli/dispersion_report.py +10 -9
  13. swift-2.23.3.data/scripts/swift-drive-audit → swift/cli/drive_audit.py +63 -21
  14. swift/cli/form_signature.py +3 -7
  15. swift-2.23.3.data/scripts/swift-get-nodes → swift/cli/get_nodes.py +8 -2
  16. swift/cli/info.py +154 -14
  17. swift/cli/manage_shard_ranges.py +705 -37
  18. swift-2.23.3.data/scripts/swift-oldies → swift/cli/oldies.py +25 -14
  19. swift-2.23.3.data/scripts/swift-orphans → swift/cli/orphans.py +7 -3
  20. swift/cli/recon.py +196 -67
  21. swift-2.23.3.data/scripts/swift-recon-cron → swift/cli/recon_cron.py +17 -20
  22. swift-2.23.3.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 +195 -128
  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 +390 -145
  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 -95
  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 +51 -18
  102. swift/common/middleware/tempauth.py +76 -58
  103. swift/common/middleware/tempurl.py +191 -173
  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.3.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} +2163 -2772
  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 +553 -535
  130. swift/container/auditor.py +14 -100
  131. swift/container/backend.py +490 -231
  132. swift/container/reconciler.py +126 -37
  133. swift/container/replicator.py +96 -22
  134. swift/container/server.py +358 -165
  135. swift/container/sharder.py +1540 -684
  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 +207 -122
  146. swift/obj/ssync_receiver.py +145 -85
  147. swift/obj/ssync_sender.py +113 -54
  148. swift/obj/updater.py +652 -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 +433 -92
  154. swift/proxy/controllers/info.py +3 -2
  155. swift/proxy/controllers/obj.py +1000 -489
  156. swift/proxy/server.py +185 -112
  157. {swift-2.23.3.dist-info → swift-2.35.0.dist-info}/AUTHORS +58 -11
  158. {swift-2.23.3.dist-info → swift-2.35.0.dist-info}/METADATA +51 -56
  159. swift-2.35.0.dist-info/RECORD +201 -0
  160. {swift-2.23.3.dist-info → swift-2.35.0.dist-info}/WHEEL +1 -1
  161. {swift-2.23.3.dist-info → swift-2.35.0.dist-info}/entry_points.txt +43 -0
  162. swift-2.35.0.dist-info/pbr.json +1 -0
  163. swift/locale/de/LC_MESSAGES/swift.po +0 -1216
  164. swift/locale/en_GB/LC_MESSAGES/swift.po +0 -1207
  165. swift/locale/es/LC_MESSAGES/swift.po +0 -1085
  166. swift/locale/fr/LC_MESSAGES/swift.po +0 -909
  167. swift/locale/it/LC_MESSAGES/swift.po +0 -894
  168. swift/locale/ja/LC_MESSAGES/swift.po +0 -965
  169. swift/locale/ko_KR/LC_MESSAGES/swift.po +0 -964
  170. swift/locale/pt_BR/LC_MESSAGES/swift.po +0 -881
  171. swift/locale/ru/LC_MESSAGES/swift.po +0 -891
  172. swift/locale/tr_TR/LC_MESSAGES/swift.po +0 -832
  173. swift/locale/zh_CN/LC_MESSAGES/swift.po +0 -833
  174. swift/locale/zh_TW/LC_MESSAGES/swift.po +0 -838
  175. swift-2.23.3.data/scripts/swift-account-auditor +0 -23
  176. swift-2.23.3.data/scripts/swift-account-info +0 -51
  177. swift-2.23.3.data/scripts/swift-account-reaper +0 -23
  178. swift-2.23.3.data/scripts/swift-account-replicator +0 -34
  179. swift-2.23.3.data/scripts/swift-account-server +0 -23
  180. swift-2.23.3.data/scripts/swift-container-auditor +0 -23
  181. swift-2.23.3.data/scripts/swift-container-info +0 -55
  182. swift-2.23.3.data/scripts/swift-container-reconciler +0 -21
  183. swift-2.23.3.data/scripts/swift-container-replicator +0 -34
  184. swift-2.23.3.data/scripts/swift-container-sharder +0 -37
  185. swift-2.23.3.data/scripts/swift-container-sync +0 -23
  186. swift-2.23.3.data/scripts/swift-container-updater +0 -23
  187. swift-2.23.3.data/scripts/swift-dispersion-report +0 -24
  188. swift-2.23.3.data/scripts/swift-form-signature +0 -20
  189. swift-2.23.3.data/scripts/swift-init +0 -119
  190. swift-2.23.3.data/scripts/swift-object-auditor +0 -29
  191. swift-2.23.3.data/scripts/swift-object-expirer +0 -33
  192. swift-2.23.3.data/scripts/swift-object-info +0 -60
  193. swift-2.23.3.data/scripts/swift-object-reconstructor +0 -33
  194. swift-2.23.3.data/scripts/swift-object-relinker +0 -41
  195. swift-2.23.3.data/scripts/swift-object-replicator +0 -37
  196. swift-2.23.3.data/scripts/swift-object-server +0 -27
  197. swift-2.23.3.data/scripts/swift-object-updater +0 -23
  198. swift-2.23.3.data/scripts/swift-proxy-server +0 -23
  199. swift-2.23.3.data/scripts/swift-recon +0 -24
  200. swift-2.23.3.data/scripts/swift-ring-builder +0 -24
  201. swift-2.23.3.data/scripts/swift-ring-builder-analyzer +0 -22
  202. swift-2.23.3.data/scripts/swift-ring-composer +0 -22
  203. swift-2.23.3.dist-info/RECORD +0 -220
  204. swift-2.23.3.dist-info/pbr.json +0 -1
  205. {swift-2.23.3.dist-info → swift-2.35.0.dist-info}/LICENSE +0 -0
  206. {swift-2.23.3.dist-info → swift-2.35.0.dist-info}/top_level.txt +0 -0
swift/account/server.py CHANGED
@@ -15,9 +15,9 @@
15
15
 
16
16
  import json
17
17
  import os
18
+ import sys
18
19
  import time
19
20
  import traceback
20
- from swift import gettext_ as _
21
21
 
22
22
  from eventlet import Timeout
23
23
 
@@ -26,12 +26,14 @@ from swift.account.backend import AccountBroker, DATADIR
26
26
  from swift.account.utils import account_listing_response, get_response_headers
27
27
  from swift.common.db import DatabaseConnectionError, DatabaseAlreadyExists
28
28
  from swift.common.request_helpers import get_param, \
29
- split_and_validate_path
29
+ split_and_validate_path, validate_internal_account, \
30
+ validate_internal_container, constrain_req_limit
30
31
  from swift.common.utils import get_logger, hash_path, public, \
31
32
  Timestamp, storage_directory, config_true_value, \
32
33
  timing_stats, replication, get_log_line, \
33
- config_fallocate_value, fs_has_free_space
34
- from swift.common.constraints import valid_timestamp, check_utf8, check_drive
34
+ config_fallocate_value, fs_has_free_space, parse_options
35
+ from swift.common.constraints import valid_timestamp, check_utf8, \
36
+ check_drive, AUTO_CREATE_ACCOUNT_PREFIX
35
37
  from swift.common import constraints
36
38
  from swift.common.db_replicator import ReplicatorRpc
37
39
  from swift.common.base_storage_server import BaseStorageServer
@@ -42,6 +44,33 @@ from swift.common.swob import HTTPAccepted, HTTPBadRequest, \
42
44
  HTTPPreconditionFailed, HTTPConflict, Request, \
43
45
  HTTPInsufficientStorage, HTTPException, wsgi_to_str
44
46
  from swift.common.request_helpers import is_sys_or_user_meta
47
+ from swift.common.wsgi import run_wsgi
48
+
49
+
50
+ def get_account_name_and_placement(req):
51
+ """
52
+ Split and validate path for an account.
53
+
54
+ :param req: a swob request
55
+
56
+ :returns: a tuple of path parts as strings
57
+ """
58
+ drive, part, account = split_and_validate_path(req, 3)
59
+ validate_internal_account(account)
60
+ return drive, part, account
61
+
62
+
63
+ def get_container_name_and_placement(req):
64
+ """
65
+ Split and validate path for a container.
66
+
67
+ :param req: a swob request
68
+
69
+ :returns: a tuple of path parts as strings
70
+ """
71
+ drive, part, account, container = split_and_validate_path(req, 3, 4)
72
+ validate_internal_container(account, container)
73
+ return drive, part, account, container
45
74
 
46
75
 
47
76
  class AccountController(BaseStorageServer):
@@ -58,10 +87,12 @@ class AccountController(BaseStorageServer):
58
87
  self.replicator_rpc = ReplicatorRpc(self.root, DATADIR, AccountBroker,
59
88
  self.mount_check,
60
89
  logger=self.logger)
61
- self.auto_create_account_prefix = \
62
- conf.get('auto_create_account_prefix') or '.'
90
+ self.auto_create_account_prefix = AUTO_CREATE_ACCOUNT_PREFIX
91
+
63
92
  swift.common.db.DB_PREALLOCATION = \
64
93
  config_true_value(conf.get('db_preallocation', 'f'))
94
+ swift.common.db.QUERY_LOGGING = \
95
+ config_true_value(conf.get('db_query_logging', 'f'))
65
96
  self.fallocate_reserve, self.fallocate_is_percent = \
66
97
  config_fallocate_value(conf.get('fallocate_reserve', '1%'))
67
98
 
@@ -96,7 +127,7 @@ class AccountController(BaseStorageServer):
96
127
  @timing_stats()
97
128
  def DELETE(self, req):
98
129
  """Handle HTTP DELETE request."""
99
- drive, part, account = split_and_validate_path(req, 3)
130
+ drive, part, account = get_account_name_and_placement(req)
100
131
  try:
101
132
  check_drive(self.root, drive, self.mount_check)
102
133
  except ValueError:
@@ -120,7 +151,7 @@ class AccountController(BaseStorageServer):
120
151
  @timing_stats()
121
152
  def PUT(self, req):
122
153
  """Handle HTTP PUT request."""
123
- drive, part, account, container = split_and_validate_path(req, 3, 4)
154
+ drive, part, account, container = get_container_name_and_placement(req)
124
155
  try:
125
156
  check_drive(self.root, drive, self.mount_check)
126
157
  except ValueError:
@@ -145,8 +176,9 @@ class AccountController(BaseStorageServer):
145
176
  broker.initialize(timestamp.internal)
146
177
  except DatabaseAlreadyExists:
147
178
  pass
148
- if req.headers.get('x-account-override-deleted', 'no').lower() != \
149
- 'yes' and broker.is_deleted():
179
+ if (req.headers.get('x-account-override-deleted', 'no').lower() !=
180
+ 'yes' and broker.is_deleted()) \
181
+ or not os.path.exists(broker.db_file):
150
182
  return HTTPNotFound(request=req)
151
183
  broker.put_container(container, req.headers['x-put-timestamp'],
152
184
  req.headers['x-delete-timestamp'],
@@ -185,7 +217,7 @@ class AccountController(BaseStorageServer):
185
217
  @timing_stats()
186
218
  def HEAD(self, req):
187
219
  """Handle HTTP HEAD request."""
188
- drive, part, account = split_and_validate_path(req, 3)
220
+ drive, part, account = get_account_name_and_placement(req)
189
221
  out_content_type = listing_formats.get_listing_content_type(req)
190
222
  try:
191
223
  check_drive(self.root, drive, self.mount_check)
@@ -198,25 +230,18 @@ class AccountController(BaseStorageServer):
198
230
  return self._deleted_response(broker, req, HTTPNotFound)
199
231
  headers = get_response_headers(broker)
200
232
  headers['Content-Type'] = out_content_type
233
+ headers['Content-Length'] = 0
201
234
  return HTTPNoContent(request=req, headers=headers, charset='utf-8')
202
235
 
203
236
  @public
204
237
  @timing_stats()
205
238
  def GET(self, req):
206
239
  """Handle HTTP GET request."""
207
- drive, part, account = split_and_validate_path(req, 3)
240
+ drive, part, account = get_account_name_and_placement(req)
208
241
  prefix = get_param(req, 'prefix')
209
242
  delimiter = get_param(req, 'delimiter')
210
- limit = constraints.ACCOUNT_LISTING_LIMIT
211
- given_limit = get_param(req, 'limit')
212
243
  reverse = config_true_value(get_param(req, 'reverse'))
213
- if given_limit and given_limit.isdigit():
214
- limit = int(given_limit)
215
- if limit > constraints.ACCOUNT_LISTING_LIMIT:
216
- return HTTPPreconditionFailed(
217
- request=req,
218
- body='Maximum limit is %d' %
219
- constraints.ACCOUNT_LISTING_LIMIT)
244
+ limit = constrain_req_limit(req, constraints.ACCOUNT_LISTING_LIMIT)
220
245
  marker = get_param(req, 'marker', '')
221
246
  end_marker = get_param(req, 'end_marker')
222
247
  out_content_type = listing_formats.get_listing_content_type(req)
@@ -262,7 +287,7 @@ class AccountController(BaseStorageServer):
262
287
  @timing_stats()
263
288
  def POST(self, req):
264
289
  """Handle HTTP POST request."""
265
- drive, part, account = split_and_validate_path(req, 3)
290
+ drive, part, account = get_account_name_and_placement(req)
266
291
  req_timestamp = valid_timestamp(req)
267
292
  try:
268
293
  check_drive(self.root, drive, self.mount_check)
@@ -280,8 +305,8 @@ class AccountController(BaseStorageServer):
280
305
  start_time = time.time()
281
306
  req = Request(env)
282
307
  self.logger.txn_id = req.headers.get('x-trans-id', None)
283
- if not check_utf8(wsgi_to_str(req.path_info)):
284
- res = HTTPPreconditionFailed(body='Invalid UTF8 or contains NULL')
308
+ if not check_utf8(wsgi_to_str(req.path_info), internal=True):
309
+ res = HTTPPreconditionFailed(body='Invalid UTF8')
285
310
  else:
286
311
  try:
287
312
  # disallow methods which are not publicly accessible
@@ -292,8 +317,8 @@ class AccountController(BaseStorageServer):
292
317
  except HTTPException as error_response:
293
318
  res = error_response
294
319
  except (Exception, Timeout):
295
- self.logger.exception(_('ERROR __call__ error with %(method)s'
296
- ' %(path)s '),
320
+ self.logger.exception('ERROR __call__ error with %(method)s'
321
+ ' %(path)s ',
297
322
  {'method': req.method, 'path': req.path})
298
323
  res = HTTPInternalServerError(body=traceback.format_exc())
299
324
  if self.log_requests:
@@ -317,3 +342,12 @@ def app_factory(global_conf, **local_conf):
317
342
  conf = global_conf.copy()
318
343
  conf.update(local_conf)
319
344
  return AccountController(conf)
345
+
346
+
347
+ def main():
348
+ conf_file, options = parse_options(test_config=True)
349
+ sys.exit(run_wsgi(conf_file, 'account-server', **options))
350
+
351
+
352
+ if __name__ == '__main__':
353
+ main()
swift/account/utils.py CHANGED
@@ -15,8 +15,7 @@
15
15
 
16
16
  import json
17
17
 
18
- import six
19
-
18
+ from swift.common import constraints
20
19
  from swift.common.middleware import listing_formats
21
20
  from swift.common.swob import HTTPOk, HTTPNoContent, str_to_wsgi
22
21
  from swift.common.utils import Timestamp
@@ -71,25 +70,43 @@ def get_response_headers(broker):
71
70
 
72
71
 
73
72
  def account_listing_response(account, req, response_content_type, broker=None,
74
- limit='', marker='', end_marker='', prefix='',
75
- delimiter='', reverse=False):
73
+ limit=constraints.ACCOUNT_LISTING_LIMIT,
74
+ marker='', end_marker='', prefix='', delimiter='',
75
+ reverse=False):
76
76
  if broker is None:
77
77
  broker = FakeAccountBroker()
78
78
 
79
79
  resp_headers = get_response_headers(broker)
80
80
 
81
81
  account_list = broker.list_containers_iter(limit, marker, end_marker,
82
- prefix, delimiter, reverse)
82
+ prefix, delimiter, reverse,
83
+ req.allow_reserved_names)
83
84
  data = []
84
- for (name, object_count, bytes_used, put_timestamp, is_subdir) \
85
+ for (name, object_count, bytes_used, put_timestamp,
86
+ storage_policy_index, is_subdir) \
85
87
  in account_list:
86
- name_ = name.decode('utf8') if six.PY2 else name
87
88
  if is_subdir:
88
- data.append({'subdir': name_})
89
+ data.append({'subdir': name})
89
90
  else:
90
- data.append(
91
- {'name': name_, 'count': object_count, 'bytes': bytes_used,
92
- 'last_modified': Timestamp(put_timestamp).isoformat})
91
+ container = {
92
+ 'name': name,
93
+ 'count': object_count,
94
+ 'bytes': bytes_used,
95
+ 'last_modified': Timestamp(put_timestamp).isoformat}
96
+ # Add the container's storage policy to the response, unless
97
+ # storage_policy_index was not found in POLICIES, which means
98
+ # the storage policy is missing from the Swift configuration
99
+ # or otherwise could not be determined.
100
+ #
101
+ # The storage policy should always be returned when
102
+ # everything is configured correctly, but clients are
103
+ # expected to be able to handle this case regardless,
104
+ # if only to support older versions of swift.
105
+ if storage_policy_index in POLICIES:
106
+ container['storage_policy'] = (
107
+ POLICIES[storage_policy_index].name
108
+ )
109
+ data.append(container)
93
110
  if response_content_type.endswith('/xml'):
94
111
  account_list = listing_formats.account_to_xml(data, account)
95
112
  ret = HTTPOk(body=account_list, request=req, headers=resp_headers)
@@ -1,4 +1,4 @@
1
- #!python
1
+ #!/usr/bin/env python
2
2
  # Copyright (c) 2010-2012 OpenStack Foundation
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,20 +14,19 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
- from __future__ import print_function
18
17
  import os
19
18
  import sys
20
- from hashlib import md5
21
19
  import getopt
22
20
  from itertools import chain
23
21
 
24
22
  import json
25
23
  from eventlet.greenpool import GreenPool
26
24
  from eventlet.event import Event
27
- from six.moves.urllib.parse import quote
25
+ from urllib.parse import quote
28
26
 
29
27
  from swift.common.ring import Ring
30
28
  from swift.common.utils import split_path
29
+ from swift.common.utils.base import md5
31
30
  from swift.common.bufferedhttp import http_connect
32
31
 
33
32
 
@@ -91,7 +90,7 @@ class Auditor(object):
91
90
  conn = http_connect(node['ip'], node['port'],
92
91
  node['device'], part, 'GET', path, {})
93
92
  resp = conn.getresponse()
94
- calc_hash = md5()
93
+ calc_hash = md5(usedforsecurity=False)
95
94
  chunk = True
96
95
  while chunk:
97
96
  chunk = resp.read(8192)
@@ -100,15 +99,15 @@ class Auditor(object):
100
99
  if resp.status // 100 != 2:
101
100
  self.object_not_found += 1
102
101
  consistent = False
103
- print(' Bad status GETting object "%s" on %s/%s'
104
- % (path, node['ip'], node['device']))
102
+ print(' Bad status %s GETting object "%s" on %s/%s'
103
+ % (resp.status, path,
104
+ node['ip'], node['device']))
105
105
  continue
106
106
  if resp.getheader('ETag').strip('"') != calc_hash:
107
107
  self.object_checksum_mismatch += 1
108
108
  consistent = False
109
109
  print(' MD5 does not match etag for "%s" on %s/%s'
110
110
  % (path, node['ip'], node['device']))
111
- etags.append((resp.getheader('ETag'), node))
112
111
  else:
113
112
  conn = http_connect(node['ip'], node['port'],
114
113
  node['device'], part, 'HEAD',
@@ -117,9 +116,16 @@ class Auditor(object):
117
116
  if resp.status // 100 != 2:
118
117
  self.object_not_found += 1
119
118
  consistent = False
120
- print(' Bad status HEADing object "%s" on %s/%s'
121
- % (path, node['ip'], node['device']))
119
+ print(' Bad status %s HEADing object "%s" on %s/%s'
120
+ % (resp.status, path,
121
+ node['ip'], node['device']))
122
122
  continue
123
+
124
+ override_etag = resp.getheader(
125
+ 'X-Object-Sysmeta-Container-Update-Override-Etag')
126
+ if override_etag:
127
+ etags.append((override_etag, node))
128
+ else:
123
129
  etags.append((resp.getheader('ETag'), node))
124
130
  except Exception:
125
131
  self.object_exceptions += 1
@@ -252,14 +258,14 @@ class Auditor(object):
252
258
  self.account_not_found += 1
253
259
  consistent = False
254
260
  print(" Bad status GETting account '%s' "
255
- " from %ss:%ss" %
261
+ " from %s:%s" %
256
262
  (account, node['ip'], node['device']))
257
263
  break
258
264
  results = json.loads(resp.read())
259
265
  except Exception:
260
266
  self.account_exceptions += 1
261
267
  consistent = False
262
- print(" Exception GETting account '%s' on %ss:%ss" %
268
+ print(" Exception GETting account '%s' on %s:%s" %
263
269
  (account, node['ip'], node['device']))
264
270
  break
265
271
  if node_id not in responses:
@@ -352,7 +358,7 @@ class Auditor(object):
352
358
  _print_stat("MD5 Mismatch", self.object_checksum_mismatch)
353
359
 
354
360
 
355
- if __name__ == '__main__':
361
+ def main():
356
362
  try:
357
363
  optlist, args = getopt.getopt(sys.argv[1:], 'c:r:e:d')
358
364
  except getopt.GetoptError as err:
@@ -377,3 +383,7 @@ if __name__ == '__main__':
377
383
  auditor.audit(*split_path(path, 1, 3, True))
378
384
  auditor.wait()
379
385
  auditor.print_stats()
386
+
387
+
388
+ if __name__ == '__main__':
389
+ 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 sys
@@ -86,5 +85,6 @@ def main():
86
85
  print('# %s = %s' % (k, v))
87
86
  print()
88
87
 
88
+
89
89
  if __name__ == "__main__":
90
90
  sys.exit(main())
@@ -28,7 +28,6 @@ import argparse
28
28
  import io
29
29
  import itertools
30
30
  import json
31
- import six
32
31
  import time
33
32
 
34
33
  from swift.common.internal_client import InternalClient
@@ -50,17 +49,11 @@ def make_delete_jobs(account, container, objects, timestamp):
50
49
  :returns: list of dicts appropriate for an UPDATE request to an
51
50
  expiring-object queue
52
51
  '''
53
- if six.PY2:
54
- if isinstance(account, str):
55
- account = account.decode('utf8')
56
- if isinstance(container, str):
57
- container = container.decode('utf8')
58
52
  return [
59
53
  {
60
54
  'name': build_task_obj(
61
55
  timestamp, account, container,
62
- obj.decode('utf8') if six.PY2 and isinstance(obj, str)
63
- else obj),
56
+ obj, high_precision=True),
64
57
  'deleted': 0,
65
58
  'created_at': timestamp.internal,
66
59
  'etag': MD5_OF_EMPTY_STRING,
@@ -133,7 +126,7 @@ def mark_for_deletion(swift, account, container, marker, end_marker,
133
126
  return enqueue_deletes()
134
127
 
135
128
 
136
- def main():
129
+ def main(args=None):
137
130
  parser = argparse.ArgumentParser(
138
131
  description=__doc__,
139
132
  formatter_class=argparse.RawTextHelpFormatter)
@@ -156,10 +149,11 @@ def main():
156
149
  parser.add_argument(
157
150
  '--timestamp', type=Timestamp, default=Timestamp.now(),
158
151
  help='delete all objects as of this time (default: now)')
159
- args = parser.parse_args()
152
+ args = parser.parse_args(args)
160
153
 
161
154
  swift = InternalClient(
162
- args.config, 'Swift Container Deleter', args.request_tries)
155
+ args.config, 'Swift Container Deleter', args.request_tries,
156
+ global_conf={'log_name': 'container-deleter-ic'})
163
157
  for deleted, marker in mark_for_deletion(
164
158
  swift, args.account, args.container,
165
159
  args.marker, args.end_marker, args.prefix, args.timestamp):
@@ -1,4 +1,4 @@
1
- #!python
1
+ #!/usr/bin/env python
2
2
  # Copyright (c) 2010-2012 OpenStack Foundation
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,7 +13,6 @@
13
13
  # implied.
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
- from __future__ import print_function
17
16
 
18
17
  import io
19
18
  import traceback
@@ -23,9 +22,7 @@ from time import time
23
22
 
24
23
  from eventlet import GreenPool, patcher, sleep
25
24
  from eventlet.pools import Pool
26
- import six
27
- from six.moves import range
28
- from six.moves.configparser import ConfigParser
25
+ from configparser import ConfigParser
29
26
 
30
27
  from swift.common.internal_client import SimpleClient
31
28
  from swift.common.ring import Ring
@@ -53,7 +50,7 @@ def put_object(connpool, container, obj, report):
53
50
  global retries_done
54
51
  try:
55
52
  with connpool.item() as conn:
56
- data = io.BytesIO(obj if six.PY2 else obj.encode('utf8'))
53
+ data = io.BytesIO(obj.encode('utf8'))
57
54
  conn.put_object(container, obj, data,
58
55
  headers={'x-object-meta-dispersion': obj})
59
56
  retries_done += conn.attempts - 1
@@ -81,7 +78,7 @@ def report(success):
81
78
  stdout.flush()
82
79
 
83
80
 
84
- if __name__ == '__main__':
81
+ def main():
85
82
  global begun, created, item_type, next_report, need_to_create, retries_done
86
83
  patcher.monkey_patch()
87
84
  try:
@@ -281,3 +278,7 @@ Usage: %%prog [options] [conf_file]
281
278
  print('\r\x1B[KTotal object coverage is now %.2f%%.' %
282
279
  ((float(obj_coverage) / object_ring.partition_count * 100)))
283
280
  stdout.flush()
281
+
282
+
283
+ if __name__ == '__main__':
284
+ main()
@@ -14,10 +14,9 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
- from __future__ import print_function
18
17
  import json
19
18
  from collections import defaultdict
20
- from six.moves.configparser import ConfigParser
19
+ from configparser import ConfigParser
21
20
  from optparse import OptionParser
22
21
  from sys import exit, stdout, stderr
23
22
  from time import time
@@ -26,14 +25,11 @@ from eventlet import GreenPool, hubs, patcher, Timeout
26
25
  from eventlet.pools import Pool
27
26
 
28
27
  from swift.common import direct_client
29
- try:
30
- from swiftclient import get_auth
31
- except ImportError:
32
- from swift.common.internal_client import get_auth
33
28
  from swift.common.internal_client import SimpleClient
34
29
  from swift.common.ring import Ring
35
30
  from swift.common.exceptions import ClientException
36
- from swift.common.utils import compute_eta, get_time_units, config_true_value
31
+ from swift.common.utils import compute_eta, get_time_units, \
32
+ config_true_value, node_to_string
37
33
  from swift.common.storage_policy import POLICIES
38
34
 
39
35
 
@@ -93,7 +89,7 @@ def container_dispersion_report(coropool, connpool, account, container_ring,
93
89
  def direct(container, part, nodes):
94
90
  found_count = 0
95
91
  for node in nodes:
96
- error_log = get_error_log('%(ip)s:%(port)s/%(device)s' % node)
92
+ error_log = get_error_log(node_to_string(node))
97
93
  try:
98
94
  attempts, _junk = direct_client.retry(
99
95
  direct_client.direct_head_container, node, part, account,
@@ -205,7 +201,7 @@ def object_dispersion_report(coropool, connpool, account, object_ring,
205
201
  def direct(obj, part, nodes):
206
202
  found_count = 0
207
203
  for node in nodes:
208
- error_log = get_error_log('%(ip)s:%(port)s/%(device)s' % node)
204
+ error_log = get_error_log(node_to_string(node))
209
205
  try:
210
206
  attempts, _junk = direct_client.retry(
211
207
  direct_client.direct_head_object, node, part, account,
@@ -365,6 +361,11 @@ Usage: %%prog [options] [conf_file]
365
361
 
366
362
 
367
363
  def generate_report(conf, policy_name=None):
364
+ try:
365
+ # Delay importing so urllib3 will import monkey-patched modules
366
+ from swiftclient import get_auth
367
+ except ImportError:
368
+ from swift.common.internal_client import get_auth
368
369
  global json_output
369
370
  json_output = config_true_value(conf.get('dump_json', 'no'))
370
371
  if policy_name is None: