diff options
Diffstat (limited to 'os_net_config')
-rw-r--r-- | os_net_config/cli.py | 2 | ||||
-rw-r--r-- | os_net_config/impl_eni.py | 9 | ||||
-rw-r--r-- | os_net_config/impl_ifcfg.py | 38 | ||||
-rw-r--r-- | os_net_config/objects.py | 7 | ||||
-rw-r--r-- | os_net_config/tests/test_impl_eni.py | 17 | ||||
-rw-r--r-- | os_net_config/tests/test_impl_ifcfg.py | 14 | ||||
-rw-r--r-- | os_net_config/tests/test_objects.py | 25 |
7 files changed, 86 insertions, 26 deletions
diff --git a/os_net_config/cli.py b/os_net_config/cli.py index c0ac5c4..479b3a3 100644 --- a/os_net_config/cli.py +++ b/os_net_config/cli.py @@ -186,7 +186,7 @@ def main(argv=sys.argv): files_changed = provider.apply(cleanup=opts.cleanup, activate=not opts.no_activate) if opts.noop: - for location, data in files_changed.iteritems(): + for location, data in files_changed.items(): print("File: %s\n" % location) print(data) print("----") diff --git a/os_net_config/impl_eni.py b/os_net_config/impl_eni.py index 5b91270..360d8c8 100644 --- a/os_net_config/impl_eni.py +++ b/os_net_config/impl_eni.py @@ -127,7 +127,10 @@ class ENINetConfig(os_net_config.NetConfig): data += address_data data += " vlan-raw-device %s\n" % interface.device else: - data += "auto %s\n" % interface.name + if isinstance(interface, objects.Interface) and interface.hotplug: + data += "allow-hotplug %s\n" % interface.name + else: + data += "auto %s\n" % interface.name data += _iface data += address_data if interface.mtu: @@ -212,12 +215,12 @@ class ENINetConfig(os_net_config.NetConfig): # write out bridges first. This ensures that an ifup -a # on reboot brings them up first - for bridge_name, bridge_data in self.bridges.iteritems(): + for bridge_name, bridge_data in self.bridges.items(): route_data = self.routes.get(bridge_name) bridge_data += (route_data or '') new_config += bridge_data - for interface_name, iface_data in self.interfaces.iteritems(): + for interface_name, iface_data in self.interfaces.items(): route_data = self.routes.get(interface_name) iface_data += (route_data or '') new_config += iface_data diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py index 41d5f8c..6d3c681 100644 --- a/os_net_config/impl_ifcfg.py +++ b/os_net_config/impl_ifcfg.py @@ -131,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" @@ -283,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 @@ -678,7 +684,7 @@ class IfcfgNetConfig(os_net_config.NetConfig): 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) @@ -706,7 +712,7 @@ class IfcfgNetConfig(os_net_config.NetConfig): 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) @@ -727,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) @@ -748,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) @@ -768,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) @@ -792,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) @@ -812,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) @@ -833,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) @@ -855,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) @@ -906,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: diff --git a/os_net_config/objects.py b/os_net_config/objects.py index 8d52e73..741f304 100644 --- a/os_net_config/objects.py +++ b/os_net_config/objects.py @@ -287,7 +287,7 @@ class Interface(_BaseOpts): def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None, routes=None, mtu=None, primary=False, nic_mapping=None, persist_mapping=False, defroute=True, dhclient_args=None, - dns_servers=None, ethtool_opts=None): + dns_servers=None, ethtool_opts=None, hotplug=False): addresses = addresses or [] routes = routes or [] dns_servers = dns_servers or [] @@ -296,13 +296,16 @@ class Interface(_BaseOpts): persist_mapping, defroute, dhclient_args, dns_servers) self.ethtool_opts = ethtool_opts + self.hotplug = hotplug @staticmethod def from_json(json): name = _get_required_field(json, 'name', 'Interface') + hotplug = strutils.bool_from_string(str(json.get('hotplug', False))) opts = _BaseOpts.base_opts_from_json(json) ethtool_opts = json.get('ethtool_opts', None) - return Interface(name, *opts, ethtool_opts=ethtool_opts) + return Interface(name, *opts, ethtool_opts=ethtool_opts, + hotplug=hotplug) class Vlan(_BaseOpts): diff --git a/os_net_config/tests/test_impl_eni.py b/os_net_config/tests/test_impl_eni.py index e445ed4..4911cb9 100644 --- a/os_net_config/tests/test_impl_eni.py +++ b/os_net_config/tests/test_impl_eni.py @@ -32,6 +32,12 @@ _V4_IFACE_STATIC_IP = _AUTO + """iface eth0 inet static netmask 255.255.255.0 """ +_IFACE_HOTPLUG = """allow-hotplug eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 +""" + _V4_IFACE_STATIC_IP_MULTIPLE = (_V4_IFACE_STATIC_IP + _AUTO + """iface eth0 inet static address 10.0.0.2 @@ -117,8 +123,9 @@ class TestENINetConfig(base.TestCase): def get_route_config(self): return self.provider.routes[self.if_name] - def _default_interface(self, addr=[], rts=[]): - return objects.Interface(self.if_name, addresses=addr, routes=rts) + def _default_interface(self, addr=[], rts=[], hotplug=False): + return objects.Interface(self.if_name, addresses=addr, routes=rts, + hotplug=hotplug) def test_interface_no_ip(self): interface = self._default_interface() @@ -131,6 +138,12 @@ class TestENINetConfig(base.TestCase): self.provider.add_interface(interface) self.assertEqual(_V4_IFACE_STATIC_IP, self.get_interface_config()) + def test_add_interface_with_hotplug(self): + v4_addr = objects.Address('192.168.1.2/24') + interface = self._default_interface(addr=[v4_addr], hotplug=True) + self.provider.add_interface(interface) + self.assertEqual(_IFACE_HOTPLUG, self.get_interface_config()) + def test_add_interface_with_v4_multiple(self): v4_addresses = [objects.Address('192.168.1.2/24'), objects.Address('10.0.0.2/8')] diff --git a/os_net_config/tests/test_impl_ifcfg.py b/os_net_config/tests/test_impl_ifcfg.py index 3a5a7db..9621b8c 100644 --- a/os_net_config/tests/test_impl_ifcfg.py +++ b/os_net_config/tests/test_impl_ifcfg.py @@ -33,6 +33,15 @@ NM_CONTROLLED=no PEERDNS=no """ +_HOTPLUG = """# This file is autogenerated by os-net-config +DEVICE=em1 +ONBOOT=yes +HOTPLUG=yes +NM_CONTROLLED=no +PEERDNS=no +BOOTPROTO=none +""" + _NO_IP = _BASE_IFCFG + "BOOTPROTO=none\n" _V4_IFCFG = _BASE_IFCFG + """BOOTPROTO=static @@ -386,6 +395,11 @@ class TestIfcfgNetConfig(base.TestCase): self.provider.add_interface(interface) self.assertEqual(_NO_IP, self.get_interface_config()) + def test_add_interface_with_hotplug(self): + interface = objects.Interface('em1', hotplug=True) + self.provider.add_interface(interface) + self.assertEqual(_HOTPLUG, self.get_interface_config()) + def test_add_base_interface_vlan(self): interface = objects.Interface('em1.120') self.provider.add_interface(interface) diff --git a/os_net_config/tests/test_objects.py b/os_net_config/tests/test_objects.py index ca2dd47..54d153c 100644 --- a/os_net_config/tests/test_objects.py +++ b/os_net_config/tests/test_objects.py @@ -98,6 +98,27 @@ class TestInterface(base.TestCase): self.assertEqual("em1", interface.name) self.assertTrue(interface.use_dhcp) + def test_from_json_hotplug(self): + data = """{ +"type": "interface", +"name": "em1", +"hotplug": true +} +""" + interface = objects.object_from_json(json.loads(data)) + self.assertEqual("em1", interface.name) + self.assertTrue(interface.hotplug) + + def test_from_json_hotplug_off_by_default(self): + data = """{ +"type": "interface", +"name": "em1" +} +""" + interface = objects.object_from_json(json.loads(data)) + self.assertEqual("em1", interface.name) + self.assertFalse(interface.hotplug) + def test_from_json_defroute(self): data = '{"type": "interface", "name": "em1", "use_dhcp": true}' interface1 = objects.object_from_json(json.loads(data)) @@ -407,7 +428,7 @@ class TestIvsInterface(base.TestCase): objects.IvsBridge.from_json, json.loads(data)) expected = 'IVS does not support bond interfaces.' - self.assertIn(expected, err) + self.assertIn(expected, six.text_type(err)) class TestNfvswitchBridge(base.TestCase): @@ -472,7 +493,7 @@ class TestNfvswitchInterface(base.TestCase): objects.NfvswitchBridge.from_json, json.loads(data)) expected = 'NFVSwitch does not support bond interfaces.' - self.assertIn(expected, err) + self.assertIn(expected, six.text_type(err)) class TestBond(base.TestCase): |