]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Define root_helper variable under the [AGENT] section
authorGary Kotton <gkotton@redhat.com>
Mon, 28 Jan 2013 13:37:47 +0000 (13:37 +0000)
committerGary Kotton <gkotton@redhat.com>
Mon, 4 Feb 2013 09:11:47 +0000 (09:11 +0000)
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

23 files changed:
etc/dhcp_agent.ini
etc/l3_agent.ini
etc/metadata_agent.ini
etc/quantum.conf
etc/quantum/plugins/linuxbridge/linuxbridge_conf.ini
etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini
etc/quantum/plugins/ryu/ryu.ini
quantum/agent/common/config.py
quantum/agent/dhcp_agent.py
quantum/agent/l3_agent.py
quantum/agent/linux/interface.py
quantum/agent/netns_cleanup_util.py
quantum/agent/ovs_cleanup_util.py
quantum/debug/debug_agent.py
quantum/debug/shell.py
quantum/plugins/linuxbridge/common/config.py
quantum/plugins/nec/common/config.py
quantum/plugins/openvswitch/common/config.py
quantum/plugins/ryu/common/config.py
quantum/tests/unit/test_agent_config.py
quantum/tests/unit/test_agent_netns_cleanup.py
quantum/tests/unit/test_l3_agent.py
quantum/tests/unit/test_linux_interface.py

