Add info about state of ring file to default command.
Try to find ring file, load and compare it with builder file, then show result state. Examples: Ring file object.ring.gz not found, probably it hasn't been written yet Ring file object.ring.gz is up-to-date Ring file object.ring.gz is obsolete Ring file object.ring.gz is invalid: ValueError('string length not a multiple of item size',) Change-Id: I4d769aa5fe1c2b1167ec088aa372874f7d13ae48
This commit is contained in:
parent
6a473e3d7b
commit
f56f29ef7a
@ -33,7 +33,7 @@ from six.moves import zip as izip
|
|||||||
from six.moves import input
|
from six.moves import input
|
||||||
|
|
||||||
from swift.common import exceptions
|
from swift.common import exceptions
|
||||||
from swift.common.ring import RingBuilder, Ring
|
from swift.common.ring import RingBuilder, Ring, RingData
|
||||||
from swift.common.ring.builder import MAX_BALANCE
|
from swift.common.ring.builder import MAX_BALANCE
|
||||||
from swift.common.ring.utils import validate_args, \
|
from swift.common.ring.utils import validate_args, \
|
||||||
validate_and_normalize_ip, build_dev_from_opts, \
|
validate_and_normalize_ip, build_dev_from_opts, \
|
||||||
@ -450,6 +450,23 @@ swift-ring-builder <builder_file>
|
|||||||
timedelta(seconds=builder.min_part_seconds_left)))
|
timedelta(seconds=builder.min_part_seconds_left)))
|
||||||
print('The overload factor is %0.2f%% (%.6f)' % (
|
print('The overload factor is %0.2f%% (%.6f)' % (
|
||||||
builder.overload * 100, builder.overload))
|
builder.overload * 100, builder.overload))
|
||||||
|
|
||||||
|
# compare ring file against builder file
|
||||||
|
if not exists(ring_file):
|
||||||
|
print('Ring file %s not found, '
|
||||||
|
'probably it hasn\'t been written yet' % ring_file)
|
||||||
|
else:
|
||||||
|
builder_dict = builder.get_ring().to_dict()
|
||||||
|
try:
|
||||||
|
ring_dict = RingData.load(ring_file).to_dict()
|
||||||
|
except Exception as exc:
|
||||||
|
print('Ring file %s is invalid: %r' % (ring_file, exc))
|
||||||
|
else:
|
||||||
|
if builder_dict == ring_dict:
|
||||||
|
print('Ring file %s is up-to-date' % ring_file)
|
||||||
|
else:
|
||||||
|
print('Ring file %s is obsolete' % ring_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 '
|
print('Devices: id region zone ip address port '
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import mock
|
import mock
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import six
|
import six
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
@ -1741,6 +1742,8 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
|||||||
"The minimum number of hours before a partition can be " \
|
"The minimum number of hours before a partition can be " \
|
||||||
"reassigned is 1 (0:00:00 remaining)\n" \
|
"reassigned is 1 (0:00:00 remaining)\n" \
|
||||||
"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 " \
|
||||||
|
"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 replication port name weight " \
|
||||||
"partitions balance flags meta\n" \
|
"partitions balance flags meta\n" \
|
||||||
@ -1755,9 +1758,68 @@ class TestCommands(unittest.TestCase, RunSwiftRingBuilderMixin):
|
|||||||
" 0 -100.00 \n" \
|
" 0 -100.00 \n" \
|
||||||
" 3 3 3 127.0.0.4 6003 " \
|
" 3 3 3 127.0.0.4 6003 " \
|
||||||
"127.0.0.4 6003 sdd4 0.00" \
|
"127.0.0.4 6003 sdd4 0.00" \
|
||||||
" 0 0.00 \n" % self.tmpfile
|
" 0 0.00 \n" % (self.tmpfile, self.tmpfile)
|
||||||
self.assertEqual(expected, mock_stdout.getvalue())
|
self.assertEqual(expected, mock_stdout.getvalue())
|
||||||
|
|
||||||
|
def test_default_ringfile_check(self):
|
||||||
|
self.create_sample_ring()
|
||||||
|
|
||||||
|
# ring file not created
|
||||||
|
mock_stdout = six.StringIO()
|
||||||
|
mock_stderr = six.StringIO()
|
||||||
|
argv = ["", self.tmpfile]
|
||||||
|
with mock.patch("sys.stdout", mock_stdout):
|
||||||
|
with mock.patch("sys.stderr", mock_stderr):
|
||||||
|
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||||
|
rnf = re.compile("Ring file .*\.ring\.gz not found")
|
||||||
|
self.assertTrue(rnf.findall(mock_stdout.getvalue()))
|
||||||
|
|
||||||
|
# write ring file
|
||||||
|
argv = ["", self.tmpfile, "rebalance"]
|
||||||
|
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||||
|
# ring file is up-to-date
|
||||||
|
mock_stdout = six.StringIO()
|
||||||
|
argv = ["", self.tmpfile]
|
||||||
|
with mock.patch("sys.stdout", mock_stdout):
|
||||||
|
with mock.patch("sys.stderr", mock_stderr):
|
||||||
|
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||||
|
rutd = re.compile("Ring file .*\.ring\.gz is up-to-date")
|
||||||
|
self.assertTrue(rutd.findall(mock_stdout.getvalue()))
|
||||||
|
|
||||||
|
# change builder (set weight)
|
||||||
|
argv = ["", self.tmpfile, "set_weight", "0", "--id", "3"]
|
||||||
|
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||||
|
# ring file is obsolete after set_weight
|
||||||
|
mock_stdout = six.StringIO()
|
||||||
|
argv = ["", self.tmpfile]
|
||||||
|
with mock.patch("sys.stdout", mock_stdout):
|
||||||
|
with mock.patch("sys.stderr", mock_stderr):
|
||||||
|
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||||
|
ro = re.compile("Ring file .*\.ring\.gz is obsolete")
|
||||||
|
self.assertTrue(ro.findall(mock_stdout.getvalue()))
|
||||||
|
|
||||||
|
# write ring file
|
||||||
|
argv = ["", self.tmpfile, "write_ring"]
|
||||||
|
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||||
|
# ring file up-to-date again
|
||||||
|
mock_stdout = six.StringIO()
|
||||||
|
argv = ["", self.tmpfile]
|
||||||
|
with mock.patch("sys.stdout", mock_stdout):
|
||||||
|
with mock.patch("sys.stderr", mock_stderr):
|
||||||
|
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||||
|
self.assertTrue(rutd.findall(mock_stdout.getvalue()))
|
||||||
|
|
||||||
|
# Break ring file e.g. just make it empty
|
||||||
|
open('%s.ring.gz' % self.tmpfile, 'w').close()
|
||||||
|
# ring file is invalid
|
||||||
|
mock_stdout = six.StringIO()
|
||||||
|
argv = ["", self.tmpfile]
|
||||||
|
with mock.patch("sys.stdout", mock_stdout):
|
||||||
|
with mock.patch("sys.stderr", mock_stderr):
|
||||||
|
self.assertRaises(SystemExit, ringbuilder.main, argv)
|
||||||
|
ro = re.compile("Ring file .*\.ring\.gz is invalid")
|
||||||
|
self.assertTrue(ro.findall(mock_stdout.getvalue()))
|
||||||
|
|
||||||
def test_rebalance(self):
|
def test_rebalance(self):
|
||||||
self.create_sample_ring()
|
self.create_sample_ring()
|
||||||
argv = ["", self.tmpfile, "rebalance", "3"]
|
argv = ["", self.tmpfile, "rebalance", "3"]
|
||||||
|
Loading…
Reference in New Issue
Block a user