chore: run nix fmt
This commit is contained in:
parent
d3f5308eaf
commit
3bc699fccf
|
@ -111,7 +111,8 @@
|
|||
devShells.ci = pkgs.mkShell { buildInputs = with pkgs; [ nodejs ]; };
|
||||
};
|
||||
|
||||
flake = let
|
||||
flake =
|
||||
let
|
||||
username = "barkeeper";
|
||||
in
|
||||
{
|
||||
|
|
|
@ -44,15 +44,15 @@
|
|||
};
|
||||
|
||||
nachtigall-test = {
|
||||
imports = [
|
||||
self.inputs.agenix.nixosModules.default
|
||||
self.nixosModules.home-manager
|
||||
./nachtigall/test-vm.nix
|
||||
self.nixosModules.overlays
|
||||
self.nixosModules.core
|
||||
self.nixosModules.docker
|
||||
];
|
||||
};
|
||||
imports = [
|
||||
self.inputs.agenix.nixosModules.default
|
||||
self.nixosModules.home-manager
|
||||
./nachtigall/test-vm.nix
|
||||
self.nixosModules.overlays
|
||||
self.nixosModules.core
|
||||
self.nixosModules.docker
|
||||
];
|
||||
};
|
||||
|
||||
flora-6 = self.nixos-flake.lib.mkLinuxSystem {
|
||||
imports = [
|
||||
|
|
|
@ -1,37 +1,36 @@
|
|||
{ flake, lib, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[
|
||||
./backups.nix
|
||||
./apps/nginx.nix
|
||||
imports = [
|
||||
./backups.nix
|
||||
./apps/nginx.nix
|
||||
|
||||
./apps/collabora.nix
|
||||
./apps/coturn.nix
|
||||
./apps/forgejo.nix
|
||||
./apps/keycloak.nix
|
||||
./apps/mailman.nix
|
||||
./apps/mastodon.nix
|
||||
./apps/mediawiki.nix
|
||||
./apps/nextcloud.nix
|
||||
./apps/nginx-mastodon.nix
|
||||
./apps/nginx-mastodon-files.nix
|
||||
./apps/nginx-prometheus-exporters.nix
|
||||
./apps/nginx-website.nix
|
||||
./apps/nginx-website-miom.nix
|
||||
./apps/opensearch.nix
|
||||
./apps/owncast.nix
|
||||
./apps/postgresql.nix
|
||||
./apps/prometheus-exporters.nix
|
||||
./apps/promtail.nix
|
||||
./apps/searx.nix
|
||||
./apps/tmate.nix
|
||||
./apps/collabora.nix
|
||||
./apps/coturn.nix
|
||||
./apps/forgejo.nix
|
||||
./apps/keycloak.nix
|
||||
./apps/mailman.nix
|
||||
./apps/mastodon.nix
|
||||
./apps/mediawiki.nix
|
||||
./apps/nextcloud.nix
|
||||
./apps/nginx-mastodon.nix
|
||||
./apps/nginx-mastodon-files.nix
|
||||
./apps/nginx-prometheus-exporters.nix
|
||||
./apps/nginx-website.nix
|
||||
./apps/nginx-website-miom.nix
|
||||
./apps/opensearch.nix
|
||||
./apps/owncast.nix
|
||||
./apps/postgresql.nix
|
||||
./apps/prometheus-exporters.nix
|
||||
./apps/promtail.nix
|
||||
./apps/searx.nix
|
||||
./apps/tmate.nix
|
||||
|
||||
./apps/matrix/irc.nix
|
||||
./apps/matrix/mautrix-telegram.nix
|
||||
./apps/matrix/synapse.nix
|
||||
./apps/nginx-matrix.nix
|
||||
];
|
||||
./apps/matrix/irc.nix
|
||||
./apps/matrix/mautrix-telegram.nix
|
||||
./apps/matrix/synapse.nix
|
||||
./apps/nginx-matrix.nix
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
{
|
||||
# Configuration common to all Linux systems
|
||||
flake = {
|
||||
lib = let
|
||||
lib =
|
||||
let
|
||||
callLibs = file: import file { inherit lib; };
|
||||
in
|
||||
rec {
|
||||
|
|
|
@ -4,11 +4,17 @@
|
|||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
utils = import "${flake.inputs.nixpkgs}/nixos/lib/utils.nix" { inherit lib; inherit config; inherit pkgs; };
|
||||
}:
|
||||
let
|
||||
utils = import "${flake.inputs.nixpkgs}/nixos/lib/utils.nix" {
|
||||
inherit lib;
|
||||
inherit config;
|
||||
inherit pkgs;
|
||||
};
|
||||
# Type for a valid systemd unit option. Needed for correctly passing "timerConfig" to "systemd.timers"
|
||||
inherit (utils.systemdUtils.unitOptions) unitOption;
|
||||
in {
|
||||
in
|
||||
{
|
||||
options.pub-solar-os.backups = {
|
||||
stores =
|
||||
with lib;
|
||||
|
|
|
@ -59,9 +59,7 @@
|
|||
"pub.solar" =
|
||||
flake.inputs.keycloak-theme-pub-solar.legacyPackages.${pkgs.system}.keycloak-theme-pub-solar;
|
||||
};
|
||||
plugins = [
|
||||
flake.inputs.keycloak-event-listener.packages.${pkgs.system}.keycloak-event-listener
|
||||
];
|
||||
plugins = [ flake.inputs.keycloak-event-listener.packages.${pkgs.system}.keycloak-event-listener ];
|
||||
};
|
||||
|
||||
pub-solar-os.backups.backups.keycloak = {
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
{ config, options, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
options,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.keycloak;
|
||||
|
@ -40,35 +46,79 @@ let
|
|||
prefixUnlessEmpty = prefix: string: optionalString (string != "") "${prefix}${string}";
|
||||
in
|
||||
{
|
||||
imports =
|
||||
[
|
||||
(mkRenamedOptionModule
|
||||
[ "services" "keycloak" "bindAddress" ]
|
||||
[ "services" "keycloak" "settings" "http-host" ])
|
||||
(mkRenamedOptionModule
|
||||
[ "services" "keycloak" "forceBackendUrlToFrontendUrl"]
|
||||
[ "services" "keycloak" "settings" "hostname-strict-backchannel"])
|
||||
(mkChangedOptionModule
|
||||
[ "services" "keycloak" "httpPort" ]
|
||||
[ "services" "keycloak" "settings" "http-port" ]
|
||||
(config:
|
||||
builtins.fromJSON config.services.keycloak.httpPort))
|
||||
(mkChangedOptionModule
|
||||
[ "services" "keycloak" "httpsPort" ]
|
||||
[ "services" "keycloak" "settings" "https-port" ]
|
||||
(config:
|
||||
builtins.fromJSON config.services.keycloak.httpsPort))
|
||||
(mkRemovedOptionModule
|
||||
[ "services" "keycloak" "frontendUrl" ]
|
||||
''
|
||||
Set `services.keycloak.settings.hostname' and `services.keycloak.settings.http-relative-path' instead.
|
||||
NOTE: You likely want to set 'http-relative-path' to '/auth' to keep compatibility with your clients.
|
||||
See its description for more information.
|
||||
'')
|
||||
(mkRemovedOptionModule
|
||||
[ "services" "keycloak" "extraConfig" ]
|
||||
"Use `services.keycloak.settings' instead.")
|
||||
];
|
||||
imports = [
|
||||
(mkRenamedOptionModule
|
||||
[
|
||||
"services"
|
||||
"keycloak"
|
||||
"bindAddress"
|
||||
]
|
||||
[
|
||||
"services"
|
||||
"keycloak"
|
||||
"settings"
|
||||
"http-host"
|
||||
]
|
||||
)
|
||||
(mkRenamedOptionModule
|
||||
[
|
||||
"services"
|
||||
"keycloak"
|
||||
"forceBackendUrlToFrontendUrl"
|
||||
]
|
||||
[
|
||||
"services"
|
||||
"keycloak"
|
||||
"settings"
|
||||
"hostname-strict-backchannel"
|
||||
]
|
||||
)
|
||||
(mkChangedOptionModule
|
||||
[
|
||||
"services"
|
||||
"keycloak"
|
||||
"httpPort"
|
||||
]
|
||||
[
|
||||
"services"
|
||||
"keycloak"
|
||||
"settings"
|
||||
"http-port"
|
||||
]
|
||||
(config: builtins.fromJSON config.services.keycloak.httpPort)
|
||||
)
|
||||
(mkChangedOptionModule
|
||||
[
|
||||
"services"
|
||||
"keycloak"
|
||||
"httpsPort"
|
||||
]
|
||||
[
|
||||
"services"
|
||||
"keycloak"
|
||||
"settings"
|
||||
"https-port"
|
||||
]
|
||||
(config: builtins.fromJSON config.services.keycloak.httpsPort)
|
||||
)
|
||||
(mkRemovedOptionModule
|
||||
[
|
||||
"services"
|
||||
"keycloak"
|
||||
"frontendUrl"
|
||||
]
|
||||
''
|
||||
Set `services.keycloak.settings.hostname' and `services.keycloak.settings.http-relative-path' instead.
|
||||
NOTE: You likely want to set 'http-relative-path' to '/auth' to keep compatibility with your clients.
|
||||
See its description for more information.
|
||||
''
|
||||
)
|
||||
(mkRemovedOptionModule [
|
||||
"services"
|
||||
"keycloak"
|
||||
"extraConfig"
|
||||
] "Use `services.keycloak.settings' instead.")
|
||||
];
|
||||
|
||||
options.services.keycloak =
|
||||
let
|
||||
|
@ -82,9 +132,11 @@ in
|
|||
path
|
||||
enum
|
||||
package
|
||||
port;
|
||||
port
|
||||
;
|
||||
|
||||
assertStringPath = optionName: value:
|
||||
assertStringPath =
|
||||
optionName: value:
|
||||
if isPath value then
|
||||
throw ''
|
||||
services.keycloak.${optionName}:
|
||||
|
@ -92,7 +144,8 @@ in
|
|||
is a Nix path, but should be a string, since Nix
|
||||
paths are copied into the world-readable Nix store.
|
||||
''
|
||||
else value;
|
||||
else
|
||||
value;
|
||||
in
|
||||
{
|
||||
enable = mkOption {
|
||||
|
@ -139,7 +192,11 @@ in
|
|||
|
||||
database = {
|
||||
type = mkOption {
|
||||
type = enum [ "mysql" "mariadb" "postgresql" ];
|
||||
type = enum [
|
||||
"mysql"
|
||||
"mariadb"
|
||||
"postgresql"
|
||||
];
|
||||
default = "postgresql";
|
||||
example = "mariadb";
|
||||
description = ''
|
||||
|
@ -286,7 +343,14 @@ in
|
|||
|
||||
settings = mkOption {
|
||||
type = lib.types.submodule {
|
||||
freeformType = attrsOf (nullOr (oneOf [ str int bool (attrsOf path) ]));
|
||||
freeformType = attrsOf (
|
||||
nullOr (oneOf [
|
||||
str
|
||||
int
|
||||
bool
|
||||
(attrsOf path)
|
||||
])
|
||||
);
|
||||
|
||||
options = {
|
||||
http-host = mkOption {
|
||||
|
@ -365,7 +429,12 @@ in
|
|||
};
|
||||
|
||||
proxy = mkOption {
|
||||
type = enum [ "edge" "reencrypt" "passthrough" "none" ];
|
||||
type = enum [
|
||||
"edge"
|
||||
"reencrypt"
|
||||
"passthrough"
|
||||
"none"
|
||||
];
|
||||
default = "none";
|
||||
example = "edge";
|
||||
description = ''
|
||||
|
@ -422,7 +491,12 @@ in
|
|||
# connect to it.
|
||||
databaseActuallyCreateLocally = cfg.database.createLocally && cfg.database.host == "localhost";
|
||||
createLocalPostgreSQL = databaseActuallyCreateLocally && cfg.database.type == "postgresql";
|
||||
createLocalMySQL = databaseActuallyCreateLocally && elem cfg.database.type [ "mysql" "mariadb" ];
|
||||
createLocalMySQL =
|
||||
databaseActuallyCreateLocally
|
||||
&& elem cfg.database.type [
|
||||
"mysql"
|
||||
"mariadb"
|
||||
];
|
||||
|
||||
mySqlCaKeystore = pkgs.runCommand "mysql-ca-keystore" { } ''
|
||||
${pkgs.jre}/bin/keytool -importcert -trustcacerts -alias MySQLCACert -file ${cfg.database.caCert} -keystore $out -storepass notsosecretpassword -noprompt
|
||||
|
@ -454,216 +528,242 @@ in
|
|||
fi
|
||||
done
|
||||
|
||||
${concatStringsSep "\n" (mapAttrsToList (name: theme: "linkTheme ${theme} ${escapeShellArg name}") cfg.themes)}
|
||||
${concatStringsSep "\n" (
|
||||
mapAttrsToList (name: theme: "linkTheme ${theme} ${escapeShellArg name}") cfg.themes
|
||||
)}
|
||||
'';
|
||||
|
||||
keycloakConfig = lib.generators.toKeyValue {
|
||||
mkKeyValue = lib.flip lib.generators.mkKeyValueDefault "=" {
|
||||
mkValueString = v:
|
||||
if isInt v then toString v
|
||||
else if isString v then v
|
||||
else if true == v then "true"
|
||||
else if false == v then "false"
|
||||
else if isSecret v then hashString "sha256" v._secret
|
||||
else throw "unsupported type ${typeOf v}: ${(lib.generators.toPretty {}) v}";
|
||||
mkValueString =
|
||||
v:
|
||||
if isInt v then
|
||||
toString v
|
||||
else if isString v then
|
||||
v
|
||||
else if true == v then
|
||||
"true"
|
||||
else if false == v then
|
||||
"false"
|
||||
else if isSecret v then
|
||||
hashString "sha256" v._secret
|
||||
else
|
||||
throw "unsupported type ${typeOf v}: ${(lib.generators.toPretty { }) v}";
|
||||
};
|
||||
};
|
||||
|
||||
isSecret = v: isAttrs v && v ? _secret && isString v._secret;
|
||||
filteredConfig = lib.converge (lib.filterAttrsRecursive (_: v: ! elem v [{ } null])) cfg.settings;
|
||||
filteredConfig = lib.converge (lib.filterAttrsRecursive (
|
||||
_: v:
|
||||
!elem v [
|
||||
{ }
|
||||
null
|
||||
]
|
||||
)) cfg.settings;
|
||||
confFile = pkgs.writeText "keycloak.conf" (keycloakConfig filteredConfig);
|
||||
keycloakBuild = cfg.package.override {
|
||||
inherit confFile;
|
||||
plugins = cfg.package.enabledPlugins ++ cfg.plugins ++
|
||||
(with cfg.package.plugins; [quarkus-systemd-notify quarkus-systemd-notify-deployment]);
|
||||
plugins =
|
||||
cfg.package.enabledPlugins
|
||||
++ cfg.plugins
|
||||
++ (with cfg.package.plugins; [
|
||||
quarkus-systemd-notify
|
||||
quarkus-systemd-notify-deployment
|
||||
]);
|
||||
};
|
||||
in
|
||||
mkIf cfg.enable
|
||||
{
|
||||
assertions = [
|
||||
{
|
||||
assertion = (cfg.database.useSSL && cfg.database.type == "postgresql") -> (cfg.database.caCert != null);
|
||||
message = "A CA certificate must be specified (in 'services.keycloak.database.caCert') when PostgreSQL is used with SSL";
|
||||
}
|
||||
{
|
||||
assertion = createLocalPostgreSQL -> config.services.postgresql.settings.standard_conforming_strings or true;
|
||||
message = "Setting up a local PostgreSQL db for Keycloak requires `standard_conforming_strings` turned on to work reliably";
|
||||
}
|
||||
{
|
||||
assertion = cfg.settings.hostname != null || ! cfg.settings.hostname-strict or true;
|
||||
message = "Setting the Keycloak hostname is required, see `services.keycloak.settings.hostname`";
|
||||
}
|
||||
{
|
||||
assertion = cfg.settings.hostname-url or null == null;
|
||||
message = ''
|
||||
The option `services.keycloak.settings.hostname-url' has been removed.
|
||||
Set `services.keycloak.settings.hostname' instead.
|
||||
See [New Hostname options](https://www.keycloak.org/docs/25.0.0/upgrading/#new-hostname-options) for details.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = cfg.settings.hostname-strict-backchannel or null == null;
|
||||
message = ''
|
||||
The option `services.keycloak.settings.hostname-strict-backchannel' has been removed.
|
||||
Set `services.keycloak.settings.hostname-backchannel-dynamic' instead.
|
||||
See [New Hostname options](https://www.keycloak.org/docs/25.0.0/upgrading/#new-hostname-options) for details.
|
||||
'';
|
||||
}
|
||||
];
|
||||
mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
(cfg.database.useSSL && cfg.database.type == "postgresql") -> (cfg.database.caCert != null);
|
||||
message = "A CA certificate must be specified (in 'services.keycloak.database.caCert') when PostgreSQL is used with SSL";
|
||||
}
|
||||
{
|
||||
assertion =
|
||||
createLocalPostgreSQL -> config.services.postgresql.settings.standard_conforming_strings or true;
|
||||
message = "Setting up a local PostgreSQL db for Keycloak requires `standard_conforming_strings` turned on to work reliably";
|
||||
}
|
||||
{
|
||||
assertion = cfg.settings.hostname != null || !cfg.settings.hostname-strict or true;
|
||||
message = "Setting the Keycloak hostname is required, see `services.keycloak.settings.hostname`";
|
||||
}
|
||||
{
|
||||
assertion = cfg.settings.hostname-url or null == null;
|
||||
message = ''
|
||||
The option `services.keycloak.settings.hostname-url' has been removed.
|
||||
Set `services.keycloak.settings.hostname' instead.
|
||||
See [New Hostname options](https://www.keycloak.org/docs/25.0.0/upgrading/#new-hostname-options) for details.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = cfg.settings.hostname-strict-backchannel or null == null;
|
||||
message = ''
|
||||
The option `services.keycloak.settings.hostname-strict-backchannel' has been removed.
|
||||
Set `services.keycloak.settings.hostname-backchannel-dynamic' instead.
|
||||
See [New Hostname options](https://www.keycloak.org/docs/25.0.0/upgrading/#new-hostname-options) for details.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
environment.systemPackages = [ keycloakBuild ];
|
||||
environment.systemPackages = [ keycloakBuild ];
|
||||
|
||||
services.keycloak.settings =
|
||||
let
|
||||
postgresParams = concatStringsSep "&" (
|
||||
optionals cfg.database.useSSL [
|
||||
"ssl=true"
|
||||
] ++ optionals (cfg.database.caCert != null) [
|
||||
"sslrootcert=${cfg.database.caCert}"
|
||||
"sslmode=verify-ca"
|
||||
]
|
||||
);
|
||||
mariadbParams = concatStringsSep "&" ([
|
||||
"characterEncoding=UTF-8"
|
||||
] ++ optionals cfg.database.useSSL [
|
||||
services.keycloak.settings =
|
||||
let
|
||||
postgresParams = concatStringsSep "&" (
|
||||
optionals cfg.database.useSSL [ "ssl=true" ]
|
||||
++ optionals (cfg.database.caCert != null) [
|
||||
"sslrootcert=${cfg.database.caCert}"
|
||||
"sslmode=verify-ca"
|
||||
]
|
||||
);
|
||||
mariadbParams = concatStringsSep "&" (
|
||||
[ "characterEncoding=UTF-8" ]
|
||||
++ optionals cfg.database.useSSL [
|
||||
"useSSL=true"
|
||||
"requireSSL=true"
|
||||
"verifyServerCertificate=true"
|
||||
] ++ optionals (cfg.database.caCert != null) [
|
||||
]
|
||||
++ optionals (cfg.database.caCert != null) [
|
||||
"trustCertificateKeyStoreUrl=file:${mySqlCaKeystore}"
|
||||
"trustCertificateKeyStorePassword=notsosecretpassword"
|
||||
]);
|
||||
dbProps = if cfg.database.type == "postgresql" then postgresParams else mariadbParams;
|
||||
in
|
||||
mkMerge [
|
||||
{
|
||||
db = if cfg.database.type == "postgresql" then "postgres" else cfg.database.type;
|
||||
db-username = if databaseActuallyCreateLocally then "keycloak" else cfg.database.username;
|
||||
db-password._secret = cfg.database.passwordFile;
|
||||
db-url-host = cfg.database.host;
|
||||
db-url-port = toString cfg.database.port;
|
||||
db-url-database = if databaseActuallyCreateLocally then "keycloak" else cfg.database.name;
|
||||
db-url-properties = prefixUnlessEmpty "?" dbProps;
|
||||
db-url = null;
|
||||
}
|
||||
(mkIf (cfg.sslCertificate != null && cfg.sslCertificateKey != null) {
|
||||
https-certificate-file = "/run/keycloak/ssl/ssl_cert";
|
||||
https-certificate-key-file = "/run/keycloak/ssl/ssl_key";
|
||||
})
|
||||
];
|
||||
]
|
||||
);
|
||||
dbProps = if cfg.database.type == "postgresql" then postgresParams else mariadbParams;
|
||||
in
|
||||
mkMerge [
|
||||
{
|
||||
db = if cfg.database.type == "postgresql" then "postgres" else cfg.database.type;
|
||||
db-username = if databaseActuallyCreateLocally then "keycloak" else cfg.database.username;
|
||||
db-password._secret = cfg.database.passwordFile;
|
||||
db-url-host = cfg.database.host;
|
||||
db-url-port = toString cfg.database.port;
|
||||
db-url-database = if databaseActuallyCreateLocally then "keycloak" else cfg.database.name;
|
||||
db-url-properties = prefixUnlessEmpty "?" dbProps;
|
||||
db-url = null;
|
||||
}
|
||||
(mkIf (cfg.sslCertificate != null && cfg.sslCertificateKey != null) {
|
||||
https-certificate-file = "/run/keycloak/ssl/ssl_cert";
|
||||
https-certificate-key-file = "/run/keycloak/ssl/ssl_key";
|
||||
})
|
||||
];
|
||||
|
||||
systemd.services.keycloakPostgreSQLInit = mkIf createLocalPostgreSQL {
|
||||
after = [ "postgresql.service" ];
|
||||
before = [ "keycloak.service" ];
|
||||
bindsTo = [ "postgresql.service" ];
|
||||
path = [ config.services.postgresql.package ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
User = "postgres";
|
||||
Group = "postgres";
|
||||
LoadCredential = [ "db_password:${cfg.database.passwordFile}" ];
|
||||
};
|
||||
script = ''
|
||||
set -o errexit -o pipefail -o nounset -o errtrace
|
||||
shopt -s inherit_errexit
|
||||
|
||||
create_role="$(mktemp)"
|
||||
trap 'rm -f "$create_role"' EXIT
|
||||
|
||||
# Read the password from the credentials directory and
|
||||
# escape any single quotes by adding additional single
|
||||
# quotes after them, following the rules laid out here:
|
||||
# https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS
|
||||
db_password="$(<"$CREDENTIALS_DIRECTORY/db_password")"
|
||||
db_password="''${db_password//\'/\'\'}"
|
||||
|
||||
echo "CREATE ROLE keycloak WITH LOGIN PASSWORD '$db_password' CREATEDB" > "$create_role"
|
||||
psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='keycloak'" | grep -q 1 || psql -tA --file="$create_role"
|
||||
psql -tAc "SELECT 1 FROM pg_database WHERE datname = 'keycloak'" | grep -q 1 || psql -tAc 'CREATE DATABASE "keycloak" OWNER "keycloak"'
|
||||
'';
|
||||
systemd.services.keycloakPostgreSQLInit = mkIf createLocalPostgreSQL {
|
||||
after = [ "postgresql.service" ];
|
||||
before = [ "keycloak.service" ];
|
||||
bindsTo = [ "postgresql.service" ];
|
||||
path = [ config.services.postgresql.package ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
User = "postgres";
|
||||
Group = "postgres";
|
||||
LoadCredential = [ "db_password:${cfg.database.passwordFile}" ];
|
||||
};
|
||||
script = ''
|
||||
set -o errexit -o pipefail -o nounset -o errtrace
|
||||
shopt -s inherit_errexit
|
||||
|
||||
systemd.services.keycloakMySQLInit = mkIf createLocalMySQL {
|
||||
after = [ "mysql.service" ];
|
||||
before = [ "keycloak.service" ];
|
||||
bindsTo = [ "mysql.service" ];
|
||||
path = [ config.services.mysql.package ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
User = config.services.mysql.user;
|
||||
Group = config.services.mysql.group;
|
||||
LoadCredential = [ "db_password:${cfg.database.passwordFile}" ];
|
||||
};
|
||||
script = ''
|
||||
set -o errexit -o pipefail -o nounset -o errtrace
|
||||
shopt -s inherit_errexit
|
||||
create_role="$(mktemp)"
|
||||
trap 'rm -f "$create_role"' EXIT
|
||||
|
||||
# Read the password from the credentials directory and
|
||||
# escape any single quotes by adding additional single
|
||||
# quotes after them, following the rules laid out here:
|
||||
# https://dev.mysql.com/doc/refman/8.0/en/string-literals.html
|
||||
db_password="$(<"$CREDENTIALS_DIRECTORY/db_password")"
|
||||
db_password="''${db_password//\'/\'\'}"
|
||||
# Read the password from the credentials directory and
|
||||
# escape any single quotes by adding additional single
|
||||
# quotes after them, following the rules laid out here:
|
||||
# https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS
|
||||
db_password="$(<"$CREDENTIALS_DIRECTORY/db_password")"
|
||||
db_password="''${db_password//\'/\'\'}"
|
||||
|
||||
( echo "SET sql_mode = 'NO_BACKSLASH_ESCAPES';"
|
||||
echo "CREATE USER IF NOT EXISTS 'keycloak'@'localhost' IDENTIFIED BY '$db_password';"
|
||||
echo "CREATE DATABASE IF NOT EXISTS keycloak CHARACTER SET utf8 COLLATE utf8_unicode_ci;"
|
||||
echo "GRANT ALL PRIVILEGES ON keycloak.* TO 'keycloak'@'localhost';"
|
||||
) | mysql -N
|
||||
'';
|
||||
echo "CREATE ROLE keycloak WITH LOGIN PASSWORD '$db_password' CREATEDB" > "$create_role"
|
||||
psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='keycloak'" | grep -q 1 || psql -tA --file="$create_role"
|
||||
psql -tAc "SELECT 1 FROM pg_database WHERE datname = 'keycloak'" | grep -q 1 || psql -tAc 'CREATE DATABASE "keycloak" OWNER "keycloak"'
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.keycloakMySQLInit = mkIf createLocalMySQL {
|
||||
after = [ "mysql.service" ];
|
||||
before = [ "keycloak.service" ];
|
||||
bindsTo = [ "mysql.service" ];
|
||||
path = [ config.services.mysql.package ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
User = config.services.mysql.user;
|
||||
Group = config.services.mysql.group;
|
||||
LoadCredential = [ "db_password:${cfg.database.passwordFile}" ];
|
||||
};
|
||||
script = ''
|
||||
set -o errexit -o pipefail -o nounset -o errtrace
|
||||
shopt -s inherit_errexit
|
||||
|
||||
systemd.services.keycloak =
|
||||
let
|
||||
databaseServices =
|
||||
if createLocalPostgreSQL then [
|
||||
# Read the password from the credentials directory and
|
||||
# escape any single quotes by adding additional single
|
||||
# quotes after them, following the rules laid out here:
|
||||
# https://dev.mysql.com/doc/refman/8.0/en/string-literals.html
|
||||
db_password="$(<"$CREDENTIALS_DIRECTORY/db_password")"
|
||||
db_password="''${db_password//\'/\'\'}"
|
||||
|
||||
( echo "SET sql_mode = 'NO_BACKSLASH_ESCAPES';"
|
||||
echo "CREATE USER IF NOT EXISTS 'keycloak'@'localhost' IDENTIFIED BY '$db_password';"
|
||||
echo "CREATE DATABASE IF NOT EXISTS keycloak CHARACTER SET utf8 COLLATE utf8_unicode_ci;"
|
||||
echo "GRANT ALL PRIVILEGES ON keycloak.* TO 'keycloak'@'localhost';"
|
||||
) | mysql -N
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.services.keycloak =
|
||||
let
|
||||
databaseServices =
|
||||
if createLocalPostgreSQL then
|
||||
[
|
||||
"keycloakPostgreSQLInit.service"
|
||||
"postgresql.service"
|
||||
]
|
||||
else if createLocalMySQL then [
|
||||
else if createLocalMySQL then
|
||||
[
|
||||
"keycloakMySQLInit.service"
|
||||
"mysql.service"
|
||||
]
|
||||
else [ ];
|
||||
secretPaths = catAttrs "_secret" (collect isSecret cfg.settings);
|
||||
mkSecretReplacement = file: ''
|
||||
replace-secret ${hashString "sha256" file} $CREDENTIALS_DIRECTORY/${baseNameOf file} /run/keycloak/conf/keycloak.conf
|
||||
'';
|
||||
secretReplacements = lib.concatMapStrings mkSecretReplacement secretPaths;
|
||||
extraStartupFlags = lib.concatStringsSep " " cfg.extraStartupFlags;
|
||||
in
|
||||
{
|
||||
after = databaseServices;
|
||||
bindsTo = databaseServices;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = with pkgs; [
|
||||
keycloakBuild
|
||||
openssl
|
||||
replace-secret
|
||||
];
|
||||
environment = {
|
||||
KC_HOME_DIR = "/run/keycloak";
|
||||
KC_CONF_DIR = "/run/keycloak/conf";
|
||||
};
|
||||
serviceConfig = {
|
||||
LoadCredential =
|
||||
map (p: "${baseNameOf p}:${p}") secretPaths
|
||||
++ optionals (cfg.sslCertificate != null && cfg.sslCertificateKey != null) [
|
||||
"ssl_cert:${cfg.sslCertificate}"
|
||||
"ssl_key:${cfg.sslCertificateKey}"
|
||||
];
|
||||
User = "keycloak";
|
||||
Group = "keycloak";
|
||||
DynamicUser = true;
|
||||
RuntimeDirectory = "keycloak";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
||||
Type = "notify"; # Requires quarkus-systemd-notify plugin
|
||||
NotifyAccess = "all";
|
||||
};
|
||||
script = ''
|
||||
else
|
||||
[ ];
|
||||
secretPaths = catAttrs "_secret" (collect isSecret cfg.settings);
|
||||
mkSecretReplacement = file: ''
|
||||
replace-secret ${hashString "sha256" file} $CREDENTIALS_DIRECTORY/${baseNameOf file} /run/keycloak/conf/keycloak.conf
|
||||
'';
|
||||
secretReplacements = lib.concatMapStrings mkSecretReplacement secretPaths;
|
||||
extraStartupFlags = lib.concatStringsSep " " cfg.extraStartupFlags;
|
||||
in
|
||||
{
|
||||
after = databaseServices;
|
||||
bindsTo = databaseServices;
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = with pkgs; [
|
||||
keycloakBuild
|
||||
openssl
|
||||
replace-secret
|
||||
];
|
||||
environment = {
|
||||
KC_HOME_DIR = "/run/keycloak";
|
||||
KC_CONF_DIR = "/run/keycloak/conf";
|
||||
};
|
||||
serviceConfig = {
|
||||
LoadCredential =
|
||||
map (p: "${baseNameOf p}:${p}") secretPaths
|
||||
++ optionals (cfg.sslCertificate != null && cfg.sslCertificateKey != null) [
|
||||
"ssl_cert:${cfg.sslCertificate}"
|
||||
"ssl_key:${cfg.sslCertificateKey}"
|
||||
];
|
||||
User = "keycloak";
|
||||
Group = "keycloak";
|
||||
DynamicUser = true;
|
||||
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
|
||||
shopt -s inherit_errexit
|
||||
|
||||
|
@ -681,24 +781,26 @@ in
|
|||
# sequences.
|
||||
sed -i '/db-/ s|\\|\\\\|g' /run/keycloak/conf/keycloak.conf
|
||||
|
||||
'' + optionalString (cfg.sslCertificate != null && cfg.sslCertificateKey != null) ''
|
||||
''
|
||||
+ optionalString (cfg.sslCertificate != null && cfg.sslCertificateKey != null) ''
|
||||
mkdir -p /run/keycloak/ssl
|
||||
cp $CREDENTIALS_DIRECTORY/ssl_{cert,key} /run/keycloak/ssl/
|
||||
'' + ''
|
||||
''
|
||||
+ ''
|
||||
export KEYCLOAK_ADMIN=admin
|
||||
export KEYCLOAK_ADMIN_PASSWORD=${escapeShellArg cfg.initialAdminPassword}
|
||||
kc.sh --verbose start --optimized ${extraStartupFlags}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
services.postgresql.enable = mkDefault createLocalPostgreSQL;
|
||||
services.mysql.enable = mkDefault createLocalMySQL;
|
||||
services.mysql.package =
|
||||
let
|
||||
dbPkg = if cfg.database.type == "mariadb" then pkgs.mariadb else pkgs.mysql80;
|
||||
in
|
||||
mkIf createLocalMySQL (mkDefault dbPkg);
|
||||
};
|
||||
services.postgresql.enable = mkDefault createLocalPostgreSQL;
|
||||
services.mysql.enable = mkDefault createLocalMySQL;
|
||||
services.mysql.package =
|
||||
let
|
||||
dbPkg = if cfg.database.type == "mariadb" then pkgs.mariadb else pkgs.mysql80;
|
||||
in
|
||||
mkIf createLocalMySQL (mkDefault dbPkg);
|
||||
};
|
||||
|
||||
meta.doc = ./keycloak.md;
|
||||
meta.maintainers = [ maintainers.talyz ];
|
||||
|
|
|
@ -5,15 +5,22 @@ args@{
|
|||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
nixos-lib = import (inputs.nixpkgs + "/nixos/lib") { };
|
||||
|
||||
loadTestFiles = with lib; dir: mapAttrs' (name: _: let
|
||||
test = ((import (dir + "/${name}")) args);
|
||||
in {
|
||||
name = "test-" + (lib.strings.removeSuffix ".nix" name);
|
||||
value = nixos-lib.runTest test;
|
||||
})
|
||||
(filterAttrs (name: _: (hasSuffix ".nix" name) && name != "default.nix")
|
||||
(builtins.readDir dir));
|
||||
in loadTestFiles ./.
|
||||
loadTestFiles =
|
||||
with lib;
|
||||
dir:
|
||||
mapAttrs' (
|
||||
name: _:
|
||||
let
|
||||
test = ((import (dir + "/${name}")) args);
|
||||
in
|
||||
{
|
||||
name = "test-" + (lib.strings.removeSuffix ".nix" name);
|
||||
value = nixos-lib.runTest test;
|
||||
}
|
||||
) (filterAttrs (name: _: (hasSuffix ".nix" name) && name != "default.nix") (builtins.readDir dir));
|
||||
in
|
||||
loadTestFiles ./.
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
puppeteer-socket = (pkgs.callPackage (import ./puppeteer-socket/puppeteer-socket.nix) {});
|
||||
puppeteer-run = (pkgs.callPackage (import ./puppeteer-socket/puppeteer-run.nix) {});
|
||||
in {
|
||||
}:
|
||||
let
|
||||
puppeteer-socket = (pkgs.callPackage (import ./puppeteer-socket/puppeteer-socket.nix) { });
|
||||
puppeteer-run = (pkgs.callPackage (import ./puppeteer-socket/puppeteer-run.nix) { });
|
||||
in
|
||||
{
|
||||
imports = [ ./global.nix ];
|
||||
|
||||
security.polkit.enable = true;
|
||||
|
@ -18,9 +20,7 @@ in {
|
|||
|
||||
services.getty.autologinUser = config.pub-solar-os.authentication.username;
|
||||
|
||||
virtualisation.qemu.options = [
|
||||
"-vga std"
|
||||
];
|
||||
virtualisation.qemu.options = [ "-vga std" ];
|
||||
|
||||
home-manager.users.${config.pub-solar-os.authentication.username} = {
|
||||
programs.bash.profileExtra = ''
|
||||
|
@ -36,7 +36,7 @@ in {
|
|||
modifier = "Mod4";
|
||||
terminal = "${pkgs.alacritty}/bin/alacritty";
|
||||
startup = [
|
||||
{command = "EXECUTABLE=${pkgs.firefox}/bin/firefox ${puppeteer-socket}/bin/puppeteer-socket";}
|
||||
{ command = "EXECUTABLE=${pkgs.firefox}/bin/firefox ${puppeteer-socket}/bin/puppeteer-socket"; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
{
|
||||
writeShellScriptBin,
|
||||
curl
|
||||
}: writeShellScriptBin "puppeteer-run" ''
|
||||
set -e
|
||||
{ writeShellScriptBin, curl }:
|
||||
writeShellScriptBin "puppeteer-run" ''
|
||||
set -e
|
||||
|
||||
exec ${curl}/bin/curl --fail-with-body -X POST -d "$@" --unix-socket "/tmp/puppeteer.sock" http://puppeteer-socket
|
||||
exec ${curl}/bin/curl --fail-with-body -X POST -d "$@" --unix-socket "/tmp/puppeteer.sock" http://puppeteer-socket
|
||||
''
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
{
|
||||
buildNpmPackage,
|
||||
nodejs,
|
||||
}:
|
||||
{ buildNpmPackage, nodejs }:
|
||||
buildNpmPackage rec {
|
||||
src = ./.;
|
||||
name = "puppeteer-socket";
|
||||
|
|
Loading…
Reference in a new issue