index 2f7c2339dc1843ac59acf6c1265bb329fc1c2964..3ec8a82fbcdfff4db0a2052bf2530dbf8d86d32c 100644 (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
 # iproute2 package that supports namespaces).
 # 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
index 9e6190cdd639a3076eca5918e41c8d212c8a1b8a..2021b17b6f7e961be26568ebfc6b021d380752d2 100644 (file)
@@ -13,11 +13,6 @@ interface_driver = quantum.agent.linux.interface.OVSInterfaceDriver
 # LinuxBridge
 #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
 # iproute2 package that supports namespaces).
 # use_namespaces = True
index 51169210a5d3d12514f0b2215f9f19a94dc51076..e7630911d31020ae23be14ca0810f7e6d97aa6b6 100644 (file)
@@ -9,11 +9,6 @@ admin_tenant_name = %SERVICE_TENANT_NAME%
 admin_user = %SERVICE_USER%
 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
 # user executing the agent.
 # state_path = /var/lib/quantum
index a9242d5946f87cadba91dd4c71aa55f19274f90a..01c00bfbe08d64bd2ba9d93c6c117d21de1d2fcd 100644 (file)
@@ -201,3 +201,9 @@ notification_topics = notifications
 [SECURITYGROUP]
 # If set to true this allows quantum to receive proxied security group calls from nova
 # 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
index 6b0bf58c44f17c56cc5fb1fa318a17f38b2c11b2..d882c7239866982a89d8fa2d169dbebff5c7a752 100644 (file)
@@ -57,7 +57,3 @@ reconnect_interval = 2
 [AGENT]
 # Agent's polling interval in seconds
 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"
index c50b898055a293ab21c9842c3232ea56e71a5024..a6308467e4067a6538df555cb330c1c656881109 100644 (file)
@@ -96,10 +96,6 @@ reconnect_interval = 2
 [AGENT]
 # Agent's polling interval in seconds
 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.
@@ -114,7 +110,6 @@ root_helper = sudo
 # integration_bridge = br-int
 # bridge_mappings = default:br-eth1
 # [AGENT]
-# root_helper = sudo
 # Add the following setting, if you want to log to a file
 #
 # 2. With tunneling.
@@ -126,5 +121,3 @@ root_helper = sudo
 # integration_bridge = br-int
 # tunnel_bridge = br-tun
 # local_ip = 10.0.0.3
-# [AGENT]
-# root_helper = sudo
index 3d687c7bc50756c7834bd15122a3b49affed3641..3376d2bbfb4d17cc72737886a5449c67c2b2b213 100644 (file)
@@ -45,9 +45,3 @@ tunnel_interface = eth0
 # ovsdb_ip =
 # ovsdb_interface =
 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
index de58ee26b5625d745a64d56e8396b7dc7d60fb5c..f9b8eb147269586e7c5f58849e6d4dc06e22c182 100644 (file)
 
 from quantum.common import config
 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():
index 660a6ca39a5ddfed09fd8e3f7c416523c2403030..b3ef9d7d5f557d05b3c5ee63a373140c40976701 100644 (file)
@@ -43,8 +43,6 @@ NS_PREFIX = 'qdhcp-'
 
 class DhcpAgent(object):
     OPTS = [
-        cfg.StrOpt('root_helper', default='sudo',
-                   help=_("Root helper application.")),
         cfg.IntOpt('resync_interval', default=30,
                    help=_("Interval to resync.")),
         cfg.StrOpt('dhcp_driver',
@@ -58,6 +56,7 @@ class DhcpAgent(object):
         self.needs_resync = False
         self.conf = conf
         self.cache = NetworkCache()
+        self.root_helper = config.get_root_helper(conf)
 
         self.dhcp_driver_cls = importutils.import_class(conf.dhcp_driver)
         ctx = context.get_admin_context_without_session()
@@ -85,7 +84,7 @@ class DhcpAgent(object):
             # the base models.
             driver = self.dhcp_driver_cls(self.conf,
                                           network,
-                                          self.conf.root_helper,
+                                          self.root_helper,
                                           self.device_manager,
                                           namespace)
             getattr(driver, action)()
@@ -394,6 +393,7 @@ class DeviceManager(object):
 
     def __init__(self, conf, plugin):
         self.conf = conf
+        self.root_helper = config.get_root_helper(conf)
         self.plugin = plugin
         if not conf.interface_driver:
             LOG.error(_('You must specify an interface driver'))
@@ -427,7 +427,7 @@ class DeviceManager(object):
             namespace = None
 
         if ip_lib.device_exists(interface_name,
-                                self.conf.root_helper,
+                                self.root_helper,
                                 namespace):
             if not reuse_existing:
                 raise exceptions.PreexistingDeviceFailure(
@@ -452,7 +452,8 @@ class DeviceManager(object):
 
         # ensure that the dhcp interface is first in the list
         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)
 
         return interface_name
@@ -547,6 +548,7 @@ class DhcpLeaseRelay(object):
 def main():
     eventlet.monkey_patch()
     cfg.CONF.register_opts(DhcpAgent.OPTS)
+    config.register_root_helper(cfg.CONF)
     cfg.CONF.register_opts(DeviceManager.OPTS)
     cfg.CONF.register_opts(DhcpLeaseRelay.OPTS)
     cfg.CONF.register_opts(dhcp.OPTS)
index f15fff6f5eee7430d57cdc0b09e9cfd557dc74f9..886b39b7af1e7db2a535684f5f68887058360e72 100644 (file)
@@ -111,8 +111,6 @@ class RouterInfo(object):
 class L3NATAgent(manager.Manager):
 
     OPTS = [
-        cfg.StrOpt('root_helper', default='sudo',
-                   help=_("Root helper application.")),
         cfg.StrOpt('external_network_bridge', default='br-ex',
                    help=_("Name of bridge used for external network "
                           "traffic.")),
@@ -150,6 +148,7 @@ class L3NATAgent(manager.Manager):
             self.conf = conf
         else:
             self.conf = cfg.CONF
+        self.root_helper = config.get_root_helper(self.conf)
         self.router_info = {}
 
         if not self.conf.interface_driver:
@@ -173,8 +172,8 @@ class L3NATAgent(manager.Manager):
         """Destroy all router namespaces on the host to eliminate
         all stale linux devices, iptables rules, and namespaces.
         """
-        root_ip = ip_lib.IPWrapper(self.conf.root_helper)
-        for ns in root_ip.get_namespaces(self.conf.root_helper):
+        root_ip = ip_lib.IPWrapper(self.root_helper)
+        for ns in root_ip.get_namespaces(self.root_helper):
             if ns.startswith(NS_PREFIX):
                 try:
                     self._destroy_router_namespace(ns)
@@ -182,8 +181,7 @@ class L3NATAgent(manager.Manager):
                     LOG.exception(_("Failed deleting namespace '%s'"), ns)
 
     def _destroy_router_namespace(self, namespace):
-        ns_ip = ip_lib.IPWrapper(self.conf.root_helper,
-                                 namespace=namespace)
+        ns_ip = ip_lib.IPWrapper(self.root_helper, namespace=namespace)
         for d in ns_ip.get_devices(exclude_loopback=True):
             if d.name.startswith(INTERNAL_DEV_PREFIX):
                 # device is on default bridge
@@ -197,7 +195,7 @@ class L3NATAgent(manager.Manager):
         #(TODO) Address the failure for the deletion of the namespace
 
     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.netns.execute(['sysctl', '-w', 'net.ipv4.ip_forward=1'])
 
@@ -218,7 +216,7 @@ class L3NATAgent(manager.Manager):
                 raise
 
     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.router_info[router_id] = ri
         if self.conf.use_namespaces:
@@ -251,7 +249,7 @@ class L3NATAgent(manager.Manager):
         pm = external_process.ProcessManager(
             self.conf,
             router_info.router_id,
-            self.conf.root_helper,
+            self.root_helper,
             router_info.ns_name())
         pm.enable(callback)
 
@@ -259,7 +257,7 @@ class L3NATAgent(manager.Manager):
         pm = external_process.ProcessManager(
             self.conf,
             router_info.router_id,
-            self.conf.root_helper,
+            self.root_helper,
             router_info.ns_name())
         pm.disable()
 
@@ -364,12 +362,12 @@ class L3NATAgent(manager.Manager):
                           ip_address]
             try:
                 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())
                     ip_wrapper.netns.execute(arping_cmd, check_exit_code=True)
                 else:
                     utils.execute(arping_cmd, check_exit_code=True,
-                                  root_helper=self.conf.root_helper)
+                                  root_helper=self.root_helper)
             except Exception as 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'])
         ex_gw_ip = ex_gw_port['fixed_ips'][0]['ip_address']
         if not ip_lib.device_exists(interface_name,
-                                    root_helper=self.conf.root_helper,
+                                    root_helper=self.root_helper,
                                     namespace=ri.ns_name()):
             self.driver.plug(ex_gw_port['network_id'],
                              ex_gw_port['id'], interface_name,
@@ -401,12 +399,12 @@ class L3NATAgent(manager.Manager):
         if ex_gw_port['subnet']['gateway_ip']:
             cmd = ['route', 'add', 'default', 'gw', gw_ip]
             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())
                 ip_wrapper.netns.execute(cmd, check_exit_code=False)
             else:
                 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,
                                                       internal_cidrs,
@@ -418,7 +416,7 @@ class L3NATAgent(manager.Manager):
 
         interface_name = self.get_external_device_name(ex_gw_port['id'])
         if ip_lib.device_exists(interface_name,
-                                root_helper=self.conf.root_helper,
+                                root_helper=self.root_helper,
                                 namespace=ri.ns_name()):
             self.driver.unplug(interface_name,
                                bridge=self.conf.external_network_bridge,
@@ -458,7 +456,7 @@ class L3NATAgent(manager.Manager):
                                internal_cidr, mac_address):
         interface_name = self.get_internal_device_name(port_id)
         if not ip_lib.device_exists(interface_name,
-                                    root_helper=self.conf.root_helper,
+                                    root_helper=self.root_helper,
                                     namespace=ri.ns_name()):
             self.driver.plug(network_id, port_id, interface_name, mac_address,
                              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):
         interface_name = self.get_internal_device_name(port_id)
         if ip_lib.device_exists(interface_name,
-                                root_helper=self.conf.root_helper,
+                                root_helper=self.root_helper,
                                 namespace=ri.ns_name()):
             self.driver.unplug(interface_name, namespace=ri.ns_name(),
                                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):
         ip_cidr = str(floating_ip) + '/32'
         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())
 
         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)
         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())
         device.addr.delete(net.version, ip_cidr)
 
