diff --git a/tobiko/shell/ip.py b/tobiko/shell/ip.py index 8e2d91df2..0662ab11e 100644 --- a/tobiko/shell/ip.py +++ b/tobiko/shell/ip.py @@ -67,7 +67,7 @@ def list_ip_addresses(ip_version=None, scope=None, **execute_params): def list_network_namespaces(**execute_params): output = execute_ip(['-o', 'netns', 'list'], **execute_params) - namespaces = list() + namespaces = tobiko.Selection() if output: for line in output.splitlines(): fields = line.strip().split() @@ -76,15 +76,10 @@ def list_network_namespaces(**execute_params): return namespaces -def execute_ip(ifconfig_args, network_namespace=None, sudo=None, - **execute_params): +def execute_ip(ifconfig_args, **execute_params): command = ['/sbin/ip'] + ifconfig_args - if network_namespace: - if sudo is None: - sudo = True - command = ['/sbin/ip', 'netns', 'exec', network_namespace] + command result = sh.execute(command, stdin=False, stdout=True, stderr=True, - expect_exit_status=None, sudo=sudo, **execute_params) + expect_exit_status=None, **execute_params) if result.exit_status: raise IpError(error=result.stderr, exit_status=result.exit_status) return result.stdout diff --git a/tobiko/shell/sh/_local.py b/tobiko/shell/sh/_local.py index fe482aaab..d350194d4 100644 --- a/tobiko/shell/sh/_local.py +++ b/tobiko/shell/sh/_local.py @@ -54,11 +54,12 @@ def local_execute(command, environment=None, timeout=None, shell=None, def local_process(command, environment=None, current_dir=None, timeout=None, - shell=None, stdin=None, stdout=None, stderr=True, sudo=None): + shell=None, stdin=None, stdout=None, stderr=True, sudo=None, + network_namespace=None): return LocalShellProcessFixture( command=command, environment=environment, current_dir=current_dir, timeout=timeout, shell=shell, stdin=stdin, stdout=stdout, - stderr=stderr, sudo=sudo) + stderr=stderr, sudo=sudo, network_namespace=network_namespace) class LocalExecutePathFixture(_path.ExecutePathFixture): diff --git a/tobiko/shell/sh/_process.py b/tobiko/shell/sh/_process.py index c6f1eb737..08f6749d1 100644 --- a/tobiko/shell/sh/_process.py +++ b/tobiko/shell/sh/_process.py @@ -79,6 +79,7 @@ class ShellProcessParameters(Parameters): buffer_size = io.DEFAULT_BUFFER_SIZE poll_interval = 1. sudo = None + network_namespace = None class ShellProcessFixture(tobiko.SharedFixture): @@ -121,6 +122,9 @@ class ShellProcessFixture(tobiko.SharedFixture): def setup_command(self): command = _command.shell_command(self.parameters.command) + network_namespace = self.parameters.network_namespace + sudo = self.parameters.sudo + shell = self.parameters.shell if shell: if shell is True: @@ -130,7 +134,12 @@ class ShellProcessFixture(tobiko.SharedFixture): command = shell + [str(command)] else: command = _command.shell_command(command) - sudo = self.parameters.sudo + + if network_namespace: + if sudo is None: + sudo = True + command = network_namespace_command(network_namespace, command) + if sudo: if sudo is True: sudo = default_sudo_command() @@ -495,3 +504,8 @@ def default_sudo_command(): from tobiko import config CONF = config.CONF return _command.shell_command(CONF.tobiko.shell.sudo) + + +def network_namespace_command(network_namespace, command): + return _command.shell_command(['/sbin/ip', 'netns', 'exec', + network_namespace]) + command diff --git a/tobiko/shell/sh/_ssh.py b/tobiko/shell/sh/_ssh.py index b35528dfd..d7f085f91 100644 --- a/tobiko/shell/sh/_ssh.py +++ b/tobiko/shell/sh/_ssh.py @@ -48,19 +48,20 @@ def ssh_execute(ssh_client, command, environment=None, timeout=None, def ssh_process(command, environment=None, current_dir=None, timeout=None, shell=None, stdin=None, stdout=None, stderr=None, - ssh_client=None, sudo=None): + ssh_client=None, sudo=None, network_namespace=None): if ssh_client is None: ssh_client = ssh.ssh_proxy_client() if ssh_client: return SSHShellProcessFixture( command=command, environment=environment, current_dir=current_dir, timeout=timeout, shell=shell, stdin=stdin, stdout=stdout, - stderr=stderr, ssh_client=ssh_client, sudo=sudo) + stderr=stderr, ssh_client=ssh_client, sudo=sudo, + network_namespace=network_namespace) else: return _local.local_process( command=command, environment=environment, current_dir=current_dir, timeout=timeout, shell=shell, stdin=stdin, stdout=stdout, - stderr=stderr, sudo=sudo) + stderr=stderr, sudo=sudo, network_namespace=network_namespace) class SSHShellProcessParameters(_process.ShellProcessParameters): diff --git a/tobiko/tests/functional/shell/test_ip.py b/tobiko/tests/functional/shell/test_ip.py index d2cf717eb..37a581f15 100644 --- a/tobiko/tests/functional/shell/test_ip.py +++ b/tobiko/tests/functional/shell/test_ip.py @@ -20,9 +20,10 @@ import six import testtools import tobiko +from tobiko.openstack import stacks +from tobiko.openstack import topology from tobiko.shell import ip from tobiko.shell import ssh -from tobiko.openstack import stacks class IpTest(testtools.TestCase): @@ -55,6 +56,7 @@ class IpTest(testtools.TestCase): elif scope == 'global': self.assertNotIn(netaddr.IPAddress('127.0.0.1'), ips) self.assertNotIn(netaddr.IPAddress('::1'), ips) + return ips def test_list_ip_addresses_with_host_scope(self, **execute_params): self.test_list_ip_addresses(scope='host', **execute_params) @@ -98,6 +100,23 @@ class IpTest(testtools.TestCase): self, **execute_params): self.test_list_ip_addresses(scope='global', **execute_params) + def test_list_ip_addresses_with_namespace(self): + for node in topology.list_openstack_nodes(): + network_namespaces = ip.list_network_namespaces( + ssh_client=node.ssh_client) + if network_namespaces: + network_namespace = network_namespaces.first + ssh_client = node.ssh_client + break + + namespace_ips = ip.list_ip_addresses( + ssh_client=ssh_client, scope='global', + network_namespace=network_namespace) + self.assertNotEqual([], namespace_ips) + + host_ips = ip.list_ip_addresses(ssh_client=ssh_client, scope='global') + self.assertNotEqual(host_ips, namespace_ips) + def test_list_namespaces(self, **execute_params): namespaces = ip.list_network_namespaces(**execute_params) self.assertIsInstance(namespaces, list)