Define root_helper variable under the [AGENT] section

Fixes bug 1105523

The patch set adds 2 new functions:
1. register_root_helper - this enables all wanting to use
the root_helper variable. This is under the section AGENT.
2. get_root_helper - this is a helper function that returns the
root_helper. This should be used when the application used to
have the root_helper defined under the section DEFAULT. This
ensures backward compatability.

Change-Id: Iba72c4fc89ba5329ea045483287012f82b306250
This commit is contained in:
Gary Kotton 2013-01-28 13:37:47 +00:00
parent f4b1c5fb7c
commit 1b7565b83c
23 changed files with 142 additions and 118 deletions

View File

@ -29,8 +29,3 @@ dhcp_driver = quantum.agent.linux.dhcp.Dnsmasq
# Allow overlapping IP (Must have kernel build with CONFIG_NET_NS=y and # Allow overlapping IP (Must have kernel build with CONFIG_NET_NS=y and
# iproute2 package that supports namespaces). # iproute2 package that supports namespaces).
# use_namespaces = True # use_namespaces = True
# Use "sudo quantum-rootwrap /etc/quantum/rootwrap.conf" to use the real
# root filter facility.
# Change to "sudo" to skip the filtering and just run the comand directly
root_helper = sudo

View File

@ -13,11 +13,6 @@ interface_driver = quantum.agent.linux.interface.OVSInterfaceDriver
# LinuxBridge # LinuxBridge
#interface_driver = quantum.agent.linux.interface.BridgeInterfaceDriver #interface_driver = quantum.agent.linux.interface.BridgeInterfaceDriver
# Use "sudo quantum-rootwrap /etc/quantum/rootwrap.conf" to use the real
# root filter facility.
# Change to "sudo" to skip the filtering and just run the comand directly
root_helper = sudo
# Allow overlapping IP (Must have kernel build with CONFIG_NET_NS=y and # Allow overlapping IP (Must have kernel build with CONFIG_NET_NS=y and
# iproute2 package that supports namespaces). # iproute2 package that supports namespaces).
# use_namespaces = True # use_namespaces = True

View File

@ -9,11 +9,6 @@ admin_tenant_name = %SERVICE_TENANT_NAME%
admin_user = %SERVICE_USER% admin_user = %SERVICE_USER%
admin_password = %SERVICE_PASSWORD% admin_password = %SERVICE_PASSWORD%
# Use "sudo quantum-rootwrap /etc/quantum/rootwrap.conf" to use the real
# root filter facility.
# Change to "sudo" to skip the filtering and just run the comand directly
root_helper = sudo
# Where to store metadata state files. This directory must be writable by the # Where to store metadata state files. This directory must be writable by the
# user executing the agent. # user executing the agent.
# state_path = /var/lib/quantum # state_path = /var/lib/quantum

View File

@ -201,3 +201,9 @@ notification_topics = notifications
[SECURITYGROUP] [SECURITYGROUP]
# If set to true this allows quantum to receive proxied security group calls from nova # If set to true this allows quantum to receive proxied security group calls from nova
# proxy_mode = False # proxy_mode = False
[AGENT]
# Use "sudo quantum-rootwrap /etc/quantum/rootwrap.conf" to use the real
# root filter facility.
# Change to "sudo" to skip the filtering and just run the comand directly
# root_helper = sudo

View File

@ -57,7 +57,3 @@ reconnect_interval = 2
[AGENT] [AGENT]
# Agent's polling interval in seconds # Agent's polling interval in seconds
polling_interval = 2 polling_interval = 2
# Use "sudo quantum-rootwrap /etc/quantum/rootwrap.conf" to use the real
# root filter facility.
# Change to "sudo" to skip the filtering and just run the comand directly
root_helper = "sudo"

View File

@ -96,10 +96,6 @@ reconnect_interval = 2
[AGENT] [AGENT]
# Agent's polling interval in seconds # Agent's polling interval in seconds
polling_interval = 2 polling_interval = 2
# Use "sudo quantum-rootwrap /etc/quantum/rootwrap.conf" to use the real
# root filter facility.
# Change to "sudo" to skip the filtering and just run the comand directly
root_helper = sudo
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Sample Configurations. # Sample Configurations.
@ -114,7 +110,6 @@ root_helper = sudo
# integration_bridge = br-int # integration_bridge = br-int
# bridge_mappings = default:br-eth1 # bridge_mappings = default:br-eth1
# [AGENT] # [AGENT]
# root_helper = sudo
# Add the following setting, if you want to log to a file # Add the following setting, if you want to log to a file
# #
# 2. With tunneling. # 2. With tunneling.
@ -126,5 +121,3 @@ root_helper = sudo
# integration_bridge = br-int # integration_bridge = br-int
# tunnel_bridge = br-tun # tunnel_bridge = br-tun
# local_ip = 10.0.0.3 # local_ip = 10.0.0.3
# [AGENT]
# root_helper = sudo

View File

@ -45,9 +45,3 @@ tunnel_interface = eth0
# ovsdb_ip = # ovsdb_ip =
# ovsdb_interface = # ovsdb_interface =
ovsdb_interface = eth0 ovsdb_interface = eth0
[AGENT]
# Use "sudo quantum-rootwrap /etc/quantum/rootwrap.conf" to use the real
# root filter facility.
# Change to "sudo" to skip the filtering and just run the comand directly
root_helper = sudo

View File

@ -18,6 +18,35 @@
from quantum.common import config from quantum.common import config
from quantum.openstack.common import cfg from quantum.openstack.common import cfg
from quantum.openstack.common import log as logging
LOG = logging.getLogger(__name__)
ROOT_HELPER_OPTS = [
cfg.StrOpt('root_helper', default='sudo',
help=_('Root helper application.')),
]
def register_root_helper(conf):
# The first call is to ensure backward compatibility
conf.register_opts(ROOT_HELPER_OPTS)
conf.register_opts(ROOT_HELPER_OPTS, 'AGENT')
def get_root_helper(conf):
root_helper = conf.AGENT.root_helper
if root_helper is not 'sudo':
return root_helper
root_helper = conf.root_helper
if root_helper is not 'sudo':
LOG.deprecated(_('DEFAULT.root_helper is deprecated!'))
return root_helper
return 'sudo'
def setup_conf(): def setup_conf():

View File

