diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index b6fd67d206ca5d..bbf341c2d60248 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -394,6 +394,7 @@ ./services/audio/squeezelite.nix ./services/audio/tts.nix ./services/audio/ympd.nix + ./services/autotierfs.nix ./services/backup/automysqlbackup.nix ./services/backup/bacula.nix ./services/backup/borgbackup.nix diff --git a/nixos/modules/services/autotierfs.nix b/nixos/modules/services/autotierfs.nix new file mode 100644 index 00000000000000..a55629e95575a7 --- /dev/null +++ b/nixos/modules/services/autotierfs.nix @@ -0,0 +1,84 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.services.autotierfs; + ini = pkgs.formats.ini { }; + format = lib.types.attrsOf ini.type; + stateDir = "/var/lib/autotier"; + + generateConfigName = name: + builtins.replaceStrings [ "/" ] [ "-" ] (lib.strings.removePrefix "/" name); + configFiles = builtins.mapAttrs + (name: val: ini.generate "${generateConfigName name}-autotier.conf" val) + cfg.settings; + + getMountDeps = settings: + builtins.concatStringsSep " " + (builtins.catAttrs "Path" (builtins.attrValues settings)); + + mountPaths = builtins.attrNames cfg.settings; +in { + options.services.autotierfs = { + enable = lib.mkEnableOption "the autotier passthrough tiering filesystem"; + package = lib.mkOption { + type = lib.types.package; + default = pkgs.autotier; + defaultText = lib.options.literalExpression "pkgs.autotier"; + description = "Configured package for the filesystem and its cli."; + }; + settings = lib.mkOption { + type = lib.types.nullOr format; + default = null; + description = '' + The contents of the configuration file for autotier. + Config can be found in the [autotier repo](https://github.com/45Drives/autotier#configuration) + ''; + example = { + "/mnt/autotier" = { + Global = { + "Log Level" = 1; + "Tier Period" = 1000; + "Copy Buffer Size" = "1 MiB"; + }; + "Tier 1" = { + Path = "/mnt/tier1"; + Quota = "30GiB"; + }; + "Tier 2" = { + Path = "/mnt/tier2"; + Quota = "200GiB"; + }; + }; + }; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [{ + assertion = cfg.enable -> cfg.settings != null; + message = "Autotier needs a config file to know how to tier your paths."; + }]; + + system.fsPackages = [ cfg.package ]; + + # Not necessary for module to work but makes it easier to pass config into cli + environment.etc = lib.attrsets.mapAttrs' (name: value: + lib.attrsets.nameValuePair "autotier/${(generateConfigName name)}.conf" { + source = value; + }) configFiles; + + systemd.tmpfiles.rules = map (path: "d ${path} 1700 - - - -") mountPaths; + + systemd.services = lib.attrsets.mapAttrs' (path: values: + lib.attrsets.nameValuePair (generateConfigName path) { + description = "Mount autotierfs virtual path ${path}"; + unitConfig.RequiresMountsFor = getMountDeps values; + serviceConfig = { + Type = "oneshot"; + ReadWritePaths = stateDir; + ExecStart = "${cfg.package}/bin/autotierfs -c ${ + configFiles.${path} + } ${path} -o allow_other,default_permissions"; + }; + }) cfg.settings; + }; +}