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; + }; +}