fix object replication on older rsync versions when using ipv4
Fixes bug 987388 Change-Id: I6eb5c45fe1f5844ad853a4ff9bc8fd23cc9abd5d
This commit is contained in:
		@@ -32,7 +32,7 @@ from webob.exc import HTTPNotFound, HTTPNoContent, HTTPAccepted, \
 | 
			
		||||
import swift.common.db
 | 
			
		||||
from swift.common.utils import get_logger, whataremyips, storage_directory, \
 | 
			
		||||
    renamer, mkdirs, lock_parent_directory, TRUE_VALUES, unlink_older_than, \
 | 
			
		||||
    dump_recon_cache
 | 
			
		||||
    dump_recon_cache, rsync_ip
 | 
			
		||||
from swift.common import ring
 | 
			
		||||
from swift.common.bufferedhttp import BufferedHTTPConnection
 | 
			
		||||
from swift.common.exceptions import DriveNotMounted, ConnectionTimeout
 | 
			
		||||
@@ -193,12 +193,13 @@ class Replicator(Daemon):
 | 
			
		||||
        :param replicate_method: remote operation to perform after rsync
 | 
			
		||||
        :param replicate_timeout: timeout to wait in seconds
 | 
			
		||||
        """
 | 
			
		||||
        device_ip = rsync_ip(device['ip'])
 | 
			
		||||
        if self.vm_test_mode:
 | 
			
		||||
            remote_file = '[%s]::%s%s/%s/tmp/%s' % (device['ip'],
 | 
			
		||||
            remote_file = '%s::%s%s/%s/tmp/%s' % (device_ip,
 | 
			
		||||
                    self.server_type, device['port'], device['device'],
 | 
			
		||||
                    local_id)
 | 
			
		||||
        else:
 | 
			
		||||
            remote_file = '[%s]::%s/%s/tmp/%s' % (device['ip'],
 | 
			
		||||
            remote_file = '%s::%s/%s/tmp/%s' % (device_ip,
 | 
			
		||||
                    self.server_type, device['device'], local_id)
 | 
			
		||||
        mtime = os.path.getmtime(broker.db_file)
 | 
			
		||||
        if not self._rsync_file(broker.db_file, remote_file):
 | 
			
		||||
 
 | 
			
		||||
@@ -1261,3 +1261,22 @@ def public(func):
 | 
			
		||||
    def wrapped(*a, **kw):
 | 
			
		||||
        return func(*a, **kw)
 | 
			
		||||
    return wrapped
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def rsync_ip(ip):
 | 
			
		||||
    """
 | 
			
		||||
    Transform ip string to an rsync-compatible form
 | 
			
		||||
 | 
			
		||||
    Will return ipv4 addresses unchanged, but will nest ipv6 addresses
 | 
			
		||||
    inside square brackets.
 | 
			
		||||
 | 
			
		||||
    :param ip: an ip string (ipv4 or ipv6)
 | 
			
		||||
 | 
			
		||||
    :returns: a string ip address
 | 
			
		||||
    """
 | 
			
		||||
    try:
 | 
			
		||||
        socket.inet_pton(socket.AF_INET6, ip)
 | 
			
		||||
    except socket.error:  # it's IPv4
 | 
			
		||||
        return ip
 | 
			
		||||
    else:
 | 
			
		||||
        return '[%s]' % ip
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,8 @@ from eventlet.support.greenlets import GreenletExit
 | 
			
		||||
 | 
			
		||||
from swift.common.ring import Ring
 | 
			
		||||
from swift.common.utils import whataremyips, unlink_older_than, lock_path, \
 | 
			
		||||
        compute_eta, get_logger, write_pickle, renamer, dump_recon_cache
 | 
			
		||||
        compute_eta, get_logger, write_pickle, renamer, dump_recon_cache, \
 | 
			
		||||
        rsync_ip
 | 
			
		||||
from swift.common.bufferedhttp import http_connect
 | 
			
		||||
from swift.common.daemon import Daemon
 | 
			
		||||
from swift.common.http import HTTP_OK, HTTP_INSUFFICIENT_STORAGE
 | 
			
		||||
@@ -315,10 +316,11 @@ class ObjectReplicator(Daemon):
 | 
			
		||||
            '--timeout=%s' % self.rsync_io_timeout,
 | 
			
		||||
            '--contimeout=%s' % self.rsync_io_timeout,
 | 
			
		||||
        ]
 | 
			
		||||
        node_ip = rsync_ip(node['ip'])
 | 
			
		||||
        if self.vm_test_mode:
 | 
			
		||||
            rsync_module = '[%s]::object%s' % (node['ip'], node['port'])
 | 
			
		||||
            rsync_module = '%s::object%s' % (node_ip, node['port'])
 | 
			
		||||
        else:
 | 
			
		||||
            rsync_module = '[%s]::object' % node['ip']
 | 
			
		||||
            rsync_module = '%s::object' % node_ip
 | 
			
		||||
        had_any = False
 | 
			
		||||
        for suffix in suffixes:
 | 
			
		||||
            spath = join(job['path'], suffix)
 | 
			
		||||
 
 | 
			
		||||
@@ -860,6 +860,18 @@ log_name = %(yarr)s'''
 | 
			
		||||
        self.assertFalse(utils.streq_const_time('a', 'aaaaa'))
 | 
			
		||||
        self.assertFalse(utils.streq_const_time('ABC123', 'abc123'))
 | 
			
		||||
 | 
			
		||||
    def test_rsync_ip_ipv4_localhost(self):
 | 
			
		||||
        self.assertEqual(utils.rsync_ip('127.0.0.1'), '127.0.0.1')
 | 
			
		||||
 | 
			
		||||
    def test_rsync_ip_ipv6_random_ip(self):
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            utils.rsync_ip('fe80:0000:0000:0000:0202:b3ff:fe1e:8329'),
 | 
			
		||||
            '[fe80:0000:0000:0000:0202:b3ff:fe1e:8329]')
 | 
			
		||||
 | 
			
		||||
    def test_rsync_ip_ipv6_ipv4_compatible(self):
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            utils.rsync_ip('::ffff:192.0.2.128'), '[::ffff:192.0.2.128]')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestStatsdLogging(unittest.TestCase):
 | 
			
		||||
    def test_get_logger_statsd_client_not_specified(self):
 | 
			
		||||
 
 | 
			
		||||
@@ -118,8 +118,10 @@ def _create_test_ring(path):
 | 
			
		||||
        {'id': 2, 'device': 'sda', 'zone': 2, 'ip': '127.0.0.2', 'port': 6000},
 | 
			
		||||
        {'id': 3, 'device': 'sda', 'zone': 4, 'ip': '127.0.0.3', 'port': 6000},
 | 
			
		||||
        {'id': 4, 'device': 'sda', 'zone': 5, 'ip': '127.0.0.4', 'port': 6000},
 | 
			
		||||
        {'id': 5, 'device': 'sda', 'zone': 6, 'ip': '127.0.0.5', 'port': 6000},
 | 
			
		||||
        {'id': 6, 'device': 'sda', 'zone': 7, 'ip': '127.0.0.6', 'port': 6000},
 | 
			
		||||
        {'id': 5, 'device': 'sda', 'zone': 6,
 | 
			
		||||
         'ip': 'fe80::202:b3ff:fe1e:8329', 'port': 6000},
 | 
			
		||||
        {'id': 6, 'device': 'sda', 'zone': 7,
 | 
			
		||||
         'ip': '2001:0db8:85a3:0000:0000:8a2e:0370:7334', 'port': 6000},
 | 
			
		||||
        ]
 | 
			
		||||
    intended_part_shift = 30
 | 
			
		||||
    intended_reload_time = 15
 | 
			
		||||
@@ -180,7 +182,7 @@ class TestObjectReplicator(unittest.TestCase):
 | 
			
		||||
                 self.ring.get_part_nodes(int(cur_part)) \
 | 
			
		||||
                     if node['ip'] not in _ips()]
 | 
			
		||||
        for node in nodes:
 | 
			
		||||
            rsync_mod = '[%s]::object/sda/objects/%s' % (node['ip'], cur_part)
 | 
			
		||||
            rsync_mod = '%s::object/sda/objects/%s' % (node['ip'], cur_part)
 | 
			
		||||
            process_arg_checker.append(
 | 
			
		||||
                (0, '', ['rsync', whole_path_from, rsync_mod]))
 | 
			
		||||
        with _mock_process(process_arg_checker):
 | 
			
		||||
@@ -387,8 +389,8 @@ class TestObjectReplicator(unittest.TestCase):
 | 
			
		||||
                     self.ring.get_part_nodes(int(cur_part)) \
 | 
			
		||||
                         if node['ip'] not in _ips()]
 | 
			
		||||
            for node in nodes:
 | 
			
		||||
                rsync_mod = '[%s]::object/sda/objects/%s' % (node['ip'],
 | 
			
		||||
                                                             cur_part)
 | 
			
		||||
                rsync_mod = '%s::object/sda/objects/%s' % (node['ip'],
 | 
			
		||||
                                                           cur_part)
 | 
			
		||||
                process_arg_checker.append(
 | 
			
		||||
                    (0, '', ['rsync', whole_path_from, rsync_mod]))
 | 
			
		||||
            self.assertTrue(os.access(os.path.join(self.objects,
 | 
			
		||||
@@ -451,8 +453,8 @@ class TestObjectReplicator(unittest.TestCase):
 | 
			
		||||
                     self.ring.get_part_nodes(int(cur_part)) \
 | 
			
		||||
                         if node['ip'] not in _ips()]
 | 
			
		||||
            for node in nodes:
 | 
			
		||||
                rsync_mod = '[%s]::object/sda/objects/%s' % (node['ip'],
 | 
			
		||||
                                                             cur_part)
 | 
			
		||||
                rsync_mod = '%s::object/sda/objects/%s' % (node['ip'],
 | 
			
		||||
                                                           cur_part)
 | 
			
		||||
                process_arg_checker.append(
 | 
			
		||||
                    (0, '', ['rsync', whole_path_from, rsync_mod]))
 | 
			
		||||
            self.assertTrue(os.access(os.path.join(self.objects,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user