Merge "Let some swift-ring-builder commands take >1 arg."
This commit is contained in:
commit
86f37c47d7
@ -18,6 +18,7 @@ import cPickle as pickle
|
||||
from array import array
|
||||
from errno import EEXIST
|
||||
from gzip import GzipFile
|
||||
from itertools import islice, izip
|
||||
from os import mkdir
|
||||
from os.path import basename, dirname, exists, join as pathjoin
|
||||
from sys import argv, exit, modules
|
||||
@ -267,27 +268,33 @@ swift-ring-builder <builder_file> list_parts <search-value> [<search-value>] ..
|
||||
|
||||
def add():
|
||||
"""
|
||||
swift-ring-builder <builder_file> add z<zone>-<ip>:<port>/<device_name>_<meta>
|
||||
<wght>
|
||||
Adds a device to the ring with the given information. No partitions will be
|
||||
swift-ring-builder <builder_file> add
|
||||
z<zone>-<ip>:<port>/<device_name>_<meta> <weight>
|
||||
[z<zone>-<ip>:<port>/<device_name>_<meta> <weight>] ...
|
||||
|
||||
Adds devices to the ring with the given information. No partitions will be
|
||||
assigned to the new device until after running 'rebalance'. This is so you
|
||||
can make multiple device changes and rebalance them all just once.
|
||||
"""
|
||||
if len(argv) < 5:
|
||||
if len(argv) < 5 or len(argv) % 2 != 1:
|
||||
print Commands.add.__doc__.strip()
|
||||
exit(EXIT_ERROR)
|
||||
|
||||
if not argv[3].startswith('z'):
|
||||
print 'Invalid add value: %s' % argv[3]
|
||||
devs_and_weights = izip(islice(argv, 3, len(argv), 2),
|
||||
islice(argv, 4, len(argv), 2))
|
||||
for devstr, weightstr in devs_and_weights:
|
||||
if not devstr.startswith('z'):
|
||||
print 'Invalid add value: %s' % devstr
|
||||
exit(EXIT_ERROR)
|
||||
i = 1
|
||||
while i < len(argv[3]) and argv[3][i].isdigit():
|
||||
while i < len(devstr) and devstr[i].isdigit():
|
||||
i += 1
|
||||
zone = int(argv[3][1:i])
|
||||
rest = argv[3][i:]
|
||||
zone = int(devstr[1:i])
|
||||
rest = devstr[i:]
|
||||
|
||||
if not rest.startswith('-'):
|
||||
print 'Invalid add value: %s' % argv[3]
|
||||
print 'Invalid add value: %s' % devstr
|
||||
print "The on-disk ring builder is unchanged.\n"
|
||||
exit(EXIT_ERROR)
|
||||
i = 1
|
||||
if rest[i] == '[':
|
||||
@ -304,7 +311,8 @@ swift-ring-builder <builder_file> add z<zone>-<ip>:<port>/<device_name>_<meta>
|
||||
rest = rest[i:]
|
||||
|
||||
if not rest.startswith(':'):
|
||||
print 'Invalid add value: %s' % argv[3]
|
||||
print 'Invalid add value: %s' % devstr
|
||||
print "The on-disk ring builder is unchanged.\n"
|
||||
exit(EXIT_ERROR)
|
||||
i = 1
|
||||
while i < len(rest) and rest[i].isdigit():
|
||||
@ -313,7 +321,8 @@ swift-ring-builder <builder_file> add z<zone>-<ip>:<port>/<device_name>_<meta>
|
||||
rest = rest[i:]
|
||||
|
||||
if not rest.startswith('/'):
|
||||
print 'Invalid add value: %s' % argv[3]
|
||||
print 'Invalid add value: %s' % devstr
|
||||
print "The on-disk ring builder is unchanged.\n"
|
||||
exit(EXIT_ERROR)
|
||||
i = 1
|
||||
while i < len(rest) and rest[i] != '_':
|
||||
@ -325,7 +334,17 @@ swift-ring-builder <builder_file> add z<zone>-<ip>:<port>/<device_name>_<meta>
|
||||
if rest.startswith('_'):
|
||||
meta = rest[1:]
|
||||
|
||||
weight = float(argv[4])
|
||||
try:
|
||||
weight = float(weightstr)
|
||||
except ValueError:
|
||||
print 'Invalid weight value: %s' % weightstr
|
||||
print "The on-disk ring builder is unchanged.\n"
|
||||
exit(EXIT_ERROR)
|
||||
|
||||
if weight < 0:
|
||||
print 'Invalid weight value (must be positive): %s' % weightstr
|
||||
print "The on-disk ring builder is unchanged.\n"
|
||||
exit(EXIT_ERROR)
|
||||
|
||||
for dev in builder.devs:
|
||||
if dev is None:
|
||||
@ -334,14 +353,15 @@ swift-ring-builder <builder_file> add z<zone>-<ip>:<port>/<device_name>_<meta>
|
||||
dev['device'] == device_name:
|
||||
print 'Device %d already uses %s:%d/%s.' % \
|
||||
(dev['id'], dev['ip'], dev['port'], dev['device'])
|
||||
print "The on-disk ring builder is unchanged.\n"
|
||||
exit(EXIT_ERROR)
|
||||
|
||||
next_dev_id = 0
|
||||
if builder.devs:
|
||||
next_dev_id = max(d['id'] for d in builder.devs if d) + 1
|
||||
builder.add_dev({'id': next_dev_id, 'zone': zone, 'ip': ip,
|
||||
'port': port, 'device': device_name, 'weight': weight,
|
||||
'meta': meta})
|
||||
'port': port, 'device': device_name,
|
||||
'weight': weight, 'meta': meta})
|
||||
if ':' in ip:
|
||||
print 'Device z%s-[%s]:%s/%s_"%s" with %s weight got id %s' % \
|
||||
(zone, ip, port, device_name, meta, weight, next_dev_id)
|
||||
@ -354,19 +374,27 @@ swift-ring-builder <builder_file> add z<zone>-<ip>:<port>/<device_name>_<meta>
|
||||
def set_weight():
|
||||
"""
|
||||
swift-ring-builder <builder_file> set_weight <search-value> <weight>
|
||||
Resets the device's weight. No partitions will be reassigned to or from the
|
||||
device until after running 'rebalance'. This is so you can make multiple
|
||||
device changes and rebalance them all just once.
|
||||
[<search-value> <weight] ...
|
||||
|
||||
Resets the devices' weights. No partitions will be reassigned to or from
|
||||
the device until after running 'rebalance'. This is so you can make
|
||||
multiple device changes and rebalance them all just once.
|
||||
"""
|
||||
if len(argv) != 5:
|
||||
if len(argv) < 5 or len(argv) % 2 != 1:
|
||||
print Commands.set_weight.__doc__.strip()
|
||||
print
|
||||
print search_devs.__doc__.strip()
|
||||
exit(EXIT_ERROR)
|
||||
devs = search_devs(builder, argv[3])
|
||||
weight = float(argv[4])
|
||||
|
||||
devs_and_weights = izip(islice(argv, 3, len(argv), 2),
|
||||
islice(argv, 4, len(argv), 2))
|
||||
for devstr, weightstr in devs_and_weights:
|
||||
devs = search_devs(builder, devstr)
|
||||
weight = float(weightstr)
|
||||
if not devs:
|
||||
print 'No matching devices found'
|
||||
print("Search value \"%s\" matched 0 devices.\n"
|
||||
"The on-disk ring builder is unchanged.\n"
|
||||
% devstr)
|
||||
exit(EXIT_ERROR)
|
||||
if len(devs) > 1:
|
||||
print 'Matched more than one device:'
|
||||
@ -379,33 +407,41 @@ swift-ring-builder <builder_file> set_weight <search-value> <weight>
|
||||
exit(EXIT_ERROR)
|
||||
for dev in devs:
|
||||
builder.set_dev_weight(dev['id'], weight)
|
||||
print 'd%(id)sz%(zone)s-%(ip)s:%(port)s/%(device)s_"%(meta)s" ' \
|
||||
'weight set to %(weight)s' % dev
|
||||
print 'd%(id)sz%(zone)s-%(ip)s:%(port)s/%(device)s_' \
|
||||
'"%(meta)s" weight set to %(weight)s' % dev
|
||||
pickle.dump(builder.to_dict(), open(argv[1], 'wb'), protocol=2)
|
||||
exit(EXIT_SUCCESS)
|
||||
|
||||
def set_info():
|
||||
"""
|
||||
swift-ring-builder <builder_file> set_info <search-value>
|
||||
<ip>:<port>/<device_name>_<meta>
|
||||
Resets the device's information. This information isn't used to assign
|
||||
partitions, so you can use 'write_ring' afterward to rewrite the current
|
||||
ring with the newer device information. Any of the parts are optional
|
||||
in the final <ip>:<port>/<device_name>_<meta> parameter; just give what you
|
||||
want to change. For instance set_info d74 _"snet: 5.6.7.8" would just
|
||||
update the meta data for device id 74.
|
||||
swift-ring-builder <builder_file> set_info
|
||||
<search-value> <ip>:<port>/<device_name>_<meta>
|
||||
[<search-value> <ip>:<port>/<device_name>_<meta>] ...
|
||||
|
||||
For each search-value, resets the matched device's information.
|
||||
This information isn't used to assign partitions, so you can use
|
||||
'write_ring' afterward to rewrite the current ring with the newer
|
||||
device information. Any of the parts are optional in the final
|
||||
<ip>:<port>/<device_name>_<meta> parameter; just give what you
|
||||
want to change. For instance set_info d74 _"snet: 5.6.7.8" would
|
||||
just update the meta data for device id 74.
|
||||
"""
|
||||
if len(argv) != 5:
|
||||
if len(argv) < 5 or len(argv) % 2 != 1:
|
||||
print Commands.set_info.__doc__.strip()
|
||||
print
|
||||
print search_devs.__doc__.strip()
|
||||
exit(EXIT_ERROR)
|
||||
devs = search_devs(builder, argv[3])
|
||||
change_value = argv[4]
|
||||
|
||||
searches_and_changes = izip(islice(argv, 3, len(argv), 2),
|
||||
islice(argv, 4, len(argv), 2))
|
||||
|
||||
for search_value, change_value in searches_and_changes:
|
||||
devs = search_devs(builder, search_value)
|
||||
change = []
|
||||
if len(change_value) and change_value[0].isdigit():
|
||||
i = 1
|
||||
while i < len(change_value) and change_value[i] in '0123456789.':
|
||||
while (i < len(change_value) and
|
||||
change_value[i] in '0123456789.'):
|
||||
i += 1
|
||||
change.append(('ip', change_value[:i]))
|
||||
change_value = change_value[i:]
|
||||
@ -435,7 +471,9 @@ swift-ring-builder <builder_file> set_info <search-value>
|
||||
raise ValueError('Invalid set info change value: %s' %
|
||||
repr(argv[4]))
|
||||
if not devs:
|
||||
print 'No matching devices found'
|
||||
print("Search value \"%s\" matched 0 devices.\n"
|
||||
"The on-disk ring builder is unchanged.\n"
|
||||
% search_value)
|
||||
exit(EXIT_ERROR)
|
||||
if len(devs) > 1:
|
||||
print 'Matched more than one device:'
|
||||
@ -457,18 +495,19 @@ swift-ring-builder <builder_file> set_info <search-value>
|
||||
check_dev['port'] == test_dev['port'] and \
|
||||
check_dev['device'] == test_dev['device']:
|
||||
print 'Device %d already uses %s:%d/%s.' % \
|
||||
(check_dev['id'], check_dev['ip'], check_dev['port'],
|
||||
check_dev['device'])
|
||||
(check_dev['id'], check_dev['ip'],
|
||||
check_dev['port'], check_dev['device'])
|
||||
exit(EXIT_ERROR)
|
||||
for key, value in change:
|
||||
dev[key] = value
|
||||
print 'Device %s is now %s' % (orig_dev_string, format_device(dev))
|
||||
print 'Device %s is now %s' % (orig_dev_string,
|
||||
format_device(dev))
|
||||
pickle.dump(builder.to_dict(), open(argv[1], 'wb'), protocol=2)
|
||||
exit(EXIT_SUCCESS)
|
||||
|
||||
def remove():
|
||||
"""
|
||||
swift-ring-builder <builder_file> remove <search-value>
|
||||
swift-ring-builder <builder_file> remove <search-value> [search-value ...]
|
||||
Removes the device(s) from the ring. This should normally just be used for
|
||||
a device that has failed. For a device you wish to decommission, it's best
|
||||
to set its weight to 0, wait for it to drain all its data, then use this
|
||||
@ -481,17 +520,20 @@ swift-ring-builder <builder_file> remove <search-value>
|
||||
print
|
||||
print search_devs.__doc__.strip()
|
||||
exit(EXIT_ERROR)
|
||||
devs = search_devs(builder, argv[3])
|
||||
|
||||
for search_value in argv[3:]:
|
||||
devs = search_devs(builder, search_value)
|
||||
if not devs:
|
||||
print 'No matching devices found'
|
||||
print("Search value \"%s\" matched 0 devices.\n"
|
||||
"The on-disk ring builder is unchanged.\n" % devstr)
|
||||
exit(EXIT_ERROR)
|
||||
if len(devs) > 1:
|
||||
print 'Matched more than one device:'
|
||||
for dev in devs:
|
||||
print ' d%(id)sz%(zone)s-%(ip)s:%(port)s/%(device)s_' \
|
||||
'"%(meta)s"' % dev
|
||||
if raw_input('Are you sure you want to remove these %s devices? '
|
||||
'(y/N) ' % len(devs)) != 'y':
|
||||
if raw_input('Are you sure you want to remove these %s '
|
||||
'devices? (y/N) ' % len(devs)) != 'y':
|
||||
print 'Aborting device removals'
|
||||
exit(EXIT_ERROR)
|
||||
for dev in devs:
|
||||
@ -499,20 +541,21 @@ swift-ring-builder <builder_file> remove <search-value>
|
||||
builder.remove_dev(dev['id'])
|
||||
except exceptions.RingBuilderError, e:
|
||||
print '-' * 79
|
||||
print ("An error occurred while removing device with id %d\n"
|
||||
"This usually means that you attempted to remove the\n"
|
||||
"last device in a ring. If this is the case, consider\n"
|
||||
"creating a new ring instead.\n"
|
||||
"The on-disk ring builder is unchanged\n"
|
||||
print(
|
||||
"An error occurred while removing device with id %d\n"
|
||||
"This usually means that you attempted to remove\n"
|
||||
"the last device in a ring. If this is the case,\n"
|
||||
"consider creating a new ring instead.\n"
|
||||
"The on-disk ring builder is unchanged.\n"
|
||||
"Original exception message: %s" %
|
||||
(dev['id'], e.message)
|
||||
)
|
||||
print '-' * 79
|
||||
exit(EXIT_ERROR)
|
||||
|
||||
print 'd%(id)sz%(zone)s-%(ip)s:%(port)s/%(device)s_"%(meta)s" ' \
|
||||
'marked for removal and will be removed next rebalance.' \
|
||||
% dev
|
||||
print 'd%(id)sz%(zone)s-%(ip)s:%(port)s/%(device)s_' \
|
||||
'"%(meta)s" marked for removal and will be removed' \
|
||||
' next rebalance.' % dev
|
||||
pickle.dump(builder.to_dict(), open(argv[1], 'wb'), protocol=2)
|
||||
exit(EXIT_SUCCESS)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user