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
@@ -20,12 +20,13 @@ import time
20
20
  from resource import getpagesize
21
21
 
22
22
  from swift import __version__ as swiftver
23
- from swift import gettext_ as _
24
23
  from swift.common.constraints import check_mount
25
24
  from swift.common.storage_policy import POLICIES
26
25
  from swift.common.swob import Request, Response
27
- from swift.common.utils import get_logger, config_true_value, \
28
- SWIFT_CONF_FILE, md5_hash_for_file
26
+ from swift.common.utils import get_logger, SWIFT_CONF_FILE, md5_hash_for_file
27
+ from swift.common.recon import RECON_OBJECT_FILE, RECON_CONTAINER_FILE, \
28
+ RECON_ACCOUNT_FILE, RECON_DRIVE_FILE, RECON_RELINKER_FILE, \
29
+ DEFAULT_RECON_CACHE_PATH
29
30
 
30
31
 
31
32
  class ReconMiddleware(object):
@@ -35,7 +36,7 @@ class ReconMiddleware(object):
35
36
  /recon/load|mem|async... will return various system metrics.
36
37
 
37
38
  Needs to be added to the pipeline and requires a filter
38
- declaration in the object-server.conf:
39
+ declaration in the [account|container|object]-server conf file:
39
40
 
40
41
  [filter:recon]
41
42
  use = egg:swift#recon
@@ -48,15 +49,17 @@ class ReconMiddleware(object):
48
49
  swift_dir = conf.get('swift_dir', '/etc/swift')
49
50
  self.logger = get_logger(conf, log_route='recon')
50
51
  self.recon_cache_path = conf.get('recon_cache_path',
51
- '/var/cache/swift')
52
+ DEFAULT_RECON_CACHE_PATH)
52
53
  self.object_recon_cache = os.path.join(self.recon_cache_path,
53
- 'object.recon')
54
+ RECON_OBJECT_FILE)
54
55
  self.container_recon_cache = os.path.join(self.recon_cache_path,
55
- 'container.recon')
56
+ RECON_CONTAINER_FILE)
56
57
  self.account_recon_cache = os.path.join(self.recon_cache_path,
57
- 'account.recon')
58
+ RECON_ACCOUNT_FILE)
58
59
  self.drive_recon_cache = os.path.join(self.recon_cache_path,
59
- 'drive.recon')
60
+ RECON_DRIVE_FILE)
61
+ self.relink_recon_cache = os.path.join(self.recon_cache_path,
62
+ RECON_RELINKER_FILE)
60
63
  self.account_ring_path = os.path.join(swift_dir, 'account.ring.gz')
61
64
  self.container_ring_path = os.path.join(swift_dir, 'container.ring.gz')
62
65
 
@@ -66,26 +69,30 @@ class ReconMiddleware(object):
66
69
  self.rings.append(os.path.join(swift_dir,
67
70
  policy.ring_name + '.ring.gz'))
68
71
 
69
- self.mount_check = config_true_value(conf.get('mount_check', 'true'))
70
-
71
- def _from_recon_cache(self, cache_keys, cache_file, openr=open):
72
+ def _from_recon_cache(self, cache_keys, cache_file, openr=open,
73
+ ignore_missing=False):
72
74
  """retrieve values from a recon cache file
73
75
 
74
76
  :params cache_keys: list of cache items to retrieve
75
77
  :params cache_file: cache file to retrieve items from.
76
78
  :params openr: open to use [for unittests]
79
+ :params ignore_missing: Some recon stats are very temporary, in this
80
+ case it would be better to not log if things are missing.
77
81
  :return: dict of cache items and their values or none if not found
78
82
  """
79
83
  try:
80
84
  with openr(cache_file, 'r') as f:
81
85
  recondata = json.load(f)
82
- return dict((key, recondata.get(key)) for key in cache_keys)
83
- except IOError:
84
- self.logger.exception(_('Error reading recon cache file'))
86
+ return {key: recondata.get(key) for key in cache_keys}
87
+ except IOError as err:
88
+ if err.errno == errno.ENOENT and ignore_missing:
89
+ pass
90
+ else:
91
+ self.logger.exception('Error reading recon cache file')
85
92
  except ValueError:
86
- self.logger.exception(_('Error parsing recon cache file'))
93
+ self.logger.exception('Error parsing recon cache file')
87
94
  except Exception:
88
- self.logger.exception(_('Error retrieving recon data'))
95
+ self.logger.exception('Error retrieving recon data')
89
96
  return dict((key, None) for key in cache_keys)
90
97
 
91
98
  def get_version(self):
@@ -127,7 +134,7 @@ class ReconMiddleware(object):
127
134
 
128
135
  def get_async_info(self):
129
136
  """get # of async pendings"""
