{ config, pkgs, lib, ...}: with lib; let cfg = config.idiosyn.ephemeral; device = mkOption { type = types.nonEmptyStr; description = mdDoc "Device to mount."; }; options = mkOption { type = with types; listOf nonEmptyStr; readOnly = true; description = mdDoc "Options used to mount the file system."; }; extraOptions = mkOption { type = with types; listOf nonEmptyStr; default = [ ]; description = mdDoc "Additional options used to mount the file system."; }; filesystem = { options = { inherit device options extraOptions; fsType = mkOption { type = types.nonEmptyStr; description = mdDoc "Type of the file system."; }; }; }; tmpfs = { options = { inherit options extraOptions; name = mkOption { type = types.nonEmptyStr; default = "none"; description = mdDoc "Name of the file system."; }; size = mkOption { type = with types; either nonEmptyStr ints.positive; description = mdDoc "Size of the file system."; }; mode = mkOption { type = types.nonEmptyStr; description = mdDoc "Initial permissions of the root directory."; }; uid = mkOption { type = with types; either nonEmptyStr ints.unsigned; default = 0; description = mdDom "Initial user ID of the root directory"; }; gid = mkOption { type = with types; either nonEmptyStr ints.unsigned; default = 0; description = mdDom "Initial group ID of the root directory"; }; }; }; subvol = { options = { inherit options extraOptions; subvolume = mkOption { type = with types; nullOr nonEmptyStr; default = null; description = mdDoc "Source path of the subvolume."; }; }; }; ephemeralDefaults = { "/" = { size = "256m"; mode = "755"; uid = 0; gid = 0; options = [ "nodev" "noexec" "nosuid" ]; extraOptions = [ ]; }; "/run/nix" = { size = "80%"; mode = "1775"; uid = 0; gid = "nixbld"; options = [ "nodev" "nosuid" ]; extraOptions = [ ]; }; "/tmp" = { size = "256m"; mode = "1777"; uid = 0; gid = 0; options = [ "nodev" "noexec" "nosuid" ]; extraOptions = [ ]; }; }; subvolumeDefaults = { "/etc/keys" = { options = [ "nodev" "noexec" "nosuid" ]; extraOptions = [ "noatime" "compress=zstd" ]; }; "/nix" = { options = [ "nodev" "nosuid" ]; extraOptions = [ "noatime" "compress=zstd" ]; }; "/var" = { options = [ "nodev" "noexec" "nosuid" ]; extraOptions = [ "noatime" "compress=zstd" ]; }; }; in { options = { idiosyn.ephemeral = { enable = mkEnableOption "ephemeral filesystem"; device = mkOption { type = types.nonEmptyStr; description = mdDoc "Persistent btrfs device."; }; boot = { inherit device; fsType = mkOption { type = types.nonEmptyStr; }; options = mkOption { inherit (options) type readOnly description; default = [ "nodev" "noexec" "nosuid" ] ++ optionals (cfg.boot.fsType == "vfat") [ "fmask=0137" "dmask=022" ] ++ optionals (builtins.match "ext[34]" cfg.boot.fsType != null) [ "data=journal" ]; }; extraOptions = mkOption { inherit (extraOptions) type description; default = [ "noatime" ]; }; }; ephemeral = mkOption { type = with types; attrsOf (submodule tmpfs); description = mdDoc "Ephemeral filesystems."; default = ephemeralDefaults; }; subvolumes = mkOption { type = with types; attrsOf (submodule subvol); description = mdDoc "Persistent subvolumes."; default = subvolumeDefaults; example = { "/home" = { options = [ "nodev" "noexec" "nosuid" ]; extraOptions = [ "noatime" "compress=zstd" ]; }; }; }; }; }; config = mkIf cfg.enable { boot.initrd.availableKernelModules = [ "zstd" ]; boot.supportedFilesystems = [ "btrfs" ]; environment.etc.machine-id.source = mkDefault "/etc/keys/machine-id"; environment.etc.secureboot.source = mkDefault "/etc/keys/secureboot"; fileSystems = { "/boot" = mkOverride 99 { device = cfg.boot.device; fsType = cfg.boot.fsType; options = cfg.boot.options ++ cfg.boot.extraOptions; }; } // (mapAttrs (key: val: mkOverride 99 { fsType = "tmpfs"; options = val.options ++ val.extraOptions ++ [ "strictatime" "size=${toString val.size}" "mode=${val.mode}" "uid=${toString val.uid}" "gid=${toString val.gid}" "huge=within_size" ]; }) (ephemeralDefaults // cfg.ephemeral)) // (mapAttrs (key: val: mkOverride 99 { device = cfg.device; fsType = "btrfs"; options = val.options ++ val.extraOptions ++ [ "subvol=${if (val ? subvolume && val.subvolume != null) then val.subvolume else key}" ]; neededForBoot = true; }) (subvolumeDefaults // cfg.subvolumes)); #nix.settings.build-dir = mkDefault "/run/nix"; systemd.services.nix-daemon.environment.TMPDIR = mkDefault "/run/nix"; systemd.tmpfiles.rules = [ "d /etc/keys 0751 root root" "D /run/nix 1775 root nixbld 1d" ]; }; }