... print line
"""
- def __init__(self, cmd, root_helper=None, respawn_interval=None):
+ def __init__(self, cmd, run_as_root=False, respawn_interval=None):
"""Constructor.
:param cmd: The list of command arguments to invoke.
- :param root_helper: Optional, utility to use when running shell cmds.
+ :param run_as_root: The process should run with elevated privileges.
:param respawn_interval: Optional, the interval in seconds to wait
to respawn after unexpected process death. Respawn will
only be attempted if a value of 0 or greater is provided.
"""
self.cmd = cmd
- self.root_helper = root_helper
+ self.run_as_root = run_as_root
if respawn_interval is not None and respawn_interval < 0:
raise ValueError(_('respawn_interval must be >= 0 if provided.'))
self.respawn_interval = respawn_interval
"""Spawn a process and its watchers."""
self._kill_event = eventlet.event.Event()
self._process, cmd = utils.create_process(self.cmd,
- root_helper=self.root_helper)
+ run_as_root=self.run_as_root)
self._watchers = []
for reader in (self._read_stdout, self._read_stderr):
# Pass the stop event directly to the greenthread to
# Halt the greenthreads
self._kill_event.send()
- pid = utils.get_root_helper_child_pid(
- self._process.pid, self.root_helper)
+ pid = utils.get_root_helper_child_pid(self._process.pid,
+ run_as_root=self.run_as_root)
if pid:
self._kill_process(pid)
try:
# A process started by a root helper will be running as
# root and need to be killed via the same helper.
- utils.execute(['kill', '-9', pid], root_helper=self.root_helper)
+ utils.execute(['kill', '-9', pid], run_as_root=self.run_as_root)
except Exception as ex:
stale_pid = (isinstance(ex, RuntimeError) and
'No such process' in str(ex))
"""Manages an invocation of 'ovsdb-client monitor'."""
def __init__(self, table_name, columns=None, format=None,
- root_helper=None, respawn_interval=None):
+ respawn_interval=None):
cmd = ['ovsdb-client', 'monitor', table_name]
if columns:
cmd.append(','.join(columns))
if format:
cmd.append('--format=%s' % format)
- super(OvsdbMonitor, self).__init__(cmd,
- root_helper=root_helper,
+ super(OvsdbMonitor, self).__init__(cmd, run_as_root=True,
respawn_interval=respawn_interval)
def _read_stdout(self):
since the previous access.
"""
- def __init__(self, root_helper=None, respawn_interval=None):
+ def __init__(self, respawn_interval=None):
super(SimpleInterfaceMonitor, self).__init__(
'Interface',
columns=['name', 'ofport'],
format='json',
- root_helper=root_helper,
respawn_interval=respawn_interval,
)
self.data_received = False
@contextlib.contextmanager
def get_polling_manager(minimize_polling=False,
- root_helper=None,
ovsdb_monitor_respawn_interval=(
constants.DEFAULT_OVSDBMON_RESPAWN)):
if minimize_polling:
pm = InterfacePollingMinimizer(
- root_helper=root_helper,
ovsdb_monitor_respawn_interval=ovsdb_monitor_respawn_interval)
pm.start()
else:
class InterfacePollingMinimizer(BasePollingManager):
"""Monitors ovsdb to determine when polling is required."""
- def __init__(self, root_helper=None,
- ovsdb_monitor_respawn_interval=(
- constants.DEFAULT_OVSDBMON_RESPAWN)):
+ def __init__(
+ self,
+ ovsdb_monitor_respawn_interval=constants.DEFAULT_OVSDBMON_RESPAWN):
super(InterfacePollingMinimizer, self).__init__()
self._monitor = ovsdb_monitor.SimpleInterfaceMonitor(
- root_helper=root_helper,
respawn_interval=ovsdb_monitor_respawn_interval)
def start(self):
config.register_root_helper(cfg.CONF)
-def create_process(cmd, root_helper=None, addl_env=None):
+def create_process(cmd, run_as_root=False, addl_env=None):
"""Create a process object for the given command.
The return value will be a tuple of the process object and the
list of command arguments used to create it.
"""
- if root_helper:
- cmd = shlex.split(root_helper) + cmd
+ if run_as_root:
+ cmd = shlex.split(config.get_root_helper(cfg.CONF)) + cmd
cmd = map(str, cmd)
LOG.debug("Running command: %s", cmd)
def execute(cmd, root_helper=None, process_input=None, addl_env=None,
check_exit_code=True, return_stderr=False, log_fail_as_error=True,
extra_ok_codes=None, run_as_root=False):
- if not root_helper and run_as_root:
- root_helper = config.get_root_helper(cfg.CONF)
+ if root_helper:
+ run_as_root = True
try:
- obj, cmd = create_process(cmd, root_helper=root_helper,
+ obj, cmd = create_process(cmd, run_as_root=run_as_root,
addl_env=addl_env)
_stdout, _stderr = obj.communicate(process_input)
obj.stdin.close()
os.unlink(file_path)
-def get_root_helper_child_pid(pid, root_helper=None):
+def get_root_helper_child_pid(pid, run_as_root=False):
"""
Get the lowest child pid in the process hierarchy
die is to target the child process directly.
"""
pid = str(pid)
- if root_helper:
+ if run_as_root:
try:
pid = find_child_pids(pid)[0]
except IndexError:
target = oslo_messaging.Target(version='1.2')
def __init__(self, integ_br, tun_br, local_ip,
- bridge_mappings, root_helper,
- polling_interval, tunnel_types=None,
+ bridge_mappings, polling_interval, tunnel_types=None,
veth_mtu=None, l2_population=False,
enable_distributed_routing=False,
minimize_polling=False,
:param tun_br: name of the tunnel bridge.
:param local_ip: local IP address of this hypervisor.
:param bridge_mappings: mappings from physical network name to bridge.
- :param root_helper: utility to use when running shell cmds.
:param polling_interval: interval (secs) to poll DB.
:param tunnel_types: A list of tunnel types to enable support for in
the agent. If set, will automatically set enable_tunneling to
super(OVSNeutronAgent, self).__init__()
self.use_veth_interconnection = use_veth_interconnection
self.veth_mtu = veth_mtu
- self.root_helper = root_helper
self.available_local_vlans = set(moves.xrange(q_const.MIN_VLAN_TAG,
q_const.MAX_VLAN_TAG))
self.use_call = True
def daemon_loop(self):
with polling.get_polling_manager(
self.minimize_polling,
- self.root_helper,
self.ovsdb_monitor_respawn_interval) as pm:
self.rpc_loop(polling_manager=pm)
tun_br=config.OVS.tunnel_bridge,
local_ip=config.OVS.local_ip,
bridge_mappings=bridge_mappings,
- root_helper=config.AGENT.root_helper,
polling_interval=config.AGENT.polling_interval,
minimize_polling=config.AGENT.minimize_polling,
tunnel_types=config.AGENT.tunnel_types,
LOG.error(_LE('%s Agent terminated!'), e)
sys.exit(1)
- is_xen_compute_host = 'rootwrap-xen-dom0' in agent_config['root_helper']
+ is_xen_compute_host = 'rootwrap-xen-dom0' in cfg.CONF.AGENT.root_helper
if is_xen_compute_host:
# Force ip_lib to always use the root helper to ensure that ip
# commands target xen dom0 rather than domU.
super(BaseLinuxTestCase, self).setUp()
config.register_root_helper(cfg.CONF)
- def check_command(self, cmd, error_text, skip_msg, root_helper=None):
+ def check_command(self, cmd, error_text, skip_msg, run_as_root=False):
try:
- utils.execute(cmd, root_helper=root_helper)
+ utils.execute(cmd, run_as_root=run_as_root)
except RuntimeError as e:
if error_text in str(e) and not self.fail_on_missing_deps:
self.skipTest(skip_msg)
import eventlet
+from neutron.agent.common import config
from neutron.agent.linux import ip_lib
from neutron.agent.linux import utils
r'^.*\s+\d+\s+.*:(?P<port>\d+)\s+[0-9:].*')
-def get_free_namespace_port(tcp=True, root_helper=None, namespace=None):
+def get_free_namespace_port(tcp=True, namespace=None):
"""Return an unused port from given namespace
WARNING: This function returns a port that is free at the execution time of
else:
param = '-una'
- ip_wrapper = ip_lib.IPWrapper(root_helper, namespace)
+ ip_wrapper = ip_lib.IPWrapper(namespace=namespace)
output = ip_wrapper.netns.execute(['ss', param])
used_ports = _get_source_ports_from_ss_output(output)
for arg in ('stdin', 'stdout', 'stderr'):
kwargs.setdefault(arg, subprocess.PIPE)
self.namespace = kwargs.pop('namespace', None)
- self.root_helper = kwargs.pop('root_helper', None)
+ self.run_as_root = kwargs.pop('run_as_root', False)
self.cmd = cmd
if self.namespace is not None:
cmd = ['ip', 'netns', 'exec', self.namespace] + cmd
- if self.root_helper is not None:
- cmd = shlex.split(self.root_helper) + cmd
+ if self.run_as_root:
+ root_helper = config.get_root_helper(utils.cfg.CONF)
+ cmd = shlex.split(root_helper) + cmd
self.child_pid = None
super(RootHelperProcess, self).__init__(cmd, *args, **kwargs)
- if self.root_helper:
+ if self.run_as_root:
self._wait_for_child_process()
def kill(self):
pid = self.child_pid or str(self.pid)
- utils.execute(['kill', '-9', pid],
- root_helper=self.root_helper)
+ utils.execute(['kill', '-9', pid], run_as_root=self.run_as_root)
def read_stdout(self, timeout=None):
return self._read_stream(self.stdout, timeout)
sleep=CHILD_PROCESS_SLEEP):
def child_is_running():
child_pid = utils.get_root_helper_child_pid(
- self.pid, root_helper=self.root_helper)
+ self.pid, run_as_root=self.run_as_root)
if pid_invoked_with_cmdline(child_pid, self.cmd):
return True
exception=RuntimeError("Process %s hasn't been spawned "
"in %d seconds" % (self.cmd, timeout)))
self.child_pid = utils.get_root_helper_child_pid(
- self.pid, root_helper=self.root_helper)
+ self.pid, run_as_root=self.run_as_root)
class NetcatTester(object):
TESTING_STRING = 'foo'
- def __init__(
- self, client_namespace, server_namespace, server_address, port,
- client_address=None, root_helper='', udp=False):
+ def __init__(self, client_namespace, server_namespace, server_address,
+ port, client_address=None, run_as_root=False, udp=False):
self.client_namespace = client_namespace
self.server_namespace = server_namespace
self._client_process = None
self.client_address = client_address or server_address
self.server_address = server_address
self.port = str(port)
- self.root_helper = root_helper
+ self.run_as_root = run_as_root
self.udp = udp
@property
else:
cmd.extend(['-w', '20'])
proc = RootHelperProcess(cmd, namespace=namespace,
- root_helper=self.root_helper)
+ run_as_root=self.run_as_root)
return proc
def stop_processes(self):
# Ensure that the same output is read twice
self._check_stdout(proc)
pid = utils.get_root_helper_child_pid(proc._process.pid,
- proc.root_helper)
+ proc.run_as_root)
proc._kill_process(pid)
self._check_stdout(proc)
proc.stop()
class TestRootHelperProcess(base.BaseLinuxTestCase):
def test_process_read_write(self):
- proc = helpers.RootHelperProcess(['tee'], root_helper=self.root_helper)
+ proc = helpers.RootHelperProcess(['tee'], run_as_root=True)
proc.writeline('foo')
output = proc.read_stdout(helpers.READ_TIMEOUT)
self.assertEqual('foo\n', output)
def test_process_kill(self):
with self.assert_max_execution_time(100):
- proc = helpers.RootHelperProcess(
- ['tee'], root_helper=self.root_helper)
+ proc = helpers.RootHelperProcess(['tee'], run_as_root=True)
proc.kill()
proc.wait()
# sudo returns 137 and
def _test_with_nc(self, fw_manager, direction, port, udp):
netcat = helpers.NetcatTester(self.client_ns, self.server_ns,
self.DST_ADDRESS, self.port,
- root_helper=self.root_helper,
- udp=udp)
+ run_as_root=True, udp=udp)
self.addCleanup(netcat.stop_processes)
protocol = 'tcp'
if udp:
# to be emulated by double sudo if rootwrap is not
# configured.
self.root_helper = '%s %s' % (self.root_helper, self.root_helper)
+ self.config(group='AGENT', root_helper=self.root_helper)
self._check_test_requirements()
self.bridge = self.create_ovs_bridge()
self.check_command(['ovsdb-client', 'list-dbs'],
'Exit code: 1',
'password-less sudo not granted for ovsdb-client',
- root_helper=self.root_helper)
+ run_as_root=True)
class TestOvsdbMonitor(BaseMonitorTest):
def setUp(self):
super(TestOvsdbMonitor, self).setUp()
- self.monitor = ovsdb_monitor.OvsdbMonitor('Bridge',
- root_helper=self.root_helper)
+ self.monitor = ovsdb_monitor.OvsdbMonitor('Bridge')
self.addCleanup(self.monitor.stop)
self.monitor.start()
self.monitor.respawn_interval = 0
old_pid = self.monitor._process.pid
output1 = self.collect_initial_output()
- pid = utils.get_root_helper_child_pid(old_pid, self.root_helper)
+ pid = utils.get_root_helper_child_pid(old_pid, run_as_root=True)
self.monitor._kill_process(pid)
self.monitor._reset_queues()
while (self.monitor._process.pid == old_pid):
def setUp(self):
super(TestSimpleInterfaceMonitor, self).setUp()
- self.monitor = ovsdb_monitor.SimpleInterfaceMonitor(
- root_helper=self.root_helper)
+ self.monitor = ovsdb_monitor.SimpleInterfaceMonitor()
self.addCleanup(self.monitor.stop)
self.monitor.start(block=True, timeout=60)
self._add_fip(router, client_address, fixed_address=server_address)
self.agent.process_router(router)
- router_ns = ip_lib.IPWrapper(self.root_helper,
- namespace=router.ns_name)
+ router_ns = ip_lib.IPWrapper(namespace=router.ns_name)
netcat = helpers.NetcatTester(router_ns, router_ns,
server_address, port,
client_address=client_address,
- root_helper=self.root_helper,
+ run_as_root=True,
udp=False)
self.addCleanup(netcat.stop_processes)
self._test__kill(False, pid='1')
def _test__kill_process(self, pid, expected, exception_message=None):
- self.proc.root_helper = 'foo'
+ self.proc.run_as_root = True
if exception_message:
exc = RuntimeError(exception_message)
else:
self.assertEqual(expected, actual)
mock_execute.assert_called_with(['kill', '-9', pid],
- root_helper=self.proc.root_helper)
+ run_as_root=self.proc.run_as_root)
def test__kill_process_returns_true_for_valid_pid(self):
self._test__kill_process('1', True)
def setUp(self):
super(TestOvsdbMonitor, self).setUp()
self.root_helper = 'sudo'
- self.monitor = ovsdb_monitor.OvsdbMonitor('Interface',
- root_helper=self.root_helper)
+ self.monitor = ovsdb_monitor.OvsdbMonitor('Interface')
def read_output_queues_and_returns_result(self, output_type, output):
with mock.patch.object(self.monitor, '_process') as mock_process:
def setUp(self):
super(TestSimpleInterfaceMonitor, self).setUp()
self.root_helper = 'sudo'
- self.monitor = ovsdb_monitor.SimpleInterfaceMonitor(
- root_helper=self.root_helper)
+ self.monitor = ovsdb_monitor.SimpleInterfaceMonitor()
def test_is_active_is_false_by_default(self):
self.assertFalse(self.monitor.is_active)
mock_target = 'neutron.agent.linux.polling.InterfacePollingMinimizer'
with mock.patch('%s.start' % mock_target) as mock_start:
with mock.patch('%s.stop' % mock_target) as mock_stop:
- with polling.get_polling_manager(minimize_polling=True,
- root_helper='test') as pm:
- self.assertEqual(pm._monitor.root_helper, 'test')
+ with polling.get_polling_manager(minimize_polling=True) as pm:
self.assertEqual(pm.__class__,
polling.InterfacePollingMinimizer)
mock_stop.assert_has_calls(mock.call())
class TestGetRoothelperChildPid(base.BaseTestCase):
def _test_get_root_helper_child_pid(self, expected=_marker,
- root_helper=None, pids=None):
+ run_as_root=False, pids=None):
def _find_child_pids(x):
if not pids:
return []
mock_pid = object()
with mock.patch.object(utils, 'find_child_pids',
side_effect=_find_child_pids):
- actual = utils.get_root_helper_child_pid(mock_pid, root_helper)
+ actual = utils.get_root_helper_child_pid(mock_pid, run_as_root)
if expected is _marker:
expected = str(mock_pid)
self.assertEqual(expected, actual)
- def test_returns_process_pid_without_root_helper(self):
+ def test_returns_process_pid_not_root(self):
self._test_get_root_helper_child_pid()
- def test_returns_child_pid_with_root_helper(self):
+ def test_returns_child_pid_as_root(self):
self._test_get_root_helper_child_pid(expected='2', pids=['1', '2'],
- root_helper='a')
+ run_as_root=True)
- def test_returns_last_child_pid_with_root_helper(self):
+ def test_returns_last_child_pid_as_root(self):
self._test_get_root_helper_child_pid(expected='3',
pids=['1', '2', '3'],
- root_helper='a')
+ run_as_root=True)
- def test_returns_none_with_root_helper(self):
- self._test_get_root_helper_child_pid(expected=None, root_helper='a')
+ def test_returns_none_as_root(self):
+ self._test_get_root_helper_child_pid(expected=None, run_as_root=True)
'neutron.agent.linux.polling.get_polling_manager') as mock_get_pm:
with mock.patch.object(self.agent, 'rpc_loop') as mock_loop:
self.agent.daemon_loop()
- mock_get_pm.assert_called_with(True, 'sudo',
+ mock_get_pm.assert_called_with(True,
constants.DEFAULT_OVSDBMON_RESPAWN)
mock_loop.assert_called_once_with(polling_manager=mock.ANY)
kwargs.setdefault('tun_br', self.TUN_BRIDGE)
kwargs.setdefault('local_ip', '10.0.0.1')
kwargs.setdefault('bridge_mappings', self.NET_MAPPING)
- kwargs.setdefault('root_helper', 'sudo')
kwargs.setdefault('polling_interval', 2)
kwargs.setdefault('tunnel_types', ['gre'])
kwargs.setdefault('veth_mtu', self.VETH_MTU)