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.
- swift/__init__.py +29 -50
- swift/account/auditor.py +21 -118
- swift/account/backend.py +33 -28
- swift/account/reaper.py +37 -28
- swift/account/replicator.py +22 -0
- swift/account/server.py +60 -26
- swift/account/utils.py +28 -11
- swift-2.23.2.data/scripts/swift-account-audit → swift/cli/account_audit.py +23 -13
- swift-2.23.2.data/scripts/swift-config → swift/cli/config.py +2 -2
- swift/cli/container_deleter.py +5 -11
- swift-2.23.2.data/scripts/swift-dispersion-populate → swift/cli/dispersion_populate.py +8 -7
- swift/cli/dispersion_report.py +10 -9
- swift-2.23.2.data/scripts/swift-drive-audit → swift/cli/drive_audit.py +63 -21
- swift/cli/form_signature.py +3 -7
- swift-2.23.2.data/scripts/swift-get-nodes → swift/cli/get_nodes.py +8 -2
- swift/cli/info.py +183 -29
- swift/cli/manage_shard_ranges.py +708 -37
- swift-2.23.2.data/scripts/swift-oldies → swift/cli/oldies.py +25 -14
- swift-2.23.2.data/scripts/swift-orphans → swift/cli/orphans.py +7 -3
- swift/cli/recon.py +196 -67
- swift-2.23.2.data/scripts/swift-recon-cron → swift/cli/recon_cron.py +17 -20
- swift-2.23.2.data/scripts/swift-reconciler-enqueue → swift/cli/reconciler_enqueue.py +2 -3
- swift/cli/relinker.py +807 -126
- swift/cli/reload.py +135 -0
- swift/cli/ringbuilder.py +217 -20
- swift/cli/ringcomposer.py +0 -1
- swift/cli/shard-info.py +4 -3
- swift/common/base_storage_server.py +9 -20
- swift/common/bufferedhttp.py +48 -74
- swift/common/constraints.py +20 -15
- swift/common/container_sync_realms.py +9 -11
- swift/common/daemon.py +25 -8
- swift/common/db.py +198 -127
- swift/common/db_auditor.py +168 -0
- swift/common/db_replicator.py +95 -55
- swift/common/digest.py +141 -0
- swift/common/direct_client.py +144 -33
- swift/common/error_limiter.py +93 -0
- swift/common/exceptions.py +25 -1
- swift/common/header_key_dict.py +2 -9
- swift/common/http_protocol.py +373 -0
- swift/common/internal_client.py +129 -59
- swift/common/linkat.py +3 -4
- swift/common/manager.py +284 -67
- swift/common/memcached.py +396 -147
- swift/common/middleware/__init__.py +4 -0
- swift/common/middleware/account_quotas.py +211 -46
- swift/common/middleware/acl.py +3 -8
- swift/common/middleware/backend_ratelimit.py +230 -0
- swift/common/middleware/bulk.py +22 -34
- swift/common/middleware/catch_errors.py +1 -3
- swift/common/middleware/cname_lookup.py +6 -11
- swift/common/middleware/container_quotas.py +1 -1
- swift/common/middleware/container_sync.py +39 -17
- swift/common/middleware/copy.py +12 -0
- swift/common/middleware/crossdomain.py +22 -9
- swift/common/middleware/crypto/__init__.py +2 -1
- swift/common/middleware/crypto/crypto_utils.py +11 -15
- swift/common/middleware/crypto/decrypter.py +28 -11
- swift/common/middleware/crypto/encrypter.py +12 -17
- swift/common/middleware/crypto/keymaster.py +8 -15
- swift/common/middleware/crypto/kms_keymaster.py +2 -1
- swift/common/middleware/dlo.py +15 -11
- swift/common/middleware/domain_remap.py +5 -4
- swift/common/middleware/etag_quoter.py +128 -0
- swift/common/middleware/formpost.py +73 -70
- swift/common/middleware/gatekeeper.py +8 -1
- swift/common/middleware/keystoneauth.py +33 -3
- swift/common/middleware/list_endpoints.py +4 -4
- swift/common/middleware/listing_formats.py +85 -49
- swift/common/middleware/memcache.py +4 -81
- swift/common/middleware/name_check.py +3 -2
- swift/common/middleware/proxy_logging.py +160 -92
- swift/common/middleware/ratelimit.py +17 -10
- swift/common/middleware/read_only.py +6 -4
- swift/common/middleware/recon.py +59 -22
- swift/common/middleware/s3api/acl_handlers.py +25 -3
- swift/common/middleware/s3api/acl_utils.py +6 -1
- swift/common/middleware/s3api/controllers/__init__.py +6 -0
- swift/common/middleware/s3api/controllers/acl.py +3 -2
- swift/common/middleware/s3api/controllers/bucket.py +242 -137
- swift/common/middleware/s3api/controllers/logging.py +2 -2
- swift/common/middleware/s3api/controllers/multi_delete.py +43 -20
- swift/common/middleware/s3api/controllers/multi_upload.py +219 -133
- swift/common/middleware/s3api/controllers/obj.py +112 -8
- swift/common/middleware/s3api/controllers/object_lock.py +44 -0
- swift/common/middleware/s3api/controllers/s3_acl.py +2 -2
- swift/common/middleware/s3api/controllers/tagging.py +57 -0
- swift/common/middleware/s3api/controllers/versioning.py +36 -7
- swift/common/middleware/s3api/etree.py +22 -9
- swift/common/middleware/s3api/exception.py +0 -4
- swift/common/middleware/s3api/s3api.py +113 -41
- swift/common/middleware/s3api/s3request.py +384 -218
- swift/common/middleware/s3api/s3response.py +126 -23
- swift/common/middleware/s3api/s3token.py +16 -17
- swift/common/middleware/s3api/schema/delete.rng +1 -1
- swift/common/middleware/s3api/subresource.py +7 -10
- swift/common/middleware/s3api/utils.py +27 -10
- swift/common/middleware/slo.py +665 -358
- swift/common/middleware/staticweb.py +64 -37
- swift/common/middleware/symlink.py +52 -19
- swift/common/middleware/tempauth.py +76 -58
- swift/common/middleware/tempurl.py +192 -174
- swift/common/middleware/versioned_writes/__init__.py +51 -0
- swift/common/middleware/{versioned_writes.py → versioned_writes/legacy.py} +27 -26
- swift/common/middleware/versioned_writes/object_versioning.py +1482 -0
- swift/common/middleware/x_profile/exceptions.py +1 -4
- swift/common/middleware/x_profile/html_viewer.py +18 -19
- swift/common/middleware/x_profile/profile_model.py +1 -2
- swift/common/middleware/xprofile.py +10 -10
- swift-2.23.2.data/scripts/swift-container-server → swift/common/recon.py +13 -8
- swift/common/registry.py +147 -0
- swift/common/request_helpers.py +324 -57
- swift/common/ring/builder.py +67 -25
- swift/common/ring/composite_builder.py +1 -1
- swift/common/ring/ring.py +177 -51
- swift/common/ring/utils.py +1 -1
- swift/common/splice.py +10 -6
- swift/common/statsd_client.py +205 -0
- swift/common/storage_policy.py +49 -44
- swift/common/swob.py +86 -102
- swift/common/{utils.py → utils/__init__.py} +2191 -2762
- swift/common/utils/base.py +131 -0
- swift/common/utils/config.py +433 -0
- swift/common/utils/ipaddrs.py +256 -0
- swift/common/utils/libc.py +345 -0
- swift/common/utils/logs.py +859 -0
- swift/common/utils/timestamp.py +412 -0
- swift/common/wsgi.py +555 -536
- swift/container/auditor.py +14 -100
- swift/container/backend.py +552 -227
- swift/container/reconciler.py +126 -37
- swift/container/replicator.py +96 -22
- swift/container/server.py +397 -176
- swift/container/sharder.py +1580 -639
- swift/container/sync.py +94 -88
- swift/container/updater.py +53 -32
- swift/obj/auditor.py +153 -35
- swift/obj/diskfile.py +466 -217
- swift/obj/expirer.py +406 -124
- swift/obj/mem_diskfile.py +7 -4
- swift/obj/mem_server.py +1 -0
- swift/obj/reconstructor.py +523 -262
- swift/obj/replicator.py +249 -188
- swift/obj/server.py +213 -122
- swift/obj/ssync_receiver.py +145 -85
- swift/obj/ssync_sender.py +113 -54
- swift/obj/updater.py +653 -139
- swift/obj/watchers/__init__.py +0 -0
- swift/obj/watchers/dark_data.py +213 -0
- swift/proxy/controllers/account.py +11 -11
- swift/proxy/controllers/base.py +848 -604
- swift/proxy/controllers/container.py +452 -86
- swift/proxy/controllers/info.py +3 -2
- swift/proxy/controllers/obj.py +1009 -490
- swift/proxy/server.py +185 -112
- swift-2.35.0.dist-info/AUTHORS +501 -0
- swift-2.35.0.dist-info/LICENSE +202 -0
- {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/METADATA +52 -61
- swift-2.35.0.dist-info/RECORD +201 -0
- {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/WHEEL +1 -1
- {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/entry_points.txt +43 -0
- swift-2.35.0.dist-info/pbr.json +1 -0
- swift/locale/de/LC_MESSAGES/swift.po +0 -1216
- swift/locale/en_GB/LC_MESSAGES/swift.po +0 -1207
- swift/locale/es/LC_MESSAGES/swift.po +0 -1085
- swift/locale/fr/LC_MESSAGES/swift.po +0 -909
- swift/locale/it/LC_MESSAGES/swift.po +0 -894
- swift/locale/ja/LC_MESSAGES/swift.po +0 -965
- swift/locale/ko_KR/LC_MESSAGES/swift.po +0 -964
- swift/locale/pt_BR/LC_MESSAGES/swift.po +0 -881
- swift/locale/ru/LC_MESSAGES/swift.po +0 -891
- swift/locale/tr_TR/LC_MESSAGES/swift.po +0 -832
- swift/locale/zh_CN/LC_MESSAGES/swift.po +0 -833
- swift/locale/zh_TW/LC_MESSAGES/swift.po +0 -838
- swift-2.23.2.data/scripts/swift-account-auditor +0 -23
- swift-2.23.2.data/scripts/swift-account-info +0 -51
- swift-2.23.2.data/scripts/swift-account-reaper +0 -23
- swift-2.23.2.data/scripts/swift-account-replicator +0 -34
- swift-2.23.2.data/scripts/swift-account-server +0 -23
- swift-2.23.2.data/scripts/swift-container-auditor +0 -23
- swift-2.23.2.data/scripts/swift-container-info +0 -51
- swift-2.23.2.data/scripts/swift-container-reconciler +0 -21
- swift-2.23.2.data/scripts/swift-container-replicator +0 -34
- swift-2.23.2.data/scripts/swift-container-sharder +0 -33
- swift-2.23.2.data/scripts/swift-container-sync +0 -23
- swift-2.23.2.data/scripts/swift-container-updater +0 -23
- swift-2.23.2.data/scripts/swift-dispersion-report +0 -24
- swift-2.23.2.data/scripts/swift-form-signature +0 -20
- swift-2.23.2.data/scripts/swift-init +0 -119
- swift-2.23.2.data/scripts/swift-object-auditor +0 -29
- swift-2.23.2.data/scripts/swift-object-expirer +0 -33
- swift-2.23.2.data/scripts/swift-object-info +0 -60
- swift-2.23.2.data/scripts/swift-object-reconstructor +0 -33
- swift-2.23.2.data/scripts/swift-object-relinker +0 -41
- swift-2.23.2.data/scripts/swift-object-replicator +0 -37
- swift-2.23.2.data/scripts/swift-object-server +0 -27
- swift-2.23.2.data/scripts/swift-object-updater +0 -23
- swift-2.23.2.data/scripts/swift-proxy-server +0 -23
- swift-2.23.2.data/scripts/swift-recon +0 -24
- swift-2.23.2.data/scripts/swift-ring-builder +0 -24
- swift-2.23.2.data/scripts/swift-ring-builder-analyzer +0 -22
- swift-2.23.2.data/scripts/swift-ring-composer +0 -22
- swift-2.23.2.dist-info/DESCRIPTION.rst +0 -166
- swift-2.23.2.dist-info/RECORD +0 -220
- swift-2.23.2.dist-info/metadata.json +0 -1
- swift-2.23.2.dist-info/pbr.json +0 -1
- {swift-2.23.2.dist-info → swift-2.35.0.dist-info}/top_level.txt +0 -0
swift/obj/auditor.py
CHANGED
@@ -18,26 +18,32 @@ 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
|
-
from swift import gettext_ as _
|
24
24
|
from contextlib import closing
|
25
25
|
from eventlet import Timeout
|
26
26
|
|
27
27
|
from swift.obj import diskfile, replicator
|
28
|
-
from swift.common.
|
29
|
-
|
30
|
-
|
31
|
-
from swift.common.exceptions import DiskFileQuarantined, DiskFileNotExist,\
|
32
|
-
DiskFileDeleted, DiskFileExpired
|
33
|
-
from swift.common.daemon import Daemon
|
28
|
+
from swift.common.exceptions import DiskFileQuarantined, DiskFileNotExist, \
|
29
|
+
DiskFileDeleted, DiskFileExpired, QuarantineRequest
|
30
|
+
from swift.common.daemon import Daemon, run_daemon
|
34
31
|
from swift.common.storage_policy import POLICIES
|
32
|
+
from swift.common.utils import (
|
33
|
+
config_auto_int_value, dump_recon_cache, get_logger, list_from_csv,
|
34
|
+
listdir, load_pkg_resource, parse_prefixed_conf, EventletRateLimiter,
|
35
|
+
readconf, round_robin_iter, unlink_paths_older_than, parse_options,
|
36
|
+
get_prefixed_logger)
|
37
|
+
from swift.common.recon import RECON_OBJECT_FILE, DEFAULT_RECON_CACHE_PATH
|
35
38
|
|
36
39
|
|
37
40
|
class AuditorWorker(object):
|
38
41
|
"""Walk through file system to audit objects"""
|
39
42
|
|
40
|
-
def __init__(self, conf, logger, rcache, devices, zero_byte_only_at_fps=0
|
43
|
+
def __init__(self, conf, logger, rcache, devices, zero_byte_only_at_fps=0,
|
44
|
+
watcher_defs=None):
|
45
|
+
if watcher_defs is None:
|
46
|
+
watcher_defs = {}
|
41
47
|
self.conf = conf
|
42
48
|
self.logger = logger
|
43
49
|
self.devices = devices
|
@@ -81,8 +87,10 @@ class AuditorWorker(object):
|
|
81
87
|
self.auditor_type = 'ZBF'
|
82
88
|
self.log_time = int(conf.get('log_time', 3600))
|
83
89
|
self.last_logged = 0
|
84
|
-
self.
|
85
|
-
|
90
|
+
self.files_rate_limiter = EventletRateLimiter(
|
91
|
+
self.max_files_per_second)
|
92
|
+
self.bytes_rate_limiter = EventletRateLimiter(
|
93
|
+
self.max_bytes_per_second)
|
86
94
|
self.bytes_processed = 0
|
87
95
|
self.total_bytes_processed = 0
|
88
96
|
self.total_files_processed = 0
|
@@ -95,6 +103,11 @@ class AuditorWorker(object):
|
|
95
103
|
self.stats_buckets = dict(
|
96
104
|
[(s, 0) for s in self.stats_sizes + ['OVER']])
|
97
105
|
|
106
|
+
self.watchers = [
|
107
|
+
WatcherWrapper(wdef['klass'], name, wdef['conf'], logger)
|
108
|
+
for name, wdef in watcher_defs.items()]
|
109
|
+
logger.debug("%d audit watcher(s) loaded", len(self.watchers))
|
110
|
+
|
98
111
|
def create_recon_nested_dict(self, top_level_key, device_list, item):
|
99
112
|
if device_list:
|
100
113
|
device_key = ''.join(sorted(device_list))
|
@@ -107,13 +120,15 @@ class AuditorWorker(object):
|
|
107
120
|
if device_dirs:
|
108
121
|
device_dir_str = ','.join(sorted(device_dirs))
|
109
122
|
if self.auditor_type == 'ALL':
|
110
|
-
description =
|
123
|
+
description = ' - parallel, %s' % device_dir_str
|
111
124
|
else:
|
112
|
-
description =
|
113
|
-
self.logger.info(
|
114
|
-
|
125
|
+
description = ' - %s' % device_dir_str
|
126
|
+
self.logger.info('Begin object audit "%(mode)s" mode (%(audi_type)s'
|
127
|
+
'%(description)s)',
|
115
128
|
{'mode': mode, 'audi_type': self.auditor_type,
|
116
129
|
'description': description})
|
130
|
+
for watcher in self.watchers:
|
131
|
+
watcher.start(self.auditor_type)
|
117
132
|
begin = reported = time.time()
|
118
133
|
self.total_bytes_processed = 0
|
119
134
|
self.total_files_processed = 0
|
@@ -135,18 +150,17 @@ class AuditorWorker(object):
|
|
135
150
|
loop_time = time.time()
|
136
151
|
self.failsafe_object_audit(location)
|
137
152
|
self.logger.timing_since('timing', loop_time)
|
138
|
-
self.
|
139
|
-
self.files_running_time, self.max_files_per_second)
|
153
|
+
self.files_rate_limiter.wait()
|
140
154
|
self.total_files_processed += 1
|
141
155
|
now = time.time()
|
142
156
|
if now - self.last_logged >= self.log_time:
|
143
|
-
self.logger.info(
|
157
|
+
self.logger.info(
|
144
158
|
'Object audit (%(type)s). '
|
145
159
|
'Since %(start_time)s: Locally: %(passes)d passed, '
|
146
160
|
'%(quars)d quarantined, %(errors)d errors, '
|
147
161
|
'files/sec: %(frate).2f, bytes/sec: %(brate).2f, '
|
148
162
|
'Total time: %(total).2f, Auditing time: %(audit).2f, '
|
149
|
-
'Rate: %(audit_rate).2f'
|
163
|
+
'Rate: %(audit_rate).2f', {
|
150
164
|
'type': '%s%s' % (self.auditor_type, description),
|
151
165
|
'start_time': time.ctime(reported),
|
152
166
|
'passes': self.passes, 'quars': self.quarantines,
|
@@ -174,12 +188,12 @@ class AuditorWorker(object):
|
|
174
188
|
time_auditing += (now - loop_time)
|
175
189
|
# Avoid divide by zero during very short runs
|
176
190
|
elapsed = (time.time() - begin) or 0.000001
|
177
|
-
self.logger.info(
|
191
|
+
self.logger.info(
|
178
192
|
'Object audit (%(type)s) "%(mode)s" mode '
|
179
193
|
'completed: %(elapsed).02fs. Total quarantined: %(quars)d, '
|
180
194
|
'Total errors: %(errors)d, Total files/sec: %(frate).2f, '
|
181
195
|
'Total bytes/sec: %(brate).2f, Auditing time: %(audit).2f, '
|
182
|
-
'Rate: %(audit_rate).2f'
|
196
|
+
'Rate: %(audit_rate).2f', {
|
183
197
|
'type': '%s%s' % (self.auditor_type, description),
|
184
198
|
'mode': mode, 'elapsed': elapsed,
|
185
199
|
'quars': total_quarantines + self.quarantines,
|
@@ -187,9 +201,11 @@ class AuditorWorker(object):
|
|
187
201
|
'frate': self.total_files_processed / elapsed,
|
188
202
|
'brate': self.total_bytes_processed / elapsed,
|
189
203
|
'audit': time_auditing, 'audit_rate': time_auditing / elapsed})
|
204
|
+
for watcher in self.watchers:
|
205
|
+
watcher.end()
|
190
206
|
if self.stats_sizes:
|
191
207
|
self.logger.info(
|
192
|
-
|
208
|
+
'Object audit stats: %s', json.dumps(self.stats_buckets))
|
193
209
|
|
194
210
|
for policy in POLICIES:
|
195
211
|
# Unset remaining partitions to not skip them in the next run
|
@@ -223,7 +239,7 @@ class AuditorWorker(object):
|
|
223
239
|
except (Exception, Timeout):
|
224
240
|
self.logger.increment('errors')
|
225
241
|
self.errors += 1
|
226
|
-
self.logger.exception(
|
242
|
+
self.logger.exception('ERROR Trying to audit %s', location)
|
227
243
|
|
228
244
|
def object_audit(self, location):
|
229
245
|
"""
|
@@ -244,6 +260,10 @@ class AuditorWorker(object):
|
|
244
260
|
try:
|
245
261
|
with df.open(modernize=True):
|
246
262
|
metadata = df.get_metadata()
|
263
|
+
if not df.validate_metadata():
|
264
|
+
df._quarantine(
|
265
|
+
df._data_file,
|
266
|
+
"Metadata failed validation")
|
247
267
|
obj_size = int(metadata['Content-Length'])
|
248
268
|
if self.stats_sizes:
|
249
269
|
self.record_stats(obj_size)
|
@@ -253,16 +273,22 @@ class AuditorWorker(object):
|
|
253
273
|
with closing(reader):
|
254
274
|
for chunk in reader:
|
255
275
|
chunk_len = len(chunk)
|
256
|
-
self.
|
257
|
-
self.bytes_running_time,
|
258
|
-
self.max_bytes_per_second,
|
259
|
-
incr_by=chunk_len)
|
276
|
+
self.bytes_rate_limiter.wait(incr_by=chunk_len)
|
260
277
|
self.bytes_processed += chunk_len
|
261
278
|
self.total_bytes_processed += chunk_len
|
279
|
+
for watcher in self.watchers:
|
280
|
+
try:
|
281
|
+
watcher.see_object(
|
282
|
+
metadata,
|
283
|
+
df._ondisk_info['data_file'])
|
284
|
+
except QuarantineRequest:
|
285
|
+
raise df._quarantine(
|
286
|
+
df._data_file,
|
287
|
+
"Requested by %s" % watcher.watcher_name)
|
262
288
|
except DiskFileQuarantined as err:
|
263
289
|
self.quarantines += 1
|
264
|
-
self.logger.error(
|
265
|
-
|
290
|
+
self.logger.error('ERROR Object %(obj)s failed audit and was'
|
291
|
+
' quarantined: %(err)s',
|
266
292
|
{'obj': location, 'err': err})
|
267
293
|
except DiskFileExpired:
|
268
294
|
pass # ignore expired objects
|
@@ -299,9 +325,23 @@ class ObjectAuditor(Daemon):
|
|
299
325
|
self.conf_zero_byte_fps = int(
|
300
326
|
conf.get('zero_byte_files_per_second', 50))
|
301
327
|
self.recon_cache_path = conf.get('recon_cache_path',
|
302
|
-
|
303
|
-
self.rcache = join(self.recon_cache_path,
|
304
|
-
self.interval =
|
328
|
+
DEFAULT_RECON_CACHE_PATH)
|
329
|
+
self.rcache = join(self.recon_cache_path, RECON_OBJECT_FILE)
|
330
|
+
self.interval = float(conf.get('interval', 30))
|
331
|
+
|
332
|
+
watcher_names = set(list_from_csv(conf.get('watchers', '')))
|
333
|
+
# Normally '__file__' is always in config, but tests neglect it often.
|
334
|
+
watcher_configs = \
|
335
|
+
parse_prefixed_conf(conf['__file__'], 'object-auditor:watcher:') \
|
336
|
+
if '__file__' in conf else {}
|
337
|
+
self.watcher_defs = {}
|
338
|
+
for name in watcher_names:
|
339
|
+
self.logger.debug("Loading entry point '%s'", name)
|
340
|
+
wconf = dict(conf)
|
341
|
+
wconf.update(watcher_configs.get(name, {}))
|
342
|
+
self.watcher_defs[name] = {
|
343
|
+
'conf': wconf,
|
344
|
+
'klass': load_pkg_resource("swift.object_audit_watcher", name)}
|
305
345
|
|
306
346
|
def _sleep(self):
|
307
347
|
time.sleep(self.interval)
|
@@ -318,7 +358,8 @@ class ObjectAuditor(Daemon):
|
|
318
358
|
device_dirs = kwargs.get('device_dirs')
|
319
359
|
worker = AuditorWorker(self.conf, self.logger, self.rcache,
|
320
360
|
self.devices,
|
321
|
-
zero_byte_only_at_fps=zero_byte_only_at_fps
|
361
|
+
zero_byte_only_at_fps=zero_byte_only_at_fps,
|
362
|
+
watcher_defs=self.watcher_defs)
|
322
363
|
worker.audit_all_objects(mode=mode, device_dirs=device_dirs)
|
323
364
|
|
324
365
|
def fork_child(self, zero_byte_fps=False, sleep_between_zbf_scanner=False,
|
@@ -329,6 +370,7 @@ class ObjectAuditor(Daemon):
|
|
329
370
|
return pid
|
330
371
|
else:
|
331
372
|
signal.signal(signal.SIGTERM, signal.SIG_DFL)
|
373
|
+
os.environ.pop('NOTIFY_SOCKET', None)
|
332
374
|
if zero_byte_fps:
|
333
375
|
kwargs['zero_byte_fps'] = self.conf_zero_byte_fps
|
334
376
|
if sleep_between_zbf_scanner:
|
@@ -337,7 +379,7 @@ class ObjectAuditor(Daemon):
|
|
337
379
|
self.run_audit(**kwargs)
|
338
380
|
except Exception as e:
|
339
381
|
self.logger.exception(
|
340
|
-
|
382
|
+
"ERROR: Unable to run auditing: %s", e)
|
341
383
|
finally:
|
342
384
|
sys.exit()
|
343
385
|
|
@@ -416,7 +458,7 @@ class ObjectAuditor(Daemon):
|
|
416
458
|
try:
|
417
459
|
self.audit_loop(parent, zbo_fps, **kwargs)
|
418
460
|
except (Exception, Timeout) as err:
|
419
|
-
self.logger.exception(
|
461
|
+
self.logger.exception('ERROR auditing: %s', err)
|
420
462
|
self._sleep()
|
421
463
|
|
422
464
|
def run_once(self, *args, **kwargs):
|
@@ -437,4 +479,80 @@ class ObjectAuditor(Daemon):
|
|
437
479
|
self.audit_loop(parent, zbo_fps, override_devices=override_devices,
|
438
480
|
**kwargs)
|
439
481
|
except (Exception, Timeout) as err:
|
440
|
-
self.logger.exception(
|
482
|
+
self.logger.exception('ERROR auditing: %s', err)
|
483
|
+
|
484
|
+
|
485
|
+
class WatcherWrapper(object):
|
486
|
+
"""
|
487
|
+
Run the user-supplied watcher.
|
488
|
+
|
489
|
+
Simple and gets the job done. Note that we aren't doing anything
|
490
|
+
to isolate ourselves from hangs or file descriptor leaks
|
491
|
+
in the plugins.
|
492
|
+
|
493
|
+
:param logger: an instance of ``SwiftLogAdapter``.
|
494
|
+
|
495
|
+
"""
|
496
|
+
|
497
|
+
def __init__(self, watcher_class, watcher_name, conf, logger):
|
498
|
+
self.watcher_name = watcher_name
|
499
|
+
self.watcher_in_error = False
|
500
|
+
self.logger = get_prefixed_logger(
|
501
|
+
logger, '[audit-watcher %s] ' % watcher_name)
|
502
|
+
|
503
|
+
try:
|
504
|
+
self.watcher = watcher_class(conf, self.logger)
|
505
|
+
except (Exception, Timeout):
|
506
|
+
self.logger.exception('Error intializing watcher')
|
507
|
+
self.watcher_in_error = True
|
508
|
+
|
509
|
+
def start(self, audit_type):
|
510
|
+
if self.watcher_in_error:
|
511
|
+
return # can't trust the state of the thing; bail
|
512
|
+
try:
|
513
|
+
self.watcher.start(audit_type=audit_type)
|
514
|
+
except (Exception, Timeout):
|
515
|
+
self.logger.exception('Error starting watcher')
|
516
|
+
self.watcher_in_error = True
|
517
|
+
|
518
|
+
def see_object(self, meta, data_file_path):
|
519
|
+
if self.watcher_in_error:
|
520
|
+
return # can't trust the state of the thing; bail
|
521
|
+
kwargs = {'object_metadata': meta,
|
522
|
+
'data_file_path': data_file_path}
|
523
|
+
try:
|
524
|
+
self.watcher.see_object(**kwargs)
|
525
|
+
except QuarantineRequest:
|
526
|
+
# Avoid extra logging.
|
527
|
+
raise
|
528
|
+
except (Exception, Timeout):
|
529
|
+
self.logger.exception(
|
530
|
+
'Error in see_object(meta=%r, data_file_path=%r)',
|
531
|
+
meta, data_file_path)
|
532
|
+
# Do *not* flag watcher as being in an error state; a failure
|
533
|
+
# to process one object shouldn't impact the ability to process
|
534
|
+
# others.
|
535
|
+
|
536
|
+
def end(self):
|
537
|
+
if self.watcher_in_error:
|
538
|
+
return # can't trust the state of the thing; bail
|
539
|
+
kwargs = {}
|
540
|
+
try:
|
541
|
+
self.watcher.end(**kwargs)
|
542
|
+
except (Exception, Timeout):
|
543
|
+
self.logger.exception('Error ending watcher')
|
544
|
+
self.watcher_in_error = True
|
545
|
+
|
546
|
+
|
547
|
+
def main():
|
548
|
+
parser = OptionParser("%prog CONFIG [options]")
|
549
|
+
parser.add_option('-z', '--zero_byte_fps',
|
550
|
+
help='Audit only zero byte files at specified files/sec')
|
551
|
+
parser.add_option('-d', '--devices',
|
552
|
+
help='Audit only given devices. Comma-separated list')
|
553
|
+
conf_file, options = parse_options(parser=parser, once=True)
|
554
|
+
run_daemon(ObjectAuditor, conf_file, **options)
|
555
|
+
|
556
|
+
|
557
|
+
if __name__ == '__main__':
|
558
|
+
main()
|