Пример #1
0
    def preprocess(self, args):
        """Preprocess arguments provided for `docker network create`"""
        pool = {}

        # subnet
        pool["subnet"] = args["subnet"]
        del args["subnet"]

        # iprange
        pool["iprange"] = args["iprange"]
        del args["iprange"]

        # gateway
        pool["gateway"] = args["gateway"]
        del args["gateway"]

        # create ipam
        ipam_pool = IPAMPool(**pool)
        ipam_config = IPAMConfig(
            driver=args["ipamdriver"],
            pool_configs=[ipam_pool],
            options=dict(args["ipamopt"]) if args["ipamopt"] else None)
        del args["ipamdriver"]
        del args["ipamopt"]
        if "None" in str(ipam_config):
            return None
        else:
            return ipam_config
Пример #2
0
    def test_create_with_ipv6_address(self):
        net_name, net_id = self.create_network(
            ipam=IPAMConfig(
                driver='default',
                pool_configs=[IPAMPool(subnet='2001:389::1/64')],
            ),
        )
        container = self.client.create_container(
            image=BUSYBOX, command='top',
            host_config=self.client.create_host_config(network_mode=net_name),
            networking_config=self.client.create_networking_config({
                net_name: self.client.create_endpoint_config(
                    ipv6_address='2001:389::f00d'
                )
            })
        )
        self.tmp_containers.append(container)
        self.client.start(container)

        container_data = self.client.inspect_container(container)
        self.assertEqual(
            container_data[
                'NetworkSettings']['Networks'][net_name]['IPAMConfig'][
                'IPv6Address'
            ],
            '2001:389::f00d'
        )
Пример #3
0
    def test_create_network_with_ipam_config(self):
        _, net_id = self.create_network(ipam=IPAMConfig(
            driver='default',
            pool_configs=[
                IPAMPool(
                    subnet="172.28.0.0/16",
                    iprange="172.28.5.0/24",
                    gateway="172.28.5.254",
                    aux_addresses={
                        "a": "172.28.1.5",
                        "b": "172.28.1.6",
                        "c": "172.28.1.7",
                    },
                ),
            ],
        ), )

        net = self.client.inspect_network(net_id)
        ipam = net['IPAM']

        assert ipam.pop('Options', None) is None

        assert ipam['Driver'] == 'default'

        assert ipam['Config'] == [{
            'Subnet': "172.28.0.0/16",
            'IPRange': "172.28.5.0/24",
            'Gateway': "172.28.5.254",
            'AuxiliaryAddresses': {
                "a": "172.28.1.5",
                "b": "172.28.1.6",
                "c": "172.28.1.7",
            },
        }]
Пример #4
0
def create_network(dc: DockerClient) -> Network:
    """


    """
    networks = dc.networks.list()
    for network in networks:
        if network.name == PROXY_BENCH_NET_NAME:
            logger.info(f"Network '{PROXY_BENCH_NET_NAME}' already exists, skipping creation.")
            return network

    ipam_pool = IPAMPool(
        subnet="172.0.10.0/24",
        gateway="172.0.10.1"
    )

    ipam_config = IPAMConfig(
        pool_configs=[ipam_pool]
    )

    network = dc.networks.create(
        name=PROXY_BENCH_NET_NAME,
        driver="bridge",
        ipam=ipam_config
    )

    logger.info(f"Created '{PROXY_BENCH_NET_NAME}' network.")
    return network
Пример #5
0
    def test_connect_with_ipv4_address(self):
        net_name, net_id = self.create_network(
            ipam=IPAMConfig(
                driver='default',
                pool_configs=[
                    IPAMPool(
                        subnet="172.28.0.0/16", iprange="172.28.5.0/24",
                        gateway="172.28.5.254"
                    )
                ]
            )
        )

        container = self.create_and_start(
            host_config=self.client.create_host_config(network_mode=net_name))

        self.client.disconnect_container_from_network(container, net_name)
        self.client.connect_container_to_network(
            container, net_name, ipv4_address='172.28.5.24'
        )

        container_data = self.client.inspect_container(container)
        net_data = container_data['NetworkSettings']['Networks'][net_name]
        self.assertEqual(
            net_data['IPAMConfig']['IPv4Address'], '172.28.5.24'
        )
