From 64c94bd40ad53df26d1c2b4b8e769262422e8e66 Mon Sep 17 00:00:00 2001 From: Benjamin Staffin Date: Mon, 21 Aug 2023 18:16:06 -0400 Subject: [PATCH 1/2] nixos/keycloak: Add systemd startup notification This makes it possible for other systemd units to depend on keycloak.service using `after` and `wants` relationships, and systemd will actually wait for Keycloak to finish its initialization before starting any dependent units. This can be important for services like oauth2-proxy, which (when configured to use Keycloak as its auth provider) will fail to start until Keycloak's `.well-known/openid-configuration` endpoint is available. --- nixos/modules/services/web-apps/keycloak.nix | 5 ++++- pkgs/servers/keycloak/all-plugins.nix | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/nixos/modules/services/web-apps/keycloak.nix b/nixos/modules/services/web-apps/keycloak.nix index 201085daa74a..6d472cf48cd0 100644 --- a/nixos/modules/services/web-apps/keycloak.nix +++ b/nixos/modules/services/web-apps/keycloak.nix @@ -466,7 +466,8 @@ in confFile = pkgs.writeText "keycloak.conf" (keycloakConfig filteredConfig); keycloakBuild = cfg.package.override { inherit confFile; - plugins = cfg.package.enabledPlugins ++ cfg.plugins; + plugins = cfg.package.enabledPlugins ++ cfg.plugins ++ + (with cfg.package.plugins; [quarkus-systemd-notify quarkus-systemd-notify-deployment]); }; in mkIf cfg.enable @@ -638,6 +639,8 @@ in RuntimeDirectory = "keycloak"; RuntimeDirectoryMode = "0700"; AmbientCapabilities = "CAP_NET_BIND_SERVICE"; + Type = "notify"; # Requires quarkus-systemd-notify plugin + NotifyAccess = "all"; }; script = '' set -o errexit -o pipefail -o nounset -o errtrace diff --git a/pkgs/servers/keycloak/all-plugins.nix b/pkgs/servers/keycloak/all-plugins.nix index f2f1117f2d84..2e4c97ea1cec 100644 --- a/pkgs/servers/keycloak/all-plugins.nix +++ b/pkgs/servers/keycloak/all-plugins.nix @@ -1,4 +1,4 @@ -{ callPackage }: +{ callPackage, fetchMavenArtifact }: { scim-for-keycloak = callPackage ./scim-for-keycloak {}; @@ -6,4 +6,20 @@ keycloak-discord = callPackage ./keycloak-discord {}; keycloak-metrics-spi = callPackage ./keycloak-metrics-spi {}; keycloak-restrict-client-auth = callPackage ./keycloak-restrict-client-auth {}; + + # These could theoretically be used by something other than Keycloak, but + # there are no other quarkus apps in nixpkgs (as of 2023-08-21) + quarkus-systemd-notify = (fetchMavenArtifact { + groupId = "io.quarkiverse.systemd.notify"; + artifactId = "quarkus-systemd-notify"; + version = "1.0.1"; + hash = "sha256-3I4j22jyIpokU4kdobkt6cDsALtxYFclA+DV+BqtmLY="; + }).passthru.jar; + + quarkus-systemd-notify-deployment = (fetchMavenArtifact { + groupId = "io.quarkiverse.systemd.notify"; + artifactId = "quarkus-systemd-notify-deployment"; + version = "1.0.1"; + hash = "sha256-xHxzBxriSd/OU8gEcDG00VRkJYPYJDfAfPh/FkQe+zg="; + }).passthru.jar; } From b45bb628ea3eadb967da73cff18a705dd0dd6cd0 Mon Sep 17 00:00:00 2001 From: Benjamin Staffin Date: Mon, 21 Aug 2023 20:04:48 -0400 Subject: [PATCH 2/2] nixos/oauth2_proxy: Conditionally depend on keycloak.service Co-Authored-By: Jade Lovelace --- .../services/security/oauth2-proxy.nix | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/nixos/modules/services/security/oauth2-proxy.nix b/nixos/modules/services/security/oauth2-proxy.nix index 78a772845a35..3079a1d030c5 100644 --- a/nixos/modules/services/security/oauth2-proxy.nix +++ b/nixos/modules/services/security/oauth2-proxy.nix @@ -577,20 +577,22 @@ in users.groups.oauth2-proxy = {}; - systemd.services.oauth2-proxy = { - description = "OAuth2 Proxy"; - path = [ cfg.package ]; - wantedBy = [ "multi-user.target" ]; - wants = [ "network-online.target" ]; - after = [ "network-online.target" ]; + systemd.services.oauth2-proxy = + let needsKeycloak = lib.elem cfg.provider ["keycloak" "keycloak-oidc"] + && config.services.keycloak.enable; + in { + description = "OAuth2 Proxy"; + path = [ cfg.package ]; + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ] ++ lib.optionals needsKeycloak [ "keycloak.service" ]; + after = [ "network-online.target" ] ++ lib.optionals needsKeycloak [ "keycloak.service" ]; - serviceConfig = { - User = "oauth2-proxy"; - Restart = "always"; - ExecStart = "${cfg.package}/bin/oauth2-proxy ${configString}"; - EnvironmentFile = lib.mkIf (cfg.keyFile != null) cfg.keyFile; + serviceConfig = { + User = "oauth2-proxy"; + Restart = "always"; + ExecStart = "${cfg.package}/bin/oauth2-proxy ${configString}"; + EnvironmentFile = lib.mkIf (cfg.keyFile != null) cfg.keyFile; + }; }; - }; - }; }