diff options
author | 2016-11-16 22:52:31 +0000 | |
---|---|---|
committer | 2016-11-16 22:52:31 +0000 | |
commit | 9971eb3af988b1f7c003048af161489ab79b1b0c (patch) | |
tree | c1308732dfd4913ae5d3ca15cc2eeb5d7198a3b0 /os_net_config | |
parent | e479535b508b4072f64300809b824dfecc3a9182 (diff) | |
parent | fceeece7676c900e5295603f318c4218ac516bcb (diff) |
Merge "Stop dhclient in os-net-config if interface not set for DHCP"
Diffstat (limited to 'os_net_config')
-rw-r--r-- | os_net_config/impl_ifcfg.py | 44 | ||||
-rw-r--r-- | os_net_config/tests/test_impl_ifcfg.py | 21 |
2 files changed, 65 insertions, 0 deletions
diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py index e8dbd46..41d5f8c 100644 --- a/os_net_config/impl_ifcfg.py +++ b/os_net_config/impl_ifcfg.py @@ -16,6 +16,7 @@ import glob import logging +import os import re import os_net_config @@ -25,6 +26,9 @@ from os_net_config import utils logger = logging.getLogger(__name__) +# Import the raw NetConfig object so we can call its methods +netconfig = os_net_config.NetConfig() + def ifcfg_config_path(name): return "/etc/sysconfig/network-scripts/ifcfg-%s" % name @@ -55,6 +59,39 @@ def cleanup_pattern(): return "/etc/sysconfig/network-scripts/ifcfg-*" +def dhclient_path(): + if os.path.exists("/usr/sbin/dhclient"): + return "/usr/sbin/dhclient" + elif os.path.exists("/sbin/dhclient"): + return "/sbin/dhclient" + else: + raise RuntimeError("Could not find dhclient") + + +def stop_dhclient_process(interface): + """Stop a DHCP process when no longer needed. + + This method exists so that it may be stubbed out for unit tests. + :param interface: The interface on which to stop dhclient. + """ + pid_file = '/var/run/dhclient-%s.pid' % (interface) + try: + dhclient = dhclient_path() + except RuntimeError as err: + logger.info('Exception when stopping dhclient: %s' % err) + return + + if os.path.exists(pid_file): + msg = 'Stopping %s on interface %s' % (dhclient, interface) + netconfig.execute(msg, dhclient, '-r', '-pf', + pid_file, interface) + try: + os.unlink(pid_file) + except OSError as err: + logger.error('Could not remove dhclient pid file \'%s\': %s' % + (pid_file, err)) + + class IfcfgNetConfig(os_net_config.NetConfig): """Configure network interfaces using the ifcfg format.""" @@ -639,6 +676,7 @@ class IfcfgNetConfig(os_net_config.NetConfig): ivs_interfaces = [] # ivs internal ports nfvswitch_interfaces = [] # nfvswitch physical interfaces nfvswitch_internal_ifaces = [] # nfvswitch internal/management ports + stop_dhclient_interfaces = [] for interface_name, iface_data in self.interface_data.iteritems(): route_data = self.route_data.get(interface_name, '') @@ -662,6 +700,8 @@ class IfcfgNetConfig(os_net_config.NetConfig): update_files[interface_path] = iface_data update_files[route_path] = route_data update_files[route6_path] = route6_data + if "BOOTPROTO=dhcp" not in iface_data: + stop_dhclient_interfaces.append(interface_name) else: logger.info('No changes required for interface: %s' % interface_name) @@ -890,6 +930,10 @@ class IfcfgNetConfig(os_net_config.NetConfig): for bridge in restart_bridges: self.ifup(bridge, iftype='bridge') + # If dhclient is running and dhcp not set, stop dhclient + for interface in stop_dhclient_interfaces: + stop_dhclient_process(interface) + for interface in restart_interfaces: self.ifup(interface) diff --git a/os_net_config/tests/test_impl_ifcfg.py b/os_net_config/tests/test_impl_ifcfg.py index 2f5b3af..3a5a7db 100644 --- a/os_net_config/tests/test_impl_ifcfg.py +++ b/os_net_config/tests/test_impl_ifcfg.py @@ -915,6 +915,7 @@ class TestIfcfgNetConfigApply(base.TestCase): self.temp_cleanup_file = tempfile.NamedTemporaryFile(delete=False) self.ifup_interface_names = [] self.ovs_appctl_cmds = [] + self.stop_dhclient_interfaces = [] def test_ifcfg_path(name): return self.temp_ifcfg_file.name @@ -936,6 +937,11 @@ class TestIfcfgNetConfigApply(base.TestCase): return self.temp_cleanup_file.name self.stubs.Set(impl_ifcfg, 'cleanup_pattern', test_cleanup_pattern) + def test_stop_dhclient_process(interface): + self.stop_dhclient_interfaces.append(interface) + self.stubs.Set(impl_ifcfg, 'stop_dhclient_process', + test_stop_dhclient_process) + def test_execute(*args, **kwargs): if args[0] == '/sbin/ifup': self.ifup_interface_names.append(args[1]) @@ -988,6 +994,21 @@ class TestIfcfgNetConfigApply(base.TestCase): route_data = utils.get_file_data(self.temp_route_file.name) self.assertEqual("", route_data) + def test_dhclient_stop_on_iface_activate(self): + self.stop_dhclient_interfaces = [] + v4_addr = objects.Address('192.168.1.2/24') + interface = objects.Interface('em1', addresses=[v4_addr]) + interface2 = objects.Interface('em2', use_dhcp=True) + interface3 = objects.Interface('em3', use_dhcp=False) + self.provider.add_interface(interface) + self.provider.add_interface(interface2) + self.provider.add_interface(interface3) + self.provider.apply() + # stop dhclient on em1 due to static IP and em3 due to no IP + self.assertIn('em1', self.stop_dhclient_interfaces) + self.assertIn('em3', self.stop_dhclient_interfaces) + self.assertNotIn('em2', self.stop_dhclient_interfaces) + def test_apply_noactivate(self): interface = objects.Interface('em1') bridge = objects.OvsBridge('br-ctlplane', use_dhcp=True, |