Пример #6
0
    def create_network(self):
        if not self.existing_network:
            params = dict(
                driver=self.parameters.driver,
                options=self.parameters.driver_options,
            )

            ipam_pools = []
            if self.parameters.ipam_config:
                for ipam_pool in self.parameters.ipam_config:
                    if HAS_DOCKER_PY_2 or HAS_DOCKER_PY_3:
                        ipam_pools.append(IPAMPool(**ipam_pool))
                    else:
                        ipam_pools.append(utils.create_ipam_pool(**ipam_pool))

            if HAS_DOCKER_PY_2 or HAS_DOCKER_PY_3:
                params['ipam'] = IPAMConfig(driver=self.parameters.ipam_driver,
                                            pool_configs=ipam_pools)
            else:
                params['ipam'] = utils.create_ipam_config(driver=self.parameters.ipam_driver,
                                                          pool_configs=ipam_pools)

            if self.parameters.enable_ipv6 is not None:
                params['enable_ipv6'] = self.parameters.enable_ipv6
            if self.parameters.internal is not None:
                params['internal'] = self.parameters.internal

            if not self.check_mode:
                resp = self.client.create_network(self.parameters.network_name, **params)

                self.existing_network = self.client.inspect_network(resp['Id'])
            self.results['actions'].append("Created network %s with driver %s" % (self.parameters.network_name, self.parameters.driver))
            self.results['changed'] = True
Пример #7
0
    def create_network(self):
        if not self.existing_network:
            ipam_pools = []
            if self.parameters.ipam_options:
                if HAS_DOCKER_PY_2:
                    ipam_pools.append(IPAMPool(**self.parameters.ipam_options))
                else:
                    ipam_pools.append(
                        utils.create_ipam_pool(**self.parameters.ipam_options))

            if HAS_DOCKER_PY_2:
                ipam_config = IPAMConfig(driver=self.parameters.ipam_driver,
                                         pool_configs=ipam_pools)
            else:
                ipam_config = utils.create_ipam_config(
                    driver=self.parameters.ipam_driver,
                    pool_configs=ipam_pools)

            if not self.check_mode:
                resp = self.client.create_network(
                    self.parameters.network_name,
                    driver=self.parameters.driver,
                    options=self.parameters.driver_options,
                    ipam=ipam_config)

                self.existing_network = self.client.inspect_network(resp['Id'])
            self.results['actions'].append(
                "Created network %s with driver %s" %
                (self.parameters.network_name, self.parameters.driver))
            self.results['changed'] = True
Пример #8
0
    def test_connect_with_ipv6_address(self):
        net_name, net_id = self.create_network(
            ipam=IPAMConfig(
                driver='default',
                pool_configs=[
                    IPAMPool(
                        subnet='2001:389::1/64', iprange='2001:389::0/96',
                        gateway='2001:389::ffff'
                    )
                ]
            )
        )

        container = self.create_and_start(
            host_config=self.client.create_host_config(network_mode=net_name))

        self.client.disconnect_container_from_network(container, net_name)
        self.client.connect_container_to_network(
            container, net_name, ipv6_address='2001:389::f00d'
        )

        container_data = self.client.inspect_container(container)
        net_data = container_data['NetworkSettings']['Networks'][net_name]
        self.assertEqual(
            net_data['IPAMConfig']['IPv6Address'], '2001:389::f00d'
        )
Пример #9
0
def resolve_create_network(*_, input):
    name = input.get("name")
    labels = kv_to_dict(input.get("labels"))
    internal = input.get("internal")
    pool_configs = []
    ipams = input.get("ipams", [])
    ipam = None
    if ipams:
        pool_configs = []
        for entry in ipams:
            pool_configs.append(
                IPAMPool(
                    entry.get("subnet", None),
                    entry.get("ipRange", None),
                    entry.get("gateway", None),
                ))
        ipam = IPAMConfig(pool_configs)

    try:
        docker_client.networks.create(
            name,
            check_duplicate=True,
            labels=labels,
            driver="bridge",
            internal=internal,
            ipam=ipam,
        )
    except APIError as e:
        raise PMException(e.explanation)
    except Exception as e:
        raise PMException(str(e))
