diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py index d3dc3d57..6e549920 100644 --- a/os_net_config/impl_ifcfg.py +++ b/os_net_config/impl_ifcfg.py @@ -15,6 +15,7 @@ # under the License. import glob +import itertools import logging import netaddr import os @@ -1130,34 +1131,6 @@ class IfcfgNetConfig(os_net_config.NetConfig): if iface_name not in restart_interfaces: apply_routes.append((iface_name, route6_data)) - 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) - vlan_route_path = self.root_dir + route_config_path(vlan_name) - vlan_route6_path = self.root_dir + route6_config_path(vlan_name) - all_file_names.append(vlan_path) - all_file_names.append(vlan_route_path) - all_file_names.append(vlan_route6_path) - if utils.diff(vlan_path, vlan_data): - if self.ifcfg_requires_restart(vlan_path, vlan_data): - restart_vlans.append(vlan_name) - else: - apply_interfaces.append( - (vlan_name, vlan_path, vlan_data)) - update_files[vlan_path] = vlan_data - else: - logger.info('No changes required for vlan interface: %s' % - vlan_name) - if utils.diff(vlan_route_path, route_data): - update_files[vlan_route_path] = route_data - if vlan_name not in restart_vlans: - apply_routes.append((vlan_name, route_data)) - if utils.diff(vlan_route6_path, route6_data): - update_files[vlan_route6_path] = route6_data - if vlan_name not in restart_vlans: - apply_routes.append((vlan_name, route6_data)) - 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, '') @@ -1320,6 +1293,45 @@ class IfcfgNetConfig(os_net_config.NetConfig): if interface_name not in restart_interfaces: apply_routes.append((interface_name, route6_data)) + # NOTE(hjensas): Process the VLAN's last so that we know if the vlan's + # parent interface is being restarted. + 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) + vlan_route_path = self.root_dir + route_config_path(vlan_name) + vlan_route6_path = self.root_dir + route6_config_path(vlan_name) + all_file_names.append(vlan_path) + all_file_names.append(vlan_route_path) + all_file_names.append(vlan_route6_path) + restarts_concatenated = itertools.chain(restart_interfaces, + restart_bridges, + restart_linux_bonds, + restart_linux_teams) + if (self.parse_ifcfg(vlan_data).get('PHYSDEV') in + restarts_concatenated): + if vlan_name not in restart_vlans: + restart_vlans.append(vlan_name) + update_files[vlan_path] = vlan_data + elif utils.diff(vlan_path, vlan_data): + if self.ifcfg_requires_restart(vlan_path, vlan_data): + restart_vlans.append(vlan_name) + else: + apply_interfaces.append( + (vlan_name, vlan_path, vlan_data)) + update_files[vlan_path] = vlan_data + else: + logger.info('No changes required for vlan interface: %s' % + vlan_name) + if utils.diff(vlan_route_path, route_data): + update_files[vlan_route_path] = route_data + if vlan_name not in restart_vlans: + apply_routes.append((vlan_name, route_data)) + if utils.diff(vlan_route6_path, route6_data): + update_files[vlan_route6_path] = route6_data + if vlan_name not in restart_vlans: + apply_routes.append((vlan_name, route6_data)) + if self.vpp_interface_data or self.vpp_bond_data: vpp_path = self.root_dir + vpp_config_path() vpp_config = utils.generate_vpp_config(vpp_path, vpp_interfaces, diff --git a/os_net_config/tests/test_impl_ifcfg.py b/os_net_config/tests/test_impl_ifcfg.py index 17d0410b..53777733 100644 --- a/os_net_config/tests/test_impl_ifcfg.py +++ b/os_net_config/tests/test_impl_ifcfg.py @@ -1782,6 +1782,32 @@ class TestIfcfgNetConfigApply(base.TestCase): self.assertIn('em1', self.ifup_interface_names) self.assertIn('em2', self.ifup_interface_names) + def test_restart_vlans_on_bond_change(self): + self.ifup_interface_names = [] + interface1 = objects.Interface('em1') + interface2 = objects.Interface('em2') + bond = objects.LinuxBond('bond0', members=[interface1, interface2]) + vlan = objects.Vlan('bond0', 10) + self.provider.add_interface(interface1) + self.provider.add_interface(interface2) + self.provider.add_linux_bond(bond) + self.provider.add_vlan(vlan) + self.provider.apply() + self.assertIn('bond0', self.ifup_interface_names) + self.assertIn('em1', self.ifup_interface_names) + self.assertIn('em2', self.ifup_interface_names) + self.assertIn('vlan10', self.ifup_interface_names) + + # Change the bond configuration + self.ifup_interface_names = [] + bond.bonding_options = 'mode=1 miimon=100' + self.provider.add_linux_bond(bond) + self.provider.apply() + self.assertIn('bond0', self.ifup_interface_names) + self.assertIn('em1', self.ifup_interface_names) + self.assertIn('em2', self.ifup_interface_names) + self.assertIn('vlan10', self.ifup_interface_names) + def test_restart_interface_counts(self): interface = objects.Interface('em1') self.provider.add_interface(interface)