Compare commits

..
Author SHA1 Message Date
h7x4 d25d0f8b56 bicep/mysql: split backups into one file per db 2026-07-21 18:18:43 +09:00
h7x4 4525de1d10 bicep/postgres: split backups into one file per db 2026-07-21 18:18:43 +09:00
29 changed files with 108 additions and 221 deletions
@@ -177,11 +177,6 @@ in
}; };
}; };
systemd.services."phpfpm-idp" = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
};
services.nginx.virtualHosts."idp.pvv.ntnu.no" = { services.nginx.virtualHosts."idp.pvv.ntnu.no" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
@@ -287,7 +287,6 @@ in {
systemd.services.mediawiki-init = lib.mkIf cfg.enable { systemd.services.mediawiki-init = lib.mkIf cfg.enable {
after = [ "sops-install-secrets.service" ]; after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
serviceConfig = { serviceConfig = {
UMask = lib.mkForce "0007"; UMask = lib.mkForce "0007";
}; };
@@ -295,7 +294,6 @@ in {
systemd.services.phpfpm-mediawiki = lib.mkIf cfg.enable { systemd.services.phpfpm-mediawiki = lib.mkIf cfg.enable {
after = [ "sops-install-secrets.service" ]; after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
serviceConfig = { serviceConfig = {
UMask = lib.mkForce "0007"; UMask = lib.mkForce "0007";
}; };
-5
View File
@@ -61,11 +61,6 @@ in {
}; };
}; };
systemd.services.vaultwarden = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
};
services.nginx.virtualHosts."${domain}" = { services.nginx.virtualHosts."${domain}" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
@@ -49,11 +49,6 @@ in
''; '';
}; };
systemd.services."phpfpm-roundcube" = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
};
# TODO: move this back to `webmail.pvv.ntnu.no/roundcube` subpath # TODO: move this back to `webmail.pvv.ntnu.no/roundcube` subpath
services.nginx.virtualHosts.${domain} = { services.nginx.virtualHosts.${domain} = {
@@ -116,11 +116,6 @@ in {
]; ];
}; };
systemd.services."phpfpm-pvv-nettsiden" = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
};
services.nginx.virtualHosts."pvv.ntnu.no" = { services.nginx.virtualHosts."pvv.ntnu.no" = {
globalRedirect = cfg.domainName; globalRedirect = cfg.domainName;
redirectCode = 307; redirectCode = 307;
-5
View File
@@ -35,9 +35,4 @@ in {
onCalendar = "*-*-* 09:00:00"; onCalendar = "*-*-* 09:00:00";
}; };
}; };
systemd.services.pvv-calendar-bot = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
};
} }
@@ -20,8 +20,6 @@ in
lfs = false; lfs = false;
}; };
# TODO: add a module setting to specify additional systemd dependencies
# and then mark "sops-install-secrets.service" as a dependency here
instances = let instances = let
defaultGithubConfig = { defaultGithubConfig = {
settings.token_file = config.sops.secrets."gickup/github-token".path; settings.token_file = config.sops.secrets."gickup/github-token".path;
-5
View File
@@ -55,11 +55,6 @@
# It needs this to be allowed to access the files with the acme group # It needs this to be allowed to access the files with the acme group
systemd.services.coturn.serviceConfig.PrivateUsers = lib.mkForce false; systemd.services.coturn.serviceConfig.PrivateUsers = lib.mkForce false;
systemd.services.coturn = {
requires = [ "sops-install-secrets.service" ];
after = [ "sops-install-secrets.service" ];
};
systemd.services."acme-${config.services.coturn.realm}".serviceConfig = { systemd.services."acme-${config.services.coturn.realm}".serviceConfig = {
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
}; };
-2
View File
@@ -39,8 +39,6 @@ in
}; };
systemd.services.mx-puppet-discord = { systemd.services.mx-puppet-discord = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
serviceConfig.SupplementaryGroups = [ serviceConfig.SupplementaryGroups = [
config.users.groups.keys-matrix-registrations.name config.users.groups.keys-matrix-registrations.name
]; ];
@@ -183,7 +183,6 @@ in
}; };
services.matrix-hookshot.serviceDependencies = [ services.matrix-hookshot.serviceDependencies = [
"sops-install-secrets.service"
"matrix-synapse.target" "matrix-synapse.target"
"nginx.service" "nginx.service"
]; ];
+1 -6
View File
@@ -43,12 +43,7 @@ in
keyFile = config.sops.templates."matrix-livekit-keyfile".path; keyFile = config.sops.templates."matrix-livekit-keyfile".path;
}; };
systemd.services.lk-jwt-service = lib.mkIf cfg.enable { systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = lib.mkIf cfg.enable (builtins.concatStringsSep "," [ "pvv.ntnu.no" "dodsorf.as" ]);
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = builtins.concatStringsSep "," [ "pvv.ntnu.no" "dodsorf.as" ];
};
services.nginx.virtualHosts.${matrixDomain} = lib.mkIf cfg.enable { services.nginx.virtualHosts.${matrixDomain} = lib.mkIf cfg.enable {
locations."^~ /livekit/jwt/" = { locations."^~ /livekit/jwt/" = {
+46 -51
View File
@@ -55,57 +55,52 @@
pantalaimon.username = "bot_admin"; pantalaimon.username = "bot_admin";
}; };
systemd.services.mjolnir = { systemd.services.mjolnir.serviceConfig = {
requires = [ "sops-install-secrets.service" ]; DynamicUser = true;
after = [ "sops-install-secrets.service" ]; RuntimeDirectory = [ "mjolnir/root-mnt" ];
RootDirectory = "/run/mjolnir/root-mnt";
BindReadOnlyPaths = [
config.sops.secrets."matrix/mjolnir/access_token".path
builtins.storeDir
"/etc"
"/run/nscd"
"/var/run/nscd"
];
serviceConfig = { AmbientCapabilities = "";
DynamicUser = true; CapabilityBoundingSet = "";
RuntimeDirectory = [ "mjolnir/root-mnt" ]; LockPersonality = true;
RootDirectory = "/run/mjolnir/root-mnt"; MemoryDenyWriteExecute = false; # node needs this
BindReadOnlyPaths = [ NoNewPrivileges = true;
config.sops.secrets."matrix/mjolnir/access_token".path PrivateDevices = true;
builtins.storeDir PrivateMounts = true;
"/etc" PrivateTmp = true;
"/run/nscd" PrivateUsers = true;
"/var/run/nscd" ProcSubset = "pid";
]; ProtectClock = true;
ProtectControlGroups = true;
AmbientCapabilities = ""; ProtectHome = true;
CapabilityBoundingSet = ""; ProtectHostname = true;
LockPersonality = true; ProtectKernelLogs = true;
MemoryDenyWriteExecute = false; # node needs this ProtectKernelModules = true;
NoNewPrivileges = true; ProtectKernelTunables = true;
PrivateDevices = true; ProtectProc = "invisible";
PrivateMounts = true; ProtectSystem = "strict";
PrivateTmp = true; RemoveIPC = true;
PrivateUsers = true; RestrictAddressFamilies = [
ProcSubset = "pid"; "AF_INET"
ProtectClock = true; "AF_INET6"
ProtectControlGroups = true; "AF_UNIX"
ProtectHome = true; ];
ProtectHostname = true; RestrictNamespaces = true;
ProtectKernelLogs = true; RestrictRealtime = true;
ProtectKernelModules = true; RestrictSUIDSGID = true;
ProtectKernelTunables = true; SystemCallArchitectures = "native";
ProtectProc = "invisible"; SystemCallFilter = [
ProtectSystem = "strict"; "@system-service"
RemoveIPC = true; "~@privileged"
RestrictAddressFamilies = [ "~@resources"
"AF_INET" ];
"AF_INET6" UMask = "0077";
"AF_UNIX"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
"~@resources"
];
UMask = "0077";
};
}; };
} }
@@ -56,15 +56,7 @@ in
enableSynapseIntegration = false; enableSynapseIntegration = false;
}; };
systemd.services."matrix-ooye-pre-start" = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
};
systemd.services."matrix-ooye" = { systemd.services."matrix-ooye" = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
serviceConfig = { serviceConfig = {
RuntimeDirectory = [ "matrix-ooye/root-mnt" ]; RuntimeDirectory = [ "matrix-ooye/root-mnt" ];
RootDirectory = "/run/matrix-ooye/root-mnt"; RootDirectory = "/run/matrix-ooye/root-mnt";
+1 -6
View File
@@ -44,11 +44,6 @@ in {
}; };
}; };
systemd.targets."matrix-synapse" = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
};
services.matrix-synapse-next = { services.matrix-synapse-next = {
enable = true; enable = true;
@@ -79,7 +74,7 @@ in {
name = "psycopg2"; name = "psycopg2";
args = { args = {
host = "/var/run/postgresql"; host = "/var/run/postgresql";
dbname = "synapse"; database = "synapse";
user = "matrix-synapse"; user = "matrix-synapse";
cp_min = 1; cp_min = 1;
cp_max = 5; cp_max = 5;
@@ -23,15 +23,6 @@ in
}; };
systemd.services.minecraft-heatmap-ingest-logs = lib.mkIf cfg.enable { systemd.services.minecraft-heatmap-ingest-logs = lib.mkIf cfg.enable {
after = [
"sops-install-secrets.service"
"network-online.target"
];
requires = [
"sops-install-secrets.service"
"network-online.target"
];
serviceConfig = { serviceConfig = {
LoadCredential = [ LoadCredential = [
"sshkey:${config.sops.secrets."minecraft-heatmap/ssh-key/private".path}" "sshkey:${config.sops.secrets."minecraft-heatmap/ssh-key/private".path}"
+25 -11
View File
@@ -41,24 +41,38 @@ in
path = with pkgs; [ path = with pkgs; [
cfg.package cfg.package
coreutils coreutils
diffutils
zstd zstd
]; ];
script = let script = ''
rotations = 2;
in ''
set -euo pipefail set -euo pipefail
OUT_FILE="$STATE_DIRECTORY/mysql-dump-$(date --iso-8601).sql.zst" dump() {
local name="$1" out tmp
out="$STATE_DIRECTORY/$name.sql.zst"
tmp="$out.tmp"
shift
"$@" | zstd -9 --rsyncable -f -o "$tmp"
if cmp -s "$tmp" "$out" 2>/dev/null; then
rm -f "$tmp"
else
mv -f "$tmp" "$out"
fi
}
mysqldump --all-databases | zstd --compress -9 --rsyncable -o "$OUT_FILE" declare -A keep
while IFS= read -r db; do
[ -n "$db" ] || continue
dump "$db" mysqldump --skip-dump-date --databases "$db"
keep["$db.sql.zst"]=1
done < <(mysql -N -e 'SHOW DATABASES' | grep -vE '^(information_schema|performance_schema)$')
# NOTE: this needs to be a hardlink for rrsync to allow sending it # drop dumps of databases that no longer exist
rm "$STATE_DIRECTORY/mysql-dump-latest.sql.zst" ||: for f in "$STATE_DIRECTORY"/*.sql.zst; do
ln -T "$OUT_FILE" "$STATE_DIRECTORY/mysql-dump-latest.sql.zst" [ -e "$f" ] || continue
base="$(basename "$f")"
while [ "$(find "$STATE_DIRECTORY" -type f -printf '.' | wc -c)" -gt '${toString (rotations + 1)}' ]; do [ -n "''${keep[$base]:-}" ] || rm -f "$f"
rm "$(find "$STATE_DIRECTORY" -type f -printf '%T+ %p\n' | sort | head -n 1 | cut -d' ' -f2)"
done done
''; '';
-4
View File
@@ -56,13 +56,9 @@ in
systemd.services.mysql = lib.mkIf cfg.enable { systemd.services.mysql = lib.mkIf cfg.enable {
after = [ after = [
"sops-install-secrets.service"
"systemd-tmpfiles-setup.service" "systemd-tmpfiles-setup.service"
"systemd-tmpfiles-resetup.service" "systemd-tmpfiles-resetup.service"
]; ];
requires = [
"sops-install-secrets.service"
];
serviceConfig = { serviceConfig = {
BindPaths = [ "${dataDir}:${cfg.dataDir}" ]; BindPaths = [ "${dataDir}:${cfg.dataDir}" ];
+27 -10
View File
@@ -41,25 +41,42 @@ in
path = with pkgs; [ path = with pkgs; [
coreutils coreutils
diffutils
zstd zstd
cfg.package cfg.package
]; ];
script = let script = ''
rotations = 2;
in ''
set -euo pipefail set -euo pipefail
OUT_FILE="$STATE_DIRECTORY/postgresql-dump-$(date --iso-8601).sql.zst" dump() {
local name="$1" out tmp
out="$STATE_DIRECTORY/$name.sql.zst"
tmp="$out.tmp"
shift
"$@" | zstd -9 --rsyncable -f -o "$tmp"
if cmp -s "$tmp" "$out" 2>/dev/null; then
rm -f "$tmp"
else
mv -f "$tmp" "$out"
fi
}
pg_dumpall -U postgres | zstd --compress -9 --rsyncable -o "$OUT_FILE" declare -A keep
dump globals pg_dumpall -U postgres --globals-only --restrict-key=backup
keep[globals.sql.zst]=1
# NOTE: this needs to be a hardlink for rrsync to allow sending it while IFS= read -r db; do
rm "$STATE_DIRECTORY/postgresql-dump-latest.sql.zst" ||: [ -n "$db" ] || continue
ln -T "$OUT_FILE" "$STATE_DIRECTORY/postgresql-dump-latest.sql.zst" dump "$db" pg_dump -U postgres -C -d "$db" --restrict-key=backup
keep["$db.sql.zst"]=1
done < <(psql -U postgres -tAc "SELECT datname FROM pg_database WHERE datallowconn ORDER BY datname")
while [ "$(find "$STATE_DIRECTORY" -type f -printf '.' | wc -c)" -gt '${toString (rotations + 1)}' ]; do # drop dumps of databases that no longer exist
rm "$(find "$STATE_DIRECTORY" -type f -printf '%T+ %p\n' | sort | head -n 1 | cut -d' ' -f2)" for f in "$STATE_DIRECTORY"/*.sql.zst; do
[ -e "$f" ] || continue
base="$(basename "$f")"
[ -n "''${keep[$base]:-}" ] || rm -f "$f"
done done
''; '';
-9
View File
@@ -82,15 +82,6 @@ in {
}; };
systemd.services."render-bluemap-maps" = { systemd.services."render-bluemap-maps" = {
after = [
"sops-install-secrets.service"
"network-online.target"
];
requires = [
"sops-install-secrets.service"
"network-online.target"
];
serviceConfig = { serviceConfig = {
StateDirectory = [ "bluemap/world" ]; StateDirectory = [ "bluemap/world" ];
ExecStartPre = let ExecStartPre = let
@@ -79,11 +79,6 @@ in {
}; };
}; };
systemd.services.grafana = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
};
services.nginx.virtualHosts.${cfg.settings.server.domain} = { services.nginx.virtualHosts.${cfg.settings.server.domain} = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
@@ -37,15 +37,9 @@ in {
}; };
}; };
systemd.services.prometheus-postgres-exporter-knakelibrak = { systemd.services.prometheus-postgres-exporter-knakelibrak.serviceConfig = let
after = [ "sops-install-secrets.service" ]; localCfg = config.services.prometheus.exporters.postgres;
requires = [ "sops-install-secrets.service" ]; in lib.recursiveUpdate config.systemd.services.prometheus-postgres-exporter.serviceConfig {
# TODO: is it really necessary to use recursiveUpdate on the entire attrset here?
# Why don't we just update the relevant attrs directly?
serviceConfig = let
localCfg = config.services.prometheus.exporters.postgres;
in lib.recursiveUpdate config.systemd.services.prometheus-postgres-exporter.serviceConfig {
EnvironmentFile = config.sops.secrets."keys/postgres/postgres_exporter_knakelibrak_env".path; EnvironmentFile = config.sops.secrets."keys/postgres/postgres_exporter_knakelibrak_env".path;
ExecStart = '' ExecStart = ''
${pkgs.prometheus-postgres-exporter}/bin/postgres_exporter \ ${pkgs.prometheus-postgres-exporter}/bin/postgres_exporter \
@@ -54,5 +48,4 @@ in {
${lib.concatStringsSep " \\\n " localCfg.extraFlags} ${lib.concatStringsSep " \\\n " localCfg.extraFlags}
''; '';
}; };
};
} }
+2 -11
View File
@@ -154,14 +154,8 @@ in {
environment.systemPackages = [ cfg.package ]; environment.systemPackages = [ cfg.package ];
systemd.services.gitea = lib.mkIf cfg.enable { systemd.services.gitea = lib.mkIf cfg.enable {
after = [ wants = [ "redis-gitea.service" ];
"sops-install-secrets.service" after = [ "redis-gitea.service" ];
"redis-gitea.service"
];
requires = [
"sops-install-secrets.service"
"redis-gitea.service"
];
serviceConfig = { serviceConfig = {
CPUSchedulingPolicy = "batch"; CPUSchedulingPolicy = "batch";
@@ -222,9 +216,6 @@ in {
}; };
systemd.services.gitea-dump = { systemd.services.gitea-dump = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
serviceConfig.ExecStart = let serviceConfig.ExecStart = let
args = lib.cli.toCommandLineShellGNU { } { args = lib.cli.toCommandLineShellGNU { } {
type = cfg.dump.type; type = cfg.dump.type;
-4
View File
@@ -32,11 +32,7 @@ in
systemd.services.gitea-ensure-gnupg-homedir = { systemd.services.gitea-ensure-gnupg-homedir = {
description = "Import gpg key for gitea"; description = "Import gpg key for gitea";
before = [ "gitea.service" ]; before = [ "gitea.service" ];
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
environment = { inherit GNUPGHOME; }; environment = { inherit GNUPGHOME; };
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
@@ -12,16 +12,6 @@ in
systemd.services.gitea-import-users = lib.mkIf cfg.enable { systemd.services.gitea-import-users = lib.mkIf cfg.enable {
enable = true; enable = true;
environment.PASSWD_FILE_PATH = "/run/gitea-import-users/passwd"; environment.PASSWD_FILE_PATH = "/run/gitea-import-users/passwd";
after = [
"sops-install-secrets.service"
"gitea.service"
"network-online.target"
];
requires = [
"sops-install-secrets.service"
"gitea.service"
"network-online.target"
];
serviceConfig = { serviceConfig = {
ExecStartPre = ''${pkgs.rsync}/bin/rsync -e "${pkgs.openssh}/bin/ssh -o UserKnownHostsFile=$CREDENTIALS_DIRECTORY/ssh-known-hosts -i $CREDENTIALS_DIRECTORY/sshkey" -a pvv@smtp.pvv.ntnu.no:/etc/passwd /run/gitea-import-users/passwd''; ExecStartPre = ''${pkgs.rsync}/bin/rsync -e "${pkgs.openssh}/bin/ssh -o UserKnownHostsFile=$CREDENTIALS_DIRECTORY/ssh-known-hosts -i $CREDENTIALS_DIRECTORY/sshkey" -a pvv@smtp.pvv.ntnu.no:/etc/passwd /run/gitea-import-users/passwd'';
ExecStart = pkgs.writers.writePython3 "gitea-import-users" { ExecStart = pkgs.writers.writePython3 "gitea-import-users" {
@@ -48,16 +48,7 @@ in
# %d - secrets directory # %d - secrets directory
systemd.services."gitea-web-secret-provider@" = { systemd.services."gitea-web-secret-provider@" = {
description = "Ensure all repos in %i has an SSH key to push web content"; description = "Ensure all repos in %i has an SSH key to push web content";
after = [ requires = [ "gitea.service" "network.target" ];
"sops-install-secrets.service"
"gitea.service"
"network-online.target"
];
requires = [
"sops-install-secrets.service"
"gitea.service"
"network-online.target"
];
serviceConfig = { serviceConfig = {
Slice = "system-giteaweb.slice"; Slice = "system-giteaweb.slice";
Type = "oneshot"; Type = "oneshot";
-5
View File
@@ -94,11 +94,6 @@ in
}; };
}; };
systemd.services."openvpn-ov-firewall" = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
};
networking.firewall = { networking.firewall = {
allowedTCPPorts = [ 1194 ]; allowedTCPPorts = [ 1194 ];
allowedUDPPorts = [ 1194 ]; allowedUDPPorts = [ 1194 ];
-5
View File
@@ -53,10 +53,5 @@
}; };
}; };
systemd.services.drumknotty-screen-session = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
};
services.roowho2.settings.rwhod.ignoreUsers = [ "drumknotty" ]; services.roowho2.settings.rwhod.ignoreUsers = [ "drumknotty" ];
} }
@@ -29,15 +29,9 @@ in
systemd.services."httpd-passwd-sync" = { systemd.services."httpd-passwd-sync" = {
requiredBy = [ "userweb.target" ]; requiredBy = [ "userweb.target" ];
after = [ after = [
"network-online.target"
"sops-install-secrets.service"
"systemd-tmpfiles-setup.service" "systemd-tmpfiles-setup.service"
"systemd-tmpfiles-resetup.service" "systemd-tmpfiles-resetup.service"
]; ];
requires = [
"network-online.target"
"sops-install-secrets.service"
];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
Slice = "system-userweb.slice"; Slice = "system-userweb.slice";
+2 -4
View File
@@ -159,6 +159,7 @@ in
description = "Out of Your Element - a Discord bridge for Matrix."; description = "Out of Your Element - a Discord bridge for Matrix.";
wants = [ wants = [
"network-online.target"
"matrix-synapse.service" "matrix-synapse.service"
"conduit.service" "conduit.service"
"dendrite.service" "dendrite.service"
@@ -167,10 +168,7 @@ in
"matrix-ooye-pre-start.service" "matrix-ooye-pre-start.service"
"network-online.target" "network-online.target"
]; ];
requires = [ requires = [ "matrix-ooye-pre-start.service" ];
"network-online.target"
"matrix-ooye-pre-start.service"
];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
startLimitIntervalSec = 5; startLimitIntervalSec = 5;