diff --git a/changelogs/fragments/12285-filesystem-gfs2.yaml b/changelogs/fragments/12285-filesystem-gfs2.yaml new file mode 100644 index 0000000000..7860e19898 --- /dev/null +++ b/changelogs/fragments/12285-filesystem-gfs2.yaml @@ -0,0 +1,2 @@ +minor_changes: + - filesystem - adds GFS2 support (https://github.com/ansible-collections/community.general/pull/12285). diff --git a/plugins/modules/filesystem.py b/plugins/modules/filesystem.py index 35585ae494..cb7d901574 100644 --- a/plugins/modules/filesystem.py +++ b/plugins/modules/filesystem.py @@ -35,11 +35,12 @@ options: default: present version_added: 1.3.0 fstype: - choices: [bcachefs, btrfs, ext2, ext3, ext4, ext4dev, f2fs, lvm, ocfs2, reiserfs, xfs, vfat, swap, ufs] + choices: [bcachefs, btrfs, ext2, ext3, ext4, ext4dev, f2fs, lvm, ocfs2, reiserfs, xfs, vfat, swap, ufs, gfs2] description: - Filesystem type to be created. This option is required with O(state=present) (or if O(state) is omitted). - V(ufs) support has been added in community.general 3.4.0. - V(bcachefs) support has been added in community.general 8.6.0. + - V(gfs2) support has been added in community.general 13.1.0. type: str aliases: [type] dev: @@ -79,11 +80,19 @@ options: - The UUID options specified in O(opts) take precedence over this value. - See xfs_admin(8) (C(xfs)), tune2fs(8) (C(ext2), C(ext3), C(ext4), C(ext4dev)) for possible values. - For O(fstype=lvm) the value is ignored, it resets the PV UUID if set. - - Supported for O(fstype) being one of V(bcachefs), V(ext2), V(ext3), V(ext4), V(ext4dev), V(lvm), or V(xfs). + - Supported for O(fstype) being one of V(bcachefs), V(ext2), V(ext3), V(ext4), V(ext4dev), V(lvm), V(gfs2) or V(xfs). - This is B(not idempotent). Specifying this option always results in a change. - Mutually exclusive with O(resizefs). type: str version_added: 7.1.0 + label: + description: + - Set filesystem's label to the given value. + - The label options specified in O(opts) take precedence over this value. + - Supported for O(fstype) being one of V(gfs2). Support for other filesystems might be added later. + - On GFS2 this sets the lock table with the C(-t) option of mkfs.gfs2(8). It has to be in the form V(CLUSTERNAME:LOCKSPACE). + type: str + version_added: 13.1.0 requirements: - Uses specific tools related to the O(fstype) for creating or resizing a filesystem (from packages e2fsprogs, xfsprogs, dosfstools, and so on). @@ -205,6 +214,7 @@ class Filesystem: MKFS_FORCE_FLAGS: list[str] | None = [] MKFS_SET_UUID_OPTIONS: list[str] | None = None MKFS_SET_UUID_EXTRA_OPTIONS: list[str] | None = [] + MKFS_SET_LABEL_OPTIONS: list[str] | None = None INFO: str | None = None GROW: str | None = None GROW_SLACK: int = 0 @@ -231,13 +241,16 @@ class Filesystem: """ raise NotImplementedError() - def create(self, opts, dev, uuid=None): + def create(self, opts, dev, uuid=None, label=None): if self.module.check_mode: return if uuid and self.MKFS_SET_UUID_OPTIONS: if not (set(self.MKFS_SET_UUID_OPTIONS) & set(opts)): opts += [self.MKFS_SET_UUID_OPTIONS[0], uuid] + self.MKFS_SET_UUID_EXTRA_OPTIONS + if label is not None and self.MKFS_SET_LABEL_OPTIONS: + if not (set(self.MKFS_SET_LABEL_OPTIONS) & set(opts)): + opts += [self.MKFS_SET_LABEL_OPTIONS[0], label] mkfs = self.module.get_bin_path(self.MKFS, required=True) cmd = [mkfs] + self.MKFS_FORCE_FLAGS + opts + [str(dev)] @@ -611,6 +624,13 @@ class UFS(Filesystem): return fragmentsize * providersize +class GFS2(Filesystem): + MKFS = "mkfs.gfs2" + MKFS_FORCE_FLAGS = ["-O"] + MKFS_SET_UUID_OPTIONS = ["-U"] + MKFS_SET_LABEL_OPTIONS = ["-t"] + + FILESYSTEMS = { "bcachefs": Bcachefs, "ext2": Ext2, @@ -626,6 +646,7 @@ FILESYSTEMS = { "LVM2_member": LVM, "swap": Swap, "ufs": UFS, + "gfs2": GFS2, } @@ -646,6 +667,7 @@ def main(): force=dict(type="bool", default=False), resizefs=dict(type="bool", default=False), uuid=dict(type="str"), + label=dict(type="str"), ), required_if=[("state", "present", ["fstype"])], mutually_exclusive=[ @@ -661,6 +683,7 @@ def main(): force = module.params["force"] resizefs = module.params["resizefs"] uuid = module.params["uuid"] + label = module.params["label"] mkfs_opts = [] if opts is not None: @@ -728,7 +751,7 @@ def main(): module.fail_json(msg=f"'{dev}' is already used as {fs}, use force=true to overwrite", rc=rc, err=err) # create fs - filesystem.create(opts=mkfs_opts, dev=dev, uuid=uuid) + filesystem.create(opts=mkfs_opts, dev=dev, uuid=uuid, label=label) changed = True elif fs: diff --git a/tests/integration/targets/filesystem/defaults/main.yml b/tests/integration/targets/filesystem/defaults/main.yml index 7ff30bcd54..1b803258c1 100644 --- a/tests/integration/targets/filesystem/defaults/main.yml +++ b/tests/integration/targets/filesystem/defaults/main.yml @@ -15,20 +15,21 @@ tested_filesystems: # - 1.7.0 requires at least 30Mo # - 1.10.0 requires at least 38Mo # - resizefs asserts when initial fs is smaller than 60Mo and seems to require 1.10.0 - bcachefs: {fssize: 20, grow: true, new_uuid: null} - ext4: {fssize: 10, grow: true, new_uuid: 'random'} - ext4dev: {fssize: 10, grow: true, new_uuid: 'random'} - ext3: {fssize: 10, grow: true, new_uuid: 'random'} - ext2: {fssize: 10, grow: true, new_uuid: 'random'} - xfs: {fssize: 300, grow: false, new_uuid: 'generate'} # grow requires a mounted filesystem - btrfs: {fssize: 150, grow: false, new_uuid: null} # grow requires a mounted filesystem - reiserfs: {fssize: 33, grow: false, new_uuid: null} # grow not implemented - vfat: {fssize: 20, grow: true, new_uuid: null} - ocfs2: {fssize: '{{ ocfs2_fssize }}', grow: false, new_uuid: null} # grow not implemented - f2fs: {fssize: '{{ f2fs_fssize|default(60) }}', grow: 'f2fs_version is version("1.10.0", ">=")', new_uuid: null} - lvm: {fssize: 20, grow: true, new_uuid: 'something'} - swap: {fssize: 10, grow: false, new_uuid: null} # grow not implemented - ufs: {fssize: 10, grow: true, new_uuid: null} + bcachefs: {fssize: 20, grow: true, new_uuid: null, label: null} + ext4: {fssize: 10, grow: true, new_uuid: 'random', label: null} + ext4dev: {fssize: 10, grow: true, new_uuid: 'random', label: null} + ext3: {fssize: 10, grow: true, new_uuid: 'random', label: null} + ext2: {fssize: 10, grow: true, new_uuid: 'random', label: null} + xfs: {fssize: 300, grow: false, new_uuid: 'generate', label: null} # grow requires a mounted filesystem + btrfs: {fssize: 150, grow: false, new_uuid: null, label: null} # grow requires a mounted filesystem + reiserfs: {fssize: 33, grow: false, new_uuid: null, label: null} # grow not implemented + vfat: {fssize: 20, grow: true, new_uuid: null, label: null} + ocfs2: {fssize: '{{ ocfs2_fssize }}', grow: false, new_uuid: null, label: null} # grow not implemented + f2fs: {fssize: '{{ f2fs_fssize|default(60) }}', grow: 'f2fs_version is version("1.10.0", ">=")', new_uuid: null, label: null} + lvm: {fssize: 20, grow: true, new_uuid: 'something', label: null} + swap: {fssize: 10, grow: false, new_uuid: null, label: null} # grow not implemented + ufs: {fssize: 10, grow: true, new_uuid: null, label: null} + gfs2: {fssize: 50, grow: false, new_uuid: null, label: 'CLUSTER:LOCKSPACE'} get_uuid_any: "blkid -c /dev/null -o value -s UUID {{ dev }}" diff --git a/tests/integration/targets/filesystem/tasks/create_fs.yml b/tests/integration/targets/filesystem/tasks/create_fs.yml index 8dcc6ee170..8a6f817046 100644 --- a/tests/integration/targets/filesystem/tasks/create_fs.yml +++ b/tests/integration/targets/filesystem/tasks/create_fs.yml @@ -7,6 +7,7 @@ community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' + label: '{{ label }}' register: fs_result - name: "Assert that results are as expected" @@ -25,6 +26,7 @@ community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' + label: '{{ label }}' register: fs2_result - name: "Get UUID of the filesystem" @@ -44,6 +46,7 @@ community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' + label: '{{ label }}' force: true register: fs3_result diff --git a/tests/integration/targets/filesystem/tasks/main.yml b/tests/integration/targets/filesystem/tasks/main.yml index 0cf1bc6794..88f6642f7d 100644 --- a/tests/integration/targets/filesystem/tasks/main.yml +++ b/tests/integration/targets/filesystem/tasks/main.yml @@ -30,13 +30,14 @@ fssize: '{{ item.0.value.fssize }}' grow: '{{ item.0.value.grow }}' new_uuid: '{{ item.0.value.new_uuid }}' + label: '{{ item.0.value.label }}' action: '{{ item.1 }}' when: # FreeBSD limited support # Not available: btrfs, lvm, f2fs, ocfs2 # All BSD systems use swap fs, but only Linux needs mkswap # Supported: ext2/3/4 (e2fsprogs), xfs (xfsprogs), reiserfs (progsreiserfs), vfat - - 'not (ansible_facts.system == "FreeBSD" and item.0.key in ["bcachefs", "btrfs", "f2fs", "swap", "lvm", "ocfs2"])' + - 'not (ansible_facts.system == "FreeBSD" and item.0.key in ["bcachefs", "btrfs", "f2fs", "swap", "lvm", "ocfs2", "gfs2"])' # Available on FreeBSD but not on testbed (util-linux conflicts with e2fsprogs): wipefs, mkfs.minix - 'not (ansible_facts.system == "FreeBSD" and item.1 in ["overwrite_another_fs", "remove_fs"])' @@ -80,6 +81,8 @@ # TODO: figure out why it fails, fix it! # swap does not work on Alpine due to no -f support in mkswap - 'not (item.0.key == "swap" and ansible_facts.distribution == "Alpine")' + # GFS2 not available on these distributions + - 'not (item.0.key == "gfs2" and ansible_facts.distribution in ["Alpine", "Archlinux", "CentOS", "RedHat"])' loop: "{{ query('dict', tested_filesystems)|product(['create_fs', 'reset_fs_uuid', 'overwrite_another_fs', 'remove_fs', 'set_fs_uuid_on_creation', 'set_fs_uuid_on_creation_with_opts'])|list }}" @@ -97,6 +100,7 @@ fstype: '{{ item.0.key }}' fssize: '{{ item.0.value.fssize }}' grow: '{{ item.0.value.grow }}' + label: '{{ item.0.value.label }}' action: '{{ item.1 }}' when: - 'ansible_facts.system == "FreeBSD"' diff --git a/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml b/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml index 69418b22f8..37b0d92abc 100644 --- a/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml +++ b/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml @@ -23,6 +23,7 @@ community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' + label: '{{ label }}' register: fs_result ignore_errors: true @@ -42,6 +43,7 @@ community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' + label: '{{ label }}' force: true register: fs_result2 diff --git a/tests/integration/targets/filesystem/tasks/remove_fs.yml b/tests/integration/targets/filesystem/tasks/remove_fs.yml index e3a90b104a..1eeb4d16a3 100644 --- a/tests/integration/targets/filesystem/tasks/remove_fs.yml +++ b/tests/integration/targets/filesystem/tasks/remove_fs.yml @@ -9,6 +9,7 @@ community.general.filesystem: dev: '{{ dev }}' fstype: '{{ fstype }}' + label: '{{ label }}' - name: "Get filesystem UUID with 'blkid'" ansible.builtin.shell: diff --git a/tests/integration/targets/filesystem/tasks/setup.yml b/tests/integration/targets/filesystem/tasks/setup.yml index 6dd7e98e23..bec4a88b71 100644 --- a/tests/integration/targets/filesystem/tasks/setup.yml +++ b/tests/integration/targets/filesystem/tasks/setup.yml @@ -102,6 +102,12 @@ state: present when: ansible_facts.os_family == 'Debian' +- name: "Install GFS2" + ansible.builtin.package: + name: gfs2-utils + state: present + when: ansible_facts.os_family in ['Debian', 'Suse', 'Ubuntu'] or ansible_facts.distribution == 'Fedora' + - name: "Install f2fs tools and get version" when: - ansible_facts.os_family != 'RedHat' or ansible_facts.distribution == 'Fedora'