2026-05-14 13:36:10 +03:00
|
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
|
let
|
|
|
|
|
sites = [
|
|
|
|
|
{ name = "sublunar"; input = "sublunar"; }
|
|
|
|
|
{ name = "tobias-raayoni-last"; input = "flux_vision"; }
|
|
|
|
|
{ name = "nmns"; input = "nfc_web"; }
|
2026-05-17 12:22:54 +03:00
|
|
|
{ name = "zonetoast"; input = "zonetoast"; }
|
2026-05-14 13:36:10 +03:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
# Template hooks.json with a placeholder secret — real secret injected at
|
|
|
|
|
# service start time from the sops-managed file.
|
|
|
|
|
hooksTemplate = pkgs.writeText "webhook-hooks-template.json" (builtins.toJSON
|
|
|
|
|
(map (site: {
|
|
|
|
|
id = "rebuild-${site.name}";
|
|
|
|
|
execute-command = "/run/current-system/sw/bin/systemctl";
|
|
|
|
|
pass-arguments-to-command = [
|
|
|
|
|
{ source = "string"; name = "start"; }
|
|
|
|
|
{ source = "string"; name = "--no-block"; }
|
|
|
|
|
{ source = "string"; name = "update-${site.name}"; }
|
|
|
|
|
];
|
|
|
|
|
response-message = "Queued rebuild of ${site.name}";
|
|
|
|
|
trigger-rule.match = {
|
|
|
|
|
type = "payload-hmac-sha256";
|
|
|
|
|
secret = "placeholder";
|
|
|
|
|
parameter = { source = "header"; name = "X-Gitea-Signature"; };
|
|
|
|
|
};
|
|
|
|
|
}) sites)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
# Writes /run/webhook-deploy/hooks.json with the real secret at startup.
|
|
|
|
|
makeHooks = pkgs.writeShellScript "make-webhook-hooks" ''
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
${pkgs.jq}/bin/jq \
|
|
|
|
|
--arg s "$(cat ${config.sops.secrets.webhook_secret.path})" \
|
|
|
|
|
'map(.["trigger-rule"].match.secret = $s)' \
|
|
|
|
|
${hooksTemplate} > /run/webhook-deploy/hooks.json
|
|
|
|
|
'';
|
|
|
|
|
|
|
|
|
|
updateScript = site: pkgs.writeShellScript "do-update-${site.name}" ''
|
|
|
|
|
set -euo pipefail
|
2026-05-14 13:46:28 +03:00
|
|
|
export PATH=/run/current-system/sw/bin:$PATH
|
2026-05-14 13:36:10 +03:00
|
|
|
cd /etc/nixos
|
|
|
|
|
OLD=$(${pkgs.jq}/bin/jq -r '.nodes.${site.input}.locked.rev' flake.lock)
|
|
|
|
|
nix flake update ${site.input}
|
|
|
|
|
NEW=$(${pkgs.jq}/bin/jq -r '.nodes.${site.input}.locked.rev' flake.lock)
|
|
|
|
|
if [ "$OLD" = "$NEW" ]; then
|
|
|
|
|
echo "${site.name}: no change, skipping rebuild"
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
echo "${site.name}: updated $OLD -> $NEW, rebuilding"
|
|
|
|
|
nixos-rebuild switch --flake /etc/nixos#bucur
|
2026-05-14 13:55:21 +03:00
|
|
|
systemctl start deploy-${site.name}
|
2026-05-14 13:36:10 +03:00
|
|
|
'';
|
|
|
|
|
in
|
|
|
|
|
{
|
|
|
|
|
sops.secrets.webhook_secret = {
|
|
|
|
|
owner = "root";
|
|
|
|
|
mode = "0400";
|
|
|
|
|
};
|
|
|
|
|
|
2026-07-23 13:00:36 +02:00
|
|
|
# All flake inputs pulled here now live on code.randogoth.com; the SSH
|
|
|
|
|
# client config for that host (same deploy key) is set up in forgejo.nix.
|
2026-05-14 13:36:10 +03:00
|
|
|
|
|
|
|
|
systemd.services = lib.listToAttrs
|
|
|
|
|
(map (site: lib.nameValuePair "update-${site.name}" {
|
|
|
|
|
description = "Pull and rebuild ${site.name}";
|
|
|
|
|
serviceConfig = {
|
|
|
|
|
Type = "oneshot";
|
|
|
|
|
ExecStart = updateScript site;
|
|
|
|
|
};
|
|
|
|
|
}) sites)
|
|
|
|
|
// {
|
|
|
|
|
webhook-deploy = {
|
|
|
|
|
description = "Webhook server for Pelican site rebuilds";
|
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
|
after = [ "network.target" "sops-nix.service" ];
|
|
|
|
|
serviceConfig = {
|
|
|
|
|
Type = "simple";
|
|
|
|
|
RuntimeDirectory = "webhook-deploy";
|
|
|
|
|
ExecStartPre = "+${makeHooks}";
|
|
|
|
|
ExecStart = "${pkgs.webhook}/bin/webhook -hooks /run/webhook-deploy/hooks.json -port 9000";
|
|
|
|
|
Restart = "on-failure";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
}
|