swift 2.33.0__py2.py3-none-any.whl → 2.34.0__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 (112) hide show
  1. swift/account/auditor.py +11 -0
  2. swift/account/reaper.py +11 -1
  3. swift/account/replicator.py +22 -0
  4. swift/account/server.py +12 -1
  5. swift-2.33.0.data/scripts/swift-account-audit → swift/cli/account_audit.py +6 -2
  6. swift-2.33.0.data/scripts/swift-config → swift/cli/config.py +1 -1
  7. swift-2.33.0.data/scripts/swift-dispersion-populate → swift/cli/dispersion_populate.py +6 -2
  8. swift-2.33.0.data/scripts/swift-drive-audit → swift/cli/drive_audit.py +12 -3
  9. swift-2.33.0.data/scripts/swift-get-nodes → swift/cli/get_nodes.py +6 -2
  10. swift/cli/info.py +103 -2
  11. swift-2.33.0.data/scripts/swift-oldies → swift/cli/oldies.py +6 -3
  12. swift-2.33.0.data/scripts/swift-orphans → swift/cli/orphans.py +7 -2
  13. swift/cli/recon_cron.py +5 -5
  14. swift-2.33.0.data/scripts/swift-reconciler-enqueue → swift/cli/reconciler_enqueue.py +2 -3
  15. swift/cli/relinker.py +1 -1
  16. swift/cli/ringbuilder.py +24 -0
  17. swift/common/db.py +2 -1
  18. swift/common/db_auditor.py +2 -2
  19. swift/common/db_replicator.py +6 -0
  20. swift/common/exceptions.py +12 -0
  21. swift/common/manager.py +102 -0
  22. swift/common/memcached.py +6 -13
  23. swift/common/middleware/account_quotas.py +144 -43
  24. swift/common/middleware/backend_ratelimit.py +166 -24
  25. swift/common/middleware/catch_errors.py +1 -3
  26. swift/common/middleware/cname_lookup.py +3 -5
  27. swift/common/middleware/container_sync.py +6 -10
  28. swift/common/middleware/crypto/crypto_utils.py +4 -5
  29. swift/common/middleware/crypto/decrypter.py +4 -5
  30. swift/common/middleware/crypto/kms_keymaster.py +2 -1
  31. swift/common/middleware/proxy_logging.py +22 -16
  32. swift/common/middleware/ratelimit.py +6 -7
  33. swift/common/middleware/recon.py +6 -7
  34. swift/common/middleware/s3api/acl_handlers.py +9 -0
  35. swift/common/middleware/s3api/controllers/multi_upload.py +1 -9
  36. swift/common/middleware/s3api/controllers/obj.py +20 -1
  37. swift/common/middleware/s3api/s3api.py +2 -0
  38. swift/common/middleware/s3api/s3request.py +171 -62
  39. swift/common/middleware/s3api/s3response.py +35 -6
  40. swift/common/middleware/s3api/s3token.py +2 -2
  41. swift/common/middleware/s3api/utils.py +1 -0
  42. swift/common/middleware/slo.py +153 -52
  43. swift/common/middleware/tempauth.py +6 -4
  44. swift/common/middleware/tempurl.py +2 -2
  45. swift/common/middleware/x_profile/exceptions.py +1 -4
  46. swift/common/middleware/x_profile/html_viewer.py +9 -10
  47. swift/common/middleware/x_profile/profile_model.py +1 -2
  48. swift/common/middleware/xprofile.py +1 -2
  49. swift/common/request_helpers.py +69 -0
  50. swift/common/statsd_client.py +207 -0
  51. swift/common/utils/__init__.py +97 -1635
  52. swift/common/utils/base.py +138 -0
  53. swift/common/utils/config.py +443 -0
  54. swift/common/utils/logs.py +999 -0
  55. swift/common/wsgi.py +11 -3
  56. swift/container/auditor.py +11 -0
  57. swift/container/backend.py +10 -10
  58. swift/container/reconciler.py +11 -2
  59. swift/container/replicator.py +22 -1
  60. swift/container/server.py +12 -1
  61. swift/container/sharder.py +36 -12
  62. swift/container/sync.py +11 -1
  63. swift/container/updater.py +11 -2
  64. swift/obj/auditor.py +18 -2
  65. swift/obj/diskfile.py +8 -6
  66. swift/obj/expirer.py +155 -36
  67. swift/obj/reconstructor.py +28 -4
  68. swift/obj/replicator.py +61 -22
  69. swift/obj/server.py +64 -36
  70. swift/obj/updater.py +11 -2
  71. swift/proxy/controllers/base.py +38 -22
  72. swift/proxy/controllers/obj.py +23 -26
  73. swift/proxy/server.py +15 -1
  74. {swift-2.33.0.dist-info → swift-2.34.0.dist-info}/AUTHORS +11 -3
  75. {swift-2.33.0.dist-info → swift-2.34.0.dist-info}/METADATA +6 -5
  76. {swift-2.33.0.dist-info → swift-2.34.0.dist-info}/RECORD +81 -107
  77. {swift-2.33.0.dist-info → swift-2.34.0.dist-info}/entry_points.txt +38 -0
  78. swift-2.34.0.dist-info/pbr.json +1 -0
  79. swift-2.33.0.data/scripts/swift-account-auditor +0 -23
  80. swift-2.33.0.data/scripts/swift-account-info +0 -52
  81. swift-2.33.0.data/scripts/swift-account-reaper +0 -23
  82. swift-2.33.0.data/scripts/swift-account-replicator +0 -34
  83. swift-2.33.0.data/scripts/swift-account-server +0 -23
  84. swift-2.33.0.data/scripts/swift-container-auditor +0 -23
  85. swift-2.33.0.data/scripts/swift-container-info +0 -59
  86. swift-2.33.0.data/scripts/swift-container-reconciler +0 -21
  87. swift-2.33.0.data/scripts/swift-container-replicator +0 -34
  88. swift-2.33.0.data/scripts/swift-container-server +0 -23
  89. swift-2.33.0.data/scripts/swift-container-sharder +0 -37
  90. swift-2.33.0.data/scripts/swift-container-sync +0 -23
  91. swift-2.33.0.data/scripts/swift-container-updater +0 -23
  92. swift-2.33.0.data/scripts/swift-dispersion-report +0 -24
  93. swift-2.33.0.data/scripts/swift-form-signature +0 -20
  94. swift-2.33.0.data/scripts/swift-init +0 -119
  95. swift-2.33.0.data/scripts/swift-object-auditor +0 -29
  96. swift-2.33.0.data/scripts/swift-object-expirer +0 -33
  97. swift-2.33.0.data/scripts/swift-object-info +0 -60
  98. swift-2.33.0.data/scripts/swift-object-reconstructor +0 -33
  99. swift-2.33.0.data/scripts/swift-object-relinker +0 -23
  100. swift-2.33.0.data/scripts/swift-object-replicator +0 -37
  101. swift-2.33.0.data/scripts/swift-object-server +0 -27
  102. swift-2.33.0.data/scripts/swift-object-updater +0 -23
  103. swift-2.33.0.data/scripts/swift-proxy-server +0 -23
  104. swift-2.33.0.data/scripts/swift-recon +0 -24
  105. swift-2.33.0.data/scripts/swift-recon-cron +0 -24
  106. swift-2.33.0.data/scripts/swift-ring-builder +0 -37
  107. swift-2.33.0.data/scripts/swift-ring-builder-analyzer +0 -22
  108. swift-2.33.0.data/scripts/swift-ring-composer +0 -22
  109. swift-2.33.0.dist-info/pbr.json +0 -1
  110. {swift-2.33.0.dist-info → swift-2.34.0.dist-info}/LICENSE +0 -0
  111. {swift-2.33.0.dist-info → swift-2.34.0.dist-info}/WHEEL +0 -0
  112. {swift-2.33.0.dist-info → swift-2.34.0.dist-info}/top_level.txt +0 -0
