Refactor NixOS module and flake configuration for lidarr-mb-gap

- Updated `flake.nix` to streamline output definitions and improve readability.
- Refactored NixOS module configurations in `nixos/lidarr-mb-gap.nix` for better structure and clarity.
- Simplified the package import process in `nix/package.nix` by removing unnecessary parameters.
- Enhanced example configurations in `nixos/EXAMPLE_CONFIG.nix` to align with the new structure.
This commit is contained in:
Danilo Reyes
2025-11-11 15:46:42 -06:00
parent 35e6c7e330
commit f3f154d1b0
4 changed files with 75 additions and 61 deletions

View File

@@ -6,7 +6,8 @@
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = { self, nixpkgs, flake-utils }: outputs =
{ nixpkgs, flake-utils }:
let let
# NixOS module output (not system-specific) # NixOS module output (not system-specific)
# The module accepts a package option, which can be set from the flake's packages # The module accepts a package option, which can be set from the flake's packages
@@ -17,7 +18,9 @@
{ {
# Export NixOS modules # Export NixOS modules
nixosModules = nixosModules; nixosModules = nixosModules;
} // flake-utils.lib.eachDefaultSystem (system: }
// flake-utils.lib.eachDefaultSystem (
system:
let let
pkgs = import nixpkgs { inherit system; }; pkgs = import nixpkgs { inherit system; };
lib = pkgs.lib; lib = pkgs.lib;
@@ -29,10 +32,12 @@
{ {
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
buildInputs = [ buildInputs = [
(pkgs.python3.withPackages (ps: with ps; [ (pkgs.python3.withPackages (
requests ps: with ps; [
python-dotenv requests
])) python-dotenv
]
))
pkgs.black pkgs.black
]; ];
shellHook = '' shellHook = ''
@@ -55,4 +60,3 @@
} }
); );
} }

View File

@@ -1,4 +1,4 @@
{ pkgs, lib, src }: { pkgs, src }:
pkgs.python3Packages.buildPythonApplication { pkgs.python3Packages.buildPythonApplication {
pname = "lidarr-mb-gap"; pname = "lidarr-mb-gap";
@@ -17,4 +17,3 @@ pkgs.python3Packages.buildPythonApplication {
description = "Lidarr to MusicBrainz Missing Albums Finder"; description = "Lidarr to MusicBrainz Missing Albums Finder";
}; };
} }

View File