130
- return self._from_recon_cache(['async_pending'],
137
+ return self._from_recon_cache(['async_pending', 'async_pending_last'],
131
138
  self.object_recon_cache)
132
139
 
133
140
  def get_driveaudit_error(self):
@@ -135,6 +142,13 @@ class ReconMiddleware(object):
135
142
  return self._from_recon_cache(['drive_audit_errors'],
136
143
  self.drive_recon_cache)
137
144
 
145
+ def get_sharding_info(self):
146
+ """get sharding info"""
147
+ return self._from_recon_cache(["sharding_stats",
148
+ "sharding_time",
149
+ "sharding_last"],
150
+ self.container_recon_cache)
151
+
138
152
  def get_replication_info(self, recon_type):
139
153
  """get replication info"""
140
154
  replication_list = ['replication_time',
@@ -154,12 +168,19 @@ class ReconMiddleware(object):
154
168
  else:
155
169
  return None
156
170
 
171
+ def get_reconstruction_info(self):
172
+ """get reconstruction info"""
173
+ reconstruction_list = ['object_reconstruction_last',
174
+ 'object_reconstruction_time']
175
+ return self._from_recon_cache(reconstruction_list,
176
+ self.object_recon_cache)
177
+
157
178
  def get_device_info(self):
158
179
  """get devices"""
159
180
  try:
160
181
  return {self.devices: os.listdir(self.devices)}
161
182
  except Exception:
162
- self.logger.exception(_('Error listing devices'))
183
+ self.logger.exception('Error listing devices')
163
184
  return {self.devices: None}
164
185
 
165
186
  def get_updater_info(self, recon_type):
@@ -168,7 +189,9 @@ class ReconMiddleware(object):
168
189
  return self._from_recon_cache(['container_updater_sweep'],
169
190
  self.container_recon_cache)
170
191
  elif recon_type == 'object':
171
- return self._from_recon_cache(['object_updater_sweep'],
192
+ return self._from_recon_cache(['object_updater_sweep',
193
+ 'object_updater_stats',
194
+ 'object_updater_last'],
172
195
  self.object_recon_cache)
173
196
  else:
174
197
  return None
@@ -255,7 +278,7 @@ class ReconMiddleware(object):
255
278
  except IOError as err:
256
279
  sums[ringfile] = None
257
280
  if err.errno != errno.ENOENT:
258
- self.logger.exception(_('Error reading ringfile'))
281
+ self.logger.exception('Error reading ringfile')
259
282
  return sums
260
283
 
261
284
  def get_swift_conf_md5(self):
@@ -265,7 +288,7 @@ class ReconMiddleware(object):
265
288
  hexsum = md5_hash_for_file(SWIFT_CONF_FILE)
266
289
  except IOError as err:
267
290
  if err.errno != errno.ENOENT:
268
- self.logger.exception(_('Error reading swift.conf'))
291
+ self.logger.exception('Error reading swift.conf')
269
292
  return {SWIFT_CONF_FILE: hexsum}
270
293
 
271
294
  def get_quarantine_count(self):
@@ -330,6 +353,14 @@ class ReconMiddleware(object):
330
353
 
331
354
  return time.time()
332
355
 
356
+ def get_relinker_info(self):
357
+ """get relinker info, if any"""
358
+
359
+ stat_keys = ['devices', 'workers']
360
+ return self._from_recon_cache(stat_keys,
361
+ self.relink_recon_cache,
362
+ ignore_missing=True)
363
+
333
364
  def GET(self, req):
334
365
  root, rcheck, rtype = req.split_path(1, 3, True)
335
366
  all_rtypes = ['account', 'container', 'object']
@@ -372,6 +403,12 @@ class ReconMiddleware(object):
372
403
  content = self.get_driveaudit_error()
373
404
  elif rcheck == "time":
374
405
  content = self.get_time()
406
+ elif rcheck == "sharding":
407
+ content = self.get_sharding_info()
408
+ elif rcheck == "relinker":
409
+ content = self.get_relinker_info()
410
+ elif rcheck == "reconstruction" and rtype == 'object':
411
+ content = self.get_reconstruction_info()
375
412
  else:
376
413
  content = "Invalid path: %s" % req.path
377
414
  return Response(request=req, status="404 Not Found",
@@ -128,9 +128,23 @@ class BaseAclHandler(object):
128
128
  raise Exception('No permission to be checked exists')
129
129
 
130
130
  if resource == 'object':
131
+ version_id = self.req.params.get('versionId')
132
+ if version_id is None:
133
+ query = {}
134
+ else:
135
+ query = {'version-id': version_id}
136
+ if self.req.method == 'HEAD':
137
+ # This HEAD for ACL is going to also be the definitive response
138
+ # to the client so we need to include client params. We don't
139
+ # do this for other client request methods because they may
140
+ # have invalid combinations of params and headers for a swift
141
+ # HEAD request.
142
+ part_number = self.req.params.get('partNumber')
143
+ if part_number is not None:
144
+ query['part-number'] = part_number
131
145
  resp = self.req.get_acl_response(app, 'HEAD',
132
146
  container, obj,
133
- headers)
147
+ headers, query=query)
134
148
  acl = resp.object_acl
135
149
  elif resource == 'container':
136
150
  resp = self.req.get_acl_response(app, 'HEAD',
@@ -162,8 +176,8 @@ class BaseAclHandler(object):
162
176
  try:
163
177
  elem = fromstring(body, ACL.root_tag)
164
178
  acl = ACL.from_elem(
165
- elem, True, self.req.allow_no_owner)
166
- except(XMLSyntaxError, DocumentInvalid):
179
+ elem, True, self.req.conf.allow_no_owner)
180
+ except (XMLSyntaxError, DocumentInvalid):
167
181
  raise MalformedACLError()
168
182
  except Exception as e:
169
183
  self.logger.error(e)
@@ -243,6 +257,9 @@ class S3AclHandler(BaseAclHandler):
243
257
  """
244
258
  S3AclHandler: Handler for S3AclController
245
259
  """
260
+ def HEAD(self, app):
261
+ self._handle_acl(app, 'HEAD', permission='READ_ACP')
262
+
246
263
  def GET(self, app):
247
264
  self._handle_acl(app, 'HEAD', permission='READ_ACP')
248
265
 
@@ -460,4 +477,9 @@ ACL_MAP = {
460
477
  # Initiate Multipart Upload
461
478
  ('POST', 'HEAD', 'container'):
462
479
  {'Permission': 'WRITE'},
480
+ # Versioning
481
+ ('PUT', 'POST', 'container'):
482
+ {'Permission': 'WRITE'},
483
+ ('DELETE', 'GET', 'container'):
484
+ {'Permission': 'WRITE'},
463
485
  }
@@ -41,6 +41,11 @@ def swift_acl_translate(acl, group='', user='', xml=False):
41
41
  # ['HTTP_X_CONTAINER_READ', group + ':' + user]]
42
42
  swift_acl['private'] = [['X-Container-Write', '.'],
43
43
  ['X-Container-Read', '.']]
44
+
45
+ # Swift doesn't have per-object ACLs, so this is best-effort
46
+ swift_acl['bucket-owner-full-control'] = swift_acl['private']
47
+ swift_acl['bucket-owner-read'] = swift_acl['private']
48
+
44
49
  if xml:
45
50
  # We are working with XML and need to parse it
46
51
  try:
@@ -62,7 +67,7 @@ def swift_acl_translate(acl, group='', user='', xml=False):
62
67
  else:
63
68
  acl = 'unsupported'
64
69
 
65
- if acl == 'authenticated-read':
70
+ if acl in ('authenticated-read', 'log-delivery-write'):
66
71
  raise S3NotImplemented()
67
72
  elif acl not in swift_acl:
68
73
  raise ACLError()
@@ -31,6 +31,10 @@ from swift.common.middleware.s3api.controllers.logging import \
31
31
  LoggingStatusController
32
32
  from swift.common.middleware.s3api.controllers.versioning import \
33
33
  VersioningController
34
+ from swift.common.middleware.s3api.controllers.tagging import \
35
+ TaggingController
36
+ from swift.common.middleware.s3api.controllers.object_lock import \
37
+ ObjectLockController
34
38
 
35
39
  __all__ = [
36
40
  'Controller',
@@ -47,6 +51,8 @@ __all__ = [
47
51
  'LocationController',
48
52
  'LoggingStatusController',
49
53
  'VersioningController',
54
+ 'TaggingController',
55
+ 'ObjectLockController',
50
56
 
51
57
  'UnsupportedController',
52
58
  ]
@@ -19,8 +19,9 @@ from swift.common.utils import public
19
19
 
20
20
  from swift.common.middleware.s3api.exception import ACLError
21
21
  from swift.common.middleware.s3api.controllers.base import Controller
22
- from swift.common.middleware.s3api.s3response import HTTPOk, S3NotImplemented, \
23
- MalformedACLError, UnexpectedContent, MissingSecurityHeader
22
+ from swift.common.middleware.s3api.s3response import (
23
+ HTTPOk, S3NotImplemented, MalformedACLError, UnexpectedContent,
24
+ MissingSecurityHeader)
24
25
  from swift.common.middleware.s3api.etree import Element, SubElement, tostring
25
26
  from swift.common.middleware.s3api.acl_utils import swift_acl_translate, \
26
27
  XMLNS_XSI