swift/common/wsgi.py CHANGED
@@ -198,9 +198,14 @@ def get_socket(conf):
198
198
  sock = listen(bind_addr, backlog=int(conf.get('backlog', 4096)),
199
199
  family=address_family)
200
200
  if 'cert_file' in conf:
201
+ if six.PY2:
202
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
203
+ else:
204
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
205
+ context.verify_mode = ssl.CERT_NONE
206
+ context.load_cert_chain(conf['cert_file'], conf['key_file'])
201
207
  warn_ssl = True
202
- sock = ssl.wrap_socket(sock, certfile=conf['cert_file'],
203
- keyfile=conf['key_file'])
208
+ sock = context.wrap_socket(sock, server_side=True)
204
209
  except socket.error as err:
205
210
  if err.args[0] != errno.EADDRINUSE:
206
211
  raise
@@ -460,7 +465,10 @@ def run_server(conf, logger, sock, global_conf=None, ready_callback=None,
460
465
  except socket.error as err:
461
466
  if err.errno != errno.EINVAL:
462
467
  raise
463
- pool.waitall()
468
+ finally:
469
+ pool.waitall()
470
+ if hasattr(app._pipeline_final_app, 'watchdog'):
471
+ app._pipeline_final_app.watchdog.kill()
464
472
 
465
473
 
466
474
  class StrategyBase(object):
@@ -15,7 +15,9 @@
15
15
 
16
16
 
17
17
  from swift.container.backend import ContainerBroker
18
+ from swift.common.daemon import run_daemon
18
19
  from swift.common.db_auditor import DatabaseAuditor
20
+ from swift.common.utils import parse_options
19
21
 
20
22
 
21
23
  class ContainerAuditor(DatabaseAuditor):
@@ -26,3 +28,12 @@ class ContainerAuditor(DatabaseAuditor):
26
28
 
27
29
  def _audit(self, job, broker):
28
30
  return None
31
+
32
+
33
+ def main():
34
+ conf_file, options = parse_options(once=True)
35
+ run_daemon(ContainerAuditor, conf_file, **options)
36
+
37
+
38
+ if __name__ == '__main__':
39
+ main()
@@ -941,16 +941,16 @@ class ContainerBroker(DatabaseBroker):
941
941
  self._do_get_info_query(conn)
942
942
 
943
943
  def _get_alternate_object_stats(self):
944
- state = self.get_db_state()
945
- if state == SHARDING:
944
+ db_state = self.get_db_state()
945
+ if db_state == SHARDING:
946
946
  other_info = self.get_brokers()[0]._get_info()
947
947
  stats = {'object_count': other_info['object_count'],
948
948
  'bytes_used': other_info['bytes_used']}
949
- elif state == SHARDED and self.is_root_container():
949
+ elif db_state == SHARDED and self.is_root_container():
950
950
  stats = self.get_shard_usage()
951
951
  else:
952
952
  stats = {}
953
- return state, stats
953
+ return db_state, stats
954
954
 
955
955
  def get_info(self):
956
956
  """
@@ -2144,10 +2144,10 @@ class ContainerBroker(DatabaseBroker):
2144
2144
  self.logger.warning("Container '%s' cannot be set to sharding "
2145
2145
  "state: missing epoch", self.path)
2146
2146
  return False
2147
- state = self.get_db_state()
2148
- if not state == UNSHARDED:
2147
+ db_state = self.get_db_state()
2148
+ if not db_state == UNSHARDED:
2149
2149
  self.logger.warning("Container '%s' cannot be set to sharding "
2150
- "state while in %s state", self.path, state)
2150
+ "state while in %s state", self.path, db_state)
2151
2151
  return False
2152
2152
 
2153
2153
  info = self.get_info()
@@ -2225,11 +2225,11 @@ class ContainerBroker(DatabaseBroker):
2225
2225
  :return: True if the retiring DB was successfully unlinked, False
2226
2226
  otherwise.
2227
2227
  """
2228
- state = self.get_db_state()
2229
- if not state == SHARDING:
2228
+ db_state = self.get_db_state()
2229
+ if not db_state == SHARDING:
2230
2230
  self.logger.warning("Container %r cannot be set to sharded "
2231
2231
  "state while in %s state",
2232
- self.path, state)
2232
+ self.path, db_state)
2233
2233
  return False
