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:
18
flake.nix
18
flake.nix
@@ -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 @@
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 = [
|
||||||
|
|||||||
@@ -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
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user