@ -43,8 +43,6 @@ NS_PREFIX = 'qdhcp-'
class DhcpAgent(object): class DhcpAgent(object):
OPTS = [ OPTS = [
cfg.StrOpt('root_helper', default='sudo',
help=_("Root helper application.")),
cfg.IntOpt('resync_interval', default=30, cfg.IntOpt('resync_interval', default=30,
help=_("Interval to resync.")), help=_("Interval to resync.")),
cfg.StrOpt('dhcp_driver', cfg.StrOpt('dhcp_driver',
@ -58,6 +56,7 @@ class DhcpAgent(object):
self.needs_resync = False self.needs_resync = False
self.conf = conf self.conf = conf
self.cache = NetworkCache() self.cache = NetworkCache()
self.root_helper = config.get_root_helper(conf)
self.dhcp_driver_cls = importutils.import_class(conf.dhcp_driver) self.dhcp_driver_cls = importutils.import_class(conf.dhcp_driver)
ctx = context.get_admin_context_without_session() ctx = context.get_admin_context_without_session()
@ -85,7 +84,7 @@ class DhcpAgent(object):
# the base models. # the base models.
driver = self.dhcp_driver_cls(self.conf, driver = self.dhcp_driver_cls(self.conf,
network, network,
self.conf.root_helper, self.root_helper,
self.device_manager, self.device_manager,
namespace) namespace)
getattr(driver, action)() getattr(driver, action)()
@ -394,6 +393,7 @@ class DeviceManager(object):
def __init__(self, conf, plugin): def __init__(self, conf, plugin):
self.conf = conf self.conf = conf
self.root_helper = config.get_root_helper(conf)
self.plugin = plugin self.plugin = plugin
if not conf.interface_driver: if not conf.interface_driver:
LOG.error(_('You must specify an interface driver')) LOG.error(_('You must specify an interface driver'))
@ -427,7 +427,7 @@ class DeviceManager(object):
namespace = None namespace = None
if ip_lib.device_exists(interface_name, if ip_lib.device_exists(interface_name,
self.conf.root_helper, self.root_helper,
namespace): namespace):
if not reuse_existing: if not reuse_existing:
raise exceptions.PreexistingDeviceFailure( raise exceptions.PreexistingDeviceFailure(
@ -452,7 +452,8 @@ class DeviceManager(object):
# ensure that the dhcp interface is first in the list # ensure that the dhcp interface is first in the list
if namespace is None: if namespace is None:
device = ip_lib.IPDevice(interface_name, self.conf.root_helper) device = ip_lib.IPDevice(interface_name,
self.root_helper)
device.route.pullup_route(interface_name) device.route.pullup_route(interface_name)
return interface_name return interface_name
@ -547,6 +548,7 @@ class DhcpLeaseRelay(object):
def main(): def main():
eventlet.monkey_patch() eventlet.monkey_patch()
cfg.CONF.register_opts(DhcpAgent.OPTS) cfg.CONF.register_opts(DhcpAgent.OPTS)
config.register_root_helper(cfg.CONF)
cfg.CONF.register_opts(DeviceManager.OPTS) cfg.CONF.register_opts(DeviceManager.OPTS)
cfg.CONF.register_opts(DhcpLeaseRelay.OPTS) cfg.CONF.register_opts(DhcpLeaseRelay.OPTS)
cfg.CONF.register_opts(dhcp.OPTS) cfg.CONF.register_opts(dhcp.OPTS)

View File

@ -111,8 +111,6 @@ class RouterInfo(object):
class L3NATAgent(manager.Manager): class L3NATAgent(manager.Manager):
OPTS = [ OPTS = [
cfg.StrOpt('root_helper', default='sudo',
help=_("Root helper application.")),
cfg.StrOpt('external_network_bridge', default='br-ex', cfg.StrOpt('external_network_bridge', default='br-ex',
help=_("Name of bridge used for external network " help=_("Name of bridge used for external network "
"traffic.")), "traffic.")),
@ -150,6 +148,7 @@ class L3NATAgent(manager.Manager):
self.conf = conf self.conf = conf
else: else:
self.conf = cfg.CONF self.conf = cfg.CONF
self.root_helper = config.get_root_helper(self.conf)
self.router_info = {} self.router_info = {}
if not self.conf.interface_driver: if not self.conf.interface_driver:
@ -173,8 +172,8 @@ class L3NATAgent(manager.Manager):
"""Destroy all router namespaces on the host to eliminate """Destroy all router namespaces on the host to eliminate
all stale linux devices, iptables rules, and namespaces. all stale linux devices, iptables rules, and namespaces.
""" """
root_ip = ip_lib.IPWrapper(self.conf.root_helper) root_ip = ip_lib.IPWrapper(self.root_helper)
for ns in root_ip.get_namespaces(self.conf.root_helper): for ns in root_ip.get_namespaces(self.root_helper):
if ns.startswith(NS_PREFIX): if ns.startswith(NS_PREFIX):
try: try:
self._destroy_router_namespace(ns) self._destroy_router_namespace(ns)
@ -182,8 +181,7 @@ class L3NATAgent(manager.Manager):
LOG.exception(_("Failed deleting namespace '%s'"), ns) LOG.exception(_("Failed deleting namespace '%s'"), ns)
def _destroy_router_namespace(self, namespace): def _destroy_router_namespace(self, namespace):
ns_ip = ip_lib.IPWrapper(self.conf.root_helper, ns_ip = ip_lib.IPWrapper(self.root_helper, namespace=namespace)
namespace=namespace)
for d in ns_ip.get_devices(exclude_loopback=True): for d in ns_ip.get_devices(exclude_loopback=True):
if d.name.startswith(INTERNAL_DEV_PREFIX): if d.name.startswith(INTERNAL_DEV_PREFIX):
# device is on default bridge # device is on default bridge
@ -197,7 +195,7 @@ class L3NATAgent(manager.Manager):
#(TODO) Address the failure for the deletion of the namespace #(TODO) Address the failure for the deletion of the namespace
def _create_router_namespace(self, ri): def _create_router_namespace(self, ri):
ip_wrapper_root = ip_lib.IPWrapper(self.conf.root_helper) ip_wrapper_root = ip_lib.IPWrapper(self.root_helper)
ip_wrapper = ip_wrapper_root.ensure_namespace(ri.ns_name()) ip_wrapper = ip_wrapper_root.ensure_namespace(ri.ns_name())
ip_wrapper.netns.execute(['sysctl', '-w', 'net.ipv4.ip_forward=1']) ip_wrapper.netns.execute(['sysctl', '-w', 'net.ipv4.ip_forward=1'])
@ -218,7 +216,7 @@ class L3NATAgent(manager.Manager):
raise raise
def _router_added(self, router_id, router=None): def _router_added(self, router_id, router=None):
ri = RouterInfo(router_id, self.conf.root_helper, ri = RouterInfo(router_id, self.root_helper,
self.conf.use_namespaces, router) self.conf.use_namespaces, router)
self.router_info[router_id] = ri self.router_info[router_id] = ri
if self.conf.use_namespaces: if self.conf.use_namespaces:
@ -251,7 +249,7 @@ class L3NATAgent(manager.Manager):
pm = external_process.ProcessManager( pm = external_process.ProcessManager(
self.conf, self.conf,
router_info.router_id, router_info.router_id,
self.conf.root_helper, self.root_helper,
router_info.ns_name()) router_info.ns_name())
pm.enable(callback) pm.enable(callback)
@ -259,7 +257,7 @@ class L3NATAgent(manager.Manager):
pm = external_process.ProcessManager( pm = external_process.ProcessManager(
self.conf, self.conf,
router_info.router_id, router_info.router_id,
self.conf.root_helper, self.root_helper,
router_info.ns_name()) router_info.ns_name())
pm.disable() pm.disable()
@ -364,12 +362,12 @@ class L3NATAgent(manager.Manager):
ip_address] ip_address]
try: try:
if self.conf.use_namespaces: if self.conf.use_namespaces:
ip_wrapper = ip_lib.IPWrapper(self.conf.root_helper, ip_wrapper = ip_lib.IPWrapper(self.root_helper,
namespace=ri.ns_name()) namespace=ri.ns_name())
ip_wrapper.netns.execute(arping_cmd, check_exit_code=True) ip_wrapper.netns.execute(arping_cmd, check_exit_code=True)
else: else:
utils.execute(arping_cmd, check_exit_code=True, utils.execute(arping_cmd, check_exit_code=True,
root_helper=self.conf.root_helper) root_helper=self.root_helper)
except Exception as e: except Exception as e:
LOG.error(_("Failed sending gratuitous ARP: %s"), str(e)) LOG.error(_("Failed sending gratuitous ARP: %s"), str(e))
@ -384,7 +382,7 @@ class L3NATAgent(manager.Manager):
interface_name = self.get_external_device_name(ex_gw_port['id']) interface_name = self.get_external_device_name(ex_gw_port['id'])
ex_gw_ip = ex_gw_port['fixed_ips'][0]['ip_address'] ex_gw_ip = ex_gw_port['fixed_ips'][0]['ip_address']
if not ip_lib.device_exists(interface_name, if not ip_lib.device_exists(interface_name,
root_helper=self.conf.root_helper, root_helper=self.root_helper,
namespace=ri.ns_name()): namespace=ri.ns_name()):
self.driver.plug(ex_gw_port['network_id'], self.driver.plug(ex_gw_port['network_id'],
ex_gw_port['id'], interface_name, ex_gw_port['id'], interface_name,
@ -401,12 +399,12 @@ class L3NATAgent(manager.Manager):
if ex_gw_port['subnet']['gateway_ip']: if ex_gw_port['subnet']['gateway_ip']:
cmd = ['route', 'add', 'default', 'gw', gw_ip] cmd = ['route', 'add', 'default', 'gw', gw_ip]
if self.conf.use_namespaces: if self.conf.use_namespaces:
ip_wrapper = ip_lib.IPWrapper(self.conf.root_helper, ip_wrapper = ip_lib.IPWrapper(self.root_helper,
namespace=ri.ns_name()) namespace=ri.ns_name())
ip_wrapper.netns.execute(cmd, check_exit_code=False) ip_wrapper.netns.execute(cmd, check_exit_code=False)
else: else:
utils.execute(cmd, check_exit_code=False, utils.execute(cmd, check_exit_code=False,
root_helper=self.conf.root_helper) root_helper=self.root_helper)
for (c, r) in self.external_gateway_nat_rules(ex_gw_ip, for (c, r) in self.external_gateway_nat_rules(ex_gw_ip,
internal_cidrs, internal_cidrs,
@ -418,7 +416,7 @@ class L3NATAgent(manager.Manager):
interface_name = self.get_external_device_name(ex_gw_port['id']) interface_name = self.get_external_device_name(ex_gw_port['id'])
if ip_lib.device_exists(interface_name, if ip_lib.device_exists(interface_name,
root_helper=self.conf.root_helper, root_helper=self.root_helper,
namespace=ri.ns_name()): namespace=ri.ns_name()):
self.driver.unplug(interface_name, self.driver.unplug(interface_name,
bridge=self.conf.external_network_bridge, bridge=self.conf.external_network_bridge,
@ -458,7 +456,7 @@ class L3NATAgent(manager.Manager):
internal_cidr, mac_address): internal_cidr, mac_address):
interface_name = self.get_internal_device_name(port_id) interface_name = self.get_internal_device_name(port_id)
if not ip_lib.device_exists(interface_name, if not ip_lib.device_exists(interface_name,
root_helper=self.conf.root_helper, root_helper=self.root_helper,
namespace=ri.ns_name()): namespace=ri.ns_name()):
self.driver.plug(network_id, port_id, interface_name, mac_address, self.driver.plug(network_id, port_id, interface_name, mac_address,
namespace=ri.ns_name(), namespace=ri.ns_name(),
@ -479,7 +477,7 @@ class L3NATAgent(manager.Manager):
def internal_network_removed(self, ri, ex_gw_port, port_id, internal_cidr): def internal_network_removed(self, ri, ex_gw_port, port_id, internal_cidr):
interface_name = self.get_internal_device_name(port_id) interface_name = self.get_internal_device_name(port_id)
if ip_lib.device_exists(interface_name, if ip_lib.device_exists(interface_name,
root_helper=self.conf.root_helper, root_helper=self.root_helper,
namespace=ri.ns_name()): namespace=ri.ns_name()):
self.driver.unplug(interface_name, namespace=ri.ns_name(), self.driver.unplug(interface_name, namespace=ri.ns_name(),
prefix=INTERNAL_DEV_PREFIX) prefix=INTERNAL_DEV_PREFIX)
@ -499,7 +497,7 @@ class L3NATAgent(manager.Manager):
def floating_ip_added(self, ri, ex_gw_port, floating_ip, fixed_ip): def floating_ip_added(self, ri, ex_gw_port, floating_ip, fixed_ip):
ip_cidr = str(floating_ip) + '/32' ip_cidr = str(floating_ip) + '/32'
interface_name = self.get_external_device_name(ex_gw_port['id']) interface_name = self.get_external_device_name(ex_gw_port['id'])
device = ip_lib.IPDevice(interface_name, self.conf.root_helper, device = ip_lib.IPDevice(interface_name, self.root_helper,
namespace=ri.ns_name()) namespace=ri.ns_name())
if ip_cidr not in [addr['cidr'] for addr in device.addr.list()]: if ip_cidr not in [addr['cidr'] for addr in device.addr.list()]:
@ -516,7 +514,7 @@ class L3NATAgent(manager.Manager):
net = netaddr.IPNetwork(ip_cidr) net = netaddr.IPNetwork(ip_cidr)
interface_name = self.get_external_device_name(ex_gw_port['id']) interface_name = self.get_external_device_name(ex_gw_port['id'])
device = ip_lib.IPDevice(interface_name, self.conf.root_helper, device = ip_lib.IPDevice(interface_name, self.root_helper,
namespace=ri.ns_name()) namespace=ri.ns_name())
device.addr.delete(net.version, ip_cidr) device.addr.delete(net.version, ip_cidr)
@ -616,6 +614,7 @@ def main():
eventlet.monkey_patch() eventlet.monkey_patch()
conf = cfg.CONF conf = cfg.CONF
conf.register_opts(L3NATAgent.OPTS) conf.register_opts(L3NATAgent.OPTS)
config.register_root_helper(conf)
conf.register_opts(interface.OPTS) conf.register_opts(interface.OPTS)
conf.register_opts(external_process.OPTS) conf.register_opts(external_process.OPTS)
conf() conf()

View File

@ -19,6 +19,7 @@ import abc
import netaddr import netaddr
from quantum.agent.common import config
from quantum.agent.linux import ip_lib from quantum.agent.linux import ip_lib
from quantum.agent.linux import ovs_lib from quantum.agent.linux import ovs_lib
from quantum.agent.linux import utils from quantum.agent.linux import utils
@ -54,12 +55,14 @@ class LinuxInterfaceDriver(object):
def __init__(self, conf): def __init__(self, conf):
self.conf = conf self.conf = conf
self.root_helper = config.get_root_helper(conf)
def init_l3(self, device_name, ip_cidrs, namespace=None): def init_l3(self, device_name, ip_cidrs, namespace=None):
"""Set the L3 settings for the interface using data from the port. """Set the L3 settings for the interface using data from the port.
ip_cidrs: list of 'X.X.X.X/YY' strings ip_cidrs: list of 'X.X.X.X/YY' strings
""" """
device = ip_lib.IPDevice(device_name, self.conf.root_helper, device = ip_lib.IPDevice(device_name,
self.root_helper,
namespace=namespace) namespace=namespace)
previous = {} previous = {}
@ -133,7 +136,7 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
'external-ids:iface-status=active', 'external-ids:iface-status=active',
'--', 'set', 'Interface', device_name, '--', 'set', 'Interface', device_name,
'external-ids:attached-mac=%s' % mac_address] 'external-ids:attached-mac=%s' % mac_address]
utils.execute(cmd, self.conf.root_helper) utils.execute(cmd, self.root_helper)
def plug(self, network_id, port_id, device_name, mac_address, def plug(self, network_id, port_id, device_name, mac_address,
bridge=None, namespace=None, prefix=None): bridge=None, namespace=None, prefix=None):
@ -144,10 +147,10 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
self.check_bridge_exists(bridge) self.check_bridge_exists(bridge)
if not ip_lib.device_exists(device_name, if not ip_lib.device_exists(device_name,
self.conf.root_helper, self.root_helper,
namespace=namespace): namespace=namespace):
ip = ip_lib.IPWrapper(self.conf.root_helper) ip = ip_lib.IPWrapper(self.root_helper)
tap_name = self._get_tap_name(device_name, prefix) tap_name = self._get_tap_name(device_name, prefix)
if self.conf.ovs_use_veth: if self.conf.ovs_use_veth:
@ -182,12 +185,13 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
tap_name = self._get_tap_name(device_name, prefix) tap_name = self._get_tap_name(device_name, prefix)
self.check_bridge_exists(bridge) self.check_bridge_exists(bridge)
ovs = ovs_lib.OVSBridge(bridge, self.conf.root_helper) ovs = ovs_lib.OVSBridge(bridge, self.root_helper)
try: try:
ovs.delete_port(tap_name) ovs.delete_port(tap_name)
if self.conf.ovs_use_veth: if self.conf.ovs_use_veth:
device = ip_lib.IPDevice(device_name, self.conf.root_helper, device = ip_lib.IPDevice(device_name,
self.root_helper,
namespace) namespace)
device.link.delete() device.link.delete()
LOG.debug(_("Unplugged interface '%s'"), device_name) LOG.debug(_("Unplugged interface '%s'"), device_name)
@ -205,9 +209,9 @@ class BridgeInterfaceDriver(LinuxInterfaceDriver):
bridge=None, namespace=None, prefix=None): bridge=None, namespace=None, prefix=None):
"""Plugin the interface.""" """Plugin the interface."""
if not ip_lib.device_exists(device_name, if not ip_lib.device_exists(device_name,
self.conf.root_helper, self.root_helper,
namespace=namespace): namespace=namespace):
ip = ip_lib.IPWrapper(self.conf.root_helper) ip = ip_lib.IPWrapper(self.root_helper)
# Enable agent to define the prefix # Enable agent to define the prefix
if prefix: if prefix:
@ -233,7 +237,7 @@ class BridgeInterfaceDriver(LinuxInterfaceDriver):
def unplug(self, device_name, bridge=None, namespace=None, prefix=None): def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
"""Unplug the interface.""" """Unplug the interface."""
device = ip_lib.IPDevice(device_name, self.conf.root_helper, namespace) device = ip_lib.IPDevice(device_name, self.root_helper, namespace)
try: try:
device.link.delete() device.link.delete()
LOG.debug(_("Unplugged interface '%s'"), device_name) LOG.debug(_("Unplugged interface '%s'"), device_name)
@ -267,7 +271,7 @@ class MetaInterfaceDriver(LinuxInterfaceDriver):
return self.flavor_driver_map[flavor] return self.flavor_driver_map[flavor]
def _get_driver_by_device_name(self, device_name, namespace=None): def _get_driver_by_device_name(self, device_name, namespace=None):
device = ip_lib.IPDevice(device_name, self.conf.root_helper, namespace) device = ip_lib.IPDevice(device_name, self.root_helper, namespace)
mac_address = device.link.address mac_address = device.link.address
ports = self.quantum.list_ports(mac_address=mac_address) ports = self.quantum.list_ports(mac_address=mac_address)
if not ports.get('ports'): if not ports.get('ports'):

View File

@ -21,6 +21,7 @@ import eventlet
from quantum.agent import dhcp_agent from quantum.agent import dhcp_agent
from quantum.agent import l3_agent from quantum.agent import l3_agent
from quantum.agent.common import config as agent_config
from quantum.agent.linux import dhcp from quantum.agent.linux import dhcp
from quantum.agent.linux import ip_lib from quantum.agent.linux import ip_lib
from quantum.agent.linux import ovs_lib from quantum.agent.linux import ovs_lib
@ -56,8 +57,6 @@ def setup_conf():
""" """
opts = [ opts = [
cfg.StrOpt('root_helper', default='sudo',
help=_("Root helper application.")),
cfg.StrOpt('dhcp_driver', cfg.StrOpt('dhcp_driver',
default='quantum.agent.linux.dhcp.Dnsmasq', default='quantum.agent.linux.dhcp.Dnsmasq',
help=_("The driver used to manage the DHCP server.")), help=_("The driver used to manage the DHCP server.")),
@ -68,8 +67,10 @@ def setup_conf():
default=False, default=False,
help=_('Delete the namespace by removing all devices.')), help=_('Delete the namespace by removing all devices.')),
] ]
conf = cfg.ConfigOpts() conf = cfg.ConfigOpts()
conf.register_opts(opts) conf.register_opts(opts)
agent_config.register_root_helper(conf)
conf.register_opts(dhcp.OPTS) conf.register_opts(dhcp.OPTS)
config.setup_logging(conf) config.setup_logging(conf)
return conf return conf
@ -77,6 +78,7 @@ def setup_conf():
def kill_dhcp(conf, namespace): def kill_dhcp(conf, namespace):
"""Disable DHCP for a network if DHCP is still active.""" """Disable DHCP for a network if DHCP is still active."""
root_helper = agent_config.get_root_helper(conf)
network_id = namespace.replace(dhcp_agent.NS_PREFIX, '') network_id = namespace.replace(dhcp_agent.NS_PREFIX, '')
null_delegate = NullDelegate() null_delegate = NullDelegate()
@ -84,7 +86,7 @@ def kill_dhcp(conf, namespace):
conf.dhcp_driver, conf.dhcp_driver,
conf, conf,
FakeNetwork(network_id), FakeNetwork(network_id),
conf.root_helper, root_helper,
null_delegate) null_delegate)
if dhcp_driver.active: if dhcp_driver.active:
@ -102,7 +104,8 @@ def eligible_for_deletion(conf, namespace, force=False):
if not re.match(NS_MANGLING_PATTERN, namespace): if not re.match(NS_MANGLING_PATTERN, namespace):
return False return False
ip = ip_lib.IPWrapper(conf.root_helper, namespace) root_helper = agent_config.get_root_helper(conf)
ip = ip_lib.IPWrapper(root_helper, namespace)
return force or ip.namespace_is_empty() return force or ip.namespace_is_empty()
@ -110,12 +113,11 @@ def unplug_device(conf, device):
try: try:
device.link.delete() device.link.delete()
except RuntimeError: except RuntimeError:
root_helper = agent_config.get_root_helper(conf)
# Maybe the device is OVS port, so try to delete # Maybe the device is OVS port, so try to delete
bridge_name = ovs_lib.get_bridge_for_iface(conf.root_helper, bridge_name = ovs_lib.get_bridge_for_iface(root_helper, device.name)
device.name)
if bridge_name: if bridge_name:
bridge = ovs_lib.OVSBridge(bridge_name, bridge = ovs_lib.OVSBridge(bridge_name, root_helper)
conf.root_helper)
bridge.delete_port(device.name) bridge.delete_port(device.name)
else: else:
LOG.debug(_('Unable to find bridge for device: %s'), device.name) LOG.debug(_('Unable to find bridge for device: %s'), device.name)
@ -129,7 +131,8 @@ def destroy_namespace(conf, namespace, force=False):
""" """
try: try:
ip = ip_lib.IPWrapper(conf.root_helper, namespace) root_helper = agent_config.get_root_helper(conf)
ip = ip_lib.IPWrapper(root_helper, namespace)
if force: if force:
kill_dhcp(conf, namespace) kill_dhcp(conf, namespace)
@ -166,9 +169,10 @@ def main():
conf = setup_conf() conf = setup_conf()
conf() conf()
root_helper = agent_config.get_root_helper(conf)
# Identify namespaces that are candidates for deletion. # Identify namespaces that are candidates for deletion.
candidates = [ns for ns in candidates = [ns for ns in
ip_lib.IPWrapper.get_namespaces(conf.root_helper) ip_lib.IPWrapper.get_namespaces(root_helper)
if eligible_for_deletion(conf, ns, conf.force)] if eligible_for_deletion(conf, ns, conf.force)]
if candidates: if candidates:

View File

@ -16,6 +16,7 @@
# under the License. # under the License.
from quantum.agent import l3_agent from quantum.agent import l3_agent
from quantum.agent.common import config as agent_config
from quantum.agent.linux import interface from quantum.agent.linux import interface
from quantum.agent.linux import ip_lib from quantum.agent.linux import ip_lib
from quantum.agent.linux import ovs_lib from quantum.agent.linux import ovs_lib
@ -42,16 +43,11 @@ def setup_conf():
'bridges.')) 'bridges.'))
] ]
agent_opts = [
cfg.StrOpt('root_helper', default='sudo',
help=_("Root helper application.")),
]
conf = cfg.ConfigOpts() conf = cfg.ConfigOpts()
conf.register_cli_opts(opts) conf.register_cli_opts(opts)
conf.register_opts(l3_agent.L3NATAgent.OPTS) conf.register_opts(l3_agent.L3NATAgent.OPTS)
conf.register_opts(interface.OPTS) conf.register_opts(interface.OPTS)
conf.register_opts(agent_opts, 'AGENT') agent_config.register_root_helper(conf)
config.setup_logging(conf) config.setup_logging(conf)
return conf return conf

