diff --git a/lib/module/default.nix b/lib/module/default.nix index 975fc2d..3f8b4f3 100644 --- a/lib/module/default.nix +++ b/lib/module/default.nix @@ -88,6 +88,15 @@ with lib; rec { #@ Type -> Any -> String mkOptAttrset' = type: default: mkOptAttrset type default null; + ## Create a store path that symlinks to a path outside the Nix store. + ## + ## This is useful for mutable/decrypted files that should not be copied into + ## the store, matching Home Manager's mkOutOfStoreSymlink behavior. + mkOutOfStoreSymlink = pkgs: path: + pkgs.runCommandLocal "${baseNameOf path}" {} '' + ln -s ${lib.escapeShellArg path} $out + ''; + ## Create a listOf NixOS module option. ## ## ```nix diff --git a/modules/nixos/services/apps/servarr/unpackerr/default.nix b/modules/nixos/services/apps/servarr/unpackerr/default.nix new file mode 100644 index 0000000..eb4c240 --- /dev/null +++ b/modules/nixos/services/apps/servarr/unpackerr/default.nix @@ -0,0 +1,76 @@ +{ + config, + lib, + namespace, + pkgs, + ... +}: let + inherit (lib) filter mkIf optional; + inherit (lib.${namespace}) getAttrByNamespace hostHasService mkOutOfStoreSymlink; + inherit (config.networking) hostName; + + networkCfg = getAttrByNamespace config "${namespace}.services.networking"; + + starrServices = ["radarr" "sonarr" "lidarr"]; + enabledStarrServices = filter (service: hostHasService networkCfg.network-services hostName service) starrServices; + isEnabled = enabledStarrServices != []; +in { + config = mkIf isEnabled { + systemd.services.unpackerr = let + unpackerrUser = config.users.users.unpackerr; + systemdDependencies = + enabledStarrServices + |> map (service: "${service}.service"); + in { + description = "Extract downloads for Starr apps"; + + wantedBy = ["multi-user.target"]; + wants = ["network-online.target"] ++ systemdDependencies; + after = ["network-online.target"] ++ systemdDependencies; + + serviceConfig = let + cfg = + "${config.users.users.c4patino.home}/dotfiles/secrets/crypt/unpackerr.toml" + |> mkOutOfStoreSymlink pkgs; + in { + Type = "simple"; + User = unpackerrUser.name; + Group = unpackerrUser.group; + UMask = "0002"; + + StateDirectory = "unpackerr"; + + LoadCredential = ["unpackerr.toml:${cfg}"]; + + ExecStart = "${pkgs.unpackerr}/bin/unpackerr --config %d/unpackerr.toml"; + Restart = "always"; + RestartSec = 30; + }; + }; + + users = { + users.unpackerr = { + isSystemUser = true; + group = "unpackerr"; + extraGroups = ["qbittorrent"] ++ enabledStarrServices; + }; + + groups.unpackerr = {}; + }; + + ${namespace}.services.storage.impermanence.folders = let + unpackerrUser = config.users.users.unpackerr; + in [ + { + directory = "/var/lib/unpackerr"; + user = unpackerrUser.name; + group = unpackerrUser.group; + mode = "700"; + } + ]; + + systemd.services.radarr.upholds = optional (builtins.elem "radarr" enabledStarrServices) "unpackerr.service"; + systemd.services.sonarr.upholds = optional (builtins.elem "sonarr" enabledStarrServices) "unpackerr.service"; + systemd.services.lidarr.upholds = optional (builtins.elem "lidarr" enabledStarrServices) "unpackerr.service"; + }; +} diff --git a/secrets/crypt/unpackerr.toml b/secrets/crypt/unpackerr.toml new file mode 100644 index 0000000..3b936a9 Binary files /dev/null and b/secrets/crypt/unpackerr.toml differ