From 486c26b2247c37428c41a094ab7db593f3355734 Mon Sep 17 00:00:00 2001 From: Stijn Tintel Date: Sat, 20 Apr 2024 13:14:15 +0300 Subject: [PATCH] filesystem: add bcachefs support (#8126) Signed-off-by: Stijn Tintel --- .../8126-filesystem-bcachefs-support.yaml | 2 + plugins/modules/filesystem.py | 50 +++++++++++++++++-- .../targets/filesystem/defaults/main.yml | 1 + .../targets/filesystem/tasks/main.yml | 6 ++- .../targets/filesystem/tasks/setup.yml | 10 ++++ 5 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/8126-filesystem-bcachefs-support.yaml diff --git a/changelogs/fragments/8126-filesystem-bcachefs-support.yaml b/changelogs/fragments/8126-filesystem-bcachefs-support.yaml new file mode 100644 index 0000000000..32ff5c64da --- /dev/null +++ b/changelogs/fragments/8126-filesystem-bcachefs-support.yaml @@ -0,0 +1,2 @@ +minor_changes: + - filesystem - add bcachefs support (https://github.com/ansible-collections/community.general/pull/8126). diff --git a/plugins/modules/filesystem.py b/plugins/modules/filesystem.py index ec361245bd..73e8c79c6a 100644 --- a/plugins/modules/filesystem.py +++ b/plugins/modules/filesystem.py @@ -40,11 +40,12 @@ options: default: present version_added: 1.3.0 fstype: - choices: [ 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 ] description: - Filesystem type to be created. This option is required with O(state=present) (or if O(state) is omitted). - ufs support has been added in community.general 3.4.0. + - bcachefs support has been added in community.general 8.6.0. type: str aliases: [type] dev: @@ -67,7 +68,7 @@ options: resizefs: description: - If V(true), if the block device and filesystem size differ, grow the filesystem into the space. - - Supported for C(btrfs), C(ext2), C(ext3), C(ext4), C(ext4dev), C(f2fs), C(lvm), C(xfs), C(ufs) and C(vfat) filesystems. + - Supported for C(bcachefs), C(btrfs), C(ext2), C(ext3), C(ext4), C(ext4dev), C(f2fs), C(lvm), C(xfs), C(ufs) and C(vfat) filesystems. Attempts to resize other filesystem types will fail. - XFS Will only grow if mounted. Currently, the module is based on commands from C(util-linux) package to perform operations, so resizing of XFS is @@ -86,7 +87,7 @@ 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 C(ext2), C(ext3), C(ext4), C(ext4dev), C(lvm), or C(xfs). + - Supported for O(fstype) being one of C(bcachefs), C(ext2), C(ext3), C(ext4), C(ext4dev), C(lvm), or C(xfs). - This is B(not idempotent). Specifying this option will always result in a change. - Mutually exclusive with O(resizefs). type: str @@ -405,6 +406,48 @@ class Reiserfs(Filesystem): MKFS_FORCE_FLAGS = ['-q'] +class Bcachefs(Filesystem): + MKFS = 'mkfs.bcachefs' + MKFS_FORCE_FLAGS = ['--force'] + MKFS_SET_UUID_OPTIONS = ['-U', '--uuid'] + INFO = 'bcachefs' + GROW = 'bcachefs' + GROW_MAX_SPACE_FLAGS = ['device', 'resize'] + + def get_fs_size(self, dev): + """Return size in bytes of filesystem on device (integer).""" + dummy, stdout, dummy = self.module.run_command([self.module.get_bin_path(self.INFO), + 'show-super', str(dev)], check_rc=True) + + for line in stdout.splitlines(): + if "Size: " in line: + parts = line.split() + unit = parts[2] + + base = None + exp = None + + units_2 = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"] + units_10 = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"] + + try: + exp = units_2.index(unit) + base = 1024 + except ValueError: + exp = units_10.index(unit) + base = 1000 + + if exp == 0: + value = int(parts[1]) + else: + value = float(parts[1]) + + if base is not None and exp is not None: + return int(value * pow(base, exp)) + + raise ValueError(repr(stdout)) + + class Btrfs(Filesystem): MKFS = 'mkfs.btrfs' INFO = 'btrfs' @@ -567,6 +610,7 @@ class UFS(Filesystem): FILESYSTEMS = { + 'bcachefs': Bcachefs, 'ext2': Ext2, 'ext3': Ext3, 'ext4': Ext4, diff --git a/tests/integration/targets/filesystem/defaults/main.yml b/tests/integration/targets/filesystem/defaults/main.yml index ec446d2417..7ff30bcd54 100644 --- a/tests/integration/targets/filesystem/defaults/main.yml +++ b/tests/integration/targets/filesystem/defaults/main.yml @@ -15,6 +15,7 @@ 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'} diff --git a/tests/integration/targets/filesystem/tasks/main.yml b/tests/integration/targets/filesystem/tasks/main.yml index 0c15c21556..51361079ce 100644 --- a/tests/integration/targets/filesystem/tasks/main.yml +++ b/tests/integration/targets/filesystem/tasks/main.yml @@ -36,7 +36,7 @@ # 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_system == "FreeBSD" and item.0.key in ["btrfs", "f2fs", "swap", "lvm", "ocfs2"])' + - 'not (ansible_system == "FreeBSD" and item.0.key in ["bcachefs", "btrfs", "f2fs", "swap", "lvm", "ocfs2"])' # Available on FreeBSD but not on testbed (util-linux conflicts with e2fsprogs): wipefs, mkfs.minix - 'not (ansible_system == "FreeBSD" and item.1 in ["overwrite_another_fs", "remove_fs"])' @@ -46,6 +46,10 @@ # Other limitations and corner cases + # bcachefs only on Alpine > 3.18 and Arch Linux for now + # other distributions have too old versions of bcachefs-tools and/or util-linux (blkid for UUID tests) + - 'ansible_distribution == "Alpine" and ansible_distribution_version is version("3.18", ">") and item.0.key == "bcachefs"' + - 'ansible_distribution == "Archlinux" and item.0.key == "bcachefs"' # f2fs-tools and reiserfs-utils packages not available with RHEL/CentOS on CI - 'not (ansible_distribution in ["CentOS", "RedHat"] and item.0.key in ["f2fs", "reiserfs"])' - 'not (ansible_os_family == "RedHat" and ansible_distribution_major_version is version("8", ">=") and diff --git a/tests/integration/targets/filesystem/tasks/setup.yml b/tests/integration/targets/filesystem/tasks/setup.yml index 97dafaeeec..77c028acaf 100644 --- a/tests/integration/targets/filesystem/tasks/setup.yml +++ b/tests/integration/targets/filesystem/tasks/setup.yml @@ -16,6 +16,16 @@ - e2fsprogs - xfsprogs +- name: "Install bcachefs tools" + ansible.builtin.package: + name: bcachefs-tools + state: present + when: + # bcachefs only on Alpine > 3.18 and Arch Linux for now + # other distributions have too old versions of bcachefs-tools and/or util-linux (blkid for UUID tests) + - ansible_distribution == "Alpine" and ansible_distribution_version is version("3.18", ">") + - ansible_distribution == "Archlinux" + - name: "Install btrfs progs" ansible.builtin.package: name: btrfs-progs