Allow to execute commands from inside a network namespace
Change-Id: I6aa499824bca146b6d2bf834b6565679cb423c4a
This commit is contained in:
parent
909dc7cf9b
commit
cc63ebb518
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue