コード例 #1
0
    def __init__(self, conf, logger, servers_per_port):
        self.conf = conf
        self.logger = logger
        self.servers_per_port = servers_per_port
        self.swift_dir = conf.get('swift_dir', '/etc/swift')
        self.ring_check_interval = int(conf.get('ring_check_interval', 15))
        self.port_pid_state = PortPidState(servers_per_port, logger)

        bind_ip = conf.get('bind_ip', '0.0.0.0')
        self.cache = BindPortsCache(self.swift_dir, bind_ip)
コード例 #2
0
    def test_bind_ports_cache(self):
        test_policies = [
            StoragePolicy(0, 'aay', True),
            StoragePolicy(1, 'bee', False),
            StoragePolicy(2, 'cee', False)
        ]

        my_ips = ['1.2.3.4', '2.3.4.5']
        other_ips = ['3.4.5.6', '4.5.6.7']
        bind_ip = my_ips[1]
        devs_by_ring_name1 = {
            'object': [  # 'aay'
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': my_ips[0],
                    'port': 6006
                }, {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': other_ips[0],
                    'port': 6007
                }, {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': my_ips[1],
                    'port': 6008
                }, None, {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': other_ips[1],
                    'port': 6009
                }
            ],
            'object-1': [  # 'bee'
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': my_ips[1],
                    'port': 6006
                },  # dupe
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': other_ips[0],
                    'port': 6010
                },
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': my_ips[1],
                    'port': 6011
                },
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': other_ips[1],
                    'port': 6012
                }
            ],
            'object-2': [  # 'cee'
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': my_ips[0],
                    'port': 6010
                },  # on our IP and a not-us IP
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': other_ips[0],
                    'port': 6013
                },
                None,
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': my_ips[1],
                    'port': 6014
                },
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': other_ips[1],
                    'port': 6015
                }
            ],
        }
        devs_by_ring_name2 = {
            'object': [  # 'aay'
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': my_ips[0],
                    'port': 6016
                }, {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': other_ips[1],
                    'port': 6019
                }
            ],
            'object-1': [  # 'bee'
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': my_ips[1],
                    'port': 6016
                },  # dupe
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': other_ips[1],
                    'port': 6022
                }
            ],
            'object-2': [  # 'cee'
                {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': my_ips[0],
                    'port': 6020
                }, {
                    'id': 0,
                    'zone': 0,
                    'region': 1,
                    'ip': other_ips[1],
                    'port': 6025
                }
            ],
        }
        ring_files = [
            ring_name + '.ring.gz' for ring_name in sorted(devs_by_ring_name1)
        ]

        def _fake_load(gz_path, stub_objs, metadata_only=False):
            return RingData(devs=stub_objs[os.path.basename(gz_path)[:-8]],
                            replica2part2dev_id=[],
                            part_shift=24)

        with mock.patch(
            'swift.common.storage_policy.RingData.load'
        ) as mock_ld, \
                patch_policies(test_policies), \
                mock.patch('swift.common.storage_policy.whataremyips') \
                as mock_whataremyips, \
                temptree(ring_files) as tempdir:
            mock_whataremyips.return_value = my_ips

            cache = BindPortsCache(tempdir, bind_ip)

            self.assertEqual([
                mock.call(bind_ip),
            ], mock_whataremyips.mock_calls)
            mock_whataremyips.reset_mock()

            mock_ld.side_effect = partial(_fake_load,
                                          stub_objs=devs_by_ring_name1)
            self.assertEqual(set([
                6006,
                6008,
                6011,
                6010,
                6014,
            ]), cache.all_bind_ports_for_node())
            self.assertEqual([
                mock.call(os.path.join(tempdir, ring_files[0]),
                          metadata_only=True),
                mock.call(os.path.join(tempdir, ring_files[1]),
                          metadata_only=True),
                mock.call(os.path.join(tempdir, ring_files[2]),
                          metadata_only=True),
            ], mock_ld.mock_calls)
            mock_ld.reset_mock()

            mock_ld.side_effect = partial(_fake_load,
                                          stub_objs=devs_by_ring_name2)
            self.assertEqual(set([
                6006,
                6008,
                6011,
                6010,
                6014,
            ]), cache.all_bind_ports_for_node())
            self.assertEqual([], mock_ld.mock_calls)

            # but when all the file mtimes are made different, it'll
            # reload
            for gz_file in [os.path.join(tempdir, n) for n in ring_files]:
                os.utime(gz_file, (88, 88))

            self.assertEqual(set([
                6016,
                6020,
            ]), cache.all_bind_ports_for_node())
            self.assertEqual([
                mock.call(os.path.join(tempdir, ring_files[0]),
                          metadata_only=True),
                mock.call(os.path.join(tempdir, ring_files[1]),
                          metadata_only=True),
                mock.call(os.path.join(tempdir, ring_files[2]),
                          metadata_only=True),
            ], mock_ld.mock_calls)
            mock_ld.reset_mock()

            # Don't do something stupid like crash if a ring file is missing.
            os.unlink(os.path.join(tempdir, 'object-2.ring.gz'))

            self.assertEqual(set([
                6016,
                6020,
            ]), cache.all_bind_ports_for_node())
            self.assertEqual([], mock_ld.mock_calls)

        # whataremyips() is only called in the constructor
        self.assertEqual([], mock_whataremyips.mock_calls)