From 31aabddc46c8f9d75ab5112e008acb1c0a49a5f8 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 08:35:36 +0200 Subject: [PATCH] [PR #12121/6e6199ae backport][stable-12] parted: ignore MBR partition type codes in flags on SUSE systems (#12146) parted: ignore MBR partition type codes in flags on SUSE systems (#12121) * parted: ignore MBR partition type codes reported as flags by SUSE parted SUSE's patched parted reports MBR partition type codes (e.g., type=8e for Linux LVM) in the machine-parseable flags output. The module was trying to unset these pseudo-flags via 'parted set N type=8e off', which is not a valid parted command, causing the task to fail when using flags: [lvm] on msdos-labelled disks on SUSE systems. Fixes #6292 * feat(changelog): add fragment for PR 12121 * Update changelogs/fragments/12121-parted-suse-msdos-type-code.yml --------- (cherry picked from commit 6e6199ae3df7b0794c8d9806d452437a6f0c2288) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 Co-authored-by: Felix Fontein --- .../12121-parted-suse-msdos-type-code.yml | 5 + plugins/modules/parted.py | 9 +- tests/unit/plugins/modules/test_parted.py | 92 +++++++++++++++++++ 3 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/12121-parted-suse-msdos-type-code.yml diff --git a/changelogs/fragments/12121-parted-suse-msdos-type-code.yml b/changelogs/fragments/12121-parted-suse-msdos-type-code.yml new file mode 100644 index 0000000000..d951a7753a --- /dev/null +++ b/changelogs/fragments/12121-parted-suse-msdos-type-code.yml @@ -0,0 +1,5 @@ +bugfixes: + - parted - ignore MBR partition type codes (for example ``type=8e``) reported as flags + by some parted builds (for example on SUSE), which cannot be managed via the ``set`` command + (https://github.com/ansible-collections/community.general/issues/6292, + https://github.com/ansible-collections/community.general/pull/12121). diff --git a/plugins/modules/parted.py b/plugins/modules/parted.py index f0ef961375..cc98a54535 100644 --- a/plugins/modules/parted.py +++ b/plugins/modules/parted.py @@ -765,9 +765,12 @@ def main(): if "esp" in flags and "boot" not in flags: flags.append("boot") - # Compute only the changes in flags status - flags_off = list(set(partition["flags"]) - set(flags)) - flags_on = list(set(flags) - set(partition["flags"])) + # Compute only the changes in flags status. + # Some parted builds (e.g., SUSE) include MBR partition type codes (e.g., + # type=8e) in the flags output; these cannot be managed via the 'set' command. + current_flags = [f for f in partition["flags"] if not re.match(r"^type=[0-9a-fA-F]+$", f)] + flags_off = list(set(current_flags) - set(flags)) + flags_on = list(set(flags) - set(current_flags)) for f in flags_on: script += ["set", str(number), f, "on"] diff --git a/tests/unit/plugins/modules/test_parted.py b/tests/unit/plugins/modules/test_parted.py index 466cc1851f..2470a5e415 100644 --- a/tests/unit/plugins/modules/test_parted.py +++ b/tests/unit/plugins/modules/test_parted.py @@ -143,6 +143,59 @@ parted_dict3 = { } +# Simulates SUSE-patched parted that exposes MBR type codes as flags. +# Partition 1 has "lvm" set + SUSE adds "type=8e" as a pseudo-flag. +parted_dict_suse_lvm = { + "generic": { + "dev": "/dev/sdb", + "size": 286061.0, + "unit": "mb", + "table": "msdos", + "model": "ATA TOSHIBA THNSFJ25", + "logical_block": 512, + "physical_block": 512, + }, + "partitions": [ + { + "num": 1, + "begin": 1.05, + "end": 106.0, + "size": 105.0, + "fstype": "", + "name": "", + "flags": ["lvm", "type=8e"], + "unit": "mb", + } + ], +} + +# Simulates SUSE-patched parted where partition has no logical flags yet, +# but SUSE reports "type=83" (Linux MBR type code) as a pseudo-flag. +parted_dict_suse_noflag = { + "generic": { + "dev": "/dev/sdb", + "size": 286061.0, + "unit": "mb", + "table": "msdos", + "model": "ATA TOSHIBA THNSFJ25", + "logical_block": 512, + "physical_block": 512, + }, + "partitions": [ + { + "num": 1, + "begin": 1.05, + "end": 106.0, + "size": 105.0, + "fstype": "", + "name": "", + "flags": ["type=83"], + "unit": "mb", + } + ], +} + + class TestParted(ModuleTestCase): def setUp(self): super().setUp() @@ -453,6 +506,45 @@ class TestParted(ModuleTestCase): ): self.execute_module(changed=True) + def test_suse_msdos_type_code_with_lvm_already_set(self): + # When SUSE parted reports "type=8e" alongside "lvm" in the flags output, + # the module must not try to unset the pseudo-flag (issue #6292). + with set_module_args( + { + "device": "/dev/sdb", + "number": 1, + "state": "present", + "flags": ["lvm"], + } + ): + with patch( + "ansible_collections.community.general.plugins.modules.parted.get_device_info", + return_value=parted_dict_suse_lvm, + ): + self.execute_module(changed=False) + + def test_suse_msdos_type_code_set_lvm_flag(self): + # When SUSE parted only reports "type=83" (no logical flags) and the user + # requests lvm, the module must set lvm without trying to unset type=83. + with set_module_args( + { + "device": "/dev/sdb", + "number": 1, + "state": "present", + "flags": ["lvm"], + } + ): + with patch( + "ansible_collections.community.general.plugins.modules.parted.get_device_info", + return_value=parted_dict_suse_noflag, + ): + self.parted.reset_mock() + self.execute_module(changed=True) + self.assertEqual( + self.parted.mock_calls, + [call(["unit", "KiB", "set", "1", "lvm", "on"], "/dev/sdb", "optimal")], + ) + def test_version_info(self): """Test that the parse_parted_version returns the expected tuple""" for key, value in parted_version_info.items():