diff options
Diffstat (limited to 'os_net_config/impl_ifcfg.py')
-rw-r--r-- | os_net_config/impl_ifcfg.py | 112 |
1 files changed, 86 insertions, 26 deletions
diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py index 56f2b33..6d3c681 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.""" @@ -94,7 +131,10 @@ class IfcfgNetConfig(os_net_config.NetConfig): data = "# This file is autogenerated by os-net-config\n" data += "DEVICE=%s\n" % base_opt.name data += "ONBOOT=yes\n" - data += "HOTPLUG=no\n" + if isinstance(base_opt, objects.Interface) and base_opt.hotplug: + data += "HOTPLUG=yes\n" + else: + data += "HOTPLUG=no\n" data += "NM_CONTROLLED=no\n" if not base_opt.dns_servers and not base_opt.use_dhcp: data += "PEERDNS=no\n" @@ -113,6 +153,8 @@ class IfcfgNetConfig(os_net_config.NetConfig): data += "TYPE=NFVSWITCHIntPort\n" elif isinstance(base_opt, objects.IbInterface): data += "TYPE=Infiniband\n" + if base_opt.ethtool_opts: + data += "ETHTOOL_OPTS=\"%s\"\n" % base_opt.ethtool_opts elif re.match('\w+\.\d+$', base_opt.name): data += "VLAN=yes\n" if base_opt.linux_bond_name: @@ -244,15 +286,18 @@ class IfcfgNetConfig(os_net_config.NetConfig): data += "OVS_BRIDGE=%s\n" % base_opt.bridge_name elif isinstance(base_opt, objects.OvsDpdkBond): ovs_extra.extend(base_opt.ovs_extra) - if base_opt.primary_interface_name: - primary_name = base_opt.primary_interface_name - self.bond_primary_ifaces[base_opt.name] = primary_name + # Referring to bug:1643026, the below commenting of the interfaces, + # is to workaround the error, but is not the long term solution. + # The long term solution is to run DPDK options before + # os-net-config, which is being tracked at BUG:1654975 + # if base_opt.primary_interface_name: + # primary_name = base_opt.primary_interface_name + # self.bond_primary_ifaces[base_opt.name] = primary_name data += "DEVICETYPE=ovs\n" data += "TYPE=OVSDPDKBond\n" data += "OVS_BRIDGE=%s\n" % base_opt.bridge_name if base_opt.members: members = [member.name for member in base_opt.members] - self.member_names[base_opt.name] = members data += ("BOND_IFACES=\"%s\"\n" % " ".join(members)) if base_opt.ovs_options: data += "OVS_OPTIONS=\"%s\"\n" % base_opt.ovs_options @@ -262,6 +307,9 @@ class IfcfgNetConfig(os_net_config.NetConfig): data += "BOOTPROTO=dhcp\n" elif not base_opt.addresses: data += "BOOTPROTO=none\n" + if isinstance(base_opt, objects.Interface): + if base_opt.ethtool_opts: + data += "ETHTOOL_OPTS=\"%s\"\n" % base_opt.ethtool_opts if base_opt.mtu: data += "MTU=%i\n" % base_opt.mtu @@ -313,24 +361,29 @@ class IfcfgNetConfig(os_net_config.NetConfig): data6 = "" first_line6 = "" for route in routes: + options = "" + if route.route_options: + options = " %s" % (route.route_options) if ":" not in route.next_hop: # Route is an IPv4 route if route.default: - first_line = "default via %s dev %s\n" % (route.next_hop, - interface_name) + first_line = "default via %s dev %s%s\n" % ( + route.next_hop, interface_name, + options) else: - data += "%s via %s dev %s\n" % (route.ip_netmask, - route.next_hop, - interface_name) + data += "%s via %s dev %s%s\n" % ( + route.ip_netmask, route.next_hop, + interface_name, options) else: # Route is an IPv6 route if route.default: - first_line6 = "default via %s dev %s\n" % (route.next_hop, - interface_name) + first_line6 = "default via %s dev %s%s\n" % ( + route.next_hop, interface_name, + options) else: - data6 += "%s via %s dev %s\n" % (route.ip_netmask, - route.next_hop, - interface_name) + data6 += "%s via %s dev %s%s\n" % ( + route.ip_netmask, route.next_hop, + interface_name, options) self.route_data[interface_name] = first_line + data self.route6_data[interface_name] = first_line6 + data6 logger.debug('route data: %s' % self.route_data[interface_name]) @@ -629,8 +682,9 @@ 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(): + for interface_name, iface_data in self.interface_data.items(): route_data = self.route_data.get(interface_name, '') route6_data = self.route6_data.get(interface_name, '') interface_path = self.root_dir + ifcfg_config_path(interface_name) @@ -652,11 +706,13 @@ 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) - for interface_name, iface_data in self.ivsinterface_data.iteritems(): + for interface_name, iface_data in self.ivsinterface_data.items(): route_data = self.route_data.get(interface_name, '') route6_data = self.route6_data.get(interface_name, '') interface_path = self.root_dir + ifcfg_config_path(interface_name) @@ -677,7 +733,7 @@ class IfcfgNetConfig(os_net_config.NetConfig): logger.info('No changes required for ivs interface: %s' % interface_name) - for iface_name, iface_data in self.nfvswitch_intiface_data.iteritems(): + for iface_name, iface_data in self.nfvswitch_intiface_data.items(): route_data = self.route_data.get(iface_name, '') route6_data = self.route6_data.get(iface_name, '') iface_path = self.root_dir + ifcfg_config_path(iface_name) @@ -698,7 +754,7 @@ class IfcfgNetConfig(os_net_config.NetConfig): logger.info('No changes required for nfvswitch interface: %s' % iface_name) - for vlan_name, vlan_data in self.vlan_data.iteritems(): + for vlan_name, vlan_data in self.vlan_data.items(): route_data = self.route_data.get(vlan_name, '') route6_data = self.route6_data.get(vlan_name, '') vlan_path = self.root_dir + ifcfg_config_path(vlan_name) @@ -718,7 +774,7 @@ class IfcfgNetConfig(os_net_config.NetConfig): logger.info('No changes required for vlan interface: %s' % vlan_name) - for bridge_name, bridge_data in self.bridge_data.iteritems(): + for bridge_name, bridge_data in self.bridge_data.items(): route_data = self.route_data.get(bridge_name, '') route6_data = self.route6_data.get(bridge_name, '') bridge_path = self.root_dir + bridge_config_path(bridge_name) @@ -742,7 +798,7 @@ class IfcfgNetConfig(os_net_config.NetConfig): else: logger.info('No changes required for bridge: %s' % bridge_name) - for bridge_name, bridge_data in self.linuxbridge_data.iteritems(): + for bridge_name, bridge_data in self.linuxbridge_data.items(): route_data = self.route_data.get(bridge_name, '') route6_data = self.route6_data.get(bridge_name, '') bridge_path = self.root_dir + bridge_config_path(bridge_name) @@ -762,7 +818,7 @@ class IfcfgNetConfig(os_net_config.NetConfig): else: logger.info('No changes required for bridge: %s' % bridge_name) - for team_name, team_data in self.linuxteam_data.iteritems(): + for team_name, team_data in self.linuxteam_data.items(): route_data = self.route_data.get(team_name, '') route6_data = self.route6_data.get(team_name, '') team_path = self.root_dir + bridge_config_path(team_name) @@ -783,7 +839,7 @@ class IfcfgNetConfig(os_net_config.NetConfig): logger.info('No changes required for linux team: %s' % team_name) - for bond_name, bond_data in self.linuxbond_data.iteritems(): + for bond_name, bond_data in self.linuxbond_data.items(): route_data = self.route_data.get(bond_name, '') route6_data = self.route6_data.get(bond_name, '') bond_path = self.root_dir + bridge_config_path(bond_name) @@ -805,7 +861,7 @@ class IfcfgNetConfig(os_net_config.NetConfig): bond_name) # Infiniband interfaces are handled similarly to Ethernet interfaces - for interface_name, iface_data in self.ib_interface_data.iteritems(): + for interface_name, iface_data in self.ib_interface_data.items(): route_data = self.route_data.get(interface_name, '') route6_data = self.route6_data.get(interface_name, '') interface_path = self.root_dir + ifcfg_config_path(interface_name) @@ -856,10 +912,10 @@ class IfcfgNetConfig(os_net_config.NetConfig): for bridge in restart_bridges: self.ifdown(bridge, iftype='bridge') - for oldname, newname in self.renamed_interfaces.iteritems(): + for oldname, newname in self.renamed_interfaces.items(): self.ifrename(oldname, newname) - for location, data in update_files.iteritems(): + for location, data in update_files.items(): self.write_config(location, data) if ivs_uplinks or ivs_interfaces: @@ -880,6 +936,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) |