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/cli/reload.py
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# Copyright (c) 2022 NVIDIA
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
12
|
+
# implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
"""
|
17
|
+
Safely reload WSGI servers while minimizing client downtime and errors by
|
18
|
+
|
19
|
+
* validating that the process is a Swift WSGI server manager,
|
20
|
+
* checking that the configuration file used is valid,
|
21
|
+
* sending the "seamless reload" signal, and
|
22
|
+
* waiting for the reload to complete.
|
23
|
+
"""
|
24
|
+
|
25
|
+
import argparse
|
26
|
+
import errno
|
27
|
+
import os
|
28
|
+
import os.path
|
29
|
+
import signal
|
30
|
+
import socket
|
31
|
+
import subprocess
|
32
|
+
import sys
|
33
|
+
|
34
|
+
from swift.common.utils import NotificationServer
|
35
|
+
|
36
|
+
|
37
|
+
EXIT_BAD_PID = 2 # similar to argparse exiting 2 on an unknown arg
|
38
|
+
EXIT_RELOAD_FAILED = 1
|
39
|
+
EXIT_RELOAD_TIMEOUT = 128 + errno.ETIMEDOUT
|
40
|
+
|
41
|
+
|
42
|
+
def validate_manager_pid(pid):
|
43
|
+
try:
|
44
|
+
with open('/proc/%d/cmdline' % pid, 'r') as fp:
|
45
|
+
cmd = fp.read().strip('\x00').split('\x00')
|
46
|
+
sid = os.getsid(pid)
|
47
|
+
except (IOError, OSError):
|
48
|
+
print("Failed to get process information for %s" % pid,
|
49
|
+
file=sys.stderr)
|
50
|
+
exit(EXIT_BAD_PID)
|
51
|
+
|
52
|
+
scripts = [os.path.basename(c) for c in cmd
|
53
|
+
if '/bin/' in c and '/bin/python' not in c]
|
54
|
+
|
55
|
+
if len(scripts) != 1 or not scripts[0].startswith("swift-"):
|
56
|
+
print("Non-swift process: %r" % ' '.join(cmd), file=sys.stderr)
|
57
|
+
exit(EXIT_BAD_PID)
|
58
|
+
|
59
|
+
if scripts[0] not in {"swift-proxy-server", "swift-account-server",
|
60
|
+
"swift-container-server", "swift-object-server"}:
|
61
|
+
print("Process does not support config checks: %s" % scripts[0],
|
62
|
+
file=sys.stderr)
|
63
|
+
exit(EXIT_BAD_PID)
|
64
|
+
|
65
|
+
if sid != pid:
|
66
|
+
print("Process appears to be a %s worker, not a manager. "
|
67
|
+
"Did you mean %s?" % (scripts[0], sid), file=sys.stderr)
|
68
|
+
exit(EXIT_BAD_PID)
|
69
|
+
|
70
|
+
return cmd, scripts[0]
|
71
|
+
|
72
|
+
|
73
|
+
def main(args=None):
|
74
|
+
parser = argparse.ArgumentParser(__doc__)
|
75
|
+
parser.add_argument("pid", type=int,
|
76
|
+
help="server PID which should be reloaded")
|
77
|
+
wait_group = parser.add_mutually_exclusive_group()
|
78
|
+
wait_group.add_argument("-t", "--timeout", type=float, default=300.0,
|
79
|
+
help="max time to wait for reload to complete")
|
80
|
+
wait_group.add_argument("-w", "--no-wait",
|
81
|
+
action="store_false", dest="wait",
|
82
|
+
help="skip waiting for reload to complete")
|
83
|
+
parser.add_argument("-v", "--verbose", action="store_true",
|
84
|
+
help="display more information as the process reloads")
|
85
|
+
args = parser.parse_args(args)
|
86
|
+
|
87
|
+
cmd, script = validate_manager_pid(args.pid)
|
88
|
+
|
89
|
+
if args.verbose:
|
90
|
+
print("Checking config for %s" % script)
|
91
|
+
try:
|
92
|
+
subprocess.check_call(cmd + ["--test-config"])
|
93
|
+
except subprocess.CalledProcessError:
|
94
|
+
print("Failed to validate config", file=sys.stderr)
|
95
|
+
exit(EXIT_RELOAD_FAILED)
|
96
|
+
|
97
|
+
if args.wait:
|
98
|
+
try:
|
99
|
+
with NotificationServer(args.pid, args.timeout) as notifications:
|
100
|
+
if args.verbose:
|
101
|
+
print("Sending USR1 signal")
|
102
|
+
os.kill(args.pid, signal.SIGUSR1)
|
103
|
+
|
104
|
+
try:
|
105
|
+
ready = False
|
106
|
+
while not ready:
|
107
|
+
data = notifications.receive()
|
108
|
+
for data in data.split(b"\n"):
|
109
|
+
if args.verbose:
|
110
|
+
if data in (b"READY=1", b"RELOADING=1",
|
111
|
+
b"STOPPING=1"):
|
112
|
+
print("Process is %s" %
|
113
|
+
data.decode("ascii")[:-2])
|
114
|
+
else:
|
115
|
+
print("Received notification %r" % data)
|
116
|
+
|
117
|
+
if data == b"READY=1":
|
118
|
+
ready = True
|
119
|
+
except socket.timeout:
|
120
|
+
print("Timed out reloading %s" % script, file=sys.stderr)
|
121
|
+
exit(EXIT_RELOAD_TIMEOUT)
|
122
|
+
except OSError as e:
|
123
|
+
print("Could not bind notification socket: %s" % e,
|
124
|
+
file=sys.stderr)
|
125
|
+
exit(EXIT_RELOAD_FAILED)
|
126
|
+
else: # --no-wait
|
127
|
+
if args.verbose:
|
128
|
+
print("Sending USR1 signal")
|
129
|
+
os.kill(args.pid, signal.SIGUSR1)
|
130
|
+
|
131
|
+
print("Reloaded %s" % script)
|
132
|
+
|
133
|
+
|
134
|
+
if __name__ == "__main__":
|
135
|
+
main()
|
swift/cli/ringbuilder.py
CHANGED
@@ -13,7 +13,6 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
from __future__ import print_function
|
17
16
|
import logging
|
18
17
|
|
19
18
|
from collections import defaultdict
|
@@ -22,16 +21,15 @@ from itertools import islice
|
|
22
21
|
from operator import itemgetter
|
23
22
|
from os import mkdir
|
24
23
|
from os.path import basename, abspath, dirname, exists, join as pathjoin
|
24
|
+
import sys
|
25
25
|
from sys import argv as sys_argv, exit, stderr, stdout
|
26
26
|
from textwrap import wrap
|
27
27
|
from time import time
|
28
|
+
import traceback
|
28
29
|
from datetime import timedelta
|
29
30
|
import optparse
|
30
31
|
import math
|
31
32
|
|
32
|
-
from six.moves import zip as izip
|
33
|
-
from six.moves import input
|
34
|
-
|
35
33
|
from swift.common import exceptions
|
36
34
|
from swift.common.ring import RingBuilder, Ring, RingData
|
37
35
|
from swift.common.ring.builder import MAX_BALANCE
|
@@ -154,8 +152,8 @@ def _parse_add_values(argvish):
|
|
154
152
|
print(Commands.add.__doc__.strip())
|
155
153
|
exit(EXIT_ERROR)
|
156
154
|
|
157
|
-
devs_and_weights =
|
158
|
-
|
155
|
+
devs_and_weights = zip(islice(args, 0, len(args), 2),
|
156
|
+
islice(args, 1, len(args), 2))
|
159
157
|
|
160
158
|
for devstr, weightstr in devs_and_weights:
|
161
159
|
dev_dict = parse_add_value(devstr)
|
@@ -194,7 +192,11 @@ def check_devs(devs, input_question, opts, abort_msg):
|
|
194
192
|
print('Matched more than one device:')
|
195
193
|
for dev in devs:
|
196
194
|
print(' %s' % format_device(dev))
|
197
|
-
|
195
|
+
try:
|
196
|
+
abort = not opts.yes and input(input_question) != 'y'
|
197
|
+
except (EOFError, KeyboardInterrupt):
|
198
|
+
abort = True
|
199
|
+
if abort:
|
198
200
|
print(abort_msg)
|
199
201
|
exit(EXIT_ERROR)
|
200
202
|
|
@@ -212,6 +214,32 @@ def _set_weight_values(devs, weight, opts):
|
|
212
214
|
dev['weight']))
|
213
215
|
|
214
216
|
|
217
|
+
def _set_region_values(devs, region, opts):
|
218
|
+
|
219
|
+
input_question = 'Are you sure you want to update the region for these ' \
|
220
|
+
'%s devices? (y/N) ' % len(devs)
|
221
|
+
abort_msg = 'Aborting device modifications'
|
222
|
+
check_devs(devs, input_question, opts, abort_msg)
|
223
|
+
|
224
|
+
for dev in devs:
|
225
|
+
builder.set_dev_region(dev['id'], region)
|
226
|
+
print('%s region set to %s' % (format_device(dev),
|
227
|
+
dev['region']))
|
228
|
+
|
229
|
+
|
230
|
+
def _set_zone_values(devs, zone, opts):
|
231
|
+
|
232
|
+
input_question = 'Are you sure you want to update the zone for these ' \
|
233
|
+
'%s devices? (y/N) ' % len(devs)
|
234
|
+
abort_msg = 'Aborting device modifications'
|
235
|
+
check_devs(devs, input_question, opts, abort_msg)
|
236
|
+
|
237
|
+
for dev in devs:
|
238
|
+
builder.set_dev_zone(dev['id'], zone)
|
239
|
+
print('%s zone set to %s' % (format_device(dev),
|
240
|
+
dev['zone']))
|
241
|
+
|
242
|
+
|
215
243
|
def _parse_set_weight_values(argvish):
|
216
244
|
|
217
245
|
new_cmd_format, opts, args = validate_args(argvish)
|
@@ -225,8 +253,8 @@ def _parse_set_weight_values(argvish):
|
|
225
253
|
print(Commands.set_weight.__doc__.strip())
|
226
254
|
exit(EXIT_ERROR)
|
227
255
|
|
228
|
-
devs_and_weights =
|
229
|
-
|
256
|
+
devs_and_weights = zip(islice(argvish, 0, len(argvish), 2),
|
257
|
+
islice(argvish, 1, len(argvish), 2))
|
230
258
|
for devstr, weightstr in devs_and_weights:
|
231
259
|
devs = (builder.search_devs(
|
232
260
|
parse_search_value(devstr)) or [])
|
@@ -301,6 +329,76 @@ def calculate_change_value(change_value, change, v_name, v_name_port):
|
|
301
329
|
return change_value
|
302
330
|
|
303
331
|
|
332
|
+
def _parse_set_region_values(argvish):
|
333
|
+
|
334
|
+
new_cmd_format, opts, args = validate_args(argvish)
|
335
|
+
|
336
|
+
# We'll either parse the all-in-one-string format or the
|
337
|
+
# --options format,
|
338
|
+
# but not both. If both are specified, raise an error.
|
339
|
+
try:
|
340
|
+
devs = []
|
341
|
+
if not new_cmd_format:
|
342
|
+
if len(args) % 2 != 0:
|
343
|
+
print(Commands.set_region.__doc__.strip())
|
344
|
+
exit(EXIT_ERROR)
|
345
|
+
|
346
|
+
devs_and_regions = zip(islice(argvish, 0, len(argvish), 2),
|
347
|
+
islice(argvish, 1, len(argvish), 2))
|
348
|
+
for devstr, regionstr in devs_and_regions:
|
349
|
+
devs.extend(builder.search_devs(
|
350
|
+
parse_search_value(devstr)) or [])
|
351
|
+
region = int(regionstr)
|
352
|
+
_set_region_values(devs, region, opts)
|
353
|
+
else:
|
354
|
+
if len(args) != 1:
|
355
|
+
print(Commands.set_region.__doc__.strip())
|
356
|
+
exit(EXIT_ERROR)
|
357
|
+
|
358
|
+
devs.extend(builder.search_devs(
|
359
|
+
parse_search_values_from_opts(opts)) or [])
|
360
|
+
region = int(args[0])
|
361
|
+
_set_region_values(devs, region, opts)
|
362
|
+
except ValueError as e:
|
363
|
+
print(e)
|
364
|
+
exit(EXIT_ERROR)
|
365
|
+
|
366
|
+
|
367
|
+
def _parse_set_zone_values(argvish):
|
368
|
+
|
369
|
+
new_cmd_format, opts, args = validate_args(argvish)
|
370
|
+
|
371
|
+
# We'll either parse the all-in-one-string format or the
|
372
|
+
# --options format,
|
373
|
+
# but not both. If both are specified, raise an error.
|
374
|
+
try:
|
375
|
+
devs = []
|
376
|
+
if not new_cmd_format:
|
377
|
+
if len(args) % 2 != 0:
|
378
|
+
print(Commands.set_zone.__doc__.strip())
|
379
|
+
exit(EXIT_ERROR)
|
380
|
+
|
381
|
+
devs_and_zones = zip(islice(argvish, 0, len(argvish), 2),
|
382
|
+
islice(argvish, 1, len(argvish), 2))
|
383
|
+
for devstr, zonestr in devs_and_zones:
|
384
|
+
devs.extend(builder.search_devs(
|
385
|
+
parse_search_value(devstr)) or [])
|
386
|
+
zone = int(zonestr)
|
387
|
+
_set_zone_values(devs, zone, opts)
|
388
|
+
else:
|
389
|
+
if len(args) != 1:
|
390
|
+
print(Commands.set_zone.__doc__.strip())
|
391
|
+
exit(EXIT_ERROR)
|
392
|
+
|
393
|
+
devs.extend(builder.search_devs(
|
394
|
+
parse_search_values_from_opts(opts)) or [])
|
395
|
+
zone = int(args[0])
|
396
|
+
_set_zone_values(devs, zone, opts)
|
397
|
+
except ValueError as e:
|
398
|
+
print(e)
|
399
|
+
exit(EXIT_ERROR)
|
400
|
+
|
401
|
+
|
304
402
|
def _parse_set_info_values(argvish):
|
305
403
|
|
306
404
|
new_cmd_format, opts, args = validate_args(argvish)
|
@@ -313,8 +411,8 @@ def _parse_set_info_values(argvish):
|
|
313
411
|
print(Commands.search.__doc__.strip())
|
314
412
|
exit(EXIT_ERROR)
|
315
413
|
|
316
|
-
searches_and_changes =
|
317
|
-
|
414
|
+
searches_and_changes = zip(islice(argvish, 0, len(argvish), 2),
|
415
|
+
islice(argvish, 1, len(argvish), 2))
|
318
416
|
|
319
417
|
for search_value, change_value in searches_and_changes:
|
320
418
|
devs = builder.search_devs(parse_search_value(search_value))
|
@@ -380,6 +478,7 @@ def _make_display_device_table(builder):
|
|
380
478
|
rep_ip_width = 14
|
381
479
|
rep_port_width = 4
|
382
480
|
ip_ipv6 = rep_ipv6 = False
|
481
|
+
weight_width = 6
|
383
482
|
for dev in builder._iter_devs():
|
384
483
|
if is_valid_ipv6(dev['ip']):
|
385
484
|
ip_ipv6 = True
|
@@ -390,6 +489,8 @@ def _make_display_device_table(builder):
|
|
390
489
|
port_width = max(len(str(dev['port'])), port_width)
|
391
490
|
rep_port_width = max(len(str(dev['replication_port'])),
|
392
491
|
rep_port_width)
|
492
|
+
weight_width = max(len('%6.02f' % dev['weight']),
|
493
|
+
weight_width)
|
393
494
|
if ip_ipv6:
|
394
495
|
ip_width += 2
|
395
496
|
if rep_ipv6:
|
@@ -397,7 +498,7 @@ def _make_display_device_table(builder):
|
|
397
498
|
header_line = ('Devices:%5s %6s %4s %' + str(ip_width)
|
398
499
|
+ 's:%-' + str(port_width) + 's %' +
|
399
500
|
str(rep_ip_width) + 's:%-' + str(rep_port_width) +
|
400
|
-
's %5s %
|
501
|
+
's %5s %' + str(weight_width) + 's %10s %7s %5s %s') % (
|
401
502
|
'id', 'region', 'zone', 'ip address',
|
402
503
|
'port', 'replication ip', 'port', 'name',
|
403
504
|
'weight', 'partitions', 'balance', 'flags',
|
@@ -415,7 +516,8 @@ def _make_display_device_table(builder):
|
|
415
516
|
'%', str(ip_width), 's:%-',
|
416
517
|
str(port_width), 'd ', '%',
|
417
518
|
str(rep_ip_width), 's', ':%-',
|
418
|
-
str(rep_port_width), 'd %5s %
|
519
|
+
str(rep_port_width), 'd %5s %',
|
520
|
+
str(weight_width), '.02f'
|
419
521
|
' %10s %7.02f %5s %s'])
|
420
522
|
args = (dev['id'], dev['region'], dev['zone'], dev_ip, dev['port'],
|
421
523
|
dev_replication_ip, dev['replication_port'], dev['device'],
|
@@ -444,7 +546,11 @@ swift-ring-builder <builder_file> create <part_power> <replicas>
|
|
444
546
|
if len(argv) < 6:
|
445
547
|
print(Commands.create.__doc__.strip())
|
446
548
|
exit(EXIT_ERROR)
|
447
|
-
|
549
|
+
try:
|
550
|
+
builder = RingBuilder(int(argv[3]), float(argv[4]), int(argv[5]))
|
551
|
+
except ValueError as e:
|
552
|
+
print(e)
|
553
|
+
exit(EXIT_ERROR)
|
448
554
|
backup_dir = pathjoin(dirname(builder_file), 'backups')
|
449
555
|
try:
|
450
556
|
mkdir(backup_dir)
|
@@ -681,7 +787,7 @@ swift-ring-builder <builder_file> add
|
|
681
787
|
if builder.next_part_power:
|
682
788
|
print('Partition power increase in progress. You need ')
|
683
789
|
print('to finish the increase first before adding devices.')
|
684
|
-
exit(
|
790
|
+
exit(EXIT_ERROR)
|
685
791
|
|
686
792
|
try:
|
687
793
|
for new_dev in _parse_add_values(argv[3:]):
|
@@ -745,6 +851,75 @@ swift-ring-builder <builder_file> set_weight
|
|
745
851
|
builder.save(builder_file)
|
746
852
|
exit(EXIT_SUCCESS)
|
747
853
|
|
854
|
+
@staticmethod
|
855
|
+
def set_region():
|
856
|
+
"""
|
857
|
+
swift-ring-builder <builder_file> set_region <search-value> <region>
|
858
|
+
[<search-value> <region] ...
|
859
|
+
|
860
|
+
or
|
861
|
+
|
862
|
+
swift-ring-builder <builder_file> set_region
|
863
|
+
--region <region> --zone <zone> --ip <ip or hostname> --port <port>
|
864
|
+
--replication-ip <r_ip or r_hostname> --replication-port <r_port>
|
865
|
+
--device <device_name> --meta <meta> <new region> [--yes]
|
866
|
+
|
867
|
+
Where <r_ip>, <r_hostname> and <r_port> are replication ip, hostname
|
868
|
+
and port.
|
869
|
+
Any of the options are optional in both cases.
|
870
|
+
|
871
|
+
Resets the devices' regions. No partitions will be reassigned to or from
|
872
|
+
the device until after running 'rebalance'. This is so you can make
|
873
|
+
multiple device changes and rebalance them all just once.
|
874
|
+
|
875
|
+
Option --yes assume a yes response to all questions.
|
876
|
+
"""
|
877
|
+
if len(argv) < 5:
|
878
|
+
print(Commands.set_region.__doc__.strip())
|
879
|
+
print()
|
880
|
+
print(parse_search_value.__doc__.strip())
|
881
|
+
exit(EXIT_ERROR)
|
882
|
+
|
883
|
+
_parse_set_region_values(argv[3:])
|
884
|
+
|
885
|
+
builder.save(builder_file)
|
886
|
+
exit(EXIT_SUCCESS)
|
887
|
+
|
888
|
+
@staticmethod
|
889
|
+
def set_zone():
|
890
|
+
"""
|
891
|
+
swift-ring-builder <builder_file> set_zone <search-value> <zone>
|
892
|
+
[<search-value> <zone] ...
|
893
|
+
|
894
|
+
or
|
895
|
+
|
896
|
+
swift-ring-builder <builder_file> set_zone
|
897
|
+
--region <region> --zone <zone> --ip <ip or hostname> --port <port>
|
898
|
+
--replication-ip <r_ip or r_hostname> --replication-port <r_port>
|
899
|
+
--device <device_name> --meta <meta> <new zone> [--yes]
|
900
|
+
|
901
|
+
Where <r_ip>, <r_hostname> and <r_port> are replication ip, hostname
|
902
|
+
and port.
|
903
|
+
Any of the options are optional in both cases.
|
904
|
+
|
905
|
+
Resets the devices' zones. No partitions will be reassigned to or from
|
906
|
+
the device until after running 'rebalance'. This is so you can make
|
907
|
+
multiple device changes and rebalance them all just once.
|
908
|
+
|
909
|
+
Option --yes assume a yes response to all questions.
|
910
|
+
"""
|
911
|
+
# if len(argv) < 5 or len(argv) % 2 != 1:
|
912
|
+
if len(argv) < 5:
|
913
|
+
print(Commands.set_zone.__doc__.strip())
|
914
|
+
print()
|
915
|
+
print(parse_search_value.__doc__.strip())
|
916
|
+
exit(EXIT_ERROR)
|
917
|
+
|
918
|
+
_parse_set_zone_values(argv[3:])
|
919
|
+
|
920
|
+
builder.save(builder_file)
|
921
|
+
exit(EXIT_SUCCESS)
|
922
|
+
|
748
923
|
@staticmethod
|
749
924
|
def set_info():
|
750
925
|
"""
|
@@ -831,7 +1006,7 @@ swift-ring-builder <builder_file> remove
|
|
831
1006
|
if builder.next_part_power:
|
832
1007
|
print('Partition power increase in progress. You need ')
|
833
1008
|
print('to finish the increase first before removing devices.')
|
834
|
-
exit(
|
1009
|
+
exit(EXIT_ERROR)
|
835
1010
|
|
836
1011
|
devs, opts = _parse_remove_values(argv[3:])
|
837
1012
|
|
@@ -898,7 +1073,7 @@ swift-ring-builder <builder_file> rebalance [options]
|
|
898
1073
|
if builder.next_part_power:
|
899
1074
|
print('Partition power increase in progress.')
|
900
1075
|
print('You need to finish the increase first before rebalancing.')
|
901
|
-
exit(
|
1076
|
+
exit(EXIT_ERROR)
|
902
1077
|
|
903
1078
|
devs_changed = builder.devs_changed
|
904
1079
|
min_part_seconds_left = builder.min_part_seconds_left
|
@@ -999,7 +1174,7 @@ swift-ring-builder <builder_file> rebalance [options]
|
|
999
1174
|
|
1000
1175
|
@staticmethod
|
1001
1176
|
def dispersion():
|
1002
|
-
"""
|
1177
|
+
r"""
|
1003
1178
|
swift-ring-builder <builder_file> dispersion <search_filter> [options]
|
1004
1179
|
|
1005
1180
|
Output report on dispersion.
|
@@ -1167,7 +1342,7 @@ swift-ring-builder <ring_file> write_builder [min_part_hours]
|
|
1167
1342
|
'parts': ring.partition_count,
|
1168
1343
|
'devs': ring.devs,
|
1169
1344
|
'devs_changed': False,
|
1170
|
-
'version': 0,
|
1345
|
+
'version': ring.version or 0,
|
1171
1346
|
'_replica2part2dev': ring._replica2part2dev_id,
|
1172
1347
|
'_last_part_moves_epoch': None,
|
1173
1348
|
'_last_part_moves': None,
|
@@ -1493,7 +1668,7 @@ def main(arguments=None):
|
|
1493
1668
|
print(msg)
|
1494
1669
|
exit(EXIT_ERROR)
|
1495
1670
|
except (exceptions.FileNotFoundError, exceptions.PermissionError) as e:
|
1496
|
-
if len(argv) < 3 or argv[2] not in('create', 'write_builder'):
|
1671
|
+
if len(argv) < 3 or argv[2] not in ('create', 'write_builder'):
|
1497
1672
|
print(e)
|
1498
1673
|
exit(EXIT_ERROR)
|
1499
1674
|
except Exception as e:
|
@@ -1521,3 +1696,25 @@ def main(arguments=None):
|
|
1521
1696
|
exit(2)
|
1522
1697
|
else:
|
1523
1698
|
getattr(Commands, command, Commands.unknown)()
|
1699
|
+
|
1700
|
+
|
1701
|
+
def error_handling_main():
|
1702
|
+
# We exit code 1 on WARNING statuses, 2 on ERROR. This means we need
|
1703
|
+
# to handle any uncaught exceptions by printing the usual backtrace,
|
1704
|
+
# but then exiting 2 (not 1 as is usual for a python
|
1705
|
+
# exception).
|
1706
|
+
|
1707
|
+
# We *don't* want to do this in main(), however, because we don't want to
|
1708
|
+
# pollute the test environment or cause a bunch of test churn to mock out
|
1709
|
+
# sys.excepthook
|
1710
|
+
|
1711
|
+
def exit_with_status_two(tp, val, tb):
|
1712
|
+
traceback.print_exception(tp, val, tb)
|
1713
|
+
exit(2)
|
1714
|
+
|
1715
|
+
sys.excepthook = exit_with_status_two
|
1716
|
+
main()
|
1717
|
+
|
1718
|
+
|
1719
|
+
if __name__ == '__main__':
|
1720
|
+
error_handling_main()
|
swift/cli/ringcomposer.py
CHANGED
swift/cli/shard-info.py
CHANGED
@@ -89,7 +89,7 @@ def print_own_shard_range(node, sr, indent_level):
|
|
89
89
|
indent = indent_level * TAB
|
90
90
|
range = '%r - %r' % (sr.lower, sr.upper)
|
91
91
|
print('%s(%s) %23s, objs: %3s, bytes: %3s, timestamp: %s (%s), '
|
92
|
-
'modified: %s (%s), %7s: %s (%s), deleted: %s epoch: %s' %
|
92
|
+
'modified: %s (%s), %7s: %s (%s), deleted: %s, epoch: %s' %
|
93
93
|
(indent, node[1][0], range, sr.object_count, sr.bytes_used,
|
94
94
|
sr.timestamp.isoformat, sr.timestamp.internal,
|
95
95
|
sr.meta_timestamp.isoformat, sr.meta_timestamp.internal,
|
@@ -108,12 +108,13 @@ def print_shard_range(node, sr, indent_level):
|
|
108
108
|
indent = indent_level * TAB
|
109
109
|
range = '%r - %r' % (sr.lower, sr.upper)
|
110
110
|
print('%s(%s) %23s, objs: %3s, bytes: %3s, timestamp: %s (%s), '
|
111
|
-
'modified: %s (%s), %7s: %s (%s), deleted: %s %s' %
|
111
|
+
'modified: %s (%s), %7s: %s (%s), deleted: %s, epoch: %s %s' %
|
112
112
|
(indent, node[1][0], range, sr.object_count, sr.bytes_used,
|
113
113
|
sr.timestamp.isoformat, sr.timestamp.internal,
|
114
114
|
sr.meta_timestamp.isoformat, sr.meta_timestamp.internal,
|
115
115
|
sr.state_text, sr.state_timestamp.isoformat,
|
116
|
-
sr.state_timestamp.internal, sr.deleted,
|
116
|
+
sr.state_timestamp.internal, sr.deleted,
|
117
|
+
sr.epoch.internal if sr.epoch else None, sr.name))
|
117
118
|
|
118
119
|
|
119
120
|
def print_shard_range_info(node, shard_ranges, indent_level=0):
|
@@ -27,10 +27,8 @@ class BaseStorageServer(object):
|
|
27
27
|
|
28
28
|
def __init__(self, conf, **kwargs):
|
29
29
|
self._allowed_methods = None
|
30
|
-
replication_server =
|
31
|
-
|
32
|
-
replication_server = config_true_value(replication_server)
|
33
|
-
self.replication_server = replication_server
|
30
|
+
self.replication_server = config_true_value(
|
31
|
+
conf.get('replication_server', 'true'))
|
34
32
|
self.log_format = conf.get('log_format', LOG_LINE_DEFAULT_FORMAT)
|
35
33
|
self.anonymization_method = conf.get('log_anonymization_method', 'md5')
|
36
34
|
self.anonymization_salt = conf.get('log_anonymization_salt', '')
|
@@ -45,22 +43,13 @@ class BaseStorageServer(object):
|
|
45
43
|
if self._allowed_methods is None:
|
46
44
|
self._allowed_methods = []
|
47
45
|
all_methods = inspect.getmembers(self, predicate=callable)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
for name, m in all_methods:
|
56
|
-
if (getattr(m, 'publicly_accessible', False) and not
|
57
|
-
getattr(m, 'replication', False)):
|
58
|
-
self._allowed_methods.append(name)
|
59
|
-
elif self.replication_server is None:
|
60
|
-
for name, m in all_methods:
|
61
|
-
if getattr(m, 'publicly_accessible', False):
|
62
|
-
self._allowed_methods.append(name)
|
63
|
-
|
46
|
+
for name, m in all_methods:
|
47
|
+
if not getattr(m, 'publicly_accessible', False):
|
48
|
+
continue
|
49
|
+
if getattr(m, 'replication', False) and \
|
50
|
+
not self.replication_server:
|
51
|
+
continue
|
52
|
+
self._allowed_methods.append(name)
|
64
53
|
self._allowed_methods.sort()
|
65
54
|
return self._allowed_methods
|
66
55
|
|