From 7d5d4d6e0f3b246842dfcf058f7d3a6956f51e5f Mon Sep 17 00:00:00 2001
From: Philip Wilk
Date: Wed, 29 Jan 2025 14:57:53 +0000
Subject: [PATCH 1/3] lib45d: init at 0.3.6
---
pkgs/by-name/li/lib45d/package.nix | 44 ++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 pkgs/by-name/li/lib45d/package.nix
diff --git a/pkgs/by-name/li/lib45d/package.nix b/pkgs/by-name/li/lib45d/package.nix
new file mode 100644
index 000000000000..26c1a86711c9
--- /dev/null
+++ b/pkgs/by-name/li/lib45d/package.nix
@@ -0,0 +1,44 @@
+{
+ stdenv,
+ fetchFromGitHub,
+ fetchpatch,
+ lib,
+}:
+stdenv.mkDerivation (finalAttrs: {
+ name = "lib45d";
+ version = "0.3.6";
+ src = fetchFromGitHub {
+ owner = "45Drives";
+ repo = "lib45d";
+ tag = "v${finalAttrs.version}";
+ hash = "sha256-42xB30Iu2WxNrBxomVBKd/uyIRt27y/Y1ah5mckOrc0=";
+ };
+
+ patches = [
+ # https://github.com/45Drives/lib45d/issues/3
+ # fix "error: 'uintmax_t' has not been declared" build failure until next release
+ (fetchpatch {
+ url = "https://github.com/45Drives/lib45d/commit/a607e278182a3184c004c45c215aa22c15d6941d.patch";
+ hash = "sha256-sMAvOp4EjBXGHa9PGuuEqJvpEvUlMuzRKCfq9oqQLgY=";
+ })
+ ];
+
+ installPhase = ''
+ runHook preInstall
+
+ install -Dm755 -t $out/lib dist/shared/lib45d.so
+
+ mkdir -p $out/include/45d
+ cp -f -r src/incl/45d/* $out/include/45d/
+
+ runHook postInstall
+ '';
+
+ meta = {
+ homepage = "https://github.com/45Drives/lib45d";
+ description = "45Drives C++ Library";
+ license = lib.licenses.gpl3;
+ maintainers = with lib.maintainers; [ philipwilk ];
+ platforms = lib.platforms.linux;
+ };
+})
From 9c4822421b230e7e76f75a15454b899fdc975fdb Mon Sep 17 00:00:00 2001
From: Philip Wilk
Date: Wed, 29 Jan 2025 14:58:04 +0000
Subject: [PATCH 2/3] autotier: init at 1.2.0
---
pkgs/by-name/au/autotier/package.nix | 88 ++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
create mode 100644 pkgs/by-name/au/autotier/package.nix
diff --git a/pkgs/by-name/au/autotier/package.nix b/pkgs/by-name/au/autotier/package.nix
new file mode 100644
index 000000000000..a6d8836eed35
--- /dev/null
+++ b/pkgs/by-name/au/autotier/package.nix
@@ -0,0 +1,88 @@
+{
+ stdenv,
+ lib,
+ fetchFromGitHub,
+ fetchpatch,
+ pkg-config,
+ rocksdb,
+ boost,
+ fuse3,
+ lib45d,
+ tbb_2021_11,
+ liburing,
+ installShellFiles,
+}:
+stdenv.mkDerivation (finalAttrs: {
+ name = "autotier";
+ version = "1.2.0";
+ src = fetchFromGitHub {
+ owner = "45Drives";
+ repo = "autotier";
+ tag = "v${finalAttrs.version}";
+ hash = "sha256-Pf1baDJsyt0ScASWrrgMu8+X5eZPGJSu0/LDQNHe1Ok=";
+ };
+
+ patches = [
+ # https://github.com/45Drives/autotier/pull/70
+ # fix "error: 'uintmax_t' has not been declared" build failure until next release
+ (fetchpatch {
+ url = "https://github.com/45Drives/autotier/commit/d447929dc4262f607d87cbc8ad40a54d64f5011a.patch";
+ hash = "sha256-0ab8YBgdJMxBHfOgUsgPpyUE1GyhAU3+WCYjYA2pjqo=";
+ })
+ # Unvendor rocksdb (nixpkgs already applies RTTI and PORTABLE flags) and use pkg-config for flags
+ (fetchpatch {
+ url = "https://github.com/45Drives/autotier/commit/fa282f5079ff17c144a7303d64dad0e44681b87f.patch";
+ hash = "sha256-+W3RwSe8zJKgZIXOaawHuI6xRzedYIcZundPC8eHuwM=";
+ })
+ # Add missing list import to src/incl/config.hpp
+ (fetchpatch {
+ url = "https://github.com/45Drives/autotier/commit/1f97703f4dfbfe093f5c18c4ee01dcc1c8fe04f3.patch";
+ hash = "sha256-3+KOh7JvbujCMbMqnZ5SGopAuOKHitKq6XV6a/jkcog=";
+ })
+ ];
+
+ buildInputs = [
+ rocksdb
+ boost
+ fuse3
+ lib45d
+ tbb_2021_11
+ liburing
+ ];
+
+ nativeBuildInputs = [
+ pkg-config
+ installShellFiles
+ ];
+
+ installPhase = ''
+ runHook preInstall
+
+ # binaries
+ installBin dist/from_source/*
+
+ # docs
+ installManPage doc/man/autotier.8
+
+ # Completions
+ installShellCompletion --bash doc/completion/autotier.bash-completion
+ installShellCompletion --bash doc/completion/autotierfs.bash-completion
+
+ # Scripts
+ installBin script/autotier-init-dirs
+
+ # Default config
+ install -Dm755 -t $out/etc/autotier.conf doc/autotier.conf.template
+
+ runHook postInstall
+ '';
+
+ meta = {
+ homepage = "https://github.com/45Drives/autotier";
+ description = "Passthrough FUSE filesystem that intelligently moves files between storage tiers based on frequency of use, file age, and tier fullness";
+ license = lib.licenses.gpl3;
+ maintainers = with lib.maintainers; [ philipwilk ];
+ mainProgram = "autotier"; # cli, for file system use autotierfs
+ platforms = lib.platforms.linux; # uses io_uring so only available on linux not unix
+ };
+})
From eb40871602415e10baf5eb9d7be04b5ecbac06d7 Mon Sep 17 00:00:00 2001
From: Philip Wilk
Date: Fri, 31 Jan 2025 22:55:44 +0000
Subject: [PATCH 3/3] 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;
+ };
+}