Merge ~ltrager/maas:lp1874917 into maas:master

Proposed by Lee Trager
Status: Merged
Approved by: Lee Trager
Approved revision: 00efbf67dd2d36e2ecd5fed61807f9271e035f10
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ltrager/maas:lp1874917
Merge into: maas:master
Diff against target: 151 lines (+82/-5)
3 files modified
src/maasserver/models/bmc.py (+2/-1)
src/metadataserver/builtin_scripts/hooks.py (+27/-4)
src/metadataserver/builtin_scripts/tests/test_hooks.py (+53/-0)
Reviewer Review Type Date Requested Status
Newell Jensen (community) Approve
MAAS Lander Approve
Review via email: mp+382958@code.launchpad.net

Commit message

LP: #1874917 - Skip network data from Controllers and Pods if duplicate MACs detected.

Controllers and Pods send commissioning information from a deployed
machine. If the machine is using a bond multiple interfaces will use
the same MAC address. Since MAAS identifies interfaces by MAC skip
updating interface information.

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b lp1874917 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/7457/console
COMMIT: 53f6e118aaa20cfb7a70375443dc757ccafd2e5a

review: Needs Fixing
~ltrager/maas:lp1874917 updated
5476114... by Lee Trager

Fix division by 0 error

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b lp1874917 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 5476114b203d32a6d2e5391b98b1dfa1c616f6ad

review: Approve
~ltrager/maas:lp1874917 updated
00efbf6... by Lee Trager

Fix showing system_id for assoicated machine.

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b lp1874917 lp:~ltrager/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 00efbf67dd2d36e2ecd5fed61807f9271e035f10

