Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions cloudinit/net/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
36 changes: 35 additions & 1 deletion cloudinit/net/tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,28 @@ def test_master_is_bridge_or_bond(self):
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'))
Expand Down Expand Up @@ -465,20 +487,32 @@ def test_get_interfaces_does_not_skip_phys_members_of_bridges_and_bonds(
):
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):
Expand Down
1 change: 1 addition & 0 deletions tools/.github-cla-signers
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ matthewruffell
nishigori
omBratteng
onitake
slyon
smoser
sshedi
TheRealFalcon
Expand Down