Пример #10
0
    def test_create_network(self):
        network_data = {
            'id': 'abc12345',
            'warning': '',
        }

        network_response = response(status_code=200, content=network_data)
        post = mock.Mock(return_value=network_response)

        with mock.patch('docker.api.client.APIClient.post', post):
            result = self.client.create_network('foo')
            self.assertEqual(result, network_data)

            self.assertEqual(post.call_args[0][0],
                             url_prefix + 'networks/create')

            self.assertEqual(json.loads(post.call_args[1]['data']), {
                'CheckDuplicate': True,
                'Name': 'foo'
            })

            opts = {
                'com.docker.network.bridge.enable_icc': False,
                'com.docker.network.bridge.enable_ip_masquerade': False,
            }
            self.client.create_network('foo', 'bridge', opts)

            self.assertEqual(
                json.loads(post.call_args[1]['data']), {
                    'CheckDuplicate': True,
                    'Name': 'foo',
                    'Driver': 'bridge',
                    'Options': opts
                })

            ipam_pool_config = IPAMPool(subnet='192.168.52.0/24',
                                        gateway='192.168.52.254')
            ipam_config = IPAMConfig(pool_configs=[ipam_pool_config])

            self.client.create_network('bar',
                                       driver='bridge',
                                       ipam=ipam_config)

            self.assertEqual(
                json.loads(post.call_args[1]['data']), {
                    'CheckDuplicate': True,
                    'Name': 'bar',
                    'Driver': 'bridge',
                    'IPAM': {
                        'Driver':
                        'default',
                        'Config': [{
                            'IPRange': None,
                            'Gateway': '192.168.52.254',
                            'Subnet': '192.168.52.0/24',
                            'AuxiliaryAddresses': None,
                        }],
                    }
                })
Пример #11
0
 def create_network(self, name, interface, subnet, gw, labels=None):
     options = {'parent': interface}
     ipam_pool = IPAMPool(subnet=subnet, gateway=gw)
     ipam_config = IPAMConfig(pool_configs=[ipam_pool])
     return self._client.create_network(name,
                                        driver='macvlan',
                                        options=options,
                                        ipam=ipam_config,
                                        labels=labels)
Пример #12
0
 def create_docker_network(self):
     name = self.network_name
     try:
         network = self.client.networks.get(name)
         return network
     except NotFound:
         pass
     ipam_pool = self.get_network_ipam_pool()
     ipam_config = IPAMConfig(pool_configs=[ipam_pool])
     network = self.client.networks.create(name, driver="bridge", ipam=ipam_config)
     return network
Пример #13
0
    def test_create_network(self):
        network_data = {
            "id": 'abc12345',
            "warning": "",
        }

        network_response = response(status_code=200, content=network_data)
        post = mock.Mock(return_value=network_response)

        with mock.patch('docker.api.client.APIClient.post', post):
            result = self.client.create_network('foo')
            self.assertEqual(result, network_data)

            self.assertEqual(post.call_args[0][0],
                             url_prefix + 'networks/create')

            self.assertEqual(json.loads(post.call_args[1]['data']),
                             {"Name": "foo"})

            opts = {
                'com.docker.network.bridge.enable_icc': False,
                'com.docker.network.bridge.enable_ip_masquerade': False,
            }
            self.client.create_network('foo', 'bridge', opts)

            self.assertEqual(json.loads(post.call_args[1]['data']), {
                "Name": "foo",
                "Driver": "bridge",
                "Options": opts
            })

            ipam_pool_config = IPAMPool(subnet="192.168.52.0/24",
                                        gateway="192.168.52.254")
            ipam_config = IPAMConfig(pool_configs=[ipam_pool_config])

            self.client.create_network("bar",
                                       driver="bridge",
                                       ipam=ipam_config)

            self.assertEqual(
                json.loads(post.call_args[1]['data']), {
                    "Name": "bar",
                    "Driver": "bridge",
                    "IPAM": {
                        "Driver":
                        "default",
                        "Config": [{
                            "IPRange": None,
                            "Gateway": "192.168.52.254",
                            "Subnet": "192.168.52.0/24",
                            "AuxiliaryAddresses": None,
                        }],
                    }
                })
