From f3f154d1b0d7fbc4c171c82b414ca026844b2482 Mon Sep 17 00:00:00 2001 From: Danilo Reyes Date: Tue, 11 Nov 2025 15:46:42 -0600 Subject: [PATCH] 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. --- flake.nix | 18 ++++--- nix/package.nix | 3 +- nixos/EXAMPLE_CONFIG.nix | 6 +-- nixos/lidarr-mb-gap.nix | 109 +++++++++++++++++++++------------------ 4 files changed, 75 insertions(+), 61 deletions(-) diff --git a/flake.nix b/flake.nix index d8e7908..80d7454 100644 --- a/flake.nix +++ b/flake.nix @@ -6,7 +6,8 @@ flake-utils.url = "github:numtide/flake-utils"; }; - outputs = { self, nixpkgs, flake-utils }: + outputs = + { nixpkgs, flake-utils }: let # NixOS module output (not system-specific) # The module accepts a package option, which can be set from the flake's packages @@ -17,7 +18,9 @@ { # Export NixOS modules nixosModules = nixosModules; - } // flake-utils.lib.eachDefaultSystem (system: + } + // flake-utils.lib.eachDefaultSystem ( + system: let pkgs = import nixpkgs { inherit system; }; lib = pkgs.lib; @@ -29,10 +32,12 @@ { devShells.default = pkgs.mkShell { buildInputs = [ - (pkgs.python3.withPackages (ps: with ps; [ - requests - python-dotenv - ])) + (pkgs.python3.withPackages ( + ps: with ps; [ + requests + python-dotenv + ] + )) pkgs.black ]; shellHook = '' @@ -55,4 +60,3 @@ } ); } - diff --git a/nix/package.nix b/nix/package.nix index 6c60104..2aef93d 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -1,4 +1,4 @@ -{ pkgs, lib, src }: +{ pkgs, src }: pkgs.python3Packages.buildPythonApplication { pname = "lidarr-mb-gap"; @@ -17,4 +17,3 @@ pkgs.python3Packages.buildPythonApplication { description = "Lidarr to MusicBrainz Missing Albums Finder"; }; } - diff --git a/nixos/EXAMPLE_CONFIG.nix b/nixos/EXAMPLE_CONFIG.nix index c1b1f0a..9d7a5d4 100644 --- a/nixos/EXAMPLE_CONFIG.nix +++ b/nixos/EXAMPLE_CONFIG.nix @@ -20,7 +20,7 @@ # # Then in your NixOS configuration: -{ config, pkgs, inputs, ... }: +{ pkgs, inputs, ... }: { imports = [ @@ -61,7 +61,7 @@ # # If you're not using flakes, import the module directly: -{ config, pkgs, ... }: +{ ... }: { imports = [ @@ -97,7 +97,7 @@ # EXAMPLE 3: Minimal Configuration (No VPS Sync) # ============================================================================ -{ config, pkgs, inputs, ... }: +{ pkgs, inputs, ... }: { imports = [ diff --git a/nixos/lidarr-mb-gap.nix b/nixos/lidarr-mb-gap.nix index 6afb97a..74f425a 100644 --- a/nixos/lidarr-mb-gap.nix +++ b/nixos/lidarr-mb-gap.nix @@ -1,92 +1,101 @@ -{ config, lib, pkgs, ... }: +{ + 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 { + 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."; + 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"; + 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"; + }; }; - 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)"; }; }; @@ -104,15 +113,15 @@ in createHome = true; }; - users.groups.lidarr-mb-gap = {}; - + 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"; @@ -121,30 +130,33 @@ in 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}/ - ''} + ${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 (use full path to ssh) + ${pkgs.rsync}/bin/rsync -avz --delete \ + -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"; StandardError = "journal"; @@ -161,4 +173,3 @@ in }; }; } -