review: Approve
Revision history for this message
Newell Jensen (newell-jensen) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/maasserver/models/bmc.py b/src/maasserver/models/bmc.py
index a3aef32..cde8004 100644
--- a/src/maasserver/models/bmc.py
+++ b/src/maasserver/models/bmc.py
@@ -642,7 +642,8 @@ class Pod(BMC):
642 interface = self.ip_address.get_interface()642 interface = self.ip_address.get_interface()
643 if interface is not None:643 if interface is not None:
644 return interface.node644 return interface.node
645 return None645 else:
646 return self.hints.nodes.first()
646647
647 def sync_hints(self, discovered_hints):648 def sync_hints(self, discovered_hints):
648 """Sync the hints with `discovered_hints`."""649 """Sync the hints with `discovered_hints`."""
diff --git a/src/metadataserver/builtin_scripts/hooks.py b/src/metadataserver/builtin_scripts/hooks.py
index 801a4c1..ee5bd82 100644
--- a/src/metadataserver/builtin_scripts/hooks.py
+++ b/src/metadataserver/builtin_scripts/hooks.py
@@ -35,6 +35,10 @@ from provisioningserver.utils.ipaddr import parse_ip_addr
35logger = logging.getLogger(__name__)35logger = logging.getLogger(__name__)
3636
3737
38class DuplicateMACs(Exception):
39 """Exception for when duplicate MAC addresses are in commissioning data."""
40
41
38SWITCH_TAG_NAME = "switch"42SWITCH_TAG_NAME = "switch"
39SWITCH_HARDWARE = [43SWITCH_HARDWARE = [
40 # Seen on Facebook Wedge 40 switch:44 # Seen on Facebook Wedge 40 switch:
@@ -143,7 +147,13 @@ def _parse_interfaces(node, data):
143 link = ip_addr_info.get(interface["name"], {})147 link = ip_addr_info.get(interface["name"], {})
144 interface["ips"] = link.get("inet", []) + link.get("inet6", [])148 interface["ips"] = link.get("inet", []) + link.get("inet6", [])
145149
146 interfaces[mac] = interface150 if mac in interfaces:
151 raise DuplicateMACs(
152 f"Duplicated MAC address({mac}) on "
153 "{interfaces[mac]['name']} and {interface['name']}"
154 )
155 else:
156 interfaces[mac] = interface
147157
148 return interfaces158 return interfaces
149159
@@ -248,7 +258,21 @@ def update_node_network_information(node, data, numa_nodes):
248 node.save(update_fields=["skip_networking"])258 node.save(update_fields=["skip_networking"])
249 return259 return
250260
251 interfaces_info = _parse_interfaces(node, data)261 try:
262 interfaces_info = _parse_interfaces(node, data)
263 except DuplicateMACs:
264 if node.is_controller or node.is_pod:
265 # Controllers and Pods send commissioning information from a
266 # deployed machine. If the machine is using a bond multiple
267 # interfaces will use the same MAC address. Since MAAS identifies
268 # interfaces by MAC skip updating interface information.
269 # When MAAS gains the ability to model LXD's commissioning
270 # information this can be removed.
271 return
272 else:
273 # Duplicate MACs are not expected on machines, raise the
274 # exception so this can be handled.
275 raise
252 current_interfaces = set()276 current_interfaces = set()
253277
254 for mac, iface in interfaces_info.items():278 for mac, iface in interfaces_info.items():
@@ -496,18 +520,17 @@ def _parse_cpuinfo(data):
496 current_average = 0520 current_average = 0
497 for socket in sockets:521 for socket in sockets:
498 current_average += socket.get("frequency", 0)522 current_average += socket.get("frequency", 0)
499 current_average /= len(sockets)
500 if current_average:523 if current_average:
501 # Fall back on the current speed, round it to524 # Fall back on the current speed, round it to
502 # the nearest hundredth as the number may be525 # the nearest hundredth as the number may be
503 # effected by CPU scaling.526 # effected by CPU scaling.
527 current_average /= len(sockets)
504 cpu_speed = round(current_average / 100) * 100528 cpu_speed = round(current_average / 100) * 100
505529
506 return cpu_count, cpu_speed, cpu_model, numa_nodes530 return cpu_count, cpu_speed, cpu_model, numa_nodes
507531
508532
509def _parse_memory(data, numa_nodes):533def _parse_memory(data, numa_nodes):
510
511 total_memory = data.get("memory", {}).get("total", 0)534 total_memory = data.get("memory", {}).get("total", 0)
512 default_numa_node = {"numa_node": 0, "total": total_memory}535 default_numa_node = {"numa_node": 0, "total": total_memory}
513 for memory_node in data.get("memory", {}).get(536 for memory_node in data.get("memory", {}).get(
diff --git a/src/metadataserver/builtin_scripts/tests/test_hooks.py b/src/metadataserver/builtin_scripts/tests/test_hooks.py
index 79474a2..c393f7d 100644
--- a/src/metadataserver/builtin_scripts/tests/test_hooks.py
+++ b/src/metadataserver/builtin_scripts/tests/test_hooks.py
@@ -2414,6 +2414,59 @@ class TestUpdateNodeNetworkInformation(MAASServerTestCase):
2414 self.assertIsNotNone(reload_object(boot_interface))2414 self.assertIsNotNone(reload_object(boot_interface))
2415 self.assertFalse(reload_object(node).skip_networking)2415 self.assertFalse(reload_object(node).skip_networking)
24162416
2417 def test__does_nothing_if_duplicate_mac_on_controller(self):
2418 mock_iface_get = self.patch(
2419 hooks_module.PhysicalInterface.objects, "get"
2420 )
2421 rack = factory.make_RackController()
2422 create_IPADDR_OUTPUT_NAME_script(rack, IP_ADDR_OUTPUT)
2423 mac = factory.make_mac_address()
2424 duplicate_mac_lxd_resources = deepcopy(SAMPLE_LXD_RESOURCES)
2425 for card in duplicate_mac_lxd_resources["network"]["cards"]:
2426 for port in card["ports"]:
2427 port["address"] = mac
2428 update_node_network_information(
2429 rack, duplicate_mac_lxd_resources, create_numa_nodes(rack)
2430 )
2431 self.assertThat(mock_iface_get, MockNotCalled())
2432
2433 def test__does_nothing_if_duplicate_mac_on_pod(self):
2434 self.useFixture(SignalsDisabled("podhints"))
2435 mock_iface_get = self.patch(
2436 hooks_module.PhysicalInterface.objects, "get"
2437 )
2438 pod = factory.make_Pod()
2439 node = factory.make_Node(
2440 status=NODE_STATUS.DEPLOYED, with_empty_script_sets=True
2441 )
2442 create_IPADDR_OUTPUT_NAME_script(node, IP_ADDR_OUTPUT)
2443 pod.hints.nodes.add(node)
2444 mac = factory.make_mac_address()
2445 duplicate_mac_lxd_resources = deepcopy(SAMPLE_LXD_RESOURCES)
2446 for card in duplicate_mac_lxd_resources["network"]["cards"]:
2447 for port in card["ports"]:
2448 port["address"] = mac
2449 update_node_network_information(
2450 node, duplicate_mac_lxd_resources, create_numa_nodes(node)
2451 )
2452 self.assertThat(mock_iface_get, MockNotCalled())
2453
2454 def test__raises_exception_if_duplicate_mac_on_machine(self):
2455 node = factory.make_Node()
2456 create_IPADDR_OUTPUT_NAME_script(node, IP_ADDR_OUTPUT)
2457 mac = factory.make_mac_address()
2458 duplicate_mac_lxd_resources = deepcopy(SAMPLE_LXD_RESOURCES)
2459 for card in duplicate_mac_lxd_resources["network"]["cards"]:
2460 for port in card["ports"]:
2461 port["address"] = mac
2462 self.assertRaises(
2463 hooks_module.DuplicateMACs,
2464 update_node_network_information,
2465 node,
2466 duplicate_mac_lxd_resources,
2467 create_numa_nodes(node),
2468 )
2469
2417 def test__add_all_interfaces(self):2470 def test__add_all_interfaces(self):
2418 """Test a node that has no previously known interfaces on which we2471 """Test a node that has no previously known interfaces on which we
2419 need to add a series of interfaces.2472 need to add a series of interfaces.

Subscribers

People subscribed via source and target branches