Пример #14
0
 def test_create_network_ipv6_enabled(self):
     _, net_id = self.create_network(
         enable_ipv6=True,
         ipam=IPAMConfig(driver='default',
                         pool_configs=[
                             IPAMPool(subnet="2001:389::1/64",
                                      iprange="2001:389::0/96",
                                      gateway="2001:389::ffff")
                         ]))
     net = self.client.inspect_network(net_id)
     assert net['EnableIPv6'] is True
Пример #15
0
def _ipam_config():
    for octet in xrange(16, 31):
        subnet = "172.%d.0.0/16" % octet
        try:
            ipam_pool = IPAMPool(subnet=subnet)
            ipam_config = IPAMConfig(pool_configs=[ipam_pool])
            return ipam_config
        except APIError as err:
            if err.status_code == 409:
                LOG.info('Subnet %s already exists', subnet)
                continue
            else:
                raise
Пример #16
0
    def create_network(self):
        if not self.existing_network:
            params = dict(
                driver=self.parameters.driver,
                options=self.parameters.driver_options,
            )

            ipam_pools = []
            if self.parameters.ipam_config:
                for ipam_pool in self.parameters.ipam_config:
                    if LooseVersion(docker_version) >= LooseVersion('2.0.0'):
                        ipam_pools.append(IPAMPool(**ipam_pool))
                    else:
                        ipam_pools.append(utils.create_ipam_pool(**ipam_pool))

            if self.parameters.ipam_driver or self.parameters.ipam_driver_options or ipam_pools:
                # Only add ipam parameter if a driver was specified or if IPAM parameters
                # were specified. Leaving this parameter away can significantly speed up
                # creation; on my machine creation with this option needs ~15 seconds,
                # and without just a few seconds.
                if LooseVersion(docker_version) >= LooseVersion('2.0.0'):
                    params['ipam'] = IPAMConfig(
                        driver=self.parameters.ipam_driver,
                        pool_configs=ipam_pools,
                        options=self.parameters.ipam_driver_options)
                else:
                    params['ipam'] = utils.create_ipam_config(
                        driver=self.parameters.ipam_driver,
                        pool_configs=ipam_pools)

            if self.parameters.enable_ipv6 is not None:
                params['enable_ipv6'] = self.parameters.enable_ipv6
            if self.parameters.internal is not None:
                params['internal'] = self.parameters.internal
            if self.parameters.scope is not None:
                params['scope'] = self.parameters.scope
            if self.parameters.attachable is not None:
                params['attachable'] = self.parameters.attachable
            if self.parameters.labels:
                params['labels'] = self.parameters.labels

            if not self.check_mode:
                resp = self.client.create_network(self.parameters.name,
                                                  **params)
                self.client.report_warnings(resp, ['Warning'])
                self.existing_network = self.client.get_network(
                    network_id=resp['Id'])
            self.results['actions'].append(
                "Created network %s with driver %s" %
                (self.parameters.name, self.parameters.driver))
            self.results['changed'] = True
Пример #17
0
def create_ipam_config_from_dict(ipam_dict):
    if not ipam_dict:
        return None

    return IPAMConfig(driver=ipam_dict.get('driver'),
                      pool_configs=[
                          IPAMPool(
                              subnet=config.get('subnet'),
                              iprange=config.get('ip_range'),
                              gateway=config.get('gateway'),
                              aux_addresses=config.get('aux_addresses'),
                          ) for config in ipam_dict.get('config', [])
                      ],
                      options=ipam_dict.get('options'))
