Related: rhbz#1070095
Examined alternatives are: 1) To make use of the uuid.UUID class to store uuids. The difficulty with this idea is that some things that are labeled uuids are not proper uuids at all. 2) To make the udev_info dict more object oriented, and have it sanitize uuids when they are added. A lot of work for very limited benefit. 3) To canonicalize uuids everytime they are extracted from the info. Brittle, since you can't stop code from accessing the entries directly, and annoyingly inefficient.
This alternative is pretty simple, and to a certain extent it's a workaround for a bug in mdadm, so it wins.
Signed-off-by: mulhern amulhern@redhat.com --- blivet/devicelibs/mdraid.py | 9 +++++++++ tests/devicelibs_test/mdraid_test.py | 6 ++++++ 2 files changed, 15 insertions(+)
diff --git a/blivet/devicelibs/mdraid.py b/blivet/devicelibs/mdraid.py index f46571a..31e5b80 100644 --- a/blivet/devicelibs/mdraid.py +++ b/blivet/devicelibs/mdraid.py @@ -242,6 +242,15 @@ def mdexamine(device): if name == "metadata": info["MD_METADATA"] = value
+ # mdadm's UUIDs are actual 128 bit uuids, but it formats them strangely. + # This converts the uuids to canonical form. + # Example: + # mdadm UUID: '3386ff85:f5012621:4a435f06:1eb47236' + # canonical UUID: '3386ff85-f501-2621-4a43-5f061eb47236' + import uuid + for k, v in ((k,v) for (k,v) in info.iteritems() if k.endswith("UUID")): + info[k] = str(uuid.UUID(v.replace(':', ''))) + return info
def md_node_from_name(name): diff --git a/tests/devicelibs_test/mdraid_test.py b/tests/devicelibs_test/mdraid_test.py index 760643f..4f2e6d8 100755 --- a/tests/devicelibs_test/mdraid_test.py +++ b/tests/devicelibs_test/mdraid_test.py @@ -1,6 +1,7 @@ #!/usr/bin/python import unittest import time +import uuid
import blivet.devicelibs.raid as raid import blivet.devicelibs.mdraid as mdraid @@ -119,6 +120,7 @@ class MDRaidAsRootTestCase(loopbackedtestcase.LoopBackedTestCase): Verifies that: - exactly the predicted names are returned by mdexamine - RAID level and number of devices are correct + - UUIDs have canonical form """ level = mdraid.RAID_levels.raidLevel(level or raid.RAID1) mdraid.mdcreate(self._dev_name, level, self.loopDevices, metadataVer=metadataVersion) @@ -138,6 +140,10 @@ class MDRaidAsRootTestCase(loopbackedtestcase.LoopBackedTestCase): self.assertEqual(info['MD_DEVICES'], '2') self.assertEqual(info['MD_LEVEL'], str(level))
+ # verify that uuids are in canonical form + for name in (k for k in iter(info.keys()) if k.endswith('UUID')): + self.assertTrue(str(uuid.UUID(info[name])) == info[name]) + def testMDExamineContainerDefault(self): self._testMDExamine(self.names_container, level="container")