2234
2234
 
2235
2235
  self.reload_db_files()
@@ -22,7 +22,7 @@ from eventlet import GreenPile, GreenPool, Timeout
22
22
  import six
23
23
 
24
24
  from swift.common import constraints
25
- from swift.common.daemon import Daemon
25
+ from swift.common.daemon import Daemon, run_daemon
26
26
  from swift.common.direct_client import (
27
27
  direct_head_container, direct_delete_container_object,
28
28
  direct_put_container_object, ClientException)
@@ -31,7 +31,7 @@ from swift.common.request_helpers import MISPLACED_OBJECTS_ACCOUNT, \
31
31
  USE_REPLICATION_NETWORK_HEADER
32
32
  from swift.common.utils import get_logger, split_path, majority_size, \
33
33
  FileLikeIter, Timestamp, last_modified_date_to_timestamp, \
34
- LRUCache, decode_timestamps, hash_path
34
+ LRUCache, decode_timestamps, hash_path, parse_options
35
35
  from swift.common.storage_policy import POLICIES
36
36
 
37
37
  MISPLACED_OBJECTS_CONTAINER_DIVISOR = 3600 # 1 hour
@@ -860,3 +860,12 @@ class ContainerReconciler(Daemon):
860
860
  self.stats = defaultdict(int)