Пример #18
0
 def create(self, replace=False):
     config = self._config
     pool = IPAMPool(
         subnet=config['subnet'],
         iprange=config['ip_range'],
         gateway=config['gateway'],
     )
     ipam_config = IPAMConfig(pool_configs=[pool])
     self._network = self._client.networks.create(
         name=config['bridge_name'],
         driver=config['driver'],
         ipam=ipam_config)
     self._logger.complete(config['bridge_name'], 'network created')
     return self
    def network(self, switchname, network=None, contname=None):
        c = self.getAPI().api
        result = dict()
        try:
            # check container id
            for case in switch(switchname):
                if case("prune"):
                    result["result"] = c.prune_networks()
                    break
                if network is None:
                    raise ValueError("value error!")
                if case("create"):
                    result["result"] = c.create_network(
                        driver="overlay",
                        internal=False,
                        attachable=True,
                        enable_ipv6=False,
                        name=network,
                        ipam=IPAMConfig(
                            pool_configs=[IPAMPool(subnet="192.168.0.0/24")]),
                        scope="swarm")
                    break
                if case("remove"):
                    result["result"] = c.remove_network(net_id=network)
                    break
                if contname is None:
                    raise ValueError("value error!")
                if case("connect"):
                    result["result"] = c.connect_container_to_network(
                        container=contname, net_id=network)
                    break
                if case("disconnect"):
                    result["result"] = c.disconnect_container_from_network(
                        container=contname, net_id=network)
                    break
            result["success"] = True

        except Exception:
            result["success"] = False
            result["result"] = traceback.format_exc()

            if "No such network" in result["result"]:
                httpResponse.print404("network is not found", action="network")
            elif "Not Found for url" in result["result"]:
                httpResponse.print404("NotFound;", action="network")
            if "swarm is not active" in result["result"]:
                httpResponse.print500("SwarmDown;", action="network")
            return result
        result["success"] = True
        return result
Пример #20
0
    def test_create_ipam_config(self):
        ipam_pool = IPAMPool(subnet='192.168.52.0/24',
                             gateway='192.168.52.254')

        ipam_config = IPAMConfig(pool_configs=[ipam_pool])
        assert ipam_config == {
            'Driver': 'default',
            'Config': [{
                'Subnet': '192.168.52.0/24',
                'Gateway': '192.168.52.254',
                'AuxiliaryAddresses': None,
                'IPRange': None,
            }]
        }
Пример #21
0
def get_network_interface(client):
    name = 'devops_network'
    nets = client.networks.list(names=[name])

    for n in nets:
        if (n.name == name):
            return n

    print('Creating name network interface: %s' % name)
    ipam_pool = IPAMPool(
        subnet='124.25.0.0/16',
        iprange='124.25.0.0/24',
        gateway='124.25.0.254',
    )
    ipam_config = IPAMConfig(driver='default', pool_configs=[ipam_pool])
    return client.networks.create(name, driver="bridge", ipam=ipam_config)
Пример #22
0
def container_network():
    client = docker_client()
    api = client.api

    network_name = 'test_network'

    ipam_pool = IPAMPool(subnet="172.25.0.0/16")
    ipam_config = IPAMConfig(pool_configs=[ipam_pool])

    network = api.create_network(name=network_name,
                                 driver="bridge",
                                 ipam=ipam_config)

    yield network_name

    api.remove_network(net_id=network['Id'])
