Merge ~ltrager/maas:lp1893690 into maas:master

Proposed by Lee Trager
Status: Merged
Approved by: Lee Trager
Approved revision: 794cf008a4327f161461bdc475c6f994950c3863
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ltrager/maas:lp1893690
Merge into: maas:master
Diff against target: 75 lines (+42/-3)
2 files modified
src/metadataserver/builtin_scripts/hooks.py (+26/-3)
src/metadataserver/builtin_scripts/tests/test_hooks.py (+16/-0)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Dougal Matthews (community) Approve
Review via email: mp+390050@code.launchpad.net

Commit message

LP: #1893690 - Remove duplicate hardware UUIDs when detected.

Some Dell hardware uses the service number for the hardware UUID. This
value is not unqiue and causes commissioning to fail. MAAS uses the
hardware UUID to identify the machine when booting. Some hardware like
IBM Z series LPARs only identify themselves this way while PXE booting
tries the UUID first and then falls back on using a MAC address. If a
duplicate is detected remove the UUID from both machines.

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

UNIT TESTS
-b lp1893690 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/8210/console
COMMIT: f56a2bf05ee8dd2dc9c42607f7dd622f440a60b1

review: Needs Fixing
Revision history for this message
Dougal Matthews (d0ugal) :
review: Needs Information
Revision history for this message
Dougal Matthews (d0ugal) wrote :

Lee explained there is a unique constraint, so the potential issue I raised can't happen.

LGTM

review: Approve
~ltrager/maas:lp1893690 updated
0fe11d1... by Lee Trager

Validate UUID

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

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

STATUS: SUCCESS
COMMIT: 0fe11d17f823c94a1236fe77a60ecb55471e8cf0

review: Approve
~ltrager/maas:lp1893690 updated
794cf00... by Lee Trager

Check duplicate UUIDs atomically

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

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

STATUS: SUCCESS
COMMIT: 794cf008a4327f161461bdc475c6f994950c3863

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/metadataserver/builtin_scripts/hooks.py b/src/metadataserver/builtin_scripts/hooks.py
2index 26c7e11..4538dce 100644
3--- a/src/metadataserver/builtin_scripts/hooks.py
4+++ b/src/metadataserver/builtin_scripts/hooks.py
5@@ -10,8 +10,10 @@ import json
6 import logging
7 import re
8
9+from django.core.exceptions import ValidationError
10+
11 from maasserver.enum import NODE_METADATA, NODE_STATUS
12-from maasserver.models import Fabric, NUMANode, Subnet
13+from maasserver.models import Fabric, Node, NUMANode, Subnet
14 from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE
15 from maasserver.models.interface import Interface, PhysicalInterface
16 from maasserver.models.nodemetadata import NodeMetadata
17@@ -414,8 +416,29 @@ def _process_system_information(node, system_data):
18 NodeMetadata.objects.filter(node=node, key=key).delete()
19
20 uuid = system_data.get("uuid")
21- # Convert "" to None, so that the unique check isn't triggered.
22- node.hardware_uuid = None if uuid == "" else uuid
23+ if not uuid or not re.search(
24+ r"^[\da-f]{8}[\-]?([\da-f]{4}[\-]?){3}[\da-f]{12}$", uuid, re.I
25+ ):
26+ # Convert "" to None, so that the unique check isn't triggered.
27+ # Some vendors store the service tag as the UUID which is not unique,
28+ # if the UUID isn't a valid UUID ignore it.
29+ node.hardware_uuid = None
30+ else:
31+ # LP:1893690 - If the UUID is valid check that it isn't duplicated
32+ # with save so the check is atomic.
33+ node.hardware_uuid = uuid
34+ try:
35+ node.save()
36+ except ValidationError as e:
37+ # Check that the ValidationError is due to the hardware_uuid
38+ # other errors will be caught and logged later.
39+ if "hardware_uuid" in e.error_dict:
40+ node.hardware_uuid = None
41+ # If the UUID isn't really unique make sure it isn't stored on
42+ # any Node.
43+ Node.objects.filter(hardware_uuid=uuid).update(
44+ hardware_uuid=None
45+ )
46
47 # Gather system information. Custom built machines and some Supermicro
48 # servers do not provide this information.
49diff --git a/src/metadataserver/builtin_scripts/tests/test_hooks.py b/src/metadataserver/builtin_scripts/tests/test_hooks.py
50index 29d0857..2bfa72d 100644
51--- a/src/metadataserver/builtin_scripts/tests/test_hooks.py
52+++ b/src/metadataserver/builtin_scripts/tests/test_hooks.py
53@@ -1273,6 +1273,22 @@ class TestProcessLXDResults(MAASServerTestCase):
54 # check for unique UUIDs isn't triggered.
55 self.assertIsNone(node.hardware_uuid)
56
57+ def test_removes_duplicate_uuid(self):
58+ uuid = factory.make_UUID()
59+ duplicate_uuid_node = factory.make_Node(hardware_uuid=uuid)
60+ node = factory.make_Node()
61+ create_IPADDR_OUTPUT_NAME_script(node, IP_ADDR_OUTPUT)
62+ process_lxd_results(node, make_lxd_output_json(uuid=uuid), 0)
63+ self.assertIsNone(reload_object(node).hardware_uuid)
64+ self.assertIsNone(reload_object(duplicate_uuid_node).hardware_uuid)
65+
66+ def test_ignores_invalid_uuid(self):
67+ uuid = factory.make_name("invalid_uuid")
68+ node = factory.make_Node()
69+ create_IPADDR_OUTPUT_NAME_script(node, IP_ADDR_OUTPUT)
70+ process_lxd_results(node, make_lxd_output_json(uuid=uuid), 0)
71+ self.assertIsNone(reload_object(node).hardware_uuid)
72+
73 def test_sets_os_hostname_for_controller(self):
74 rack = factory.make_RackController()
75 create_IPADDR_OUTPUT_NAME_script(rack, IP_ADDR_OUTPUT)

Subscribers

People subscribed via source and target branches