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
@@ -1,4 +1,4 @@
|
|
1
|
-
|
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");
|
@@ -18,13 +18,13 @@ import datetime
|
|
18
18
|
import glob
|
19
19
|
import locale
|
20
20
|
import os
|
21
|
+
import os.path
|
21
22
|
import re
|
22
23
|
import subprocess
|
23
24
|
import sys
|
24
25
|
|
25
26
|
|
26
|
-
import
|
27
|
-
from six.moves.configparser import ConfigParser
|
27
|
+
from configparser import ConfigParser
|
28
28
|
|
29
29
|
from swift.common.utils import backward, get_logger, dump_recon_cache, \
|
30
30
|
config_true_value
|
@@ -32,6 +32,27 @@ from swift.common.utils import backward, get_logger, dump_recon_cache, \
|
|
32
32
|
|
33
33
|
def get_devices(device_dir, logger):
|
34
34
|
devices = []
|
35
|
+
majmin_devices = {}
|
36
|
+
|
37
|
+
# List /dev/block
|
38
|
+
# Using os.scandir on recent versions of python, else os.listdir
|
39
|
+
if 'scandir' in dir(os):
|
40
|
+
with os.scandir("/dev/block") as it:
|
41
|
+
for ent in it:
|
42
|
+
if ent.is_symlink():
|
43
|
+
dev_name = os.path.basename(os.readlink(ent.path))
|
44
|
+
majmin = os.path.basename(ent.path).split(':')
|
45
|
+
majmin_devices[dev_name] = {'major': majmin[0],
|
46
|
+
'minor': majmin[1]}
|
47
|
+
else:
|
48
|
+
for ent in os.listdir("/dev/block"):
|
49
|
+
ent_path = os.path.join("/dev/block", ent)
|
50
|
+
if os.path.is_symlink(ent_path):
|
51
|
+
dev_name = os.path.basename(os.readlink(ent_path))
|
52
|
+
majmin = os.path.basename(ent_path).split(':')
|
53
|
+
majmin_devices[dev_name] = {'major': majmin[0],
|
54
|
+
'minor': majmin[1]}
|
55
|
+
|
35
56
|
for line in open('/proc/mounts').readlines():
|
36
57
|
data = line.strip().split()
|
37
58
|
block_device = data[0]
|
@@ -40,15 +61,25 @@ def get_devices(device_dir, logger):
|
|
40
61
|
device = {}
|
41
62
|
device['mount_point'] = mount_point
|
42
63
|
device['block_device'] = block_device
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
64
|
+
dev_name = os.path.basename(block_device)
|
65
|
+
if dev_name in majmin_devices:
|
66
|
+
# If symlink is in /dev/block
|
67
|
+
device['major'] = majmin_devices[dev_name]['major']
|
68
|
+
device['minor'] = majmin_devices[dev_name]['minor']
|
69
|
+
else:
|
70
|
+
# Else we try to stat block_device
|
71
|
+
try:
|
72
|
+
device_num = os.stat(block_device).st_rdev
|
73
|
+
except OSError:
|
74
|
+
# If we can't stat the device,
|
75
|
+
# then something weird is going on
|
76
|
+
logger.error(
|
77
|
+
'Could not determine major:minor numbers for %s '
|
78
|
+
'(mounted at %s)! Skipping...',
|
79
|
+
block_device, mount_point)
|
80
|
+
continue
|
81
|
+
device['major'] = str(os.major(device_num))
|
82
|
+
device['minor'] = str(os.minor(device_num))
|
52
83
|
devices.append(device)
|
53
84
|
for line in open('/proc/partitions').readlines()[2:]:
|
54
85
|
major, minor, blocks, kernel_device = line.strip().split()
|
@@ -84,7 +115,7 @@ def get_errors(error_re, log_file_pattern, minutes, logger,
|
|
84
115
|
# track of the year and month in case the year recently
|
85
116
|
# ticked over
|
86
117
|
year = now_time.year
|
87
|
-
|
118
|
+
prev_ent_month = now_time.strftime('%b')
|
88
119
|
errors = {}
|
89
120
|
|
90
121
|
reached_old_logs = False
|
@@ -96,8 +127,7 @@ def get_errors(error_re, log_file_pattern, minutes, logger,
|
|
96
127
|
print("Unable to open " + path)
|
97
128
|
sys.exit(1)
|
98
129
|
for line in backward(f):
|
99
|
-
|
100
|
-
line = line.decode(log_file_encoding, 'surrogateescape')
|
130
|
+
line = line.decode(log_file_encoding, 'surrogateescape')
|
101
131
|
if '[ 0.000000]' in line \
|
102
132
|
or 'KERNEL supported cpus:' in line \
|
103
133
|
or 'BIOS-provided physical RAM map:' in line:
|
@@ -106,16 +136,21 @@ def get_errors(error_re, log_file_pattern, minutes, logger,
|
|
106
136
|
break
|
107
137
|
# Solves the problem with year change - kern.log does not
|
108
138
|
# keep track of the year.
|
109
|
-
|
110
|
-
if
|
139
|
+
log_time_ent = line.split()[:3]
|
140
|
+
if log_time_ent[0] == 'Dec' and prev_ent_month == 'Jan':
|
111
141
|
year -= 1
|
112
|
-
|
113
|
-
log_time_string = '%d %s' % (year, ' '.join(
|
142
|
+
prev_ent_month = log_time_ent[0]
|
143
|
+
log_time_string = '%d %s' % (year, ' '.join(log_time_ent))
|
114
144
|
try:
|
115
145
|
log_time = datetime.datetime.strptime(
|
116
146
|
log_time_string, '%Y %b %d %H:%M:%S')
|
117
147
|
except ValueError:
|
118
|
-
|
148
|
+
# Some versions use ISO timestamps instead
|
149
|
+
try:
|
150
|
+
log_time = datetime.datetime.strptime(
|
151
|
+
line[0:19], '%Y-%m-%dT%H:%M:%S')
|
152
|
+
except ValueError:
|
153
|
+
continue
|
119
154
|
if log_time > end_time:
|
120
155
|
for err in error_re:
|
121
156
|
for device in err.findall(line):
|
@@ -142,7 +177,7 @@ def comment_fstab(mount_point):
|
|
142
177
|
os.rename('/etc/fstab.new', '/etc/fstab')
|
143
178
|
|
144
179
|
|
145
|
-
|
180
|
+
def main():
|
146
181
|
c = ConfigParser()
|
147
182
|
try:
|
148
183
|
conf_path = sys.argv[1]
|
@@ -222,3 +257,10 @@ if __name__ == '__main__':
|
|
222
257
|
|
223
258
|
if unmounts == 0:
|
224
259
|
logger.info("No drives were unmounted")
|
260
|
+
elif os.path.isdir("/run/systemd/system"):
|
261
|
+
logger.debug("fstab updated, calling systemctl daemon-reload")
|
262
|
+
subprocess.call(["/usr/bin/systemctl", "daemon-reload"])
|
263
|
+
|
264
|
+
|
265
|
+
if __name__ == '__main__':
|
266
|
+
main()
|
swift/cli/form_signature.py
CHANGED
@@ -15,9 +15,7 @@
|
|
15
15
|
"""
|
16
16
|
Script for generating a form signature for use with FormPost middleware.
|
17
17
|
"""
|
18
|
-
from __future__ import print_function
|
19
18
|
import hmac
|
20
|
-
import six
|
21
19
|
from hashlib import sha1
|
22
20
|
from os.path import basename
|
23
21
|
from time import time
|
@@ -95,11 +93,9 @@ def main(argv):
|
|
95
93
|
return 1
|
96
94
|
data = '%s\n%s\n%s\n%s\n%s' % (path, redirect, max_file_size,
|
97
95
|
max_file_count, expires)
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
key = key if isinstance(key, six.binary_type) else \
|
102
|
-
key.encode('utf8')
|
96
|
+
data = data.encode('utf8')
|
97
|
+
key = key if isinstance(key, bytes) else \
|
98
|
+
key.encode('utf8')
|
103
99
|
sig = hmac.new(key, data,
|
104
100
|
sha1).hexdigest()
|
105
101
|
print(' Expires:', expires)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
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");
|
@@ -25,7 +25,7 @@ from swift.cli.info import (parse_get_node_args, print_item_locations,
|
|
25
25
|
InfoSystemExit)
|
26
26
|
|
27
27
|
|
28
|
-
|
28
|
+
def main():
|
29
29
|
|
30
30
|
usage = '''
|
31
31
|
Shows the nodes responsible for the item specified.
|
@@ -52,6 +52,8 @@ if __name__ == '__main__':
|
|
52
52
|
help='Specify which policy to use')
|
53
53
|
parser.add_option('-d', '--swift-dir', default='/etc/swift',
|
54
54
|
dest='swift_dir', help='Path to swift directory')
|
55
|
+
parser.add_option('-Q', '--quoted', action='store_true',
|
56
|
+
help='Assume swift paths are quoted')
|
55
57
|
options, args = parser.parse_args()
|
56
58
|
|
57
59
|
if set_swift_dir(options.swift_dir):
|
@@ -72,3 +74,7 @@ if __name__ == '__main__':
|
|
72
74
|
print_item_locations(ring, ring_name, *args, **vars(options))
|
73
75
|
except InfoSystemExit:
|
74
76
|
sys.exit(1)
|
77
|
+
|
78
|
+
|
79
|
+
if __name__ == '__main__':
|
80
|
+
main()
|
swift/cli/info.py
CHANGED
@@ -10,15 +10,19 @@
|
|
10
10
|
# License for the specific language governing permissions and limitations
|
11
11
|
# under the License.
|
12
12
|
|
13
|
-
|
13
|
+
|
14
|
+
import codecs
|
14
15
|
import itertools
|
15
16
|
import json
|
17
|
+
from optparse import OptionParser
|
16
18
|
import os
|
17
19
|
import sqlite3
|
18
|
-
|
20
|
+
import sys
|
21
|
+
from collections import defaultdict
|
19
22
|
|
20
|
-
|
23
|
+
import urllib
|
21
24
|
|
25
|
+
from swift.common.exceptions import LockTimeout
|
22
26
|
from swift.common.utils import hash_path, storage_directory, \
|
23
27
|
Timestamp, is_valid_ipv6
|
24
28
|
from swift.common.ring import Ring
|
@@ -29,8 +33,10 @@ from swift.account.backend import AccountBroker, DATADIR as ABDATADIR
|
|
29
33
|
from swift.container.backend import ContainerBroker, DATADIR as CBDATADIR
|
30
34
|
from swift.obj.diskfile import get_data_dir, read_metadata, DATADIR_BASE, \
|
31
35
|
extract_policy
|
32
|
-
from swift.common.storage_policy import POLICIES
|
36
|
+
from swift.common.storage_policy import POLICIES, reload_storage_policies
|
37
|
+
from swift.common.swob import wsgi_to_str
|
33
38
|
from swift.common.middleware.crypto.crypto_utils import load_crypto_meta
|
39
|
+
from swift.common.utils import md5, set_swift_dir
|
34
40
|
|
35
41
|
|
36
42
|
class InfoSystemExit(Exception):
|
@@ -57,6 +63,8 @@ def parse_get_node_args(options, args):
|
|
57
63
|
else:
|
58
64
|
raise InfoSystemExit('Ring file does not exist')
|
59
65
|
|
66
|
+
if options.quoted:
|
67
|
+
args = [urllib.parse.unquote(arg) for arg in args]
|
60
68
|
if len(args) == 1:
|
61
69
|
args = args[0].strip('/').split('/', 2)
|
62
70
|
|
@@ -95,6 +103,7 @@ def curl_head_command(ip, port, device, part, target, policy_index):
|
|
95
103
|
if policy_index is not None:
|
96
104
|
cmd += ' -H "%s: %s"' % ('X-Backend-Storage-Policy-Index',
|
97
105
|
policy_index)
|
106
|
+
cmd += ' --path-as-is'
|
98
107
|
return cmd
|
99
108
|
|
100
109
|
|
@@ -193,7 +202,30 @@ def print_ring_locations(ring, datadir, account, container=None, obj=None,
|
|
193
202
|
'real value is set in the config file on each storage node.')
|
194
203
|
|
195
204
|
|
196
|
-
def
|
205
|
+
def get_max_len_sync_item(syncs, item, title):
|
206
|
+
def map_func(element):
|
207
|
+
return str(element[item])
|
208
|
+
return max(list(map(len, map(map_func, syncs))) + [len(title)])
|
209
|
+
|
210
|
+
|
211
|
+
def print_db_syncs(incoming, syncs):
|
212
|
+
max_sync_point_len = get_max_len_sync_item(syncs, 'sync_point',
|
213
|
+
"Sync Point")
|
214
|
+
max_remote_len = get_max_len_sync_item(syncs, 'remote_id', "Remote ID")
|
215
|
+
print('%s Syncs:' % ('Incoming' if incoming else 'Outgoing'))
|
216
|
+
print(' %s\t%s\t%s' % ("Sync Point".ljust(max_sync_point_len),
|
217
|
+
"Remote ID".ljust(max_remote_len),
|
218
|
+
"Updated At"))
|
219
|
+
for sync in syncs:
|
220
|
+
print(' %s\t%s\t%s (%s)' % (
|
221
|
+
str(sync['sync_point']).ljust(max_sync_point_len),
|
222
|
+
sync['remote_id'].ljust(max_remote_len),
|
223
|
+
Timestamp(sync['updated_at']).isoformat,
|
224
|
+
sync['updated_at']))
|
225
|
+
|
226
|
+
|
227
|
+
def print_db_info_metadata(db_type, info, metadata, drop_prefixes=False,
|
228
|
+
verbose=False):
|
197
229
|
"""
|
198
230
|
print out data base info/metadata based on its type
|
199
231
|
|
@@ -227,6 +259,7 @@ def print_db_info_metadata(db_type, info, metadata, drop_prefixes=False):
|
|
227
259
|
if db_type == 'container':
|
228
260
|
print(' Container: %s' % container)
|
229
261
|
|
262
|
+
print(' Deleted: %s' % info['is_deleted'])
|
230
263
|
path_hash = hash_path(account, container)
|
231
264
|
if db_type == 'container':
|
232
265
|
print(' Container Hash: %s' % path_hash)
|
@@ -291,12 +324,16 @@ def print_db_info_metadata(db_type, info, metadata, drop_prefixes=False):
|
|
291
324
|
title = key.replace('_', '-').title()
|
292
325
|
print(' %s: %s' % (title, value))
|
293
326
|
if sys_metadata:
|
294
|
-
print(' System Metadata:
|
327
|
+
print(' System Metadata:')
|
328
|
+
for key, value in sys_metadata.items():
|
329
|
+
print(' %s: %s' % (key, value))
|
295
330
|
else:
|
296
331
|
print('No system metadata found in db file')
|
297
332
|
|
298
333
|
if user_metadata:
|
299
|
-
print(' User Metadata:
|
334
|
+
print(' User Metadata:')
|
335
|
+
for key, value in user_metadata.items():
|
336
|
+
print(' %s: %s' % (key, value))
|
300
337
|
else:
|
301
338
|
print('No user metadata found in db file')
|
302
339
|
|
@@ -306,20 +343,31 @@ def print_db_info_metadata(db_type, info, metadata, drop_prefixes=False):
|
|
306
343
|
print(' Type: %s' % shard_type)
|
307
344
|
print(' State: %s' % info['db_state'])
|
308
345
|
if info.get('shard_ranges'):
|
309
|
-
|
346
|
+
num_shards = len(info['shard_ranges'])
|
347
|
+
print('Shard Ranges (%d):' % num_shards)
|
348
|
+
count_by_state = defaultdict(int)
|
310
349
|
for srange in info['shard_ranges']:
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
350
|
+
count_by_state[(srange.state, srange.state_text)] += 1
|
351
|
+
print(' States:')
|
352
|
+
for key_state, count in sorted(count_by_state.items()):
|
353
|
+
key, state = key_state
|
354
|
+
print(' %9s: %s' % (state, count))
|
355
|
+
if verbose:
|
356
|
+
for srange in info['shard_ranges']:
|
357
|
+
srange = dict(srange, state_text=srange.state_text)
|
358
|
+
print(' Name: %(name)s' % srange)
|
359
|
+
print(' lower: %(lower)r, upper: %(upper)r' % srange)
|
360
|
+
print(' Object Count: %(object_count)d, Bytes Used: '
|
361
|
+
'%(bytes_used)d, State: %(state_text)s (%(state)d)'
|
362
|
+
% srange)
|
363
|
+
print(' Created at: %s (%s)'
|
364
|
+
% (Timestamp(srange['timestamp']).isoformat,
|
365
|
+
srange['timestamp']))
|
366
|
+
print(' Meta Timestamp: %s (%s)'
|
367
|
+
% (Timestamp(srange['meta_timestamp']).isoformat,
|
368
|
+
srange['meta_timestamp']))
|
369
|
+
else:
|
370
|
+
print('(Use -v/--verbose to show more Shard Ranges details)')
|
323
371
|
|
324
372
|
|
325
373
|
def print_obj_metadata(metadata, drop_prefixes=False):
|
@@ -417,7 +465,7 @@ def print_obj_metadata(metadata, drop_prefixes=False):
|
|
417
465
|
|
418
466
|
|
419
467
|
def print_info(db_type, db_file, swift_dir='/etc/swift', stale_reads_ok=False,
|
420
|
-
drop_prefixes=False):
|
468
|
+
drop_prefixes=False, verbose=False, sync=False):
|
421
469
|
if db_type not in ('account', 'container'):
|
422
470
|
print("Unrecognized DB type: internal error")
|
423
471
|
raise InfoSystemExit()
|
@@ -442,13 +490,20 @@ def print_info(db_type, db_file, swift_dir='/etc/swift', stale_reads_ok=False,
|
|
442
490
|
raise
|
443
491
|
account = info['account']
|
444
492
|
container = None
|
493
|
+
info['is_deleted'] = broker.is_deleted()
|
445
494
|
if db_type == 'container':
|
446
495
|
container = info['container']
|
447
496
|
info['is_root'] = broker.is_root_container()
|
448
497
|
sranges = broker.get_shard_ranges()
|
449
498
|
if sranges:
|
450
499
|
info['shard_ranges'] = sranges
|
451
|
-
print_db_info_metadata(
|
500
|
+
print_db_info_metadata(
|
501
|
+
db_type, info, broker.metadata, drop_prefixes, verbose)
|
502
|
+
if sync:
|
503
|
+
# Print incoming / outgoing sync tables.
|
504
|
+
for incoming in (True, False):
|
505
|
+
print_db_syncs(incoming, broker.get_syncs(incoming,
|
506
|
+
include_timestamp=True))
|
452
507
|
try:
|
453
508
|
ring = Ring(swift_dir, ring_name=db_type)
|
454
509
|
except Exception:
|
@@ -518,6 +573,8 @@ def print_obj(datafile, check_etag=True, swift_dir='/etc/swift',
|
|
518
573
|
except EOFError:
|
519
574
|
print("Invalid metadata")
|
520
575
|
raise InfoSystemExit()
|
576
|
+
metadata = {wsgi_to_str(k): v if k == 'name' else wsgi_to_str(v)
|
577
|
+
for k, v in metadata.items()}
|
521
578
|
|
522
579
|
etag = metadata.pop('ETag', '')
|
523
580
|
length = metadata.pop('Content-Length', '')
|
@@ -527,7 +584,7 @@ def print_obj(datafile, check_etag=True, swift_dir='/etc/swift',
|
|
527
584
|
# Optional integrity check; it's useful, but slow.
|
528
585
|
file_len = None
|
529
586
|
if check_etag:
|
530
|
-
h = md5()
|
587
|
+
h = md5(usedforsecurity=False)
|
531
588
|
file_len = 0
|
532
589
|
while True:
|
533
590
|
data = fp.read(64 * 1024)
|
@@ -612,15 +669,15 @@ def print_item_locations(ring, ring_name=None, account=None, container=None,
|
|
612
669
|
ring = POLICIES.get_object_ring(policy_index, swift_dir)
|
613
670
|
ring_name = (POLICIES.get_by_name(policy_name)).ring_name
|
614
671
|
|
615
|
-
if
|
672
|
+
if (container or obj) and not account:
|
616
673
|
print('No account specified')
|
617
674
|
raise InfoSystemExit()
|
618
675
|
|
619
|
-
if
|
676
|
+
if obj and not container:
|
620
677
|
print('No container specified')
|
621
678
|
raise InfoSystemExit()
|
622
679
|
|
623
|
-
if account
|
680
|
+
if not account and not part:
|
624
681
|
print('No target specified')
|
625
682
|
raise InfoSystemExit()
|
626
683
|
|
@@ -652,8 +709,105 @@ def print_item_locations(ring, ring_name=None, account=None, container=None,
|
|
652
709
|
print('Warning: account specified ' +
|
653
710
|
'but ring not named "account"')
|
654
711
|
|
655
|
-
|
656
|
-
|
657
|
-
|
712
|
+
if account:
|
713
|
+
print('\nAccount \t%s' % urllib.parse.quote(account))
|
714
|
+
if container:
|
715
|
+
print('Container\t%s' % urllib.parse.quote(container))
|
716
|
+
if obj:
|
717
|
+
print('Object \t%s\n\n' % urllib.parse.quote(obj))
|
658
718
|
print_ring_locations(ring, loc, account, container, obj, part, all_nodes,
|
659
719
|
policy_index=policy_index)
|
720
|
+
|
721
|
+
|
722
|
+
def obj_main():
|
723
|
+
# Make stdout able to write escaped bytes
|
724
|
+
sys.stdout = codecs.getwriter("utf-8")(
|
725
|
+
sys.stdout.detach(), errors='surrogateescape')
|
726
|
+
|
727
|
+
parser = OptionParser('%prog [options] OBJECT_FILE')
|
728
|
+
parser.add_option(
|
729
|
+
'-n', '--no-check-etag', default=True,
|
730
|
+
action="store_false", dest="check_etag",
|
731
|
+
help="Don't verify file contents against stored etag")
|
732
|
+
parser.add_option(
|
733
|
+
'-d', '--swift-dir', default='/etc/swift', dest='swift_dir',
|
734
|
+
help="Pass location of swift directory")
|
735
|
+
parser.add_option(
|
736
|
+
'--drop-prefixes', default=False, action="store_true",
|
737
|
+
help="When outputting metadata, drop the per-section common prefixes")
|
738
|
+
parser.add_option(
|
739
|
+
'-P', '--policy-name', dest='policy_name',
|
740
|
+
help="Specify storage policy name")
|
741
|
+
|
742
|
+
options, args = parser.parse_args()
|
743
|
+
|
744
|
+
if len(args) != 1:
|
745
|
+
sys.exit(parser.print_help())
|
746
|
+
|
747
|
+
if set_swift_dir(options.swift_dir):
|
748
|
+
reload_storage_policies()
|
749
|
+
|
750
|
+
try:
|
751
|
+
print_obj(*args, **vars(options))
|
752
|
+
except InfoSystemExit:
|
753
|
+
sys.exit(1)
|
754
|
+
|
755
|
+
|
756
|
+
def run_print_info(db_type, args, opts):
|
757
|
+
try:
|
758
|
+
print_info(db_type, *args, **opts)
|
759
|
+
except InfoSystemExit:
|
760
|
+
sys.exit(1)
|
761
|
+
except (sqlite3.OperationalError, LockTimeout) as e:
|
762
|
+
if not opts.get('stale_reads_ok'):
|
763
|
+
opts['stale_reads_ok'] = True
|
764
|
+
print('Warning: Possibly Stale Data')
|
765
|
+
run_print_info(db_type, args, opts)
|
766
|
+
sys.exit(2)
|
767
|
+
else:
|
768
|
+
print('%s info failed: %s' % (db_type.title(), e))
|
769
|
+
sys.exit(1)
|
770
|
+
|
771
|
+
|
772
|
+
def container_main():
|
773
|
+
parser = OptionParser('%prog [options] CONTAINER_DB_FILE')
|
774
|
+
parser.add_option(
|
775
|
+
'-d', '--swift-dir', default='/etc/swift',
|
776
|
+
help="Pass location of swift directory")
|
777
|
+
parser.add_option(
|
778
|
+
'--drop-prefixes', default=False, action="store_true",
|
779
|
+
help="When outputting metadata, drop the per-section common prefixes")
|
780
|
+
parser.add_option(
|
781
|
+
'-v', '--verbose', default=False, action="store_true",
|
782
|
+
help="Show all shard ranges. By default, only the number of shard "
|
783
|
+
"ranges is displayed if there are many shards.")
|
784
|
+
parser.add_option(
|
785
|
+
'--sync', '-s', default=False, action="store_true",
|
786
|
+
help="Output the contents of the incoming/outging sync tables")
|
787
|
+
|
788
|
+
options, args = parser.parse_args()
|
789
|
+
|
790
|
+
if len(args) != 1:
|
791
|
+
sys.exit(parser.print_help())
|
792
|
+
|
793
|
+
run_print_info('container', args, vars(options))
|
794
|
+
|
795
|
+
|
796
|
+
def account_main():
|
797
|
+
parser = OptionParser('%prog [options] ACCOUNT_DB_FILE')
|
798
|
+
parser.add_option(
|
799
|
+
'-d', '--swift-dir', default='/etc/swift',
|
800
|
+
help="Pass location of swift directory")
|
801
|
+
parser.add_option(
|
802
|
+
'--drop-prefixes', default=False, action="store_true",
|
803
|
+
help="When outputting metadata, drop the per-section common prefixes")
|
804
|
+
parser.add_option(
|
805
|
+
'--sync', '-s', default=False, action="store_true",
|
806
|
+
help="Output the contents of the incoming/outging sync tables")
|
807
|
+
|
808
|
+
options, args = parser.parse_args()
|
809
|
+
|
810
|
+
if len(args) != 1:
|
811
|
+
sys.exit(parser.print_help())
|
812
|
+
|
813
|
+
run_print_info('account', args, vars(options))
|