Пример #23
0
    def create_network(self):
        if not self.existing_network:
            params = dict(
                driver=self.parameters.driver,
                options=self.parameters.driver_options,
            )

            ipam_pools = []
            if self.parameters.ipam_config:
                for ipam_pool in self.parameters.ipam_config:
                    if HAS_DOCKER_PY_2 or HAS_DOCKER_PY_3:
                        ipam_pools.append(IPAMPool(**ipam_pool))
                    else:
                        ipam_pools.append(utils.create_ipam_pool(**ipam_pool))

            if self.parameters.ipam_driver or ipam_pools:
                # Only add ipam parameter if a driver was specified or if IPAM parameters
                # were specified. Leaving this parameter away can significantly speed up
                # creation; on my machine creation with this option needs ~15 seconds,
                # and without just a few seconds.
                if HAS_DOCKER_PY_2 or HAS_DOCKER_PY_3:
                    params['ipam'] = IPAMConfig(
                        driver=self.parameters.ipam_driver,
                        pool_configs=ipam_pools)
                else:
                    params['ipam'] = utils.create_ipam_config(
                        driver=self.parameters.ipam_driver,
                        pool_configs=ipam_pools)

            if self.parameters.enable_ipv6 is not None:
                params['enable_ipv6'] = self.parameters.enable_ipv6
            if self.parameters.internal is not None:
                params['internal'] = self.parameters.internal

            if not self.check_mode:
                resp = self.client.create_network(self.parameters.network_name,
                                                  **params)

                self.existing_network = self.client.inspect_network(resp['Id'])
            self.results['actions'].append(
                "Created network %s with driver %s" %
                (self.parameters.network_name, self.parameters.driver))
            self.results['changed'] = True
Пример #24
0
    def test_create_with_ipv4_address(self):
        net_name, net_id = self.create_network(ipam=IPAMConfig(
            driver='default',
            pool_configs=[IPAMPool(subnet="132.124.0.0/16")],
        ), )
        container = self.client.create_container(
            image='busybox',
            command='top',
            host_config=self.client.create_host_config(network_mode=net_name),
            networking_config=self.client.create_networking_config({
                net_name:
                self.client.create_endpoint_config(ipv4_address='132.124.0.23')
            }))
        self.tmp_containers.append(container)
        self.client.start(container)

        container_data = self.client.inspect_container(container)
        self.assertEqual(
            container_data['NetworkSettings']['Networks'][net_name]
            ['IPAMConfig']['IPv4Address'], '132.124.0.23')
Пример #25
0
def docker_network_add(name):
    cli = get_docker_client(DOCKER_BASE_URL)
    ipam_pool = IPAMPool(subnet=CALICO_NETWORK)
    ipam_config = IPAMConfig(driver="calico-ipam", pool_configs=[ipam_pool])
    result = cli.create_network(name, driver="calico", ipam=ipam_config)
    logger.info("create docker network for app %s : %s" % (name, result))
Пример #26
0
def get_subnet():
    return IPAMConfig(
        pool_configs=[IPAMPool(subnet=Config.available_subnets.pop())])