@@ -616,6 +614,7 @@ def main():
     eventlet.monkey_patch()
     conf = cfg.CONF
     conf.register_opts(L3NATAgent.OPTS)
+    config.register_root_helper(conf)
     conf.register_opts(interface.OPTS)
     conf.register_opts(external_process.OPTS)
     conf()
index 1dc8e791ef3740bbcddf148e45d145bc7fc15a4b..e32e375e58a11ab1ea14485ab792d25b378ec82e 100644 (file)
@@ -19,6 +19,7 @@ import abc
 
 import netaddr
 
+from quantum.agent.common import config
 from quantum.agent.linux import ip_lib
 from quantum.agent.linux import ovs_lib
 from quantum.agent.linux import utils
@@ -54,12 +55,14 @@ class LinuxInterfaceDriver(object):
 
     def __init__(self, conf):
         self.conf = conf
+        self.root_helper = config.get_root_helper(conf)
 
     def init_l3(self, device_name, ip_cidrs, namespace=None):
         """Set the L3 settings for the interface using data from the port.
            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)
 
         previous = {}
@@ -133,7 +136,7 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
                 'external-ids:iface-status=active',
                 '--', 'set', 'Interface', device_name,
                 '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,
              bridge=None, namespace=None, prefix=None):
@@ -144,10 +147,10 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
         self.check_bridge_exists(bridge)
 
         if not ip_lib.device_exists(device_name,
-                                    self.conf.root_helper,
+                                    self.root_helper,
                                     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)
 
             if self.conf.ovs_use_veth:
@@ -182,12 +185,13 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
 
         tap_name = self._get_tap_name(device_name, prefix)
         self.check_bridge_exists(bridge)
-        ovs = ovs_lib.OVSBridge(bridge, self.conf.root_helper)
+        ovs = ovs_lib.OVSBridge(bridge, self.root_helper)
 
         try:
             ovs.delete_port(tap_name)
             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)
                 device.link.delete()
                 LOG.debug(_("Unplugged interface '%s'"), device_name)
@@ -205,9 +209,9 @@ class BridgeInterfaceDriver(LinuxInterfaceDriver):
              bridge=None, namespace=None, prefix=None):
         """Plugin the interface."""
         if not ip_lib.device_exists(device_name,
-                                    self.conf.root_helper,
+                                    self.root_helper,
                                     namespace=namespace):
-            ip = ip_lib.IPWrapper(self.conf.root_helper)
+            ip = ip_lib.IPWrapper(self.root_helper)
 
             # Enable agent to define the prefix
             if prefix:
@@ -233,7 +237,7 @@ class BridgeInterfaceDriver(LinuxInterfaceDriver):
 
     def unplug(self, device_name, bridge=None, namespace=None, prefix=None):
         """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:
             device.link.delete()
             LOG.debug(_("Unplugged interface '%s'"), device_name)