@@ -20,7 +20,7 @@
# #
# Then in your NixOS configuration: # Then in your NixOS configuration:
{ config, pkgs, inputs, ... }: { pkgs, inputs, ... }:
{ {
imports = [ imports = [
@@ -61,7 +61,7 @@
# #
# If you're not using flakes, import the module directly: # If you're not using flakes, import the module directly:
{ config, pkgs, ... }: { ... }:
{ {
imports = [ imports = [
@@ -97,7 +97,7 @@
# EXAMPLE 3: Minimal Configuration (No VPS Sync) # EXAMPLE 3: Minimal Configuration (No VPS Sync)
# ============================================================================ # ============================================================================
{ config, pkgs, inputs, ... }: { pkgs, inputs, ... }:
{ {
imports = [ imports = [

View File

@@ -1,92 +1,101 @@
{ config, lib, pkgs, ... }: {
config,
lib,
pkgs,
...
}:
let let
reportDir = "/var/lib/lidarr-mb-gap/reports"; reportDir = "/var/lib/lidarr-mb-gap/reports";
envFile = "/var/lib/lidarr-mb-gap/.env"; envFile = "/var/lib/lidarr-mb-gap/.env";
# Determine which package to use # Determine which package to use
lidarrMbGapPackage = if config.services.lidarr-mb-gap.package != null lidarrMbGapPackage =
then config.services.lidarr-mb-gap.package if config.services.lidarr-mb-gap.package != null then
else if config.services.lidarr-mb-gap.src != null config.services.lidarr-mb-gap.package
then import ../nix/package.nix { else if config.services.lidarr-mb-gap.src != null then
import ../nix/package.nix {
inherit pkgs; inherit pkgs;
lib = pkgs.lib; lib = pkgs.lib;
src = config.services.lidarr-mb-gap.src; src = config.services.lidarr-mb-gap.src;
} }
else throw "services.lidarr-mb-gap: Either 'package' or 'src' must be set."; else
throw "services.lidarr-mb-gap: Either 'package' or 'src' must be set.";
in in
{ {
options.services.lidarr-mb-gap = { options.services.lidarr-mb-gap = {
enable = lib.mkEnableOption "Lidarr MusicBrainz Gap Reporter"; enable = lib.mkEnableOption "Lidarr MusicBrainz Gap Reporter";
package = lib.mkOption { package = lib.mkOption {
type = lib.types.nullOr lib.types.package; type = lib.types.nullOr lib.types.package;
default = null; default = null;
description = "The lidarr-mb-gap package to use. If null, will be built from src."; description = "The lidarr-mb-gap package to use. If null, will be built from src.";
}; };
src = lib.mkOption { src = lib.mkOption {
type = lib.types.nullOr lib.types.path; type = lib.types.nullOr lib.types.path;
default = null; default = null;
description = "Source path for building the package. Required if package is not explicitly set."; description = "Source path for building the package. Required if package is not explicitly set.";
}; };
reportDir = lib.mkOption { reportDir = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = reportDir; default = reportDir;
description = "Directory where reports will be generated"; description = "Directory where reports will be generated";
}; };
envFile = lib.mkOption { envFile = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = envFile; default = envFile;
description = "Path to .env file with LIDARR_URL and LIDARR_API_KEY"; description = "Path to .env file with LIDARR_URL and LIDARR_API_KEY";
}; };
runInterval = lib.mkOption { runInterval = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "daily"; default = "daily";
description = "systemd timer interval (e.g., 'daily', 'hourly', '*-*-* 02:00:00')"; description = "systemd timer interval (e.g., 'daily', 'hourly', '*-*-* 02:00:00')";
}; };
syncToVPS = lib.mkOption { syncToVPS = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = false; default = false;
description = "Whether to sync reports to VPS via rsync"; description = "Whether to sync reports to VPS via rsync";
}; };
vpsHost = lib.mkOption { vpsHost = lib.mkOption {
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
description = "VPS hostname or IP for rsync (e.g., 'vps' or 'user@vps.example.com')"; description = "VPS hostname or IP for rsync (e.g., 'vps' or 'user@vps.example.com')";
}; };
vpsPath = lib.mkOption { vpsPath = lib.mkOption {
type = lib.types.str; type = lib.types.str;
default = "/var/www/html"; default = "/var/www/html";
description = "Path on VPS where reports should be synced"; description = "Path on VPS where reports should be synced";
}; };
sshKeyFile = lib.mkOption { sshKeyFile = lib.mkOption {
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
description = "Path to SSH private key file for rsync. If null, uses default SSH key location."; description = "Path to SSH private key file for rsync. If null, uses default SSH key location.";
}; };
sshKnownHosts = lib.mkOption { sshKnownHosts = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule { type = lib.types.attrsOf (
options = { lib.types.submodule {
hostNames = lib.mkOption { options = {
type = lib.types.listOf lib.types.str; hostNames = lib.mkOption {
description = "List of hostnames/IPs for this known host"; 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";
};
}; };
publicKey = lib.mkOption { }
type = lib.types.str; );
description = "SSH public key for the host"; default = { };
};
};
});
default = {};
description = "SSH known hosts configuration for the VPS (same format as programs.ssh.knownHosts)"; description = "SSH known hosts configuration for the VPS (same format as programs.ssh.knownHosts)";
}; };
}; };
@@ -104,15 +113,15 @@ in
createHome = true; createHome = true;
}; };
users.groups.lidarr-mb-gap = {}; users.groups.lidarr-mb-gap = { };
programs.ssh.knownHosts = config.services.lidarr-mb-gap.sshKnownHosts; programs.ssh.knownHosts = config.services.lidarr-mb-gap.sshKnownHosts;
systemd.services.lidarr-mb-gap = { systemd.services.lidarr-mb-gap = {
description = "Generate Lidarr MusicBrainz Gap Report"; description = "Generate Lidarr MusicBrainz Gap Report";
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
User = "lidarr-mb-gap"; User = "lidarr-mb-gap";
@@ -121,30 +130,33 @@ in
EnvironmentFile = config.services.lidarr-mb-gap.envFile; EnvironmentFile = config.services.lidarr-mb-gap.envFile;
ExecStart = pkgs.writeShellScript "lidarr-mb-gap-run" '' ExecStart = pkgs.writeShellScript "lidarr-mb-gap-run" ''
set -euo pipefail set -euo pipefail
# Export OUTPUT_DIR to environment # Export OUTPUT_DIR to environment
export OUTPUT_DIR=${config.services.lidarr-mb-gap.reportDir} export OUTPUT_DIR=${config.services.lidarr-mb-gap.reportDir}
# Run the binary # Run the binary
${lib.getExe lidarrMbGapPackage} || { ${lib.getExe lidarrMbGapPackage} || {
echo "Failed to generate report" echo "Failed to generate report"
exit 1 exit 1
} }
# Sync to VPS if enabled # Sync to VPS if enabled
${lib.optionalString (config.services.lidarr-mb-gap.syncToVPS && config.services.lidarr-mb-gap.vpsHost != null) '' ${lib.optionalString
# Set up SSH options (config.services.lidarr-mb-gap.syncToVPS && config.services.lidarr-mb-gap.vpsHost != null)
SSH_OPTS="" ''
${lib.optionalString (config.services.lidarr-mb-gap.sshKeyFile != null) '' # Set up SSH options
SSH_OPTS="-i ${config.services.lidarr-mb-gap.sshKeyFile}" 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" \ # Use SSH options with rsync (use full path to ssh)
${config.services.lidarr-mb-gap.reportDir}/ \ ${pkgs.rsync}/bin/rsync -avz --delete \
${config.services.lidarr-mb-gap.vpsHost}:${config.services.lidarr-mb-gap.vpsPath}/ -e "${pkgs.openssh}/bin/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"; StandardOutput = "journal";
StandardError = "journal"; StandardError = "journal";
@@ -161,4 +173,3 @@ in
}; };
}; };
} }