861
861
  self.logger.info('sleeping between intervals (%ss)', self.interval)
862
862
  time.sleep(self.interval)
863
+
864
+
865
+ def main():
866
+ conf_file, options = parse_options(once=True)
867
+ run_daemon(ContainerReconciler, conf_file, **options)
868
+
869
+
870
+ if __name__ == '__main__':
871
+ main()
@@ -17,6 +17,7 @@ import os
17
17
  import json
18
18
  from collections import defaultdict
19
19
  from eventlet import Timeout
20
+ import optparse
20
21
  from random import choice
21
22
 
22
23
  from swift.container.sync_store import ContainerSyncStore
@@ -26,10 +27,12 @@ from swift.container.reconciler import (
26
27
  MISPLACED_OBJECTS_ACCOUNT, incorrect_policy_index,
27
28
  get_reconciler_container_name, get_row_to_q_entry_translator)
28
29
  from swift.common import db_replicator
30
+ from swift.common.daemon import run_daemon
29
31
  from swift.common.storage_policy import POLICIES
30
32
  from swift.common.swob import HTTPOk, HTTPAccepted
31
33
  from swift.common.http import is_success
32
- from swift.common.utils import Timestamp, majority_size, get_db_files
34
+ from swift.common.utils import Timestamp, majority_size, get_db_files, \
35
+ parse_options
33
36
 
34
37
 
35
38
  def check_merge_own_shard_range(shards, broker, logger, source):
@@ -440,3 +443,21 @@ class ContainerReplicatorRpc(db_replicator.ReplicatorRpc):
440
443
  def get_shard_ranges(self, broker, args):
441
444
  return HTTPOk(headers={'Content-Type': 'application/json'},
442
445
  body=json.dumps(broker.get_all_shard_range_data()))
446
+
447
+
448
+ def main():
449
+ parser = optparse.OptionParser("%prog CONFIG [options]")
450
+ parser.add_option('-d', '--devices',
451
+ help=('Replicate only given devices. '
452
+ 'Comma-separated list. '
453
+ 'Only has effect if --once is used.'))
454
+ parser.add_option('-p', '--partitions',
455
+ help=('Replicate only given partitions. '
456
+ 'Comma-separated list. '
457
+ 'Only has effect if --once is used.'))
458
+ conf_file, options = parse_options(parser=parser, once=True)
459
+ run_daemon(ContainerReplicator, conf_file, **options)
460
+
461
+
462
+ if __name__ == '__main__':
463
+ main()
swift/container/server.py CHANGED
@@ -15,6 +15,7 @@
15
15
 
16
16
  import json
17
17
  import os
18
+ import sys
18
19
  import time
19
20
  import traceback
20
21
 
@@ -38,7 +39,7 @@ from swift.common.utils import get_logger, hash_path, public, \
38
39
  config_true_value, timing_stats, replication, \
