cluster/services/chant: init
This commit is contained in:
parent
5f3661d06a
commit
607fb9a28c
2 changed files with 94 additions and 0 deletions
10
cluster/services/chant/default.nix
Normal file
10
cluster/services/chant/default.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
services.chant = {
|
||||||
|
nodes.listener = config.services.consul.nodes.agent;
|
||||||
|
nixos.listener = [
|
||||||
|
./listener.nix
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
84
cluster/services/chant/listener.nix
Normal file
84
cluster/services/chant/listener.nix
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
consulCfg = config.services.consul.extraConfig;
|
||||||
|
consulIpAddr = consulCfg.addresses.http or "127.0.0.1";
|
||||||
|
consulHttpAddr = "${consulIpAddr}:${toString (consulCfg.ports.http or 8500)}";
|
||||||
|
|
||||||
|
validTargets = lib.pipe config.systemd.services [
|
||||||
|
(lib.filterAttrs (name: value: value.chant.enable))
|
||||||
|
lib.attrNames
|
||||||
|
];
|
||||||
|
|
||||||
|
validTargetsJson = pkgs.writeText "chant-targets.json" (builtins.toJSON validTargets);
|
||||||
|
|
||||||
|
eventHandler = pkgs.writers.writePython3 "chant-listener-event-handler" {
|
||||||
|
flakeIgnore = [ "E501" ];
|
||||||
|
} ''
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import base64
|
||||||
|
|
||||||
|
validTargets = set()
|
||||||
|
with open("${validTargetsJson}", "r") as f:
|
||||||
|
validTargets = set(json.load(f))
|
||||||
|
|
||||||
|
events = json.load(sys.stdin)
|
||||||
|
|
||||||
|
cacheDir = os.getenv("CACHE_DIRECTORY", "/var/cache/chant")
|
||||||
|
|
||||||
|
indexFile = f"{cacheDir}/index"
|
||||||
|
|
||||||
|
oldIndex = "old-index"
|
||||||
|
if os.path.isfile(indexFile):
|
||||||
|
with open(indexFile, "r") as f:
|
||||||
|
oldIndex = f.readline()
|
||||||
|
|
||||||
|
newIndex = os.getenv("CONSUL_INDEX", "no-index")
|
||||||
|
|
||||||
|
if oldIndex != newIndex:
|
||||||
|
triggers = set()
|
||||||
|
for event in events:
|
||||||
|
if event["Name"].startswith("chant:"):
|
||||||
|
target = event["Name"].removeprefix("chant:")
|
||||||
|
if target not in validTargets:
|
||||||
|
print(f"Skipping invalid target: {target}")
|
||||||
|
continue
|
||||||
|
with open(f"/run/chant/{target}", "wb") as f:
|
||||||
|
if event["Payload"] is not None:
|
||||||
|
f.write(base64.b64decode(event["Payload"]))
|
||||||
|
triggers.add(target)
|
||||||
|
|
||||||
|
for trigger in triggers:
|
||||||
|
subprocess.run(["${config.systemd.package}/bin/systemctl", "start", "--no-block", f"{trigger}.service"])
|
||||||
|
|
||||||
|
with open(indexFile, "w") as f:
|
||||||
|
f.write(newIndex)
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.services.chant-listener = {
|
||||||
|
description = "Chant Listener";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
wants = [ "consul.service" ];
|
||||||
|
after = [ "consul.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${config.services.consul.package}/bin/consul watch --type=event ${eventHandler}";
|
||||||
|
|
||||||
|
RuntimeDirectory = "chant";
|
||||||
|
RuntimeDirectoryMode = "0700";
|
||||||
|
CacheDirectory = "chant";
|
||||||
|
CacheDirectoryMode = "0700";
|
||||||
|
|
||||||
|
RestartSec = 60;
|
||||||
|
Restart = "always";
|
||||||
|
IPAddressDeny = [ "any" ];
|
||||||
|
IPAddressAllow = [ consulIpAddr ];
|
||||||
|
};
|
||||||
|
environment = {
|
||||||
|
CONSUL_HTTP_ADDR = consulHttpAddr;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue