- Updated `flake.nix` to import the new Nix package definition from `nix/package.nix`, streamlining the build process for the lidarr-mb-gap application. - Enhanced the README.md to include new features such as NixOS module support for automated deployment, detailed deployment instructions, and configuration options for SSH and output directories. - Added sections for troubleshooting output file issues and clarified the structure of the project, including new files for deployment and web serving.
165 lines
5.3 KiB
Nix
165 lines
5.3 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
let
|
|
reportDir = "/var/lib/lidarr-mb-gap/reports";
|
|
envFile = "/var/lib/lidarr-mb-gap/.env";
|
|
|
|
# Determine which package to use
|
|
lidarrMbGapPackage = if config.services.lidarr-mb-gap.package != null
|
|
then config.services.lidarr-mb-gap.package
|
|
else if config.services.lidarr-mb-gap.src != null
|
|
then import ../nix/package.nix {
|
|
inherit pkgs;
|
|
lib = pkgs.lib;
|
|
src = config.services.lidarr-mb-gap.src;
|
|
}
|
|
else throw "services.lidarr-mb-gap: Either 'package' or 'src' must be set.";
|
|
in
|
|
{
|
|
options.services.lidarr-mb-gap = {
|
|
enable = lib.mkEnableOption "Lidarr MusicBrainz Gap Reporter";
|
|
|
|
package = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.package;
|
|
default = null;
|
|
description = "The lidarr-mb-gap package to use. If null, will be built from src.";
|
|
};
|
|
|
|
src = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.path;
|
|
default = null;
|
|
description = "Source path for building the package. Required if package is not explicitly set.";
|
|
};
|
|
|
|
reportDir = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = reportDir;
|
|
description = "Directory where reports will be generated";
|
|
};
|
|
|
|
envFile = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = envFile;
|
|
description = "Path to .env file with LIDARR_URL and LIDARR_API_KEY";
|
|
};
|
|
|
|
runInterval = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "daily";
|
|
description = "systemd timer interval (e.g., 'daily', 'hourly', '*-*-* 02:00:00')";
|
|
};
|
|
|
|
syncToVPS = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = "Whether to sync reports to VPS via rsync";
|
|
};
|
|
|
|
vpsHost = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.str;
|
|
default = null;
|
|
description = "VPS hostname or IP for rsync (e.g., 'vps' or 'user@vps.example.com')";
|
|
};
|
|
|
|
vpsPath = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "/var/www/html";
|
|
description = "Path on VPS where reports should be synced";
|
|
};
|
|
|
|
sshKeyFile = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.str;
|
|
default = null;
|
|
description = "Path to SSH private key file for rsync. If null, uses default SSH key location.";
|
|
};
|
|
|
|
sshKnownHosts = lib.mkOption {
|
|
type = lib.types.attrsOf (lib.types.submodule {
|
|
options = {
|
|
hostNames = lib.mkOption {
|
|
type = lib.types.listOf lib.types.str;
|
|
description = "List of hostnames/IPs for this known host";
|
|
};
|
|
publicKey = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "SSH public key for the host";
|
|
};
|
|
};
|
|
});
|
|
default = {};
|
|
description = "SSH known hosts configuration for the VPS (same format as programs.ssh.knownHosts)";
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf config.services.lidarr-mb-gap.enable {
|
|
systemd.tmpfiles.rules = [
|
|
"d ${config.services.lidarr-mb-gap.reportDir} 0755 lidarr-mb-gap lidarr-mb-gap -"
|
|
"d /var/lib/lidarr-mb-gap/.ssh 0700 lidarr-mb-gap lidarr-mb-gap -"
|
|
];
|
|
|
|
users.users.lidarr-mb-gap = {
|
|
isSystemUser = true;
|
|
group = "lidarr-mb-gap";
|
|
home = "/var/lib/lidarr-mb-gap";
|
|
createHome = true;
|
|
};
|
|
|
|
users.groups.lidarr-mb-gap = {};
|
|
|
|
programs.ssh.knownHosts = config.services.lidarr-mb-gap.sshKnownHosts;
|
|
|
|
systemd.services.lidarr-mb-gap = {
|
|
description = "Generate Lidarr MusicBrainz Gap Report";
|
|
after = [ "network.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
User = "lidarr-mb-gap";
|
|
Group = "lidarr-mb-gap";
|
|
WorkingDirectory = config.services.lidarr-mb-gap.reportDir;
|
|
EnvironmentFile = config.services.lidarr-mb-gap.envFile;
|
|
ExecStart = pkgs.writeShellScript "lidarr-mb-gap-run" ''
|
|
set -euo pipefail
|
|
|
|
# Export OUTPUT_DIR to environment
|
|
export OUTPUT_DIR=${config.services.lidarr-mb-gap.reportDir}
|
|
|
|
# Run the binary
|
|
${lib.getExe lidarrMbGapPackage} || {
|
|
echo "Failed to generate report"
|
|
exit 1
|
|
}
|
|
|
|
# Sync to VPS if enabled
|
|
${lib.optionalString (config.services.lidarr-mb-gap.syncToVPS && config.services.lidarr-mb-gap.vpsHost != null) ''
|
|
# Set up SSH options
|
|
SSH_OPTS=""
|
|
${lib.optionalString (config.services.lidarr-mb-gap.sshKeyFile != null) ''
|
|
SSH_OPTS="-i ${config.services.lidarr-mb-gap.sshKeyFile}"
|
|
''}
|
|
|
|
# Use SSH options with rsync
|
|
${pkgs.rsync}/bin/rsync -avz --delete \
|
|
-e "ssh $SSH_OPTS -o StrictHostKeyChecking=yes" \
|
|
${config.services.lidarr-mb-gap.reportDir}/ \
|
|
${config.services.lidarr-mb-gap.vpsHost}:${config.services.lidarr-mb-gap.vpsPath}/
|
|
''}
|
|
'';
|
|
StandardOutput = "journal";
|
|
StandardError = "journal";
|
|
};
|
|
};
|
|
|
|
systemd.timers.lidarr-mb-gap = {
|
|
description = "Timer for Lidarr MusicBrainz Gap Report";
|
|
wantedBy = [ "timers.target" ];
|
|
timerConfig = {
|
|
OnCalendar = config.services.lidarr-mb-gap.runInterval;
|
|
Persistent = true;
|
|
};
|
|
};
|
|
};
|
|
}
|
|
|