39
40
  override_bytes_from_content_type, get_log_line, \
40
41
  config_fallocate_value, fs_has_free_space, list_from_csv, \
41
- ShardRange
42
+ ShardRange, parse_options
42
43
  from swift.common.constraints import valid_timestamp, check_utf8, \
43
44
  check_drive, AUTO_CREATE_ACCOUNT_PREFIX
44
45
  from swift.common.bufferedhttp import http_connect
@@ -53,6 +54,7 @@ from swift.common.swob import HTTPAccepted, HTTPBadRequest, HTTPConflict, \
53
54
  HTTPPreconditionFailed, HTTPMethodNotAllowed, Request, Response, \
54
55
  HTTPInsufficientStorage, HTTPException, HTTPMovedPermanently, \
55
56
  wsgi_to_str, str_to_wsgi
57
+ from swift.common.wsgi import run_wsgi
56
58
 
57
59
 
58
60
  def gen_resp_headers(info, is_deleted=False):
@@ -1048,3 +1050,12 @@ def app_factory(global_conf, **local_conf):
1048
1050
  conf = global_conf.copy()
1049
1051
  conf.update(local_conf)
1050
1052
  return ContainerController(conf)
1053
+
1054
+
1055
+ def main():
1056
+ conf_file, options = parse_options(test_config=True)
1057
+ sys.exit(run_wsgi(conf_file, 'container-server', **options))
1058
+
1059
+
1060
+ if __name__ == '__main__':
1061
+ main()
@@ -17,6 +17,7 @@ import errno
17
17
  import json
18
18
  import logging
19
19
  import operator
20
+ from optparse import OptionParser
20
21
  import time
21
22
  from collections import defaultdict
22
23
  from operator import itemgetter
@@ -32,6 +33,7 @@ from swift.common import internal_client
32
33
  from swift.common.constraints import check_drive, AUTO_CREATE_ACCOUNT_PREFIX
33
34
  from swift.common.direct_client import (direct_put_container,
34
35
  DirectClientException)
36
+ from swift.common.daemon import run_daemon
35
37
  from swift.common.request_helpers import USE_REPLICATION_NETWORK_HEADER
36
38
  from swift.common.ring.utils import is_local_device
37
39
  from swift.common.swob import str_to_wsgi
@@ -39,7 +41,7 @@ from swift.common.utils import get_logger, config_true_value, \
39
41
  dump_recon_cache, whataremyips, Timestamp, ShardRange, GreenAsyncPile, \
40
42
  config_positive_int_value, quorum_size, parse_override_options, \
41
43
  Everything, config_auto_int_value, ShardRangeList, config_percent_value, \
42
- node_to_string
44
+ node_to_string, parse_options
43
45
  from swift.container.backend import ContainerBroker, \
44
46
  RECORD_TYPE_SHARD, UNSHARDED, SHARDING, SHARDED, COLLAPSED, \
45
47
  SHARD_UPDATE_STATES, sift_shard_ranges, SHARD_UPDATE_STAT_STATES
@@ -1817,12 +1819,12 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator):
1817
1819
 
1818
1820
  def _make_misplaced_object_bounds(self, broker):
1819
1821
  bounds = []
1820
- state = broker.get_db_state()
1821
- if state == SHARDED:
1822
+ db_state = broker.get_db_state()
1823
+ if db_state == SHARDED:
1822
1824
  # Anything in the object table is treated as a misplaced object.
1823
1825
  bounds.append(('', ''))
1824
1826
 
1825
- if not bounds and state == SHARDING:
1827
+ if not bounds and db_state == SHARDING:
1826
1828
  # Objects outside of this container's own range are misplaced.
1827
1829
  # Objects in already cleaved shard ranges are also misplaced.
1828
1830
  cleave_context = CleavingContext.load(broker)
@@ -2342,9 +2344,9 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator):
2342
2344
 
2343
2345
  def _process_broker(self, broker, node, part):
2344
2346
  broker.get_info() # make sure account/container are populated
2345
- state = broker.get_db_state()
2347
+ db_state = broker.get_db_state()
2346
2348
  is_deleted = broker.is_deleted()
