refactor(nixos): simplify navidrome options

This commit is contained in:
2026-09-12 20:30:48 -04:00
parent 8d8ca9682d
commit 5be062fbf5
2 changed files with 45 additions and 150 deletions

View File

@@ -4,9 +4,11 @@
... ...
}: }:
let let
cfg = config.guests.navidrome; dataDir = "/var/lib/navidrome";
musicDir = "/music";
envFile = "/run/secrets/navidrome.env"; envFile = "/run/secrets/navidrome.env";
hasLastfmSecrets = cfg.lastfmApiKeySecret != null && cfg.lastfmSecretSecret != null; lastfmApiKeySecret = "services/navidrome/lastfm/api-key";
lastfmSecretSecret = "services/navidrome/lastfm/secret";
hostSecrets = ../secrets + "/${config.networking.hostName}.yaml"; hostSecrets = ../secrets + "/${config.networking.hostName}.yaml";
in in
{ {
@@ -15,105 +17,50 @@ in
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = "/srv/navidrome"; example = "/srv/navidrome";
description = "Host path bind-mounted as Navidrome's state directory."; description = "Host path mounted as Navidrome's data folder.";
}; };
musicPath = lib.mkOption { musicPath = lib.mkOption {
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = "/srv/music"; example = "/srv/music";
description = "Host path bind-mounted as Navidrome's music directory."; description = "Host path mounted as Navidrome's music library.";
};
dataDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/navidrome";
description = "Guest path where Navidrome stores state.";
};
musicDir = lib.mkOption {
type = lib.types.str;
default = "/music";
description = "Guest path where Navidrome reads the music library.";
};
port = lib.mkOption {
type = lib.types.port;
default = 4533;
description = "Port Navidrome listens on.";
};
enableSharing = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enables Navidrome sharing support.";
};
settings = lib.mkOption {
type = lib.types.attrs;
default = { };
description = "Additional non-secret Navidrome settings.";
};
lastfmApiKeySecret = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "services/navidrome/lastfm/api-key";
description = "SOPS secret name containing the Navidrome Last.fm API key.";
};
lastfmSecretSecret = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "services/navidrome/lastfm/secret";
description = "SOPS secret name containing the Navidrome Last.fm secret.";
}; };
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf config.guests.navidrome.enable {
assertions = [ assertions = [
{ {
assertion = cfg.dataPath != null; assertion = config.guests.navidrome.dataPath != null;
message = "guests.navidrome.dataPath must point at the host directory that stores Navidrome state."; message = "guests.navidrome.dataPath must point at the host directory that stores Navidrome data.";
} }
{ {
assertion = cfg.musicPath != null; assertion = config.guests.navidrome.musicPath != null;
message = "guests.navidrome.musicPath must point at the host directory that stores the music library."; message = "guests.navidrome.musicPath must point at the host directory that stores the music library.";
} }
]; ];
guests.navidrome = { guests.navidrome = {
interior.modules.services.navidrome = { interior.modules.services.navidrome.enable = true;
enable = true;
inherit (cfg)
dataDir
musicDir
port
enableSharing
settings
;
environmentFile = if hasLastfmSecrets then envFile else null;
};
mounts = mounts = {
{ ${dataDir} = {
${cfg.dataDir} = { directory = config.guests.navidrome.dataPath;
directory = cfg.dataPath; owner = config.registry."stable-uid".${config.networking.hostName}.navidrome;
owner = config.registry."stable-uid".${config.networking.hostName}.navidrome; group = "storage";
group = "storage"; mode = "2770";
mode = "2770";
};
${cfg.musicDir} = {
directory = cfg.musicPath;
owner = "root";
group = "storage";
mode = "2770";
};
}
// lib.optionalAttrs hasLastfmSecrets {
${envFile} = {
file = config.sops.templates."navidrome.env".path;
readOnly = true;
};
}; };
${musicDir} = {
directory = config.guests.navidrome.musicPath;
owner = "root";
group = "storage";
mode = "2770";
};
${envFile} = {
file = config.sops.templates."navidrome.env".path;
readOnly = true;
};
};
limits = { limits = {
memory = lib.mkDefault "2G"; memory = lib.mkDefault "2G";
@@ -122,18 +69,18 @@ in
}; };
}; };
sops.secrets = lib.optionalAttrs hasLastfmSecrets { sops.secrets = {
${cfg.lastfmApiKeySecret}.sopsFile = hostSecrets; ${lastfmApiKeySecret}.sopsFile = hostSecrets;
${cfg.lastfmSecretSecret}.sopsFile = hostSecrets; ${lastfmSecretSecret}.sopsFile = hostSecrets;
}; };
sops.templates."navidrome.env" = lib.mkIf hasLastfmSecrets { sops.templates."navidrome.env" = {
owner = "root"; owner = "root";
group = "storage"; group = "storage";
mode = "0440"; mode = "0440";
content = '' content = ''
ND_LASTFM_APIKEY=${config.sops.placeholder.${cfg.lastfmApiKeySecret}} ND_LASTFM_APIKEY=${config.sops.placeholder.${lastfmApiKeySecret}}
ND_LASTFM_SECRET=${config.sops.placeholder.${cfg.lastfmSecretSecret}} ND_LASTFM_SECRET=${config.sops.placeholder.${lastfmSecretSecret}}
''; '';
}; };
}; };

View File

@@ -1,62 +1,11 @@
{ {
config, config,
lib, lib,
pkgs,
... ...
}: }:
{ {
options.modules.services.navidrome = { options.modules.services.navidrome = {
enable = lib.mkEnableOption "Navidrome"; enable = lib.mkEnableOption "Navidrome";
package = lib.mkPackageOption pkgs "navidrome" { };
port = lib.mkOption {
type = lib.types.port;
default = 4533;
description = "Port Navidrome listens on.";
};
dataDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/navidrome";
description = "Directory where Navidrome stores state.";
};
musicDir = lib.mkOption {
type = lib.types.str;
default = "/music";
description = "Directory where Navidrome reads the music library.";
};
user = lib.mkOption {
type = lib.types.str;
default = "navidrome";
description = "User account that runs Navidrome.";
};
group = lib.mkOption {
type = lib.types.str;
default = "storage";
description = "Group account that owns Navidrome state and media access.";
};
enableSharing = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enables Navidrome sharing support.";
};
settings = lib.mkOption {
type = lib.types.attrs;
default = { };
description = "Additional non-secret Navidrome settings.";
};
environmentFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "File containing secret Navidrome environment variables.";
};
}; };
config = lib.mkMerge [ config = lib.mkMerge [
@@ -65,26 +14,25 @@
} }
(lib.mkIf config.modules.services.navidrome.enable { (lib.mkIf config.modules.services.navidrome.enable {
users.users.${config.modules.services.navidrome.user} = { users.users.navidrome = {
isSystemUser = true; isSystemUser = true;
uid = config.registry."stable-uid".${config.networking.hostName}.navidrome; uid = config.registry."stable-uid".${config.networking.hostName}.navidrome;
group = config.modules.services.navidrome.group; group = "storage";
home = config.modules.services.navidrome.dataDir; home = "/var/lib/navidrome";
}; };
services.navidrome = { services.navidrome = {
enable = true; enable = true;
package = config.modules.services.navidrome.package; user = "navidrome";
user = config.modules.services.navidrome.user; group = "storage";
group = config.modules.services.navidrome.group; environmentFile = "/run/secrets/navidrome.env";
environmentFile = config.modules.services.navidrome.environmentFile;
openFirewall = true; openFirewall = true;
settings = config.modules.services.navidrome.settings // { settings = {
Address = "0.0.0.0"; Address = "0.0.0.0";
Port = config.modules.services.navidrome.port; Port = 4533;
DataFolder = config.modules.services.navidrome.dataDir; DataFolder = "/var/lib/navidrome";
MusicFolder = config.modules.services.navidrome.musicDir; MusicFolder = "/music";
EnableSharing = config.modules.services.navidrome.enableSharing; EnableSharing = true;
}; };
}; };
}) })