Skip to content
Open
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
16 changes: 13 additions & 3 deletions src/maasserver/models/bmc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1088,8 +1088,10 @@ def _assign_interfaces(
):
# Enumerating the LabeledConstraintMap of interfaces will yield the
# name of each interface, in the same order that they will exist
# on the hypervisor. (This is a fortunate coincidence, since
# dictionaries in Python 3.6+ preserve insertion order.)
# on the hypervisor for virsh. (This is a fortunate coincidence,
# since dictionaries in Python 3.6+ preserve insertion order.)
# For lxd this is not the case, as there is an API boundary in the
# middle that returns reordered interfaces.
if interface_constraints is not None:
interface_names = [
get_ifname_for_label(label) for label in interface_constraints
Expand All @@ -1107,8 +1109,16 @@ def _assign_interfaces(
# configuration.
created_interfaces = []
for idx, discovered_nic in enumerate(discovered_machine.interfaces):
# For the scenario of lxd, it returns the interfaces ordered
Comment thread
AloizioMacedo marked this conversation as resolved.
# alphabetically likely due to it being written in Go. So we need
# to properly match the correct name here instead of relying on
# order.
# When coming from virsh, the interfaces do not have a meaningful
# name. So we fall back to the previous behavior (which might
# be even correct in that scenario.)
name = discovered_nic.name or interface_names[idx]
interface = self._create_interface(
discovered_nic, machine, name=interface_names[idx]
discovered_nic, machine, name=name
)
created_interfaces.append(interface)
if discovered_nic.boot:
Expand Down
61 changes: 61 additions & 0 deletions src/maasserver/models/tests/test_bmc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,67 @@ def test_create_machine_sets_interface_names_using_constraint_labels(self):
),
)

def test_create_machine_uses_discovered_interface_name_when_out_of_order(
self,
):
interfaces = [
self.make_discovered_interface(),
self.make_discovered_interface(),
self.make_discovered_interface(),
]
interfaces[0].boot = True

# Adding names out of alphabetical order, as a previous
# bug was inadvertendly reordering things alphabetically.
interfaces[0].name = "maas1"
interfaces[1].name = "maas0"
interfaces[2].name = "maas2"

mac_to_expected_name = {
iface.mac_address: iface.name for iface in interfaces
}
discovered_machine = self.make_discovered_machine(
interfaces=interfaces
)

self.patch(Machine, "set_default_storage_layout")
self.patch(Machine, "set_initial_networking_configuration")
self.patch(Machine, "start_commissioning")

fabric = factory.make_Fabric()
vlan = factory.make_VLAN(
fabric=fabric,
dhcp_on=True,
primary_rack=factory.make_RackController(),
)
vlan2 = factory.make_VLAN(
fabric=fabric,
dhcp_on=False,
primary_rack=factory.make_RackController(),
)
vlan3 = factory.make_VLAN(
fabric=fabric,
dhcp_on=False,
primary_rack=factory.make_RackController(),
)

pod = factory.make_Pod()
machine = pod.create_machine(
discovered_machine,
factory.make_User(),
interfaces=LabeledConstraintMap(
"maas0:vlan=id:%d;maas1:vlan=id:%d;maas2:vlan=id:%d"
% (vlan.id, vlan2.id, vlan3.id)
),
)
# Each created interface must keep the name reported by the
# driver (matched by MAC address), regardless of the position it
# occupied in the discovered interfaces list.
for interface in machine.current_config.interface_set.all():
self.assertEqual(
mac_to_expected_name[interface.mac_address], interface.name
)

def test_create_machine_allocates_requested_ip_addresses(self):
discovered_machine = self.make_discovered_machine()
self.patch(Machine, "set_default_storage_layout")
Expand Down
1 change: 1 addition & 0 deletions src/provisioningserver/drivers/pod/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ class DiscoveredMachineInterface:
attach_name = attr.ib(
converter=converter_obj(str, optional=True), default=None
)
name = attr.ib(converter=converter_obj(str, optional=True), default=None)


@attr.s
Expand Down
1 change: 1 addition & 0 deletions src/provisioningserver/drivers/pod/lxd.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,7 @@ def _get_discovered_interface(name, device, boot):
boot=boot,
attach_type=attach_type,
attach_name=attach_name,
name=name,
)

extra_block_devices = 0
Expand Down
6 changes: 6 additions & 0 deletions src/provisioningserver/drivers/pod/tests/test_lxd.py
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,7 @@ def test_get_discovered_machine(self):
boot=True,
attach_type=InterfaceAttachType.BRIDGE,
attach_name="lxdbr0",
name="eth0",
Comment thread
AloizioMacedo marked this conversation as resolved.
),
)
self.assertEqual(
Expand All @@ -1006,6 +1007,7 @@ def test_get_discovered_machine(self):
boot=False,
attach_type=InterfaceAttachType.BRIDGE,
attach_name="br1",
name="eth1",
),
)
self.assertEqual(
Expand All @@ -1017,6 +1019,7 @@ def test_get_discovered_machine(self):
boot=False,
attach_type=InterfaceAttachType.MACVLAN,
attach_name="eno2",
name="eth2",
),
)
self.assertEqual(
Expand All @@ -1028,6 +1031,7 @@ def test_get_discovered_machine(self):
boot=False,
attach_type=InterfaceAttachType.SRIOV,
attach_name="eno3",
name="eth3",
),
)
self.assertEqual(
Expand All @@ -1039,6 +1043,7 @@ def test_get_discovered_machine(self):
boot=False,
attach_type=InterfaceAttachType.SRIOV,
attach_name="eno3",
name="eth4",
),
)
self.assertEqual(
Expand All @@ -1050,6 +1055,7 @@ def test_get_discovered_machine(self):
boot=False,
attach_type=InterfaceAttachType.SRIOV,
attach_name="eno3",
name="eth5",
),
)
self.assertEqual([], discovered_machine.tags)
Expand Down