2347
- self.debug(broker, 'Starting processing, state %s%s', state,
2349
+ self.debug(broker, 'Starting processing, state %s%s', db_state,
2348
2350
  ' (deleted)' if is_deleted else '')
2349
2351
 
2350
2352
  if not self._audit_container(broker):
@@ -2358,7 +2360,7 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator):
2358
2360
 
2359
2361
  is_leader = node['index'] == 0 and self.auto_shard and not is_deleted
2360
2362
 
2361
- if state in (UNSHARDED, COLLAPSED):
2363
+ if db_state in (UNSHARDED, COLLAPSED):
2362
2364
  if is_leader and broker.is_root_container():
2363
2365
  # bootstrap sharding of root container
2364
2366
  own_shard_range = broker.get_own_shard_range()
@@ -2374,7 +2376,7 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator):
2374
2376
  # or manually triggered cleaving.
2375
2377
  db_start_ts = time.time()
2376
2378
  if broker.set_sharding_state():
2377
- state = SHARDING
2379
+ db_state = SHARDING
2378
2380
  self.info(broker, 'Kick off container cleaving, '
2379
2381
  'own shard range in state %r',
2380
2382
  own_shard_range.state_text)
@@ -2382,14 +2384,14 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator):
2382
2384
  'sharder.sharding.set_state', db_start_ts)
2383
2385
  elif is_leader:
2384
2386
  if broker.set_sharding_state():
2385
- state = SHARDING
2387
+ db_state = SHARDING
2386
2388
  else:
2387
2389
  self.debug(broker,
2388
2390
  'Own shard range in state %r but no shard '
2389
2391
  'ranges and not leader; remaining unsharded',
2390
2392
  own_shard_range.state_text)
2391
2393
 
2392
- if state == SHARDING:
2394
+ if db_state == SHARDING:
2393
2395
  cleave_start_ts = time.time()
2394
2396
  if is_leader:
2395
2397
  num_found = self._find_shard_ranges(broker)
@@ -2410,7 +2412,7 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator):
2410
2412
 
2411
2413
  if cleave_complete:
2412
2414
  if self._complete_sharding(broker):
2413
- state = SHARDED
2415
+ db_state = SHARDED
2414
2416
  self._increment_stat('visited', 'completed', statsd=True)
2415
2417
  self.info(broker, 'Completed cleaving, DB set to sharded '
2416
2418
  'state')
@@ -2422,7 +2424,7 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator):
2422
2424
  'sharding state')
2423
2425
 
2424
2426
  if not broker.is_deleted():
2425
- if state == SHARDED and broker.is_root_container():
2427
+ if db_state == SHARDED and broker.is_root_container():
2426
2428
  # look for shrink stats
2427
2429
  send_start_ts = time.time()
2428
2430
  self._identify_shrinking_candidate(broker, node)
@@ -2574,3 +2576,25 @@ class ContainerSharder(ContainerSharderConf, ContainerReplicator):
2574
2576
  elapsed = time.time() - begin
2575
2577
  self.logger.info(
2576
2578
  'Container sharder "once" mode completed: %.02fs', elapsed)
2579
+
2580
+
2581
+ def main():
2582
+ parser = OptionParser("%prog CONFIG [options]")
2583
+ parser.add_option('-d', '--devices',
2584
+ help='Shard containers only on given devices. '
2585
+ 'Comma-separated list. '
2586
+ 'Only has effect if --once is used.')
2587
+ parser.add_option('-p', '--partitions',
2588
+ help='Shard containers only in given partitions. '
2589
+ 'Comma-separated list. '
2590
+ 'Only has effect if --once is used.')
2591
+ parser.add_option('--no-auto-shard', action='store_false',
2592
+ dest='auto_shard', default=None,
2593
+ help='Disable auto-sharding. Overrides the auto_shard '
2594
+ 'value in the config file.')
2595
+ conf_file, options = parse_options(parser=parser, once=True)
2596
+ run_daemon(ContainerSharder, conf_file, **options)
2597
+
2598
+
2599
+ if __name__ == '__main__':
2600
+ main()
swift/container/sync.py CHANGED
@@ -29,6 +29,7 @@ from swift.common.db import DatabaseConnectionError
29
29
  from swift.container.backend import ContainerBroker