View File

@ -20,6 +20,7 @@ import socket
import netaddr import netaddr
from quantum.agent.common import config
from quantum.agent.dhcp_agent import DictModel from quantum.agent.dhcp_agent import DictModel
from quantum.agent.linux import ip_lib from quantum.agent.linux import ip_lib
from quantum.agent.linux import utils from quantum.agent.linux import utils
@ -35,8 +36,6 @@ DEVICE_OWNER_PROBE = 'network:probe'
class QuantumDebugAgent(): class QuantumDebugAgent():
OPTS = [ OPTS = [
cfg.StrOpt('root_helper', default='sudo',
help=_("Root helper application.")),
# Needed for drivers # Needed for drivers
cfg.StrOpt('admin_user', cfg.StrOpt('admin_user',
help=_("Admin user")), help=_("Admin user")),
@ -62,6 +61,7 @@ class QuantumDebugAgent():
def __init__(self, conf, client, driver): def __init__(self, conf, client, driver):
self.conf = conf self.conf = conf
self.root_helper = config.get_root_helper(conf)
self.client = client self.client = client
self.driver = driver self.driver = driver
@ -81,8 +81,7 @@ class QuantumDebugAgent():
if self.conf.use_namespaces: if self.conf.use_namespaces:
namespace = self._get_namespace(port) namespace = self._get_namespace(port)
if ip_lib.device_exists(interface_name, if ip_lib.device_exists(interface_name, self.root_helper, namespace):
self.conf.root_helper, namespace):
LOG.debug(_('Reusing existing device: %s.'), interface_name) LOG.debug(_('Reusing existing device: %s.'), interface_name)
else: else:
self.driver.plug(network.id, self.driver.plug(network.id,
@ -125,7 +124,7 @@ class QuantumDebugAgent():
bridge = None bridge = None
if network.external: if network.external:
bridge = self.conf.external_network_bridge bridge = self.conf.external_network_bridge
ip = ip_lib.IPWrapper(self.conf.root_helper) ip = ip_lib.IPWrapper(self.root_helper)
namespace = self._get_namespace(port) namespace = self._get_namespace(port)
if self.conf.use_namespaces and ip.netns.exists(namespace): if self.conf.use_namespaces and ip.netns.exists(namespace):
self.driver.unplug(self.driver.get_device_name(port), self.driver.unplug(self.driver.get_device_name(port),
@ -149,7 +148,7 @@ class QuantumDebugAgent():
def exec_command(self, port_id, command=None): def exec_command(self, port_id, command=None):
port = DictModel(self.client.show_port(port_id)['port']) port = DictModel(self.client.show_port(port_id)['port'])
ip = ip_lib.IPWrapper(self.conf.root_helper) ip = ip_lib.IPWrapper(self.root_helper)
namespace = self._get_namespace(port) namespace = self._get_namespace(port)
if self.conf.use_namespaces: if self.conf.use_namespaces:
if not command: if not command:

View File

@ -69,6 +69,7 @@ class QuantumDebugShell(QuantumShell):
client = self.client_manager.quantum client = self.client_manager.quantum
cfg.CONF.register_opts(interface.OPTS) cfg.CONF.register_opts(interface.OPTS)
cfg.CONF.register_opts(QuantumDebugAgent.OPTS) cfg.CONF.register_opts(QuantumDebugAgent.OPTS)
config.register_root_helper(cfg.CONF)
cfg.CONF(['--config-file', self.options.config_file]) cfg.CONF(['--config-file', self.options.config_file])
config.setup_logging(cfg.CONF) config.setup_logging(cfg.CONF)
driver = importutils.import_object(cfg.CONF.interface_driver, cfg.CONF) driver = importutils.import_object(cfg.CONF.interface_driver, cfg.CONF)

View File

@ -17,6 +17,7 @@
# @author: Sumit Naiksatam, Cisco Systems, Inc. # @author: Sumit Naiksatam, Cisco Systems, Inc.
# @author: Rohit Agarwalla, Cisco Systems, Inc. # @author: Rohit Agarwalla, Cisco Systems, Inc.
from quantum.agent.common import config
from quantum.openstack.common import cfg from quantum.openstack.common import cfg
DEFAULT_VLAN_RANGES = [] DEFAULT_VLAN_RANGES = []
@ -43,11 +44,10 @@ agent_opts = [
cfg.IntOpt('polling_interval', default=2, cfg.IntOpt('polling_interval', default=2,
help=_("The number of seconds the agent will wait between " help=_("The number of seconds the agent will wait between "
"polling for local device changes.")), "polling for local device changes.")),
cfg.StrOpt('root_helper', default='sudo',
help=_("Root helper application.")),
] ]
cfg.CONF.register_opts(vlan_opts, "VLANS") cfg.CONF.register_opts(vlan_opts, "VLANS")
cfg.CONF.register_opts(bridge_opts, "LINUX_BRIDGE") cfg.CONF.register_opts(bridge_opts, "LINUX_BRIDGE")
cfg.CONF.register_opts(agent_opts, "AGENT") cfg.CONF.register_opts(agent_opts, "AGENT")
config.register_root_helper(cfg.CONF)

View File

@ -15,6 +15,7 @@
# under the License. # under the License.
# @author: Ryota MIBU # @author: Ryota MIBU
from quantum.agent.common import config
from quantum.openstack.common import cfg from quantum.openstack.common import cfg
# import rpc config options # import rpc config options
from quantum.openstack.common import rpc from quantum.openstack.common import rpc
@ -29,8 +30,6 @@ agent_opts = [
cfg.IntOpt('polling_interval', default=2, cfg.IntOpt('polling_interval', default=2,
help=_("The number of seconds the agent will wait between " help=_("The number of seconds the agent will wait between "
"polling for local device changes.")), "polling for local device changes.")),
cfg.StrOpt('root_helper', default='sudo',
help=_("Root helper application.")),
] ]
ofc_opts = [ ofc_opts = [
@ -54,6 +53,7 @@ ofc_opts = [
cfg.CONF.register_opts(ovs_opts, "OVS") cfg.CONF.register_opts(ovs_opts, "OVS")
cfg.CONF.register_opts(agent_opts, "AGENT") cfg.CONF.register_opts(agent_opts, "AGENT")
cfg.CONF.register_opts(ofc_opts, "OFC") cfg.CONF.register_opts(ofc_opts, "OFC")
config.register_root_helper(cfg.CONF)
# shortcuts # shortcuts
CONF = cfg.CONF CONF = cfg.CONF

View File

@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from quantum.agent.common import config
from quantum.openstack.common import cfg from quantum.openstack.common import cfg
@ -55,10 +56,9 @@ agent_opts = [
cfg.IntOpt('polling_interval', default=2, cfg.IntOpt('polling_interval', default=2,
help=_("The number of seconds the agent will wait between " help=_("The number of seconds the agent will wait between "
"polling for local device changes.")), "polling for local device changes.")),
cfg.StrOpt('root_helper', default='sudo',
help=_("Root helper application.")),
] ]
cfg.CONF.register_opts(ovs_opts, "OVS") cfg.CONF.register_opts(ovs_opts, "OVS")
cfg.CONF.register_opts(agent_opts, "AGENT") cfg.CONF.register_opts(agent_opts, "AGENT")
config.register_root_helper(cfg.CONF)

View File

@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from quantum.agent.common import config
from quantum.openstack.common import cfg from quantum.openstack.common import cfg
@ -38,11 +39,6 @@ ovs_opts = [
help=_("OVSDB interface to connect to")), help=_("OVSDB interface to connect to")),
] ]
agent_opts = [
cfg.StrOpt('root_helper', default='sudo',
help=_("Root helper application.")),
]
cfg.CONF.register_opts(ovs_opts, "OVS") cfg.CONF.register_opts(ovs_opts, "OVS")
cfg.CONF.register_opts(agent_opts, "AGENT") config.register_root_helper(cfg.CONF)

View File

@ -15,9 +15,31 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import unittest2
from quantum.agent.common import config from quantum.agent.common import config
def test_setup_conf(): def test_setup_conf():
conf = config.setup_conf() conf = config.setup_conf()
assert conf.state_path.endswith('/var/lib/quantum') assert conf.state_path.endswith('/var/lib/quantum')
class TestRootHelper(unittest2.TestCase):
def test_agent_root_helper(self):
conf = config.setup_conf()
config.register_root_helper(conf)
conf.set_override('root_helper', 'my_root_helper', 'AGENT')
self.assertEquals(config.get_root_helper(conf), 'my_root_helper')
def test_root_helper(self):
conf = config.setup_conf()
config.register_root_helper(conf)
conf.set_override('root_helper', 'my_root_helper')
self.assertEquals(config.get_root_helper(conf), 'my_root_helper')
def test_root_default(self):
conf = config.setup_conf()
config.register_root_helper(conf)
self.assertEquals(config.get_root_helper(conf), 'sudo')

View File

@ -35,7 +35,7 @@ class TestNetnsCleanup(unittest.TestCase):
def test_kill_dhcp(self, dhcp_active=True): def test_kill_dhcp(self, dhcp_active=True):
conf = mock.Mock() conf = mock.Mock()
conf.root_helper = 'sudo', conf.AGENT.root_helper = 'sudo',
conf.dhcp_driver = 'driver' conf.dhcp_driver = 'driver'
method_to_patch = 'quantum.openstack.common.importutils.import_object' method_to_patch = 'quantum.openstack.common.importutils.import_object'
@ -47,7 +47,8 @@ class TestNetnsCleanup(unittest.TestCase):
util.kill_dhcp(conf, 'ns') util.kill_dhcp(conf, 'ns')
import_object.called_once_with('driver', conf, mock.ANY, 'sudo', import_object.called_once_with('driver', conf, mock.ANY,
conf.AGENT.root_helper,
mock.ANY) mock.ANY)
if dhcp_active: if dhcp_active:
@ -66,14 +67,13 @@ class TestNetnsCleanup(unittest.TestCase):
expected): expected):
ns = prefix + '6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d' ns = prefix + '6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d'
conf = mock.Mock() conf = mock.Mock()
conf.root_helper = 'sudo'
with mock.patch('quantum.agent.linux.ip_lib.IPWrapper') as ip_wrap: with mock.patch('quantum.agent.linux.ip_lib.IPWrapper') as ip_wrap:
ip_wrap.return_value.namespace_is_empty.return_value = is_empty ip_wrap.return_value.namespace_is_empty.return_value = is_empty
self.assertEqual(util.eligible_for_deletion(conf, ns, force), self.assertEqual(util.eligible_for_deletion(conf, ns, force),
expected) expected)
expected_calls = [mock.call('sudo', ns)] expected_calls = [mock.call(conf.AGENT.root_helper, ns)]
if not force: if not force:
expected_calls.append(mock.call().namespace_is_empty()) expected_calls.append(mock.call().namespace_is_empty())
ip_wrap.assert_has_calls(expected_calls) ip_wrap.assert_has_calls(expected_calls)
@ -97,7 +97,6 @@ class TestNetnsCleanup(unittest.TestCase):
def test_unplug_device_ovs_port(self): def test_unplug_device_ovs_port(self):
conf = mock.Mock() conf = mock.Mock()
conf.ovs_integration_bridge = 'br-int' conf.ovs_integration_bridge = 'br-int'
conf.root_helper = 'sudo'
device = mock.Mock() device = mock.Mock()
device.name = 'tap1' device.name = 'tap1'
@ -114,15 +113,14 @@ class TestNetnsCleanup(unittest.TestCase):
util.unplug_device(conf, device) util.unplug_device(conf, device)
mock_get_bridge_for_iface.assert_called_once_with( mock_get_bridge_for_iface.assert_called_once_with(
conf.root_helper, 'tap1') conf.AGENT.root_helper, 'tap1')
ovs_br_cls.called_once_with('br-int', 'sudo') ovs_br_cls.called_once_with('br-int', conf.AGENT.root_helper)
ovs_bridge.assert_has_calls( ovs_bridge.assert_has_calls(
[mock.call.delete_port(device.name)]) [mock.call.delete_port(device.name)])
def test_unplug_device_cannot_determine_bridge_port(self): def test_unplug_device_cannot_determine_bridge_port(self):
conf = mock.Mock() conf = mock.Mock()
conf.ovs_integration_bridge = 'br-int' conf.ovs_integration_bridge = 'br-int'
conf.root_helper = 'sudo'
device = mock.Mock() device = mock.Mock()
device.name = 'tap1' device.name = 'tap1'
@ -140,14 +138,14 @@ class TestNetnsCleanup(unittest.TestCase):
util.unplug_device(conf, device) util.unplug_device(conf, device)
mock_get_bridge_for_iface.assert_called_once_with( mock_get_bridge_for_iface.assert_called_once_with(
conf.root_helper, 'tap1') conf.AGENT.root_helper, 'tap1')
self.assertEqual(ovs_br_cls.mock_calls, []) self.assertEqual(ovs_br_cls.mock_calls, [])
self.assertTrue(debug.called) self.assertTrue(debug.called)
def _test_destroy_namespace_helper(self, force, num_devices): def _test_destroy_namespace_helper(self, force, num_devices):
ns = 'qrouter-6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d' ns = 'qrouter-6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d'
conf = mock.Mock() conf = mock.Mock()
conf.root_helper = 'sudo' # conf.AGENT.root_helper = 'sudo'
lo_device = mock.Mock() lo_device = mock.Mock()
lo_device.name = 'lo' lo_device.name = 'lo'
@ -168,7 +166,7 @@ class TestNetnsCleanup(unittest.TestCase):
with mock.patch.object(util, 'kill_dhcp') as kill_dhcp: with mock.patch.object(util, 'kill_dhcp') as kill_dhcp:
util.destroy_namespace(conf, ns, force) util.destroy_namespace(conf, ns, force)
expected = [mock.call('sudo', ns)] expected = [mock.call(conf.AGENT.root_helper, ns)]
if force: if force:
expected.extend([ expected.extend([
@ -194,7 +192,7 @@ class TestNetnsCleanup(unittest.TestCase):
def test_destroy_namespace_exception(self): def test_destroy_namespace_exception(self):
ns = 'qrouter-6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d' ns = 'qrouter-6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d'
conf = mock.Mock() conf = mock.Mock()
conf.root_helper = 'sudo' conf.AGENT.root_helper = 'sudo'
with mock.patch('quantum.agent.linux.ip_lib.IPWrapper') as ip_wrap: with mock.patch('quantum.agent.linux.ip_lib.IPWrapper') as ip_wrap:
ip_wrap.side_effect = Exception() ip_wrap.side_effect = Exception()
util.destroy_namespace(conf, ns) util.destroy_namespace(conf, ns)
@ -206,7 +204,6 @@ class TestNetnsCleanup(unittest.TestCase):
with mock.patch('eventlet.sleep') as eventlet_sleep: with mock.patch('eventlet.sleep') as eventlet_sleep:
conf = mock.Mock() conf = mock.Mock()
conf.root_helper = 'sudo'
conf.force = False conf.force = False
methods_to_mock = dict( methods_to_mock = dict(
eligible_for_deletion=mock.DEFAULT, eligible_for_deletion=mock.DEFAULT,
@ -227,7 +224,7 @@ class TestNetnsCleanup(unittest.TestCase):
mock.call(conf, 'ns2', False)]) mock.call(conf, 'ns2', False)])
ip_wrap.assert_has_calls( ip_wrap.assert_has_calls(
[mock.call.get_namespaces('sudo')]) [mock.call.get_namespaces(conf.AGENT.root_helper)])
eventlet_sleep.assert_called_once_with(2) eventlet_sleep.assert_called_once_with(2)
@ -238,7 +235,6 @@ class TestNetnsCleanup(unittest.TestCase):
with mock.patch('eventlet.sleep') as eventlet_sleep: with mock.patch('eventlet.sleep') as eventlet_sleep:
conf = mock.Mock() conf = mock.Mock()
conf.root_helper = 'sudo'
conf.force = False conf.force = False
methods_to_mock = dict( methods_to_mock = dict(
eligible_for_deletion=mock.DEFAULT, eligible_for_deletion=mock.DEFAULT,
@ -251,7 +247,7 @@ class TestNetnsCleanup(unittest.TestCase):
util.main() util.main()
ip_wrap.assert_has_calls( ip_wrap.assert_has_calls(
[mock.call.get_namespaces('sudo')]) [mock.call.get_namespaces(conf.AGENT.root_helper)])
mocks['eligible_for_deletion'].assert_has_calls( mocks['eligible_for_deletion'].assert_has_calls(
[mock.call(conf, 'ns1', False), [mock.call(conf, 'ns1', False),

View File

@ -21,6 +21,7 @@ import unittest2
import mock import mock
from quantum.agent import l3_agent from quantum.agent import l3_agent
from quantum.agent.common import config as agent_config
from quantum.agent.linux import interface from quantum.agent.linux import interface
from quantum.common import config as base_config from quantum.common import config as base_config
from quantum.common import constants as l3_constants from quantum.common import constants as l3_constants
@ -38,6 +39,7 @@ class TestBasicRouterOperations(unittest2.TestCase):
self.conf = cfg.ConfigOpts() self.conf = cfg.ConfigOpts()
self.conf.register_opts(base_config.core_opts) self.conf.register_opts(base_config.core_opts)
self.conf.register_opts(l3_agent.L3NATAgent.OPTS) self.conf.register_opts(l3_agent.L3NATAgent.OPTS)
agent_config.register_root_helper(self.conf)
self.conf.register_opts(interface.OPTS) self.conf.register_opts(interface.OPTS)
self.conf.set_override('interface_driver', self.conf.set_override('interface_driver',
'quantum.agent.linux.interface.NullDriver') 'quantum.agent.linux.interface.NullDriver')

View File

@ -65,7 +65,7 @@ class TestBase(unittest.TestCase):
] ]
self.conf = config.setup_conf() self.conf = config.setup_conf()
self.conf.register_opts(interface.OPTS) self.conf.register_opts(interface.OPTS)
self.conf.register_opts(root_helper_opt) config.register_root_helper(self.conf)
self.ip_dev_p = mock.patch.object(ip_lib, 'IPDevice') self.ip_dev_p = mock.patch.object(ip_lib, 'IPDevice')
self.ip_dev = self.ip_dev_p.start() self.ip_dev = self.ip_dev_p.start()
self.ip_p = mock.patch.object(ip_lib, 'IPWrapper') self.ip_p = mock.patch.object(ip_lib, 'IPWrapper')