@@ -267,7 +271,7 @@ class MetaInterfaceDriver(LinuxInterfaceDriver):
         return self.flavor_driver_map[flavor]
 
     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
         ports = self.quantum.list_ports(mac_address=mac_address)
         if not ports.get('ports'):
index c4d93f89366e134344bdf1a5b94713425fdb2840..aed80bec5e9c88d28ac2b50a9359e37e69a43fc4 100644 (file)
@@ -21,6 +21,7 @@ import eventlet
 
 from quantum.agent import dhcp_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 ip_lib
 from quantum.agent.linux import ovs_lib
@@ -56,8 +57,6 @@ def setup_conf():
     """
 
     opts = [
-        cfg.StrOpt('root_helper', default='sudo',
-                   help=_("Root helper application.")),
         cfg.StrOpt('dhcp_driver',
                    default='quantum.agent.linux.dhcp.Dnsmasq',
                    help=_("The driver used to manage the DHCP server.")),
@@ -68,8 +67,10 @@ def setup_conf():
                     default=False,
                     help=_('Delete the namespace by removing all devices.')),
     ]
+
     conf = cfg.ConfigOpts()
     conf.register_opts(opts)
+    agent_config.register_root_helper(conf)
     conf.register_opts(dhcp.OPTS)
     config.setup_logging(conf)
     return conf
@@ -77,6 +78,7 @@ def setup_conf():
 
 def kill_dhcp(conf, namespace):
     """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, '')
 
     null_delegate = NullDelegate()