30
30
  from swift.container.sync_store import ContainerSyncStore
31
31
  from swift.common.container_sync_realms import ContainerSyncRealms
32
+ from swift.common.daemon import run_daemon
32
33
  from swift.common.internal_client import (
33
34
  delete_object, put_object, head_object,
34
35
  InternalClient, UnexpectedResponse)
@@ -39,7 +40,7 @@ from swift.common.swob import normalize_etag
39
40
  from swift.common.utils import (
40
41
  clean_content_type, config_true_value,
41
42
  FileLikeIter, get_logger, hash_path, quote, validate_sync_to,
42
- whataremyips, Timestamp, decode_timestamps)
43
+ whataremyips, Timestamp, decode_timestamps, parse_options)
43
44
  from swift.common.daemon import Daemon
44
45
  from swift.common.http import HTTP_UNAUTHORIZED, HTTP_NOT_FOUND, HTTP_CONFLICT
45
46
  from swift.common.wsgi import ConfigString
@@ -650,3 +651,12 @@ class ContainerSync(Daemon):
650
651
 
651
652
  def select_http_proxy(self):
652
653
  return choice(self.http_proxies) if self.http_proxies else None
654
+
655
+
656
+ def main():
657
+ conf_file, options = parse_options(once=True)
658
+ run_daemon(ContainerSync, conf_file, **options)
659
+
660
+
661
+ if __name__ == '__main__':
662
+ main()
@@ -32,8 +32,8 @@ from swift.common.exceptions import ConnectionTimeout, LockTimeout
32
32
  from swift.common.ring import Ring
33
33
  from swift.common.utils import get_logger, config_true_value, \
34
34
  dump_recon_cache, majority_size, Timestamp, EventletRateLimiter, \
35
- eventlet_monkey_patch, node_to_string
36
- from swift.common.daemon import Daemon
35
+ eventlet_monkey_patch, node_to_string, parse_options
36
+ from swift.common.daemon import Daemon, run_daemon
37
37
  from swift.common.http import is_success, HTTP_INTERNAL_SERVER_ERROR
38
38
  from swift.common.recon import RECON_CONTAINER_FILE, DEFAULT_RECON_CACHE_PATH
39
39
 
@@ -357,3 +357,12 @@ class ContainerUpdater(Daemon):
357
357
  return HTTP_INTERNAL_SERVER_ERROR
358
358
  finally:
359
359
  conn.close()
360
+
361
+
362
+ def main():
363
+ conf_file, options = parse_options(once=True)
364
+ run_daemon(ContainerUpdater, conf_file, **options)
365
+
366
+
367
+ if __name__ == '__main__':
368
+ main()
swift/obj/auditor.py CHANGED
@@ -18,6 +18,7 @@ import os
18
18
  import sys
19
19
  import time
20
20
  import signal
21
+ from optparse import OptionParser
21
22
  from os.path import basename, dirname, join
22
23
  from random import shuffle
23
24
  from contextlib import closing
@@ -26,12 +27,13 @@ from eventlet import Timeout
26
27
  from swift.obj import diskfile, replicator
27
28
  from swift.common.exceptions import DiskFileQuarantined, DiskFileNotExist, \
28
29
  DiskFileDeleted, DiskFileExpired, QuarantineRequest
29
- from swift.common.daemon import Daemon
30
+ from swift.common.daemon import Daemon, run_daemon
30
31
  from swift.common.storage_policy import POLICIES
31
32
  from swift.common.utils import (
32
33
  config_auto_int_value, dump_recon_cache, get_logger, list_from_csv,
33
34
  listdir, load_pkg_resource, parse_prefixed_conf, EventletRateLimiter,
34
- readconf, round_robin_iter, unlink_paths_older_than, PrefixLoggerAdapter)
35
+ readconf, round_robin_iter, unlink_paths_older_than, PrefixLoggerAdapter,
36
+ parse_options)
35
37
  from swift.common.recon import RECON_OBJECT_FILE, DEFAULT_RECON_CACHE_PATH
