summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Märdian <luk@slyon.de>2020-10-29 14:38:56 +0100
committerGitHub <noreply@github.com>2020-10-29 09:38:56 -0400
commit3c432b32de1bdce2699525201396a8bbc6a41f3e (patch)
treeafe8fcd51982887a85f98e2a318875e025b353a0
parentf99d4f96b00a9cfec1c721d364cbfd728674e5dc (diff)
downloadcloud-init-git-3c432b32de1bdce2699525201396a8bbc6a41f3e.tar.gz
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
-rw-r--r--cloudinit/net/__init__.py15
-rw-r--r--cloudinit/net/tests/test_init.py36
-rw-r--r--tools/.github-cla-signers1
3 files changed, 49 insertions, 3 deletions
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
index 75e79ca8..de65e7af 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
@@ -862,8 +871,10 @@ def get_interfaces(blacklist_drivers=None) -> list:
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 475f0872..2d81b700 100644
--- a/tools/.github-cla-signers
+++ b/tools/.github-cla-signers
@@ -20,6 +20,7 @@ matthewruffell
nishigori
omBratteng
onitake
+slyon
smoser
sshedi
TheRealFalcon