Compare commits

..
Author SHA1 Message Date
h7x4 384534bf86 treewide: add missing systemd ordering directives
In particular, we were missing `sops-install-secrets.service` in a ton
of places, and `network-online.target` for some homebrewn services.

This has caused failure of some services on machine startup.
2026-07-22 17:56:06 +09:00
28 changed files with 215 additions and 116 deletions
@@ -177,6 +177,11 @@ 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,6 +287,7 @@ 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";
}; };
@@ -294,6 +295,7 @@ 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,6 +61,11 @@ 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,6 +49,11 @@ 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,6 +116,11 @@ 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;
+12 -57
View File
@@ -1,70 +1,25 @@
{ lib, ... }: { lib, ... }:
{ {
# TODO: move this to base so that all virtualHosts take effect on their respecitve hosts services.nginx.virtualHosts = lib.genAttrs [
# NOTE: automatically hosting well-known files by looping over all existing `virtualHosts`
# unfortunately causes infinite recursuion due to submodule usage within the nginx
# module. For now, the easiest solution was to manually specify a list of virtualHosts
# here, but it would be nice to find a better solution in the future.
services.nginx.virtualHosts = lib.mkMerge [
(lib.genAttrs [
"pvv.ntnu.no" "pvv.ntnu.no"
"pvv.org"
"www.pvv.ntnu.no" "www.pvv.ntnu.no"
"www.pvv.org"
"www2.pvv.ntnu.no"
"www2.pvv.org"
# NOTE: this list is probably not complete
"alps.pvv.ntnu.no"
"chat.pvv.ntnu.no"
"grafana.pvv.ntnu.no"
"status.pvv.ntnu.no"
"matrix.pvv.ntnu.no"
"mirrors.pvv.ntnu.no"
"pages.pvv.ntnu.no"
"ooye.pvv.ntnu.no"
"ooye.pvv.ntnu.no"
"dav.pvv.ntnu.no"
"git.pvv.ntnu.no"
"idp.pvv.ntnu.no"
"minecraft.pvv.ntnu.no"
"pw.pvv.ntnu.no"
"snappymail.pvv.ntnu.no"
"webmail.pvv.ntnu.no"
"wiki.pvv.ntnu.no"
] (_: {
locations."^~ /.well-known/security.txt" = {
alias = toString ./root/security.txt;
};
}))
(lib.genAttrs [
"pvv.ntnu.no"
"pvv.org" "pvv.org"
"mail.pvv.ntnu.no"
"mail.pvv.org"
"smtp.pvv.ntnu.no"
"smtp.pvv.org"
] (_: {
locations."^~ /.well-known/autoconfig/mail/" = {
root = toString ./root/autoconfig/mail;
};
}))
(lib.genAttrs [
"pvv.ntnu.no"
"pvv.org"
"www.pvv.ntnu.no"
"www.pvv.org" "www.pvv.org"
] (_: { ] (_: {
locations."^~ /.well-known/matrix/" = { locations = {
"^~ /.well-known/" = {
alias = (toString ./root) + "/";
};
# Proxy the matrix well-known files
# Host has be set before proxy_pass
# The header must be set so nginx on the other side routes it to the right place
"^~ /.well-known/matrix/" = {
extraConfig = '' extraConfig = ''
proxy_set_header Host matrix.pvv.ntnu.no; proxy_set_header Host matrix.pvv.ntnu.no;
proxy_pass https://matrix.pvv.ntnu.no/.well-known/matrix/; proxy_pass https://matrix.pvv.ntnu.no/.well-known/matrix/;
''; '';
}; };
})) };
]; });
} }
+5
View File
@@ -35,4 +35,9 @@ 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,6 +20,8 @@ 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,6 +55,11 @@
# 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,6 +39,8 @@ 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,6 +183,7 @@ in
}; };
services.matrix-hookshot.serviceDependencies = [ services.matrix-hookshot.serviceDependencies = [
"sops-install-secrets.service"
"matrix-synapse.target" "matrix-synapse.target"
"nginx.service" "nginx.service"
]; ];
+6 -1
View File
@@ -43,7 +43,12 @@ in
keyFile = config.sops.templates."matrix-livekit-keyfile".path; keyFile = config.sops.templates."matrix-livekit-keyfile".path;
}; };
systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = lib.mkIf cfg.enable (builtins.concatStringsSep "," [ "pvv.ntnu.no" "dodsorf.as" ]); systemd.services.lk-jwt-service = lib.mkIf cfg.enable {
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/" = {
+6 -1
View File
@@ -55,7 +55,11 @@
pantalaimon.username = "bot_admin"; pantalaimon.username = "bot_admin";
}; };
systemd.services.mjolnir.serviceConfig = { systemd.services.mjolnir = {
requires = [ "sops-install-secrets.service" ];
after = [ "sops-install-secrets.service" ];
serviceConfig = {
DynamicUser = true; DynamicUser = true;
RuntimeDirectory = [ "mjolnir/root-mnt" ]; RuntimeDirectory = [ "mjolnir/root-mnt" ];
RootDirectory = "/run/mjolnir/root-mnt"; RootDirectory = "/run/mjolnir/root-mnt";
@@ -103,4 +107,5 @@
]; ];
UMask = "0077"; UMask = "0077";
}; };
};
} }
@@ -56,7 +56,15 @@ 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";
+6 -1
View File
@@ -44,6 +44,11 @@ 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;
@@ -74,7 +79,7 @@ in {
name = "psycopg2"; name = "psycopg2";
args = { args = {
host = "/var/run/postgresql"; host = "/var/run/postgresql";
database = "synapse"; dbname = "synapse";
user = "matrix-synapse"; user = "matrix-synapse";
cp_min = 1; cp_min = 1;
cp_max = 5; cp_max = 5;
@@ -23,6 +23,15 @@ 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}"
+4
View File
@@ -56,9 +56,13 @@ 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}" ];
+9
View File
@@ -82,6 +82,15 @@ 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,6 +79,11 @@ 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,7 +37,13 @@ in {
}; };
}; };
systemd.services.prometheus-postgres-exporter-knakelibrak.serviceConfig = let systemd.services.prometheus-postgres-exporter-knakelibrak = {
after = [ "sops-install-secrets.service" ];
requires = [ "sops-install-secrets.service" ];
# 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; localCfg = config.services.prometheus.exporters.postgres;
in lib.recursiveUpdate config.systemd.services.prometheus-postgres-exporter.serviceConfig { 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;
@@ -48,4 +54,5 @@ in {
${lib.concatStringsSep " \\\n " localCfg.extraFlags} ${lib.concatStringsSep " \\\n " localCfg.extraFlags}
''; '';
}; };
};
} }
+11 -2
View File
@@ -154,8 +154,14 @@ in {
environment.systemPackages = [ cfg.package ]; environment.systemPackages = [ cfg.package ];
systemd.services.gitea = lib.mkIf cfg.enable { systemd.services.gitea = lib.mkIf cfg.enable {
wants = [ "redis-gitea.service" ]; after = [
after = [ "redis-gitea.service" ]; "sops-install-secrets.service"
"redis-gitea.service"
];
requires = [
"sops-install-secrets.service"
"redis-gitea.service"
];
serviceConfig = { serviceConfig = {
CPUSchedulingPolicy = "batch"; CPUSchedulingPolicy = "batch";
@@ -216,6 +222,9 @@ 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,7 +32,11 @@ 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,6 +12,16 @@ 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,7 +48,16 @@ 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";
requires = [ "gitea.service" "network.target" ]; after = [
"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,6 +94,11 @@ 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,5 +53,10 @@
}; };
}; };
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,9 +29,15 @@ 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";
+4 -2
View File
@@ -159,7 +159,6 @@ 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"
@@ -168,7 +167,10 @@ in
"matrix-ooye-pre-start.service" "matrix-ooye-pre-start.service"
"network-online.target" "network-online.target"
]; ];
requires = [ "matrix-ooye-pre-start.service" ]; requires = [
"network-online.target"
"matrix-ooye-pre-start.service"
];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
startLimitIntervalSec = 5; startLimitIntervalSec = 5;