Пример #27
0
def bench(args):
    config_dir = '{0}/{1}'.format(args.dir, args.bench_name)
    dckr_net_name = args.docker_network_name or args.bench_name + '-br'

    for target_class in [BIRDTarget, GoBGPTarget, QuaggaTarget]:
        if ctn_exists(target_class.CONTAINER_NAME):
            print 'removing target container', target_class.CONTAINER_NAME
            dckr.remove_container(target_class.CONTAINER_NAME, force=True)

    if not args.repeat:
        if ctn_exists(Monitor.CONTAINER_NAME):
            print 'removing monitor container', Monitor.CONTAINER_NAME
            dckr.remove_container(Monitor.CONTAINER_NAME, force=True)

        for ctn_name in get_ctn_names():
            if ctn_name.startswith(ExaBGPTester.CONTAINER_NAME_PREFIX) or \
                ctn_name.startswith(ExaBGPMrtTester.CONTAINER_NAME_PREFIX) or \
                ctn_name.startswith(GoBGPMRTTester.CONTAINER_NAME_PREFIX):
                print 'removing tester container', ctn_name
                dckr.remove_container(ctn_name, force=True)

        if os.path.exists(config_dir):
            shutil.rmtree(config_dir)

    if args.file:
        with open(args.file) as f:
            conf = yaml.load(Template(f.read()).render())
    else:
        conf = gen_conf(args)
        if not os.path.exists(config_dir):
            os.makedirs(config_dir)
        with open('{0}/scenario.yaml'.format(config_dir), 'w') as f:
            f.write(conf)
        conf = yaml.load(Template(conf).render())

    bridge_found = False
    for network in dckr.networks(names=[dckr_net_name]):
        if network['Name'] == dckr_net_name:
            print 'Docker network "{}" already exists'.format(dckr_net_name)
            bridge_found = True
            break
    if not bridge_found:
        subnet = conf['local_prefix']
        print 'creating Docker network "{}" with subnet {}'.format(
            dckr_net_name, subnet)
        ipam = IPAMConfig(pool_configs=[IPAMPool(subnet=subnet)])
        network = dckr.create_network(dckr_net_name,
                                      driver='bridge',
                                      ipam=ipam)

    num_tester = sum(
        len(t.get('neighbors', [])) for t in conf.get('testers', []))
    if num_tester > gc_thresh3():
        print 'gc_thresh3({0}) is lower than the number of peer({1})'.format(
            gc_thresh3(), num_tester)
        print 'type next to increase the value'
        print '$ echo 16384 | sudo tee /proc/sys/net/ipv4/neigh/default/gc_thresh3'

    print 'run monitor'
    m = Monitor(config_dir + '/monitor', conf['monitor'])
    m.run(conf, dckr_net_name)

    is_remote = True if 'remote' in conf['target'] and conf['target'][
        'remote'] else False

    if is_remote:
        print 'target is remote ({})'.format(conf['target']['local-address'])

        ip = IPRoute()

        # r: route to the target
        r = ip.get_routes(dst=conf['target']['local-address'], family=AF_INET)
        if len(r) == 0:
            print 'no route to remote target {0}'.format(
                conf['target']['local-address'])
            sys.exit(1)

        # intf: interface used to reach the target
        idx = [t[1] for t in r[0]['attrs'] if t[0] == 'RTA_OIF'][0]
        intf = ip.get_links(idx)[0]
        intf_name = intf.get_attr('IFLA_IFNAME')

        # raw_bridge_name: Linux bridge name of the Docker bridge
        # TODO: not sure if the linux bridge name is always given by
        #       "br-<first 12 characters of Docker network ID>".
        raw_bridge_name = args.bridge_name or 'br-{}'.format(
            network['Id'][0:12])

        # raw_bridges: list of Linux bridges that match raw_bridge_name
        raw_bridges = ip.link_lookup(ifname=raw_bridge_name)
        if len(raw_bridges) == 0:
            if not args.bridge_name:
                print(
                    'can\'t determine the Linux bridge interface name starting '
                    'from the Docker network {}'.format(dckr_net_name))
            else:
                print('the Linux bridge name provided ({}) seems nonexistent'.
                      format(raw_bridge_name))
            print(
                'Since the target is remote, the host interface used to '
                'reach the target ({}) must be part of the Linux bridge '
                'used by the Docker network {}, but without the correct Linux '
                'bridge name it\'s impossible to verify if that\'s true'.
                format(intf_name, dckr_net_name))
            if not args.bridge_name:
                print(
                    'Please supply the Linux bridge name corresponding to the '
                    'Docker network {} using the --bridge-name argument.'.
                    format(dckr_net_name))
            sys.exit(1)

        # intf_bridge: bridge interface that intf is already member of
        intf_bridge = intf.get_attr('IFLA_MASTER')

        # if intf is not member of the bridge, add it
        if intf_bridge not in raw_bridges:
            if intf_bridge is None:
                print(
                    'Since the target is remote, the host interface used to '
                    'reach the target ({}) must be part of the Linux bridge '
                    'used by the Docker network {}'.format(
                        intf_name, dckr_net_name))
                sys.stdout.write('Do you confirm to add the interface {} '
                                 'to the bridge {}? [yes/NO] '.format(
                                     intf_name, raw_bridge_name))
                try:
                    answer = raw_input()
                except:
                    print 'aborting'
                    sys.exit(1)
                answer = answer.strip()
                if answer.lower() != 'yes':
                    print 'aborting'
                    sys.exit(1)

                print 'adding interface {} to the bridge {}'.format(
                    intf_name, raw_bridge_name)
                br = raw_bridges[0]

                try:
                    ip.link('set', index=idx, master=br)
                except Exception as e:
                    print('Something went wrong: {}'.format(str(e)))
                    print(
                        'Please consider running the following command to '
                        'add the {iface} interface to the {br} bridge:\n'
                        '   sudo brctl addif {br} {iface}'.format(
                            iface=intf_name, br=raw_bridge_name))
                    print('\n\n\n')
                    raise
            else:
                curr_bridge_name = ip.get_links(intf_bridge)[0].get_attr(
                    'IFLA_IFNAME')
                print(
                    'the interface used to reach the target ({}) '
                    'is already member of the bridge {}, which is not '
                    'the one used in this configuration'.format(
                        intf_name, curr_bridge_name))
                print(
                    'Please consider running the following command to '
                    'remove the {iface} interface from the {br} bridge:\n'
                    '   sudo brctl addif {br} {iface}'.format(
                        iface=intf_name, br=curr_bridge_name))
                sys.exit(1)
    else:
        if args.target == 'gobgp':
            target_class = GoBGPTarget
        elif args.target == 'bird':
            target_class = BIRDTarget
        elif args.target == 'quagga':
            target_class = QuaggaTarget

        print 'run', args.target
        if args.image:
            target = target_class('{0}/{1}'.format(config_dir, args.target),
                                  conf['target'],
                                  image=args.image)
        else:
            target = target_class('{0}/{1}'.format(config_dir, args.target),
                                  conf['target'])
        target.run(conf, dckr_net_name)

    time.sleep(1)

    print 'waiting bgp connection between {0} and monitor'.format(args.target)
    m.wait_established(conf['target']['local-address'])

    if not args.repeat:
        for idx, tester in enumerate(conf['testers']):
            if 'name' not in tester:
                name = 'tester{0}'.format(idx)
            else:
                name = tester['name']
            if 'type' not in tester:
                tester_type = 'normal'
            else:
                tester_type = tester['type']
            if tester_type == 'normal':
                tester_class = ExaBGPTester
            elif tester_type == 'mrt':
                if 'mrt_injector' not in tester:
                    mrt_injector = 'gobgp'
                else:
                    mrt_injector = tester['mrt_injector']
                if mrt_injector == 'gobgp':
                    tester_class = GoBGPMRTTester
                elif mrt_injector == 'exabgp':
                    tester_class = ExaBGPMrtTester
                else:
                    print 'invalid mrt_injector:', mrt_injector
                    sys.exit(1)
            else:
                print 'invalid tester type:', tester_type
                sys.exit(1)
            t = tester_class(name, config_dir + '/' + name, tester)
            print 'run tester', name, 'type', tester_type
            t.run(conf['target'], dckr_net_name)

    start = datetime.datetime.now()

    q = Queue()

    m.stats(q)
    if not is_remote:
        target.stats(q)

    def mem_human(v):
        if v > 1000 * 1000 * 1000:
            return '{0:.2f}GB'.format(float(v) / (1000 * 1000 * 1000))
        elif v > 1000 * 1000:
            return '{0:.2f}MB'.format(float(v) / (1000 * 1000))
        elif v > 1000:
            return '{0:.2f}KB'.format(float(v) / 1000)
        else:
            return '{0:.2f}B'.format(float(v))

    f = open(args.output, 'w') if args.output else None
    cpu = 0
    mem = 0
    cooling = -1
    while True:
        info = q.get()

        if not is_remote and info['who'] == target.name:
            cpu = info['cpu']
            mem = info['mem']

        if info['who'] == m.name:
            now = datetime.datetime.now()
            elapsed = now - start
            recved = info['state']['adj-table'][
                'accepted'] if 'accepted' in info['state']['adj-table'] else 0
            if elapsed.seconds > 0:
                rm_line()
            print 'elapsed: {0}sec, cpu: {1:>4.2f}%, mem: {2}, recved: {3}'.format(
                elapsed.seconds, cpu, mem_human(mem), recved)
            f.write('{0}, {1}, {2}, {3}\n'.format(elapsed.seconds, cpu, mem,
                                                  recved)) if f else None
            f.flush() if f else None

            if cooling == args.cooling:
                f.close() if f else None
                return

            if cooling >= 0:
                cooling += 1

            if info['checked']:
                cooling = 0