*arr: fix (?)
This commit is contained in:
@@ -285,5 +285,84 @@ lib.extend (
|
||||
# Returns a string suitable for $() command substitution in shell scripts.
|
||||
extractArrApiKey =
|
||||
configXmlPath: "${lib.getExe pkgs.gnugrep} -oP '(?<=<ApiKey>)[^<]+' ${configXmlPath}";
|
||||
|
||||
# Creates a NixOS-managed *arr settings sync service.
|
||||
# Spawns a oneshot systemd unit that PUTs the requested values into the *arr API
|
||||
# whenever the *arr service starts (or when the desired settings change). The
|
||||
# API key is read from the *arr's own config.xml at runtime.
|
||||
#
|
||||
# `settings` is keyed by API endpoint under /api/v3/config/, with one nested
|
||||
# attrset of field-name -> value pairs per endpoint. Idempotent: it skips the
|
||||
# PUT when the live config already matches.
|
||||
mkArrSettingsService =
|
||||
{
|
||||
name,
|
||||
port,
|
||||
dataDir,
|
||||
settings,
|
||||
}:
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
configXml = "${dataDir}/config.xml";
|
||||
endpoints = lib.attrNames settings;
|
||||
applyOne =
|
||||
endpoint:
|
||||
let
|
||||
jqFilter = lib.concatStringsSep " | " (
|
||||
lib.mapAttrsToList (k: v: ".${k} = ${builtins.toJSON v}") settings.${endpoint}
|
||||
);
|
||||
in
|
||||
''
|
||||
echo ":: ${name} config/${endpoint}"
|
||||
CFG=$(curl -fsS -H "X-Api-Key: $KEY" "$BASE/config/${endpoint}")
|
||||
NEW=$(jq '${jqFilter}' <<<"$CFG")
|
||||
if [ "$CFG" = "$NEW" ]; then
|
||||
echo " unchanged"
|
||||
else
|
||||
ID=$(jq -r .id <<<"$NEW")
|
||||
curl -fsS -X PUT \
|
||||
-H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
|
||||
--data "$NEW" "$BASE/config/${endpoint}/$ID" >/dev/null
|
||||
echo ${final.escapeShellArg " applied: ${jqFilter}"}
|
||||
fi
|
||||
'';
|
||||
applyScript = pkgs.writeShellApplication {
|
||||
name = "${name}-apply-settings";
|
||||
runtimeInputs = with pkgs; [
|
||||
curl
|
||||
jq
|
||||
gnugrep
|
||||
];
|
||||
text = ''
|
||||
set -euo pipefail
|
||||
KEY=$(grep -oP '(?<=<ApiKey>)[^<]+' ${configXml})
|
||||
BASE="http://localhost:${toString port}/api/v3"
|
||||
|
||||
# Wait up to 60s for the API to come online.
|
||||
for _ in $(seq 1 30); do
|
||||
if curl -fsS --max-time 2 -H "X-Api-Key: $KEY" "$BASE/system/status" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
${lib.concatStringsSep "\n" (map applyOne endpoints)}
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
systemd.services."${name}-apply-settings" = {
|
||||
description = "Apply NixOS-managed ${name} settings via API";
|
||||
after = [ "${name}.service" ];
|
||||
wantedBy = [ "${name}.service" ];
|
||||
restartTriggers = [ applyScript ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = config.services.${name}.user;
|
||||
Group = config.services.${name}.group;
|
||||
ExecStart = lib.getExe applyScript;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user