From a0601a472dc5b05106617b35b81d8a0578ade339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=A4rdian?= Date: Thu, 29 Oct 2020 14:38:56 +0100 Subject: [PATCH 1/2] get_interfaces: don't exclude Open vSwitch bridge/bond members (#608) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RH-Author: Eduardo Otubo (otubo) RH-MergeRequest: 6: Patch series to fix "Bug 1957135 - Intermittent failure to start cloud-init due to failure to detect macs" RH-Commit: [1/2] 4362f855d2d1a250a7d18490b35e65a1133a00c2 (otubo/cloud-init) RH-Bugzilla: 1957135 RH-Acked-by: Mohammed Gamal RH-Acked-by: Emanuele Giuseppe Esposito <[eesposit@redhat.com](mailto:eesposit@redhat.com> commit 3c432b32de1bdce2699525201396a8bbc6a41f3e Author: Lukas Märdian Date: Thu Oct 29 14:38:56 2020 +0100 get_interfaces: don't exclude Open vSwitch bridge/bond members (#608) If an OVS bridge was used as the only/primary interface, the 'init' stage failed with a "Not all expected physical devices present" error, leaving the system with a broken SSH setup. LP: #1898997 Signed-off-by: Eduardo Otubo --- cloudinit/net/__init__.py | 15 +++++++++++-- cloudinit/net/tests/test_init.py | 36 +++++++++++++++++++++++++++++++- tools/.github-cla-signers | 1 + 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py index e233149a..0aa58b27 100644 --- a/cloudinit/net/__init__.py +++ b/cloudinit/net/__init__.py @@ -124,6 +124,15 @@ def master_is_bridge_or_bond(devname): return (os.path.exists(bonding_path) or os.path.exists(bridge_path)) +def master_is_openvswitch(devname): + """Return a bool indicating if devname's master is openvswitch""" + master_path = get_master(devname) + if master_path is None: + return False + ovs_path = sys_dev_path(devname, path="upper_ovs-system") + return os.path.exists(ovs_path) + + def is_netfailover(devname, driver=None): """ netfailover driver uses 3 nics, master, primary and standby. this returns True if the device is either the primary or standby @@ -855,8 +864,10 @@ def get_interfaces(): continue if is_bond(name): continue - if get_master(name) is not None and not master_is_bridge_or_bond(name): - continue + if get_master(name) is not None: + if (not master_is_bridge_or_bond(name) and + not master_is_openvswitch(name)): + continue if is_netfailover(name): continue mac = get_interface_mac(name) diff --git a/cloudinit/net/tests/test_init.py b/cloudinit/net/tests/test_init.py index 311ab6f8..0535387a 100644 --- a/cloudinit/net/tests/test_init.py +++ b/cloudinit/net/tests/test_init.py @@ -190,6 +190,28 @@ class TestReadSysNet(CiTestCase): self.assertTrue(net.master_is_bridge_or_bond('eth1')) self.assertTrue(net.master_is_bridge_or_bond('eth2')) + def test_master_is_openvswitch(self): + ovs_mac = 'bb:cc:aa:bb:cc:aa' + + # No master => False + write_file(os.path.join(self.sysdir, 'eth1', 'address'), ovs_mac) + + self.assertFalse(net.master_is_bridge_or_bond('eth1')) + + # masters without ovs-system => False + write_file(os.path.join(self.sysdir, 'ovs-system', 'address'), ovs_mac) + + os.symlink('../ovs-system', os.path.join(self.sysdir, 'eth1', + 'master')) + + self.assertFalse(net.master_is_openvswitch('eth1')) + + # masters with ovs-system => True + os.symlink('../ovs-system', os.path.join(self.sysdir, 'eth1', + 'upper_ovs-system')) + + self.assertTrue(net.master_is_openvswitch('eth1')) + def test_is_vlan(self): """is_vlan is True when /sys/net/devname/uevent has DEVTYPE=vlan.""" ensure_file(os.path.join(self.sysdir, 'eth0', 'uevent')) @@ -465,20 +487,32 @@ class TestGetInterfaceMAC(CiTestCase): ): bridge_mac = 'aa:bb:cc:aa:bb:cc' bond_mac = 'cc:bb:aa:cc:bb:aa' + ovs_mac = 'bb:cc:aa:bb:cc:aa' + write_file(os.path.join(self.sysdir, 'br0', 'address'), bridge_mac) write_file(os.path.join(self.sysdir, 'br0', 'bridge'), '') write_file(os.path.join(self.sysdir, 'bond0', 'address'), bond_mac) write_file(os.path.join(self.sysdir, 'bond0', 'bonding'), '') + write_file(os.path.join(self.sysdir, 'ovs-system', 'address'), + ovs_mac) + write_file(os.path.join(self.sysdir, 'eth1', 'address'), bridge_mac) os.symlink('../br0', os.path.join(self.sysdir, 'eth1', 'master')) write_file(os.path.join(self.sysdir, 'eth2', 'address'), bond_mac) os.symlink('../bond0', os.path.join(self.sysdir, 'eth2', 'master')) + write_file(os.path.join(self.sysdir, 'eth3', 'address'), ovs_mac) + os.symlink('../ovs-system', os.path.join(self.sysdir, 'eth3', + 'master')) + os.symlink('../ovs-system', os.path.join(self.sysdir, 'eth3', + 'upper_ovs-system')) + interface_names = [interface[0] for interface in net.get_interfaces()] - self.assertEqual(['eth1', 'eth2'], sorted(interface_names)) + self.assertEqual(['eth1', 'eth2', 'eth3', 'ovs-system'], + sorted(interface_names)) class TestInterfaceHasOwnMAC(CiTestCase): diff --git a/tools/.github-cla-signers b/tools/.github-cla-signers index e5d2b95c..db55361a 100644 --- a/tools/.github-cla-signers +++ b/tools/.github-cla-signers @@ -16,6 +16,7 @@ matthewruffell nishigori omBratteng onitake +slyon smoser sshedi TheRealFalcon -- 2.27.0