From c9a77e5b58d2bba865546693840221bdd6c839b8 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Fri, 21 Mar 2025 01:33:17 +0000 Subject: [PATCH] feat(ops/meta01): deploy irccat This deploys irccat, connected to the #snix channel. We drop the custom irccat third_party, it's 2 years older than the latest version in nixpkgs. The irccat.nix module file contains some of the code present in the TVL version, it however moves the secrets merging to ExecStartPre=, given https://github.com/systemd/systemd/issues/19604#issuecomment-989279884 has been fixed for almost a year. Contrary to the setup there, we don't let irccat connect to ZNC, but hackint directly (so make use of the secrets logic). We also drop the network-online.target, and make this overall more tolerant by using Restart=on-failure. Change-Id: Ieac3b744b7ea58b8dddf1cdc37a8bc057b205b1b Reviewed-on: https://cl.snix.dev/c/snix/+/30504 Autosubmit: Florian Klink Reviewed-by: Ryan Lahfa Tested-by: besadii --- ops/machines/meta01/default.nix | 19 +++++++++++ ops/modules/irccat.nix | 60 +++++++++++++++++++++++++++++++++ ops/secrets/irccat-secrets.age | 11 ++++++ ops/secrets/secrets.nix | 2 +- third_party/irccat/default.nix | 16 --------- 5 files changed, 91 insertions(+), 17 deletions(-) create mode 100644 ops/modules/irccat.nix create mode 100644 ops/secrets/irccat-secrets.age delete mode 100644 third_party/irccat/default.nix diff --git a/ops/machines/meta01/default.nix b/ops/machines/meta01/default.nix index d1450808f..602496deb 100644 --- a/ops/machines/meta01/default.nix +++ b/ops/machines/meta01/default.nix @@ -16,6 +16,7 @@ in (mod "o11y/alertmanager-irc-relay.nix") (mod "known-hosts.nix") (mod "clbot.nix") + (mod "irccat.nix") (mod "www/mimir.snix.dev.nix") (mod "www/loki.snix.dev.nix") @@ -79,6 +80,23 @@ in }; }; + services.irccat = { + enable = true; + config = { + generic.listen = "127.0.0.1:4722"; + irc = { + server = "irc.eu.hackint.org:6697"; + tls = true; + sasl_pass = "filled_in_by_secret"; + nick = "snixbot"; + channels = [ + "#snix" + ]; + }; + }; + secretsFile = config.age.secrets.irccat-secrets.path; + }; + networking.nftables.enable = true; networking.firewall.extraInputRules = '' # Prometheus, Loki, Tempo @@ -99,6 +117,7 @@ in metrics-push-htpasswd.owner = "nginx"; mimir-webhook-url.file = secretFile "mimir-webhook-url"; alertmanager-irc-relay-environment.file = secretFile "alertmanager-irc-relay-environment"; + irccat-secrets.file = secretFile "irccat-secrets"; restic-repository-password.file = secretFile "restic-repository-password"; restic-bucket-credentials.file = secretFile "restic-bucket-credentials"; }; diff --git a/ops/modules/irccat.nix b/ops/modules/irccat.nix new file mode 100644 index 000000000..af47733ea --- /dev/null +++ b/ops/modules/irccat.nix @@ -0,0 +1,60 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.irccat; + description = "irccat - forward messages to IRC"; + + # irccat expects to read its configuration from the *current + # directory*, and its configuration contains secrets. + # + # To make this work we construct the JSON configuration file and + # then recursively merge it with an on-disk secret using jq on + # service launch. + configJson = pkgs.writeText "irccat.json" (builtins.toJSON cfg.config); +in +{ + options.services.irccat = { + enable = lib.mkEnableOption description; + + config = lib.mkOption { + type = lib.types.attrsOf lib.types.anything; # varying value types + description = "Configuration structure (unchecked!)"; + }; + + secretsFile = lib.mkOption { + type = lib.types.str; + description = "Path to the secrets file to be merged"; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.irccat = { + inherit description; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + wants = [ "network.target" ]; + + serviceConfig = { + ExecStartPre = (pkgs.writeShellScript "merge-irccat-config" '' + if [ ! -f "$CREDENTIALS_DIRECTORY/secrets" ]; then + echo "irccat secrets file is missing" + exit 1 + fi + + # jq's * is the recursive merge operator + ${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${configJson} "$CREDENTIALS_DIRECTORY/secrets" \ + > /var/lib/irccat/irccat.json + ''); + + ExecStart = "${pkgs.irccat}/bin/irccat"; + DynamicUser = true; + StateDirectory = "irccat"; + WorkingDirectory = "/var/lib/irccat"; + LoadCredential = "secrets:${cfg.secretsFile}"; + Restart = "on-failure"; + RestartSec = "5s"; + }; + }; + }; +} + diff --git a/ops/secrets/irccat-secrets.age b/ops/secrets/irccat-secrets.age new file mode 100644 index 000000000..44fb8bd5f --- /dev/null +++ b/ops/secrets/irccat-secrets.age @@ -0,0 +1,11 @@ +age-encryption.org/v1 +-> ssh-ed25519 +qVung 3O7R2kPSWKYtSj2UtPdLihY0DTkoy0Cdjmk/mp2YTgA +Z3ySYVXGzKy7EbIl1KKjPvcWE+Gr+YrDxQjSWhtjnOQ +-> X25519 Z0zakQU8dXGTFghkdRFOBJ/lHZenShAxNyM+Vf8ccjs +kggGzVfLrdfS21RTQPMQESf7h0UNGpHwLj0MhLf11qw +-> ssh-ed25519 C2zWnA Byg3pvqGgZWgmbpnhsziFDzndMM6p0pd/Emsw+1NoTI +PCPzVeD8iImOAJ/bP6x/LYKQA9iWT42efWWAZsGl7xg +-> ssh-ed25519 LzO4tw yIkoQYky8Er+lodlBUUE0BYd4VfMdGKIHlVIaXTQPio +XlS7JQp+yZP0qgZV0e1YIjF4KcQ/LZE5Za6CAB/gZOo +--- mDqJdL1X9lyrrsjW0nYRbW13UN+xPDzW8j1rMp7PDBg +`5sr?Ғs>İ$e weX5j_LR]RkӘWў*?{B#O^eQfĨbi"~y \ No newline at end of file diff --git a/ops/secrets/secrets.nix b/ops/secrets/secrets.nix index 360f0a9a9..7dd3e3489 100644 --- a/ops/secrets/secrets.nix +++ b/ops/secrets/secrets.nix @@ -47,7 +47,6 @@ in "grafana-oauth-secret.age" = public01Default; - "binary-cache-key.age" = build01Default; "buildkite-agent-token.age" = build01Default; "buildkite-ssh-private-key.age" = build01Default; @@ -56,6 +55,7 @@ in "metrics-push-htpasswd.age" = meta01Default; "alertmanager-irc-relay-environment.age" = meta01Default; + "irccat-secrets.age" = meta01Default; "mimir-environment.age" = meta01Default; "mimir-webhook-url.age" = meta01Default; diff --git a/third_party/irccat/default.nix b/third_party/irccat/default.nix deleted file mode 100644 index c5d7a5f6d..000000000 --- a/third_party/irccat/default.nix +++ /dev/null @@ -1,16 +0,0 @@ -# https://github.com/irccloud/irccat -{ lib, pkgs, ... }: - -pkgs.buildGoModule rec { - pname = "irccat"; - version = "20201108"; - meta.license = lib.licenses.gpl3; - vendorHash = "sha256:06a985y4alw1rsghgmhfyczns6klz7bbkfn5mnqc9fdfclgg4s3r"; - - src = pkgs.fetchFromGitHub { - owner = "irccloud"; - repo = "irccat"; - rev = "17451e7e267f099e9614ec945541b624520f607e"; - sha256 = "0l99mycxymyslwi8mmyfdcqa8pdp79wcyb04s5j5y4grmlsxw1wx"; - }; -}