36
38
 
37
39
 
@@ -537,3 +539,17 @@ class WatcherWrapper(object):
537
539
  except (Exception, Timeout):
538
540
  self.logger.exception('Error ending watcher')
539
541
  self.watcher_in_error = True
542
+
543
+
544
+ def main():
545
+ parser = OptionParser("%prog CONFIG [options]")
546
+ parser.add_option('-z', '--zero_byte_fps',
547
+ help='Audit only zero byte files at specified files/sec')
548
+ parser.add_option('-d', '--devices',
549
+ help='Audit only given devices. Comma-separated list')
550
+ conf_file, options = parse_options(parser=parser, once=True)
551
+ run_daemon(ObjectAuditor, conf_file, **options)
552
+
553
+
554
+ if __name__ == '__main__':
555
+ main()
swift/obj/diskfile.py CHANGED
@@ -600,7 +600,8 @@ def object_audit_location_generator(devices, datadir, mount_check=True,
600
600
  try:
601
601
  suffixes = listdir(part_path)
602
602
  except OSError as e:
603
- if e.errno not in (errno.ENOTDIR, errno.ENODATA):
603
+ if e.errno not in (errno.ENOTDIR, errno.ENODATA,
604
+ errno.EUCLEAN):
604
605
  raise
605
606
  continue
606
607
  for asuffix in suffixes:
@@ -608,7 +609,8 @@ def object_audit_location_generator(devices, datadir, mount_check=True,
608
609
  try:
609
610
  hashes = listdir(suff_path)
610
611
  except OSError as e:
611
- if e.errno not in (errno.ENOTDIR, errno.ENODATA):
612
+ if e.errno not in (errno.ENOTDIR, errno.ENODATA,
613
+ errno.EUCLEAN):
612
614
  raise
613
615
  continue
614
616
  for hsh in hashes:
@@ -1214,7 +1216,7 @@ class BaseDiskFileManager(object):
1214
1216
  'it is not a directory', {'hsh_path': hsh_path,
1215
1217
  'quar_path': quar_path})
1216
1218
  continue
1217
- elif err.errno == errno.ENODATA:
1219
+ elif err.errno in (errno.ENODATA, errno.EUCLEAN):
1218
1220
  try:
1219
1221
  # We've seen cases where bad sectors lead to ENODATA
1220
1222
  # here; use a similar hack as above
@@ -1569,7 +1571,7 @@ class BaseDiskFileManager(object):
1569
1571
  'it is not a directory', {'object_path': object_path,
1570
1572
  'quar_path': quar_path})
1571
1573
  raise DiskFileNotExist()
1572
- elif err.errno == errno.ENODATA:
1574
+ elif err.errno in (errno.ENODATA, errno.EUCLEAN):
1573
1575
  try:
1574
1576
  # We've seen cases where bad sectors lead to ENODATA here;
1575
1577
  # use a similar hack as above
@@ -2610,7 +2612,7 @@ class BaseDiskFile(object):
2610
2612
  # want this one file and not its parent.
2611
2613
  os.path.join(self._datadir, "made-up-filename"),
2612
2614
  "Expected directory, found file at %s" % self._datadir)
2613
- elif err.errno == errno.ENODATA:
2615
+ elif err.errno in (errno.ENODATA, errno.EUCLEAN):
2614
2616
  try:
2615
2617
  # We've seen cases where bad sectors lead to ENODATA here
2616
2618
  raise self._quarantine(
@@ -2640,7 +2642,7 @@ class BaseDiskFile(object):
2640
2642
  self._fp = self._construct_from_data_file(
2641
2643
  current_time=current_time, modernize=modernize, **file_info)
2642
2644
  except IOError as e:
2643
- if e.errno == errno.ENODATA:
2645
+ if e.errno in (errno.ENODATA, errno.EUCLEAN):
2644
2646
  raise self._quarantine(
2645
2647
  file_info['data_file'],
2646
2648
  "Failed to open %s: %s" % (file_info['data_file'], e))