From eb40871602415e10baf5eb9d7be04b5ecbac06d7 Mon Sep 17 00:00:00 2001
From: Philip Wilk
Date: Fri, 31 Jan 2025 22:55:44 +0000
Subject: [PATCH] autotier: init at 1.2.0
---
.../manual/release-notes/rl-2505.section.md | 2 +
nixos/modules/module-list.nix | 1 +
nixos/modules/services/autotierfs.nix | 95 +++++++++++++++++++
3 files changed, 98 insertions(+)
create mode 100644 nixos/modules/services/autotierfs.nix
diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md
index 311d285a701d..1c3f0475559a 100644
--- a/nixos/doc/manual/release-notes/rl-2505.section.md
+++ b/nixos/doc/manual/release-notes/rl-2505.section.md
@@ -95,6 +95,8 @@
- [Bat](https://github.com/sharkdp/bat), a {manpage}`cat(1)` clone with wings. Available as [programs.bat](options.html#opt-programs.bat).
+- [Autotier](https://github.com/45Drives/autotier), a passthrough FUSE filesystem. Available as [services.autotierfs](options.html#opt-services.autotierfs.enable).
+
- [µStreamer](https://github.com/pikvm/ustreamer), a lightweight MJPEG-HTTP streamer. Available as [services.ustreamer](options.html#opt-services.ustreamer).
- [Whoogle Search](https://github.com/benbusby/whoogle-search), a self-hosted, ad-free, privacy-respecting metasearch engine. Available as [services.whoogle-search](options.html#opt-services.whoogle-search.enable).
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index dd5b09d91610..8a292a774aa6 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -417,6 +417,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 000000000000..62200708bbb4
--- /dev/null
+++ b/nixos/modules/services/autotierfs.nix
@@ -0,0 +1,95 @@
+{
+ 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}.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.mkPackageOption pkgs "autotier" { };
+ settings = lib.mkOption {
+ type = lib.types.submodule {
+ freeformType = format;
+ };
+ default = { };
+ description = ''
+ The contents of the configuration file for autotier.
+ See the [autotier repo](https://github.com/45Drives/autotier#configuration) for supported values.
+ '';
+ example = lib.literalExpression ''
+ {
+ "/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.settings != { };
+ message = "`services.autotierfs.settings` must be configured.";
+ }
+ ];
+
+ 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} 0770 - autotier - -") mountPaths) ++ [
+ "d ${stateDir} 0774 - autotier - -"
+ ];
+
+ users.groups.autotier = { };
+
+ systemd.services = lib.attrsets.mapAttrs' (
+ path: values:
+ lib.attrsets.nameValuePair (generateConfigName path) {
+ description = "Mount autotierfs virtual path ${path}";
+ unitConfig.RequiresMountsFor = getMountDeps values;
+ wantedBy = [ "local-fs.target" ];
+ serviceConfig = {
+ Type = "forking";
+ ExecStart = "${lib.getExe' cfg.package "autotierfs"} -c /etc/autotier/${generateConfigName path}.conf ${path} -o allow_other,default_permissions";
+ ExecStop = "umount ${path}";
+ };
+ }
+ ) cfg.settings;
+ };
+}