diff --git a/README.md b/README.md index 19ad8d44..b4edc784 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ You can keep your configuration and re-use it for other installations, or for a - Disk layouts: GPT, MBR, and mixed. - Partition tools: LVM, mdadm, LUKS, and more. -- Filesystems: ext4, btrfs, ZFS, bcachefs, tmpfs, and others. +- Filesystems: ext4, bcachefs, btrfs, ZFS, bcachefs, tmpfs, and others. It can work with these in various configurations and orders, and supports recursive layouts. diff --git a/example/bcachefs.nix b/example/bcachefs.nix index 008e67eb..33877f2b 100644 --- a/example/bcachefs.nix +++ b/example/bcachefs.nix @@ -20,8 +20,8 @@ name = "root"; end = "-0"; content = { - type = "filesystem"; - format = "bcachefs"; + type = "bcachefs"; + passwordFile = "/tmp/secret.key"; mountpoint = "/"; }; }; diff --git a/lib/default.nix b/lib/default.nix index 565dd0a3..9799cb38 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -35,7 +35,7 @@ let # option for valid contents of partitions (basically like devices, but without tables) partitionType = extraArgs: lib.mkOption { type = lib.types.nullOr (diskoLib.subType { - types = { inherit (diskoLib.types) btrfs filesystem zfs mdraid luks lvm_pv swap; }; + types = { inherit (diskoLib.types) bcachefs btrfs filesystem zfs mdraid luks lvm_pv swap; }; inherit extraArgs; }); default = null; @@ -45,7 +45,7 @@ let # option for valid contents of devices deviceType = extraArgs: lib.mkOption { type = lib.types.nullOr (diskoLib.subType { - types = { inherit (diskoLib.types) table gpt btrfs filesystem zfs mdraid luks lvm_pv swap; }; + types = { inherit (diskoLib.types) table gpt bcachefs btrfs filesystem zfs mdraid luks lvm_pv swap; }; inherit extraArgs; }); default = null; diff --git a/lib/types/bcachefs.nix b/lib/types/bcachefs.nix new file mode 100644 index 00000000..0fa37855 --- /dev/null +++ b/lib/types/bcachefs.nix @@ -0,0 +1,98 @@ +{ config, options, diskoLib, lib, rootMountPoint, parent, device, ... }: +{ + options = { + type = lib.mkOption { + type = lib.types.enum [ "bcachefs" ]; + internal = true; + description = "Type"; + }; + device = lib.mkOption { + type = lib.types.str; + default = device; + description = "Device to use"; + }; + extraArgs = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "Extra arguments"; + }; + passwordFile = lib.mkOption { + type = lib.types.nullOr diskoLib.optionTypes.absolute-pathname; + default = null; + description = "Path to the file containing the password for encryption"; + example = "/tmp/disk.key"; + }; + mountOptions = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ "defaults" ]; + description = "A list of options to pass to mount."; + }; + mountpoint = lib.mkOption { + type = lib.types.nullOr diskoLib.optionTypes.absolute-pathname; + default = null; + description = "A path to mount the Bcachefs filesystem to."; + }; + _parent = lib.mkOption { + internal = true; + default = parent; + }; + _meta = lib.mkOption { + internal = true; + readOnly = true; + type = lib.types.functionTo diskoLib.jsonType; + default = dev: { }; + description = "Metadata"; + }; + _create = diskoLib.mkCreateOption { + inherit config options; + default = '' + # Currently the keyutils package is required due to an upstream bug + # https://github.com/NixOS/nixpkgs/issues/32279 + keyctl link @u @s + bcachefs format ${config.device} \ + ${toString config.extraArgs} \ + ${lib.optionalString (config.passwordFile != null) "--encrypted <<<\"$(cat ${config.passwordFile})\""} + ${lib.optionalString (config.passwordFile != null) "bcachefs unlock ${config.device} <<<\"$(cat ${config.passwordFile})\""} + ''; + }; + _mount = diskoLib.mkMountOption { + inherit config options; + default = { + fs = lib.optionalAttrs (config.mountpoint != null) { + ${config.mountpoint} = '' + if ! findmnt ${config.device} "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then + ${lib.optionalString (config.passwordFile != null) "bcachefs unlock ${config.device} <<<\"$(cat ${config.passwordFile})\""} + mount -t bcachefs ${config.device} "${rootMountPoint}${config.mountpoint}" \ + ${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \ + -o X-mount.mkdir + fi + ''; + }; + }; + }; + _config = lib.mkOption { + internal = true; + readOnly = true; + default = [ + (lib.optional (config.mountpoint != null) { + fileSystems.${config.mountpoint} = { + device = config.device; + fsType = "bcachefs"; + options = config.mountOptions; + }; + }) + ]; + description = "NixOS configuration"; + }; + _pkgs = lib.mkOption { + internal = true; + readOnly = true; + type = lib.types.functionTo (lib.types.listOf lib.types.package); + default = pkgs: + # Currently the keyutils package is required due to an upstream bug + # https://github.com/NixOS/nixpkgs/issues/32279 + with pkgs; [ bcachefs-tools coreutils keyutils ]; + description = "Packages"; + }; + }; +} diff --git a/lib/types/table.nix b/lib/types/table.nix index bc492aae..b54882a9 100644 --- a/lib/types/table.nix +++ b/lib/types/table.nix @@ -25,7 +25,7 @@ description = "Partition type"; }; fs-type = lib.mkOption { - type = lib.types.nullOr (lib.types.enum [ "btrfs" "ext2" "ext3" "ext4" "fat16" "fat32" "hfs" "hfs+" "linux-swap" "ntfs" "reiserfs" "udf" "xfs" ]); + type = lib.types.nullOr (lib.types.enum [ "bcachefs" "btrfs" "ext2" "ext3" "ext4" "fat16" "fat32" "hfs" "hfs+" "linux-swap" "ntfs" "reiserfs" "udf" "xfs" ]); default = null; description = "Filesystem type to use"; };