Debug Helper Script for Quantum
- Configure
-export TEST_CONFIG_FILE=/etc/quantum/dhcp_agent.ini
+export TEST_CONFIG_FILE=/etc/quantum/debug.ini
or
export TEST_CONFIG_FILE=/etc/quantum/l3_agent.ini
- Usage
quantum-debug commands
-probe-create <net-id> Create probe port - create port and interface, then plug it in.
+probe-create <net-id>
+ Create probe port - create port and interface, then plug it in.
This commands returns a port id of a probe port. A probe port is a port which is used to test.
The port id is probe id.
We can have multiple probe probes in a network, in order to check connectivity between ports.
quantum-debug probe-exec probe_id_1 'nc -l 192.168.100.3 22'
quantum-debug probe-exec probe_id_2 'nc -vz 192.168.100.4 22'
+ Note: You should use a user and a tenant who has permission to
+ modify network and subnet if you want to probe. For example, you need to be admin user if you
+ want to probe external network.
+
probe-delete <port-id> Delete probe - delete port then uplug
probe-exec <port-id> 'command' Exec commands on the namespace of the probe
`probe-exec <port-id>` 'interactive command' Exec interactive command (eg, ssh)
cfg.StrOpt('auth_region'),
cfg.BoolOpt('use_namespaces', default=True),
cfg.StrOpt('interface_driver',
- help="The driver used to manage the virtual interface.")
+ help="The driver used to manage the virtual interface."),
+ cfg.StrOpt('external_network_bridge', default='br-ex',
+ help="Name of bridge used for external network traffic."),
]
def __init__(self, conf, client, driver):
def create_probe(self, network_id):
network = self._get_network(network_id)
+ bridge = None
+ if network.external:
+ bridge = self.conf.external_network_bridge
+
port = self._create_port(network)
port.network = network
interface_name = self.driver.get_device_name(port)
port.id,
interface_name,
port.mac_address,
+ bridge=bridge,
namespace=namespace)
ip_cidrs = []
for fixed_ip in port.fixed_ips:
def _get_network(self, network_id):
network_dict = self.client.show_network(network_id)['network']
network = DictModel(network_dict)
+ network.external = network_dict.get('router:external')
obj_subnet = [self._get_subnet(s_id) for s_id in network.subnets]
network.subnets = obj_subnet
return network
def delete_probe(self, port_id):
port = DictModel(self.client.show_port(port_id)['port'])
+ network = self._get_network(port.network_id)
+ bridge = None
+ if network.external:
+ bridge = self.conf.external_network_bridge
ip = ip_lib.IPWrapper(self.conf.root_helper)
namespace = self._get_namespace(port)
if self.conf.use_namespaces and ip.netns.exists(namespace):
self.driver.unplug(self.driver.get_device_name(port),
+ bridge=bridge,
namespace=namespace)
- ip.netns.delete(namespace)
+ try:
+ ip.netns.delete(namespace)
+ except:
+ LOG.warn(_('failed to delete namespace %s') % namespace)
else:
- self.driver.unplug(self.driver.get_device_name(port))
+ self.driver.unplug(self.driver.get_device_name(port),
+ bridge=bridge)
self.client.delete_port(port.id)
def list_probes(self):
self.addCleanup(mock.patch.stopall)
device_exists_p = mock.patch(
- 'quantum.agent.linux.ip_lib.device_exists')
+ 'quantum.agent.linux.ip_lib.device_exists', return_value=False)
device_exists_p.start()
namespace_p = mock.patch(
'quantum.agent.linux.ip_lib.IpNetnsCommand')
mock.call.show_subnet('fake_subnet'),
mock.call.create_port(fake_port),
mock.call.show_subnet('fake_subnet')])
- self.driver.assert_has_calls([mock.call.init_l3('tap12345678-12',
+ self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
+ mock.call.plug('fake_net',
+ 'fake_port',
+ 'tap12345678-12',
+ 'aa:bb:cc:dd:ee:ffa',
+ bridge=None,
+ namespace=namespace),
+ mock.call.init_l3('tap12345678-12',
+ ['10.0.0.3/24'],
+ namespace=namespace
+ )])
+
+ def test_create_probe_external(self):
+ fake_network = {'network': {'id': 'fake_net',
+ 'tenant_id': 'fake_tenant',
+ 'router:external': True,
+ 'subnets': ['fake_subnet']}}
+ self.client.show_network.return_value = fake_network
+ cmd = commands.CreateProbe(self.app, None)
+ cmd_parser = cmd.get_parser('create_probe')
+ args = ['fake_net']
+ parsed_args = cmd_parser.parse_args(args)
+ cmd.run(parsed_args)
+ fake_port = {'port':
+ {'device_owner': DEVICE_OWNER_PROBE,
+ 'admin_state_up': True,
+ 'network_id': 'fake_net',
+ 'tenant_id': 'fake_tenant',
+ 'fixed_ips': [{'subnet_id': 'fake_subnet'}],
+ 'device_id': socket.gethostname()}}
+ namespace = 'qprobe-fake_port'
+ self.client.assert_has_calls([mock.call.show_network('fake_net'),
+ mock.call.show_subnet('fake_subnet'),
+ mock.call.create_port(fake_port),
+ mock.call.show_subnet('fake_subnet')])
+ self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
+ mock.call.plug('fake_net',
+ 'fake_port',
+ 'tap12345678-12',
+ 'aa:bb:cc:dd:ee:ffa',
+ bridge='br-ex',
+ namespace=namespace),
+ mock.call.init_l3('tap12345678-12',
['10.0.0.3/24'],
namespace=namespace
)])
cmd.run(parsed_args)
namespace = 'qprobe-fake_port'
self.client.assert_has_calls([mock.call.show_port('fake_port'),
+ mock.call.show_network('fake_net'),
+ mock.call.show_subnet('fake_subnet'),
mock.call.delete_port('fake_port')])
self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
mock.call.unplug('tap12345678-12',
- namespace=namespace)])
+ namespace=namespace,
+ bridge=None)])
+
+ def test_delete_probe_external(self):
+ fake_network = {'network': {'id': 'fake_net',
+ 'tenant_id': 'fake_tenant',
+ 'router:external': True,
+ 'subnets': ['fake_subnet']}}
+ self.client.show_network.return_value = fake_network
+ cmd = commands.DeleteProbe(self.app, None)
+ cmd_parser = cmd.get_parser('delete_probe')
+ args = ['fake_port']
+ parsed_args = cmd_parser.parse_args(args)
+ cmd.run(parsed_args)
+ namespace = 'qprobe-fake_port'
+ self.client.assert_has_calls([mock.call.show_port('fake_port'),
+ mock.call.show_network('fake_net'),
+ mock.call.show_subnet('fake_subnet'),
+ mock.call.delete_port('fake_port')])
+ self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
+ mock.call.unplug('tap12345678-12',
+ namespace=namespace,
+ bridge='br-ex')])
def test_delete_probe_without_namespace(self):
cfg.CONF.set_override('use_namespaces', False)
parsed_args = cmd_parser.parse_args(args)
cmd.run(parsed_args)
self.client.assert_has_calls([mock.call.show_port('fake_port'),
+ mock.call.show_network('fake_net'),
+ mock.call.show_subnet('fake_subnet'),
mock.call.delete_port('fake_port')])
self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
- mock.call.unplug('tap12345678-12')])
+ mock.call.unplug('tap12345678-12',
+ bridge=None)])
def test_list_probe(self):
cmd = commands.ListProbe(self.app, None)
device_id=socket.gethostname(),
device_owner=DEVICE_OWNER_PROBE),
mock.call.show_port('fake_port'),
+ mock.call.show_network('fake_net'),
+ mock.call.show_subnet('fake_subnet'),
mock.call.delete_port('fake_port')])
self.driver.assert_has_calls([mock.call.get_device_name(mock.ANY),
mock.call.unplug('tap12345678-12',
- namespace=namespace)])
+ namespace=namespace,
+ bridge=None)])
def test_ping_all_with_ensure_port(self):
fake_ports = self.fake_ports