|
| 1 | +{ |
| 2 | + config, |
| 3 | + lib, |
| 4 | + pkgs, |
| 5 | + ... |
| 6 | +}: |
| 7 | +let |
| 8 | + cfg = config.services.autotierfs; |
| 9 | + ini = pkgs.formats.ini { }; |
| 10 | + format = lib.types.attrsOf ini.type; |
| 11 | + stateDir = "/var/lib/autotier"; |
| 12 | + |
| 13 | + generateConfigName = |
| 14 | + name: builtins.replaceStrings [ "/" ] [ "-" ] (lib.strings.removePrefix "/" name); |
| 15 | + configFiles = builtins.mapAttrs ( |
| 16 | + name: val: ini.generate "${generateConfigName name}.conf" val |
| 17 | + ) cfg.settings; |
| 18 | + |
| 19 | + getMountDeps = |
| 20 | + settings: builtins.concatStringsSep " " (builtins.catAttrs "Path" (builtins.attrValues settings)); |
| 21 | + |
| 22 | + mountPaths = builtins.attrNames cfg.settings; |
| 23 | +in |
| 24 | +{ |
| 25 | + options.services.autotierfs = { |
| 26 | + enable = lib.mkEnableOption "the autotier passthrough tiering filesystem"; |
| 27 | + package = lib.mkPackageOption pkgs "autotier" { }; |
| 28 | + settings = lib.mkOption { |
| 29 | + type = lib.types.submodule { |
| 30 | + freeformType = format; |
| 31 | + }; |
| 32 | + default = { }; |
| 33 | + description = '' |
| 34 | + The contents of the configuration file for autotier. |
| 35 | + See the [autotier repo](https://github.com/45Drives/autotier#configuration) for supported values. |
| 36 | + ''; |
| 37 | + example = lib.literalExpression '' |
| 38 | + { |
| 39 | + "/mnt/autotier" = { |
| 40 | + Global = { |
| 41 | + "Log Level" = 1; |
| 42 | + "Tier Period" = 1000; |
| 43 | + "Copy Buffer Size" = "1 MiB"; |
| 44 | + }; |
| 45 | + "Tier 1" = { |
| 46 | + Path = "/mnt/tier1"; |
| 47 | + Quota = "30GiB"; |
| 48 | + }; |
| 49 | + "Tier 2" = { |
| 50 | + Path = "/mnt/tier2"; |
| 51 | + Quota = "200GiB"; |
| 52 | + }; |
| 53 | + }; |
| 54 | + } |
| 55 | + ''; |
| 56 | + }; |
| 57 | + }; |
| 58 | + |
| 59 | + config = lib.mkIf cfg.enable { |
| 60 | + assertions = [ |
| 61 | + { |
| 62 | + assertion = cfg.settings != { }; |
| 63 | + message = "`services.autotierfs.settings` must be configured."; |
| 64 | + } |
| 65 | + ]; |
| 66 | + |
| 67 | + system.fsPackages = [ cfg.package ]; |
| 68 | + |
| 69 | + # Not necessary for module to work but makes it easier to pass config into cli |
| 70 | + environment.etc = lib.attrsets.mapAttrs' ( |
| 71 | + name: value: |
| 72 | + lib.attrsets.nameValuePair "autotier/${(generateConfigName name)}.conf" { source = value; } |
| 73 | + ) configFiles; |
| 74 | + |
| 75 | + systemd.tmpfiles.rules = (map (path: "d ${path} 0770 - autotier - -") mountPaths) ++ [ |
| 76 | + "d ${stateDir} 0774 - autotier - -" |
| 77 | + ]; |
| 78 | + |
| 79 | + users.groups.autotier = { }; |
| 80 | + |
| 81 | + systemd.services = lib.attrsets.mapAttrs' ( |
| 82 | + path: values: |
| 83 | + lib.attrsets.nameValuePair (generateConfigName path) { |
| 84 | + description = "Mount autotierfs virtual path ${path}"; |
| 85 | + unitConfig.RequiresMountsFor = getMountDeps values; |
| 86 | + wantedBy = [ "local-fs.target" ]; |
| 87 | + serviceConfig = { |
| 88 | + Type = "forking"; |
| 89 | + ExecStart = "${lib.getExe' cfg.package "autotierfs"} -c /etc/autotier/${generateConfigName path}.conf ${path} -o allow_other,default_permissions"; |
| 90 | + ExecStop = "umount ${path}"; |
| 91 | + }; |
| 92 | + } |
| 93 | + ) cfg.settings; |
| 94 | + }; |
| 95 | +} |
0 commit comments