Handle IPv6 addresses in swift-get-nodes.
The curl commands needed a little tweaking. Change-Id: I6551d65241950c65e7160587cc414deb4a2122f5 Closes-Bug: 1555860
This commit is contained in:
parent
902cb8f8d7
commit
457cea864c
@ -20,7 +20,7 @@ from six.moves import urllib
|
||||
|
||||
from swift.common.utils import hash_path, storage_directory, \
|
||||
Timestamp
|
||||
from swift.common.ring import Ring
|
||||
from swift.common.ring import Ring, utils as ring_utils
|
||||
from swift.common.request_helpers import is_sys_meta, is_user_meta, \
|
||||
strip_sys_meta_prefix, strip_user_meta_prefix
|
||||
from swift.account.backend import AccountBroker, DATADIR as ABDATADIR
|
||||
@ -37,6 +37,32 @@ class InfoSystemExit(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def curl_head_command(ip, port, device, part, target, policy_index):
|
||||
"""
|
||||
Provide a string that is a well formatted curl command to HEAD an object
|
||||
on a storage node.
|
||||
|
||||
:param ip: the ip of the node
|
||||
:param port: the port of the node
|
||||
:param device: the device of the node
|
||||
:param target: the path of the target resource
|
||||
:param policy_index: the policy_index of the target resource (can be None)
|
||||
|
||||
:returns: a string, a well formatted curl command
|
||||
"""
|
||||
if ring_utils.is_valid_ipv6(ip):
|
||||
formatted_ip = '[%s]' % ip
|
||||
else:
|
||||
formatted_ip = ip
|
||||
|
||||
cmd = 'curl -g -I -XHEAD "http://%s:%s/%s/%s/%s"' % (
|
||||
formatted_ip, port, device, part, urllib.parse.quote(target))
|
||||
if policy_index is not None:
|
||||
cmd += ' -H "%s: %s"' % ('X-Backend-Storage-Policy-Index',
|
||||
policy_index)
|
||||
return cmd
|
||||
|
||||
|
||||
def print_ring_locations(ring, datadir, account, container=None, obj=None,
|
||||
tpart=None, all_nodes=False, policy_index=None):
|
||||
"""
|
||||
@ -99,20 +125,12 @@ def print_ring_locations(ring, datadir, account, container=None, obj=None,
|
||||
print("\n")
|
||||
|
||||
for node in primary_nodes:
|
||||
cmd = 'curl -I -XHEAD "http://%s:%s/%s/%s/%s"' \
|
||||
% (node['ip'], node['port'], node['device'], part,
|
||||
urllib.parse.quote(target))
|
||||
if policy_index is not None:
|
||||
cmd += ' -H "%s: %s"' % ('X-Backend-Storage-Policy-Index',
|
||||
policy_index)
|
||||
cmd = curl_head_command(node['ip'], node['port'], node['device'],
|
||||
part, target, policy_index)
|
||||
print(cmd)
|
||||
for node in handoff_nodes:
|
||||
cmd = 'curl -I -XHEAD "http://%s:%s/%s/%s/%s"' \
|
||||
% (node['ip'], node['port'], node['device'], part,
|
||||
urllib.parse.quote(target))
|
||||
if policy_index is not None:
|
||||
cmd += ' -H "%s: %s"' % ('X-Backend-Storage-Policy-Index',
|
||||
policy_index)
|
||||
cmd = curl_head_command(node['ip'], node['port'], node['device'],
|
||||
part, target, policy_index)
|
||||
cmd += ' # [Handoff]'
|
||||
print(cmd)
|
||||
|
||||
|
@ -34,7 +34,8 @@ from swift.obj.diskfile import write_metadata
|
||||
|
||||
@patch_policies([StoragePolicy(0, 'zero', True),
|
||||
StoragePolicy(1, 'one', False),
|
||||
StoragePolicy(2, 'two', False)])
|
||||
StoragePolicy(2, 'two', False),
|
||||
StoragePolicy(3, 'three', False)])
|
||||
class TestCliInfoBase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.orig_hp = utils.HASH_PATH_PREFIX, utils.HASH_PATH_SUFFIX
|
||||
@ -72,6 +73,13 @@ class TestCliInfoBase(unittest.TestCase):
|
||||
# ... and another for policy 2
|
||||
self.two_ring_path = os.path.join(self.testdir, 'object-2.ring.gz')
|
||||
write_fake_ring(self.two_ring_path, *object_devs)
|
||||
# ... and one for policy 3 with some v6 IPs in it
|
||||
object_devs_ipv6 = [
|
||||
{'ip': 'feed:face::dead:beef', 'port': 42},
|
||||
{'ip': 'deca:fc0f:feeb:ad11::1', 'port': 43}
|
||||
]
|
||||
self.three_ring_path = os.path.join(self.testdir, 'object-3.ring.gz')
|
||||
write_fake_ring(self.three_ring_path, *object_devs_ipv6)
|
||||
|
||||
def tearDown(self):
|
||||
utils.HASH_PATH_PREFIX, utils.HASH_PATH_SUFFIX = self.orig_hp
|
||||
@ -569,6 +577,88 @@ class TestPrintObjFullMeta(TestCliInfoBase):
|
||||
os.chdir(cwd)
|
||||
self.assertTrue('X-Backend-Storage-Policy-Index: 1' in out.getvalue())
|
||||
|
||||
def test_print_obj_curl_command_ipv4(self):
|
||||
# Note: policy 2 has IPv4 addresses in its ring
|
||||
datafile2 = os.path.join(
|
||||
self.testdir,
|
||||
'sda', 'objects-2', '1', 'ea8',
|
||||
'db4449e025aca992307c7c804a67eea8', '1402017884.18202.data')
|
||||
utils.mkdirs(os.path.dirname(datafile2))
|
||||
with open(datafile2, 'wb') as fp:
|
||||
md = {'name': '/AUTH_admin/c/obj',
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'ETag': 'd41d8cd98f00b204e9800998ecf8427e',
|
||||
'Content-Length': 0}
|
||||
write_metadata(fp, md)
|
||||
|
||||
object_ring = ring.Ring(self.testdir, ring_name='object-2')
|
||||
part, nodes = object_ring.get_nodes('AUTH_admin', 'c', 'obj')
|
||||
node = nodes[0]
|
||||
|
||||
out = StringIO()
|
||||
hash_dir = os.path.dirname(datafile2)
|
||||
file_name = os.path.basename(datafile2)
|
||||
|
||||
# Change working directory to object hash dir
|
||||
cwd = os.getcwd()
|
||||
try:
|
||||
os.chdir(hash_dir)
|
||||
with mock.patch('sys.stdout', out):
|
||||
print_obj(file_name, swift_dir=self.testdir)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
exp_curl = (
|
||||
'curl -g -I -XHEAD '
|
||||
'"http://{host}:{port}/{device}/{part}/AUTH_admin/c/obj" '
|
||||
'-H "X-Backend-Storage-Policy-Index: 2"').format(
|
||||
host=node['ip'],
|
||||
port=node['port'],
|
||||
device=node['device'],
|
||||
part=part)
|
||||
self.assertIn(exp_curl, out.getvalue())
|
||||
|
||||
def test_print_obj_curl_command_ipv6(self):
|
||||
# Note: policy 3 has IPv6 addresses in its ring
|
||||
datafile3 = os.path.join(
|
||||
self.testdir,
|
||||
'sda', 'objects-3', '1', 'ea8',
|
||||
'db4449e025aca992307c7c804a67eea8', '1402017884.18202.data')
|
||||
utils.mkdirs(os.path.dirname(datafile3))
|
||||
with open(datafile3, 'wb') as fp:
|
||||
md = {'name': '/AUTH_admin/c/obj',
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'ETag': 'd41d8cd98f00b204e9800998ecf8427e',
|
||||
'Content-Length': 0}
|
||||
write_metadata(fp, md)
|
||||
|
||||
object_ring = ring.Ring(self.testdir, ring_name='object-3')
|
||||
part, nodes = object_ring.get_nodes('AUTH_admin', 'c', 'obj')
|
||||
node = nodes[0]
|
||||
|
||||
out = StringIO()
|
||||
hash_dir = os.path.dirname(datafile3)
|
||||
file_name = os.path.basename(datafile3)
|
||||
|
||||
# Change working directory to object hash dir
|
||||
cwd = os.getcwd()
|
||||
try:
|
||||
os.chdir(hash_dir)
|
||||
with mock.patch('sys.stdout', out):
|
||||
print_obj(file_name, swift_dir=self.testdir)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
exp_curl = (
|
||||
'curl -g -I -XHEAD '
|
||||
'"http://[{host}]:{port}'
|
||||
'/{device}/{part}/AUTH_admin/c/obj" ').format(
|
||||
host=node['ip'],
|
||||
port=node['port'],
|
||||
device=node['device'],
|
||||
part=part)
|
||||
self.assertIn(exp_curl, out.getvalue())
|
||||
|
||||
def test_print_obj_meta_and_ts_files(self):
|
||||
# verify that print_obj will also read from meta and ts files
|
||||
base = os.path.splitext(self.datafile)[0]
|
||||
|
Loading…
x
Reference in New Issue
Block a user