Merge "swift-ring-builder output corrected for ipv6"
This commit is contained in:
commit
6d472f8a7a
@ -39,7 +39,7 @@ from swift.common.ring.utils import validate_args, \
|
|||||||
parse_builder_ring_filename_args, parse_search_value, \
|
parse_builder_ring_filename_args, parse_search_value, \
|
||||||
parse_search_values_from_opts, parse_change_values_from_opts, \
|
parse_search_values_from_opts, parse_change_values_from_opts, \
|
||||||
dispersion_report, parse_add_value
|
dispersion_report, parse_add_value
|
||||||
from swift.common.utils import lock_parent_directory
|
from swift.common.utils import lock_parent_directory, is_valid_ipv6
|
||||||
|
|
||||||
MAJOR_VERSION = 1
|
MAJOR_VERSION = 1
|
||||||
MINOR_VERSION = 3
|
MINOR_VERSION = 3
|
||||||
@ -376,6 +376,58 @@ def _parse_remove_values(argvish):
|
|||||||
exit(EXIT_ERROR)
|
exit(EXIT_ERROR)
|
||||||
|
|
||||||
|
|
||||||
|
def _make_display_device_table(builder):
|
||||||
|
ip_width = 10
|
||||||
|
port_width = 4
|
||||||
|
rep_ip_width = 14
|
||||||
|
rep_port_width = 4
|
||||||
|
ip_ipv6 = rep_ipv6 = False
|
||||||
|
for dev in builder._iter_devs():
|
||||||
|
if is_valid_ipv6(dev['ip']):
|
||||||
|
ip_ipv6 = True
|
||||||
|
if is_valid_ipv6(dev['replication_ip']):
|
||||||
|
rep_ipv6 = True
|
||||||
|
ip_width = max(len(dev['ip']), ip_width)
|
||||||
|
rep_ip_width = max(len(dev['replication_ip']), rep_ip_width)
|
||||||
|
port_width = max(len(str(dev['port'])), port_width)
|
||||||
|
rep_port_width = max(len(str(dev['replication_port'])),
|
||||||
|
rep_port_width)
|
||||||
|
if ip_ipv6:
|
||||||
|
ip_width += 2
|
||||||
|
if rep_ipv6:
|
||||||
|
rep_ip_width += 2
|
||||||
|
header_line = ('Devices:%5s %6s %4s %' + str(ip_width)
|
||||||
|
+ 's:%-' + str(port_width) + 's %' +
|
||||||
|
str(rep_ip_width) + 's:%-' + str(rep_port_width) +
|
||||||
|
's %5s %6s %10s %7s %5s %s') % (
|
||||||
|
'id', 'region', 'zone', 'ip address',
|
||||||
|
'port', 'replication ip', 'port', 'name',
|
||||||
|
'weight', 'partitions', 'balance', 'flags',
|
||||||
|
'meta')
|
||||||
|
|
||||||
|
def print_dev_f(dev, balance_per_dev=0.00, flags=''):
|
||||||
|
def get_formated_ip(key):
|
||||||
|
value = dev[key]
|
||||||
|
if ':' in value:
|
||||||
|
value = '[%s]' % value
|
||||||
|
return value
|
||||||
|
dev_ip = get_formated_ip('ip')
|
||||||
|
dev_replication_ip = get_formated_ip('replication_ip')
|
||||||
|
format_string = ''.join(['%13d %6d %4d ',
|
||||||
|
'%', str(ip_width), 's:%-',
|
||||||
|
str(port_width), 'd ', '%',
|
||||||
|
str(rep_ip_width), 's', ':%-',
|
||||||
|
str(rep_port_width), 'd %5s %6.02f'
|
||||||
|
' %10s %7.02f %5s %s'])
|
||||||
|
args = (dev['id'], dev['region'], dev['zone'], dev_ip, dev['port'],
|
||||||
|
dev_replication_ip, dev['replication_port'], dev['device'],
|
||||||
|
dev['weight'], dev['parts'], balance_per_dev, flags,
|
||||||
|
dev['meta'])
|
||||||
|
print(format_string % args)
|
||||||
|
|
||||||
|
return header_line, print_dev_f
|
||||||
|
|
||||||
|
|
||||||
class Commands(object):
|
class Commands(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unknown():
|
def unknown():
|
||||||
@ -458,18 +510,11 @@ swift-ring-builder <builder_file>
|
|||||||
|
|
||||||
if builder.devs:
|
if builder.devs:
|
||||||
balance_per_dev = builder._build_balance_per_dev()
|
balance_per_dev = builder._build_balance_per_dev()
|
||||||
print('Devices: id region zone ip address port '
|
header_line, print_dev_f = _make_display_device_table(builder)
|
||||||
'replication ip replication port name '
|
print(header_line)
|
||||||
'weight partitions balance flags meta')
|
|
||||||
for dev in builder._iter_devs():
|
for dev in builder._iter_devs():
|
||||||
flags = 'DEL' if dev in builder._remove_devs else ''
|
flags = 'DEL' if dev in builder._remove_devs else ''
|
||||||
print(' %5d %7d %5d %15s %5d %15s %17d %9s %6.02f '
|
print_dev_f(dev, balance_per_dev[dev['id']], flags)
|
||||||
'%10s %7.02f %5s %s' %
|
|
||||||
(dev['id'], dev['region'], dev['zone'], dev['ip'],
|
|
||||||
dev['port'], dev['replication_ip'],
|
|
||||||
dev['replication_port'], dev['device'], dev['weight'],
|
|
||||||
dev['parts'], balance_per_dev[dev['id']], flags,
|
|
||||||
dev['meta']))
|
|
||||||
exit(EXIT_SUCCESS)
|
exit(EXIT_SUCCESS)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -905,7 +950,7 @@ swift-ring-builder <builder_file> dispersion <search_filter> [options]
|
|||||||
--verbose option will display dispersion graph broken down by tier
|
--verbose option will display dispersion graph broken down by tier
|
||||||
|
|
||||||
You can filter which tiers are evaluated to drill down using a regex
|
You can filter which tiers are evaluated to drill down using a regex
|
||||||
in the optional search_filter arguemnt. i.e.
|
in the optional search_filter argument. i.e.
|
||||||
|
|
||||||
swift-ring-builder <builder_file> dispersion "r\d+z\d+$" -v
|
swift-ring-builder <builder_file> dispersion "r\d+z\d+$" -v
|
||||||
|
|
||||||
|
11
test/unit/cli/test_default_output.stub
Normal file
11
test/unit/cli/test_default_output.stub
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
__RINGFILE__, build version 4
|
||||||
|
64 partitions, 3.000000 replicas, 4 regions, 4 zones, 4 devices, 100.00 balance, 0.00 dispersion
|
||||||
|
The minimum number of hours before a partition can be reassigned is 1 (0:00:00 remaining)
|
||||||
|
The overload factor is 0.00% (0.000000)
|
||||||
|
Ring file __RINGFILE__.ring.gz not found, probably it hasn't been written yet
|
||||||
|
Devices: id region zone ip address:port replication ip:port name weight partitions balance flags meta
|
||||||
|
0 0 0 127.0.0.1:6200 127.0.0.1:6200 sda1 100.00 0 -100.00 some meta data
|
||||||
|
1 1 1 127.0.0.2:6201 127.0.0.2:6201 sda2 100.00 0 -100.00
|
||||||
|
2 2 2 127.0.0.3:6202 127.0.0.3:6202 sdc3 100.00 0 -100.00
|
||||||
|
3 3 3 127.0.0.4:6203 127.0.0.4:6203 sdd4 100.00 0 -100.00
|
||||||
|
|
10
test/unit/cli/test_ipv6_output.stub
Normal file
10
test/unit/cli/test_ipv6_output.stub
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
__RINGFILE__, build version 4
|
||||||
|
256 partitions, 3.000000 replicas, 4 regions, 4 zones, 4 devices, 100.00 balance, 0.00 dispersion
|
||||||
|
The minimum number of hours before a partition can be reassigned is 1 (0:00:00 remaining)
|
||||||
|
The overload factor is 0.00% (0.000000)
|
||||||
|
Ring file __RINGFILE__.ring.gz not found, probably it hasn't been written yet
|
||||||
|
Devices: id region zone ip address:port replication ip:port name weight partitions balance flags meta
|
||||||
|
0 0 0 [2001:db8:85a3::8a2e:370:7334]:6200 [2001:db8:85a3::8a2e:370:7334]:6200 sda1 100.00 0 -100.00 some meta data
|
||||||
|
1 1 1 127.0.0.1:66201 127.0.0.1:66201 sda2 100.00 0 -100.00
|
||||||
|
2 2 2 [2001:db8:85a3::8a2e:370:7336]:6202 127.0.10.127:7070 sdc3 100.00 0 -100.00
|
||||||
|
3 3 3 [2001:db8:85a3::8a2e:370:7337]:6203 [7001:db8:85a3::8a2e:370:7337]:11664 sdd4 100.00 0 -100.00
|
@ -13,6 +13,8 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import errno
|
||||||
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
import mock
|
import mock
|
||||||
import os
|
import os
|
||||||
@ -92,6 +94,43 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
|||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def assertOutputStub(self, output, ext='stub'):
|
||||||
|
"""
|
||||||
|
assert that the given output string is equal to a in-tree stub file,
|
||||||
|
if a test needs to check multiple outputs it can use custom ext's
|
||||||
|
"""
|
||||||
|
filepath = os.path.abspath(
|
||||||
|
os.path.join(os.path.dirname(__file__), self.id().split('.')[-1]))
|
||||||
|
print(filepath)
|
||||||
|
filepath = '%s.%s' % (filepath, ext)
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r') as f:
|
||||||
|
stub = f.read()
|
||||||
|
except (IOError, OSError) as e:
|
||||||
|
if e.errno == errno.ENOENT:
|
||||||
|
self.fail('%r does not exist' % filepath)
|
||||||
|
else:
|
||||||
|
self.fail('%r could not be read (%s)' % (filepath, e))
|
||||||
|
output = output.replace(self.tempfile, '__RINGFILE__')
|
||||||
|
for i, (value, expected) in enumerate(
|
||||||
|
itertools.izip_longest(
|
||||||
|
output.splitlines(), stub.splitlines())):
|
||||||
|
# N.B. differences in trailing whitespace are ignored!
|
||||||
|
value = (value or '').rstrip()
|
||||||
|
expected = (expected or '').rstrip()
|
||||||
|
try:
|
||||||
|
self.assertEqual(value, expected)
|
||||||
|
except AssertionError:
|
||||||
|
msg = 'Line #%s value is not like expected:\n%r\n%r' % (
|
||||||
|
i, value, expected)
|
||||||
|
msg += '\n\nFull output was:\n'
|
||||||
|
for i, line in enumerate(output.splitlines()):
|
||||||
|
msg += '%3d: %s\n' % (i, line)
|
||||||
|
msg += '\n\nCompared to stub:\n'
|
||||||
|
for i, line in enumerate(stub.splitlines()):
|
||||||
|
msg += '%3d: %s\n' % (i, line)
|
||||||
|
self.fail(msg)
|
||||||
|
|
||||||
def create_sample_ring(self, part_power=6):
|
def create_sample_ring(self, part_power=6):
|
||||||
""" Create a sample ring with four devices
|
""" Create a sample ring with four devices
|
||||||
|
|
||||||
@ -1614,6 +1653,50 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
|||||||
argv = ["", self.tmpfile]
|
argv = ["", self.tmpfile]
|
||||||
self.assertSystemExit(EXIT_SUCCESS, ringbuilder.main, argv)
|
self.assertSystemExit(EXIT_SUCCESS, ringbuilder.main, argv)
|
||||||
|
|
||||||
|
def test_default_output(self):
|
||||||
|
self.create_sample_ring()
|
||||||
|
out, err = self.run_srb('')
|
||||||
|
self.assertOutputStub(out)
|
||||||
|
|
||||||
|
def test_ipv6_output(self):
|
||||||
|
ring = RingBuilder(8, 3, 1)
|
||||||
|
ring.add_dev({'weight': 100.0,
|
||||||
|
'region': 0,
|
||||||
|
'zone': 0,
|
||||||
|
'ip': '2001:db8:85a3::8a2e:370:7334',
|
||||||
|
'port': 6200,
|
||||||
|
'device': 'sda1',
|
||||||
|
'meta': 'some meta data',
|
||||||
|
})
|
||||||
|
ring.add_dev({'weight': 100.0,
|
||||||
|
'region': 1,
|
||||||
|
'zone': 1,
|
||||||
|
'ip': '127.0.0.1',
|
||||||
|
'port': 66201,
|
||||||
|
'device': 'sda2',
|
||||||
|
})
|
||||||
|
ring.add_dev({'weight': 100.0,
|
||||||
|
'region': 2,
|
||||||
|
'zone': 2,
|
||||||
|
'ip': '2001:db8:85a3::8a2e:370:7336',
|
||||||
|
'port': 6202,
|
||||||
|
'device': 'sdc3',
|
||||||
|
'replication_ip': '127.0.10.127',
|
||||||
|
'replication_port': 7070,
|
||||||
|
})
|
||||||
|
ring.add_dev({'weight': 100.0,
|
||||||
|
'region': 3,
|
||||||
|
'zone': 3,
|
||||||
|
'ip': '2001:db8:85a3::8a2e:370:7337',
|
||||||
|
'port': 6203,
|
||||||
|
'device': 'sdd4',
|
||||||
|
'replication_ip': '7001:db8:85a3::8a2e:370:7337',
|
||||||
|
'replication_port': 11664,
|
||||||
|
})
|
||||||
|
ring.save(self.tmpfile)
|
||||||
|
out, err = self.run_srb('')
|
||||||
|
self.assertOutputStub(out)
|
||||||
|
|
||||||
def test_default_show_removed(self):
|
def test_default_show_removed(self):
|
||||||
mock_stdout = six.StringIO()
|
mock_stdout = six.StringIO()
|
||||||
mock_stderr = six.StringIO()
|
mock_stderr = six.StringIO()
|
||||||
@ -1642,20 +1725,20 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
|||||||
"The overload factor is 0.00%% (0.000000)\n" \
|
"The overload factor is 0.00%% (0.000000)\n" \
|
||||||
"Ring file %s.ring.gz not found, probably " \
|
"Ring file %s.ring.gz not found, probably " \
|
||||||
"it hasn't been written yet\n" \
|
"it hasn't been written yet\n" \
|
||||||
"Devices: id region zone ip address port " \
|
"Devices: id region zone ip address:port " \
|
||||||
"replication ip replication port name weight " \
|
"replication ip:port name weight " \
|
||||||
"partitions balance flags meta\n" \
|
"partitions balance flags meta\n" \
|
||||||
" 0 0 0 127.0.0.1 6200 " \
|
" 0 0 0 127.0.0.1:6200 " \
|
||||||
"127.0.0.1 6200 sda1 100.00" \
|
" 127.0.0.1:6200 sda1 100.00" \
|
||||||
" 0 -100.00 some meta data\n" \
|
" 0 -100.00 some meta data\n" \
|
||||||
" 1 1 1 127.0.0.2 6201 " \
|
" 1 1 1 127.0.0.2:6201 " \
|
||||||
"127.0.0.2 6201 sda2 0.00" \
|
" 127.0.0.2:6201 sda2 0.00" \
|
||||||
" 0 0.00 DEL \n" \
|
" 0 0.00 DEL \n" \
|
||||||
" 2 2 2 127.0.0.3 6202 " \
|
" 2 2 2 127.0.0.3:6202 " \
|
||||||
"127.0.0.3 6202 sdc3 100.00" \
|
" 127.0.0.3:6202 sdc3 100.00" \
|
||||||
" 0 -100.00 \n" \
|
" 0 -100.00 \n" \
|
||||||
" 3 3 3 127.0.0.4 6203 " \
|
" 3 3 3 127.0.0.4:6203 " \
|
||||||
"127.0.0.4 6203 sdd4 0.00" \
|
" 127.0.0.4:6203 sdd4 0.00" \
|
||||||
" 0 0.00 \n" % (self.tmpfile, self.tmpfile)
|
" 0 0.00 \n" % (self.tmpfile, self.tmpfile)
|
||||||
self.assertEqual(expected, mock_stdout.getvalue())
|
self.assertEqual(expected, mock_stdout.getvalue())
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user