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
29 changes: 28 additions & 1 deletion cloudinit/net/network_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from cloudinit import safeyaml, util
from cloudinit.net import (
get_interfaces_by_mac,
ipv4_mask_to_net_prefix,
ipv6_mask_to_net_prefix,
is_ipv6_addr,
Expand Down Expand Up @@ -665,10 +666,18 @@ def handle_ethernets(self, command):
]
}
"""

# Get the interfaces by MAC address to update an interface's
# device name to the name of the device that matches a provided
# MAC address when the set-name directive is not present.
#
# Please see https://bugs.launchpad.net/cloud-init/+bug/1855945
# for more information.
ifaces_by_mac = get_interfaces_by_mac()

for eth, cfg in command.items():
phy_cmd = {
"type": "physical",
"name": cfg.get("set-name", eth),
}
match = cfg.get("match", {})
mac_address = match.get("macaddress", None)
Expand All @@ -680,6 +689,24 @@ def handle_ethernets(self, command):
str(cfg),
)
phy_cmd["mac_address"] = mac_address

# Determine the name of the interface by using one of the
# following in the order they are listed:
# * set-name
# * interface name looked up by mac
# * value of "eth" key from this loop
name = eth
set_name = cfg.get("set-name", None)
if set_name:
name = set_name
elif mac_address and ifaces_by_mac:
lcase_mac_address = mac_address.lower()
Comment thread
TheRealFalcon marked this conversation as resolved.
for iface_mac, iface_name in ifaces_by_mac.items():
if lcase_mac_address == iface_mac.lower():
name = iface_name
break
phy_cmd["name"] = name

driver = match.get("driver", None)
if driver:
phy_cmd["params"] = {"driver": driver}
Expand Down
81 changes: 79 additions & 2 deletions tests/unittests/test_net.py
Original file line number Diff line number Diff line change
Expand Up @@ -3871,6 +3871,29 @@
),
},
},
"v2-dev-name-via-mac-lookup": {
"expected_sysconfig_rhel": {
"ifcfg-eth0": textwrap.dedent(
"""\
BOOTPROTO=none
DEVICE=eth0
HWADDR=cf:d6:af:48:e8:80
NM_CONTROLLED=no
ONBOOT=yes
TYPE=Ethernet
USERCTL=no"""
),
},
"yaml": textwrap.dedent(
"""\
version: 2
ethernets:
nic0:
match:
macaddress: 'cf:d6:af:48:e8:80'
"""
),
},
}


Expand Down Expand Up @@ -3954,6 +3977,9 @@
"device/driver": None,
"device/device": None,
"name_assign_type": "4",
"addr_assign_type": "0",
"uevent": "",
"type": "32",
}
}

Expand Down Expand Up @@ -4080,16 +4106,22 @@ def test_device_driver(
"device/driver": "hv_netsvc",
"device/device": "0x3",
"name_assign_type": "4",
"addr_assign_type": "0",
"uevent": "",
"type": "32",
},
"eth1": {
"bridge": False,
"carrier": False,
"dormant": False,
"operstate": "down",
"address": "00:11:22:33:44:55",
"address": "00:11:22:33:44:56",
"device/driver": "mlx4_core",
"device/device": "0x7",
"name_assign_type": "4",
"addr_assign_type": "0",
"uevent": "",
"type": "32",
},
}

Expand Down Expand Up @@ -4158,16 +4190,22 @@ def test_device_driver_blacklist(
"device/driver": "hv_netsvc",
"device/device": "0x3",
"name_assign_type": "4",
"addr_assign_type": "0",
"uevent": "",
"type": "32",
},
"eth0": {
"bridge": False,
"carrier": False,
"dormant": False,
"operstate": "down",
"address": "00:11:22:33:44:55",
"address": "00:11:22:33:44:56",
"device/driver": "mlx4_core",
"device/device": "0x7",
"name_assign_type": "4",
"addr_assign_type": "0",
"uevent": "",
"type": "32",
},
}

Expand Down Expand Up @@ -5099,6 +5137,45 @@ def test_from_v2_route_metric(self):
expected, self._render_and_read(network_config=v2data)
)

@mock.patch("cloudinit.net.sys_dev_path")
@mock.patch("cloudinit.net.read_sys_net")
@mock.patch("cloudinit.net.get_devicelist")
def test_iface_name_from_device_with_matching_mac_address(
self,
mock_get_devicelist,
mock_read_sys_net,
mock_sys_dev_path,
):
devices = {
"eth0": {
"bridge": False,
"carrier": False,
"dormant": False,
"operstate": "down",
"address": "CF:D6:AF:48:E8:80",
"device/driver": "hv_netsvc",
"device/device": "0x3",
"name_assign_type": "4",
"addr_assign_type": "0",
"uevent": "",
"type": "32",
},
}

tmp_dir = self.tmp_dir()
_setup_test(
tmp_dir,
mock_get_devicelist,
mock_read_sys_net,
mock_sys_dev_path,
dev_attrs=devices,
)

entry = NETWORK_CONFIGS["v2-dev-name-via-mac-lookup"]
found = self._render_and_read(network_config=yaml.load(entry["yaml"]))
self._compare_files_to_expected(entry[self.expected_name], found)
self._assert_headers(found)


@mock.patch(
"cloudinit.net.is_openvswitch_internal_interface",
Expand Down