From 8ecb48f363eba0616394290b4ccebbed411d1d6e Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 24 Jan 2024 17:00:50 +0100 Subject: [PATCH] Add support for setting label when creating GFS2 format Related: https://github.com/linux-system-roles/storage/pull/418 --- blivet/formats/fs.py | 1 + blivet/tasks/fslabeling.py | 17 +++++++++++++++++ blivet/tasks/fsmkfs.py | 2 +- tests/storage_tests/formats_test/fs_test.py | 13 +++++++++++++ tests/storage_tests/formats_test/fstesting.py | 11 ++++++----- .../storage_tests/formats_test/labeling_test.py | 6 ++++++ tests/unit_tests/formats_tests/init_test.py | 8 ++++++++ 7 files changed, 52 insertions(+), 6 deletions(-) diff --git a/blivet/formats/fs.py b/blivet/formats/fs.py index 1e102b6a0..9f0525f1e 100644 --- a/blivet/formats/fs.py +++ b/blivet/formats/fs.py @@ -1123,6 +1123,7 @@ class GFS2(FS): _check = True _packages = ["gfs2-utils"] _mkfs_class = fsmkfs.GFS2Mkfs + _labelfs = fslabeling.GFS2Labeling() # FIXME parted needs to be thaught about btrfs so that we can set the # partition table type correctly for btrfs partitions # parted_system = fileSystemType["gfs2"] diff --git a/blivet/tasks/fslabeling.py b/blivet/tasks/fslabeling.py index d9427e522..34765d3ae 100644 --- a/blivet/tasks/fslabeling.py +++ b/blivet/tasks/fslabeling.py @@ -20,6 +20,7 @@ # Red Hat Author(s): Anne Mulhern import abc +import string import gi gi.require_version("BlockDev", "3.0") @@ -92,3 +93,19 @@ class F2FSLabeling(FSLabeling): @classmethod def label_format_ok(cls, label): return cls._blockdev_check_label("f2fs", label) + + +class GFS2Labeling(FSLabeling): + + @classmethod + def label_format_ok(cls, label): + try: + clustername, lockspace = label.split(":") + except ValueError: + return False + + if len(clustername) > 32 or len(lockspace) > 30: + return False + + allowed = string.ascii_letters + string.digits + "-_" + return all(c in allowed for c in clustername) and all(c in allowed for c in lockspace) diff --git a/blivet/tasks/fsmkfs.py b/blivet/tasks/fsmkfs.py index 717cee3a3..096b02295 100644 --- a/blivet/tasks/fsmkfs.py +++ b/blivet/tasks/fsmkfs.py @@ -213,7 +213,7 @@ def do_task(self, options=None, label=False, set_uuid=False, nodiscard=False): class GFS2Mkfs(FSMkfs): ext = availability.MKFS_GFS2_APP - label_option = None + label_option = "-t" nodiscard_option = None get_uuid_args = None diff --git a/tests/storage_tests/formats_test/fs_test.py b/tests/storage_tests/formats_test/fs_test.py index 253b01428..f3c9fef5a 100644 --- a/tests/storage_tests/formats_test/fs_test.py +++ b/tests/storage_tests/formats_test/fs_test.py @@ -119,6 +119,19 @@ class BTRFSTestCase(fstesting.FSAsRoot): class GFS2TestCase(fstesting.FSAsRoot): _fs_class = fs.GFS2 + _valid_label = "label:label" + + @classmethod + def setUpClass(cls): + # allow creating gfs2 + flags.gfs2 = True + super(GFS2TestCase, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + # reset flag back to default + flags.gfs2 = False + super(GFS2TestCase, cls).tearDownClass() class XFSTestCase(fstesting.FSAsRoot): diff --git a/tests/storage_tests/formats_test/fstesting.py b/tests/storage_tests/formats_test/fstesting.py index 4c4f4cd6a..16d6dba45 100644 --- a/tests/storage_tests/formats_test/fstesting.py +++ b/tests/storage_tests/formats_test/fstesting.py @@ -16,6 +16,7 @@ class FSAsRoot(loopbackedtestcase.LoopBackedTestCase, metaclass=abc.ABCMeta): doc="The class of the filesystem being tested on.") _DEVICE_SIZE = Size("100 MiB") + _valid_label = "label" def __init__(self, methodName='run_test'): super(FSAsRoot, self).__init__(methodName=methodName, device_spec=[self._DEVICE_SIZE]) @@ -125,15 +126,15 @@ def test_labeling(self): if not an_fs.formattable or not an_fs.labeling(): self.skipTest("can not label filesystem %s" % an_fs.name) an_fs.device = self.loop_devices[0] - an_fs.label = "label" - self.assertTrue(an_fs.label_format_ok("label")) + an_fs.label = self._valid_label + self.assertTrue(an_fs.label_format_ok(self._valid_label)) self.assertIsNone(an_fs.create()) try: label = an_fs.read_label() if an_fs.type in ("vfat", "efi"): - self.assertEqual(label, "LABEL") + self.assertEqual(label, self._valid_label.upper()) else: - self.assertEqual(label, "label") + self.assertEqual(label, self._valid_label) except FSError: pass @@ -144,7 +145,7 @@ def test_relabeling(self): an_fs.device = self.loop_devices[0] self.assertIsNone(an_fs.create()) an_fs.label = "label" - self.assertTrue(an_fs.label_format_ok("label")) + self.assertTrue(an_fs.label_format_ok(self._valid_label)) if an_fs.relabels(): self.assertIsNone(an_fs.write_label()) else: diff --git a/tests/storage_tests/formats_test/labeling_test.py b/tests/storage_tests/formats_test/labeling_test.py index 513ec619d..e92781151 100644 --- a/tests/storage_tests/formats_test/labeling_test.py +++ b/tests/storage_tests/formats_test/labeling_test.py @@ -37,6 +37,12 @@ class NTFSTestCase(fslabeling.CompleteLabelingAsRoot): _default_label = "" +class GFS2TestCase(fslabeling.CompleteLabelingAsRoot): + _fs_class = fs.GFS2 + _invalid_label = "label:label*" + _default_label = "" + + class LabelingSwapSpaceTestCase(loopbackedtestcase.LoopBackedTestCase): def test_labeling(self): diff --git a/tests/unit_tests/formats_tests/init_test.py b/tests/unit_tests/formats_tests/init_test.py index 420230056..ee5c42620 100644 --- a/tests/unit_tests/formats_tests/init_test.py +++ b/tests/unit_tests/formats_tests/init_test.py @@ -69,6 +69,14 @@ def test_labels(self): self.assertFalse(formats.fs.NTFS().label_format_ok("n" * 129)) self.assertTrue(formats.fs.NTFS().label_format_ok("n" * 128)) + # GFS2 has special format: two parts, limited lengths and characters + self.assertFalse(formats.fs.GFS2().label_format_ok("label")) + self.assertFalse(formats.fs.GFS2().label_format_ok("label:label:label")) + self.assertFalse(formats.fs.GFS2().label_format_ok("n" * 33 + ":label")) + self.assertFalse(formats.fs.GFS2().label_format_ok("label:" + "n" * 31)) + self.assertFalse(formats.fs.GFS2().label_format_ok("label:label*")) + self.assertTrue(formats.fs.GFS2().label_format_ok("label:label")) + # all devices are permitted to be passed a label argument of None # some will ignore it completely for _k, v in formats.device_formats.items():