@@ -84,7 +86,7 @@ def kill_dhcp(conf, namespace):
         conf.dhcp_driver,
         conf,
         FakeNetwork(network_id),
-        conf.root_helper,
+        root_helper,
         null_delegate)
 
     if dhcp_driver.active:
@@ -102,7 +104,8 @@ def eligible_for_deletion(conf, namespace, force=False):
     if not re.match(NS_MANGLING_PATTERN, namespace):
         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()
 
 
@@ -110,12 +113,11 @@ def unplug_device(conf, device):
     try:
         device.link.delete()
     except RuntimeError:
+        root_helper = agent_config.get_root_helper(conf)
         # Maybe the device is OVS port, so try to delete
-        bridge_name = ovs_lib.get_bridge_for_iface(conf.root_helper,
-                                                   device.name)
+        bridge_name = ovs_lib.get_bridge_for_iface(root_helper, device.name)
         if bridge_name:
-            bridge = ovs_lib.OVSBridge(bridge_name,
-                                       conf.root_helper)
+            bridge = ovs_lib.OVSBridge(bridge_name, root_helper)
             bridge.delete_port(device.name)
         else:
             LOG.debug(_('Unable to find bridge for device: %s'), device.name)
@@ -129,7 +131,8 @@ def destroy_namespace(conf, namespace, force=False):
     """
 
     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:
             kill_dhcp(conf, namespace)
@@ -166,9 +169,10 @@ def main():
     conf = setup_conf()
     conf()
 
+    root_helper = agent_config.get_root_helper(conf)
     # Identify namespaces that are candidates for deletion.
     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 candidates:
index 31d1f4b041c3bbfc3483ccade986a902dfdad5a3..12d2fe9e6daaf2a85001dab4f3cbf269d76b4677 100644 (file)
@@ -16,6 +16,7 @@
 #    under the License.
 
 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 ip_lib
 from quantum.agent.linux import ovs_lib
@@ -42,16 +43,11 @@ def setup_conf():
                            'bridges.'))
     ]
 
-    agent_opts = [
-        cfg.StrOpt('root_helper', default='sudo',
-                   help=_("Root helper application.")),
-    ]
-
     conf = cfg.ConfigOpts()
     conf.register_cli_opts(opts)
     conf.register_opts(l3_agent.L3NATAgent.OPTS)
     conf.register_opts(interface.OPTS)
-    conf.register_opts(agent_opts, 'AGENT')
+    agent_config.register_root_helper(conf)
     config.setup_logging(conf)
     return conf
 
index 06138d63278c0f8533ccd28591efea438d8d4867..27c3f69f7eaf05d15832a5c7d91d22f3d390df4b 100644 (file)
@@ -20,6 +20,7 @@ import socket
 
 import netaddr
 
+from quantum.agent.common import config
 from quantum.agent.dhcp_agent import DictModel
 from quantum.agent.linux import ip_lib
 from quantum.agent.linux import utils
@@ -35,8 +36,6 @@ DEVICE_OWNER_PROBE = 'network:probe'
 class QuantumDebugAgent():
 
     OPTS = [
-        cfg.StrOpt('root_helper', default='sudo',
-                   help=_("Root helper application.")),
         # Needed for drivers
         cfg.StrOpt('admin_user',
                    help=_("Admin user")),
@@ -62,6 +61,7 @@ class QuantumDebugAgent():
 
     def __init__(self, conf, client, driver):
         self.conf = conf
+        self.root_helper = config.get_root_helper(conf)
         self.client = client
         self.driver = driver
 
@@ -81,8 +81,7 @@ class QuantumDebugAgent():
         if self.conf.use_namespaces:
             namespace = self._get_namespace(port)
 
-        if ip_lib.device_exists(interface_name,
-                                self.conf.root_helper, namespace):
+        if ip_lib.device_exists(interface_name, self.root_helper, namespace):
             LOG.debug(_('Reusing existing device: %s.'), interface_name)
         else:
             self.driver.plug(network.id,
@@ -125,7 +124,7 @@ class QuantumDebugAgent():
         bridge = None
         if network.external:
             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)
         if self.conf.use_namespaces and ip.netns.exists(namespace):
             self.driver.unplug(self.driver.get_device_name(port),
@@ -149,7 +148,7 @@ class QuantumDebugAgent():
 
     def exec_command(self, port_id, command=None):
         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)
         if self.conf.use_namespaces:
             if not command:
index 39c5f0b1acbcc84fb77156c6e3453a532fd90908..327012554dbba7fbc21dd2675688a38956d58019 100644 (file)
@@ -69,6 +69,7 @@ class QuantumDebugShell(QuantumShell):
         client = self.client_manager.quantum
         cfg.CONF.register_opts(interface.OPTS)
         cfg.CONF.register_opts(QuantumDebugAgent.OPTS)
+        config.register_root_helper(cfg.CONF)
         cfg.CONF(['--config-file', self.options.config_file])
         config.setup_logging(cfg.CONF)
         driver = importutils.import_object(cfg.CONF.interface_driver, cfg.CONF)
index 39cffdd4736fdba3e803fc481a56ded021af80b4..af56d5b9c773a054538d5bfdb4e3ba990c31d225 100644 (file)
@@ -17,6 +17,7 @@
 # @author: Sumit Naiksatam, Cisco Systems, Inc.
 # @author: Rohit Agarwalla, Cisco Systems, Inc.
 
+from quantum.agent.common import config
 from quantum.openstack.common import cfg
 
 DEFAULT_VLAN_RANGES = []
@@ -43,11 +44,10 @@ agent_opts = [
     cfg.IntOpt('polling_interval', default=2,
                help=_("The number of seconds the agent will wait between "
                       "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(bridge_opts, "LINUX_BRIDGE")
 cfg.CONF.register_opts(agent_opts, "AGENT")
+config.register_root_helper(cfg.CONF)
index 0c9228bde3e15d8b4c128b6e94655438f98b3e43..e778251695323233cd0c6566007ff704915dd743 100644 (file)
@@ -15,6 +15,7 @@
 #    under the License.
 # @author: Ryota MIBU
 
+from quantum.agent.common import config
 from quantum.openstack.common import cfg
 # import rpc config options
 from quantum.openstack.common import rpc
@@ -29,8 +30,6 @@ agent_opts = [
     cfg.IntOpt('polling_interval', default=2,
                help=_("The number of seconds the agent will wait between "
                       "polling for local device changes.")),
-    cfg.StrOpt('root_helper', default='sudo',
-               help=_("Root helper application.")),
 ]
 
 ofc_opts = [
@@ -54,6 +53,7 @@ ofc_opts = [
 cfg.CONF.register_opts(ovs_opts, "OVS")
 cfg.CONF.register_opts(agent_opts, "AGENT")
 cfg.CONF.register_opts(ofc_opts, "OFC")
+config.register_root_helper(cfg.CONF)
 
 # shortcuts
 CONF = cfg.CONF
index fdd7c3918d25382247a52789c4485cff38bbda0e..4ffe58841919b7c4ca284b2e52fcc27a72bfdc04 100644 (file)
@@ -14,6 +14,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from quantum.agent.common import config
 from quantum.openstack.common import cfg
 
 
@@ -55,10 +56,9 @@ agent_opts = [
     cfg.IntOpt('polling_interval', default=2,
                help=_("The number of seconds the agent will wait between "
                       "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(agent_opts, "AGENT")
+config.register_root_helper(cfg.CONF)
index 02c1ea462a3c670f91180ab4e92f84c893406135..db2c19f2d00f14bbf08b7ff2fc60bcede9375476 100644 (file)
@@ -14,6 +14,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from quantum.agent.common import config
 from quantum.openstack.common import cfg
 
 
@@ -38,11 +39,6 @@ ovs_opts = [
                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(agent_opts, "AGENT")
+config.register_root_helper(cfg.CONF)
index 73e10ed01c38a3c8382b6568a9ce9648e594e29b..688f75009c43bb8ff981d46bd2ca8a875800798a 100644 (file)
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import unittest2
+
 from quantum.agent.common import config
 
 
 def test_setup_conf():
     conf = config.setup_conf()
     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')
index 8c864548631bfe2dc062409c7d93bbdb1e6f2978..a08dc2766ed6916abb4563e24fb9ef1a3041bcfd 100644 (file)
@@ -35,7 +35,7 @@ class TestNetnsCleanup(unittest.TestCase):
 
     def test_kill_dhcp(self, dhcp_active=True):
         conf = mock.Mock()
-        conf.root_helper = 'sudo',
+        conf.AGENT.root_helper = 'sudo',
         conf.dhcp_driver = 'driver'
 
         method_to_patch = 'quantum.openstack.common.importutils.import_object'
@@ -47,7 +47,8 @@ class TestNetnsCleanup(unittest.TestCase):
 
             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)
 
             if dhcp_active:
@@ -66,14 +67,13 @@ class TestNetnsCleanup(unittest.TestCase):
                                            expected):
         ns = prefix + '6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d'
         conf = mock.Mock()
-        conf.root_helper = 'sudo'
 
         with mock.patch('quantum.agent.linux.ip_lib.IPWrapper') as ip_wrap:
             ip_wrap.return_value.namespace_is_empty.return_value = is_empty
             self.assertEqual(util.eligible_for_deletion(conf, ns, force),
                              expected)
 
-            expected_calls = [mock.call('sudo', ns)]
+            expected_calls = [mock.call(conf.AGENT.root_helper, ns)]
             if not force:
                 expected_calls.append(mock.call().namespace_is_empty())
             ip_wrap.assert_has_calls(expected_calls)
@@ -97,7 +97,6 @@ class TestNetnsCleanup(unittest.TestCase):
     def test_unplug_device_ovs_port(self):
         conf = mock.Mock()
         conf.ovs_integration_bridge = 'br-int'
-        conf.root_helper = 'sudo'
 
         device = mock.Mock()
         device.name = 'tap1'
@@ -114,15 +113,14 @@ class TestNetnsCleanup(unittest.TestCase):
                 util.unplug_device(conf, device)
 
                 mock_get_bridge_for_iface.assert_called_once_with(
-                    conf.root_helper, 'tap1')
-                ovs_br_cls.called_once_with('br-int', 'sudo')
+                    conf.AGENT.root_helper, 'tap1')
+                ovs_br_cls.called_once_with('br-int', conf.AGENT.root_helper)
                 ovs_bridge.assert_has_calls(
                     [mock.call.delete_port(device.name)])
 
     def test_unplug_device_cannot_determine_bridge_port(self):
         conf = mock.Mock()
         conf.ovs_integration_bridge = 'br-int'
-        conf.root_helper = 'sudo'
 
         device = mock.Mock()
         device.name = 'tap1'
@@ -140,14 +138,14 @@ class TestNetnsCleanup(unittest.TestCase):
                     util.unplug_device(conf, device)
 
                     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.assertTrue(debug.called)
 
     def _test_destroy_namespace_helper(self, force, num_devices):
         ns = 'qrouter-6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d'
         conf = mock.Mock()
-        conf.root_helper = 'sudo'
+#        conf.AGENT.root_helper = 'sudo'
 
         lo_device = mock.Mock()
         lo_device.name = 'lo'
@@ -168,7 +166,7 @@ class TestNetnsCleanup(unittest.TestCase):
 
                 with mock.patch.object(util, 'kill_dhcp') as kill_dhcp:
                     util.destroy_namespace(conf, ns, force)
-                    expected = [mock.call('sudo', ns)]
+                    expected = [mock.call(conf.AGENT.root_helper, ns)]
 
                     if force:
                         expected.extend([
@@ -194,7 +192,7 @@ class TestNetnsCleanup(unittest.TestCase):
     def test_destroy_namespace_exception(self):
         ns = 'qrouter-6e322ac7-ab50-4f53-9cdc-d1d3c1164b6d'
         conf = mock.Mock()
-        conf.root_helper = 'sudo'
+        conf.AGENT.root_helper = 'sudo'
         with mock.patch('quantum.agent.linux.ip_lib.IPWrapper') as ip_wrap:
             ip_wrap.side_effect = Exception()
             util.destroy_namespace(conf, ns)
@@ -206,7 +204,6 @@ class TestNetnsCleanup(unittest.TestCase):
 
             with mock.patch('eventlet.sleep') as eventlet_sleep:
                 conf = mock.Mock()
-                conf.root_helper = 'sudo'
                 conf.force = False
                 methods_to_mock = dict(
                     eligible_for_deletion=mock.DEFAULT,
@@ -227,7 +224,7 @@ class TestNetnsCleanup(unittest.TestCase):
                          mock.call(conf, 'ns2', False)])
 
                     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)
 
@@ -238,7 +235,6 @@ class TestNetnsCleanup(unittest.TestCase):
 
             with mock.patch('eventlet.sleep') as eventlet_sleep:
                 conf = mock.Mock()
-                conf.root_helper = 'sudo'
                 conf.force = False
                 methods_to_mock = dict(
                     eligible_for_deletion=mock.DEFAULT,
@@ -251,7 +247,7 @@ class TestNetnsCleanup(unittest.TestCase):
                     util.main()
 
                     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(
                         [mock.call(conf, 'ns1', False),
index 1088489f044f0d52776d421e14a3269623f5e9ec..d5dcf368c91f9065cbd41268909682ae25f36280 100644 (file)
@@ -21,6 +21,7 @@ import unittest2
 import mock
 
 from quantum.agent import l3_agent
+from quantum.agent.common import config as agent_config
 from quantum.agent.linux import interface
 from quantum.common import config as base_config
 from quantum.common import constants as l3_constants
@@ -38,6 +39,7 @@ class TestBasicRouterOperations(unittest2.TestCase):
         self.conf = cfg.ConfigOpts()
         self.conf.register_opts(base_config.core_opts)
         self.conf.register_opts(l3_agent.L3NATAgent.OPTS)
+        agent_config.register_root_helper(self.conf)
         self.conf.register_opts(interface.OPTS)
         self.conf.set_override('interface_driver',
                                'quantum.agent.linux.interface.NullDriver')
index 50d7c65fa41f70c62ffc5e5fa7bf1fa7083e0579..4f5007f22f0a2b46b3dcff807c4da8e7a95b0b3f 100644 (file)
@@ -65,7 +65,7 @@ class TestBase(unittest.TestCase):
         ]
         self.conf = config.setup_conf()
         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 = self.ip_dev_p.start()
         self.ip_p = mock.patch.object(ip_lib, 'IPWrapper')