From 5142b7afa88db6ccec229521ad96df4419f6abe4 Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Sun, 17 Mar 2024 11:54:30 +0100 Subject: [PATCH] nixos/postgresql: turn `settings` into a submodule The main idea behind that was to be able to do more sophisticated merging for stuff that goes into `postgresql.conf`: `shared_preload_libraries` is a comma-separated list in a `types.str` and thus not mergeable. With this change, the option accepts both a comma-separated string xor a list of strings. This can be implemented rather quick using `coercedTo` + freeform modules. The interface still behaves equally, but it allows to merge declarations for this option together. One side-effect was that I had to change the `attrsOf (oneOf ...)` part into a submodule to allow declaring options for certain things. While at it, I decided to move `log_line_prefix` and `port` into this structure as well. --- .../modules/services/databases/postgresql.md | 6 +- .../modules/services/databases/postgresql.nix | 61 +++++++++++-------- nixos/modules/services/misc/forgejo.nix | 4 +- nixos/modules/services/misc/gitea.nix | 4 +- .../services/monitoring/zabbix-proxy.nix | 4 +- .../services/monitoring/zabbix-server.nix | 4 +- nixos/modules/services/web-apps/invidious.nix | 4 +- nixos/modules/services/web-apps/zabbix.nix | 4 +- nixos/tests/invidious.nix | 2 +- nixos/tests/miniflux.nix | 2 +- nixos/tests/pg_anonymizer.nix | 2 +- nixos/tests/pgmanage.nix | 2 +- .../web-apps/mastodon/remote-databases.nix | 2 +- 13 files changed, 57 insertions(+), 44 deletions(-) diff --git a/nixos/modules/services/databases/postgresql.md b/nixos/modules/services/databases/postgresql.md index 6cce8f542a53..8a587832cd8c 100644 --- a/nixos/modules/services/databases/postgresql.md +++ b/nixos/modules/services/databases/postgresql.md @@ -118,7 +118,7 @@ are already created. before = "service1.service"; after = "postgresql.service"; serviceConfig.User = "postgres"; - environment.PSQL = "psql --port=${toString services.postgresql.port}"; + environment.PSQL = "psql --port=${toString services.postgresql.settings.port}"; path = [ postgresql ]; script = '' $PSQL service1 -c 'GRANT SELECT ON ALL TABLES IN SCHEMA public TO "extraUser1"' @@ -139,7 +139,7 @@ are already created. ```nix { - environment.PSQL = "psql --port=${toString services.postgresql.port}"; + environment.PSQL = "psql --port=${toString services.postgresql.settings.port}"; path = [ postgresql ]; systemd.services."service1".preStart = '' $PSQL -c 'GRANT SELECT ON ALL TABLES IN SCHEMA public TO "extraUser1"' @@ -159,7 +159,7 @@ are already created. before = "service1.service"; after = "postgresql.service"; serviceConfig.User = "service1"; - environment.PSQL = "psql --port=${toString services.postgresql.port}"; + environment.PSQL = "psql --port=${toString services.postgresql.settings.port}"; path = [ postgresql ]; script = '' $PSQL -c 'GRANT SELECT ON ALL TABLES IN SCHEMA public TO "extraUser1"' diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix index c3f3b98ae5e7..d3fd6db6aea1 100644 --- a/nixos/modules/services/databases/postgresql.nix +++ b/nixos/modules/services/databases/postgresql.nix @@ -27,7 +27,7 @@ let else toString value; # The main PostgreSQL configuration file. - configFile = pkgs.writeTextDir "postgresql.conf" (concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") cfg.settings)); + configFile = pkgs.writeTextDir "postgresql.conf" (concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") (filterAttrs (const (x: x != null)) cfg.settings))); configFileCheck = pkgs.runCommand "postgresql-configfile-check" {} '' ${cfg.package}/bin/postgres -D${configFile} -C config_file >/dev/null @@ -41,6 +41,9 @@ in { imports = [ (mkRemovedOptionModule [ "services" "postgresql" "extraConfig" ] "Use services.postgresql.settings instead.") + + (mkRenamedOptionModule [ "services" "postgresql" "logLinePrefix" ] [ "services" "postgresql" "settings" "log_line_prefix" ]) + (mkRenamedOptionModule [ "services" "postgresql" "port" ] [ "services" "postgresql" "settings" "port" ]) ]; ###### interface @@ -57,14 +60,6 @@ in example = "postgresql_15"; }; - port = mkOption { - type = types.port; - default = 5432; - description = lib.mdDoc '' - The port on which PostgreSQL listens. - ''; - }; - checkConfig = mkOption { type = types.bool; default = true; @@ -352,17 +347,6 @@ in ''; }; - logLinePrefix = mkOption { - type = types.str; - default = "[%p] "; - example = "%m [%p] "; - description = lib.mdDoc '' - A printf-style string that is output at the beginning of each log line. - Upstream default is `'%m [%p] '`, i.e. it includes the timestamp. We do - not include the timestamp, because journal has it anyway. - ''; - }; - extraPlugins = mkOption { type = with types; coercedTo (listOf path) (path: _ignorePg: path) (functionTo (listOf path)); default = _: []; @@ -373,7 +357,38 @@ in }; settings = mkOption { - type = with types; attrsOf (oneOf [ bool float int str ]); + type = with types; submodule { + freeformType = attrsOf (oneOf [ bool float int str ]); + options = { + shared_preload_libraries = mkOption { + type = nullOr (coercedTo (listOf str) (concatStringsSep ", ") str); + default = null; + example = literalExpression ''[ "auto_explain" "anon" ]''; + description = mdDoc '' + List of libraries to be preloaded. + ''; + }; + + log_line_prefix = mkOption { + type = types.str; + default = "[%p] "; + example = "%m [%p] "; + description = lib.mdDoc '' + A printf-style string that is output at the beginning of each log line. + Upstream default is `'%m [%p] '`, i.e. it includes the timestamp. We do + not include the timestamp, because journal has it anyway. + ''; + }; + + port = mkOption { + type = types.port; + default = 5432; + description = lib.mdDoc '' + The port on which PostgreSQL listens. + ''; + }; + }; + }; default = {}; description = lib.mdDoc '' PostgreSQL configuration. Refer to @@ -439,9 +454,7 @@ in hba_file = "${pkgs.writeText "pg_hba.conf" cfg.authentication}"; ident_file = "${pkgs.writeText "pg_ident.conf" cfg.identMap}"; log_destination = "stderr"; - log_line_prefix = cfg.logLinePrefix; listen_addresses = if cfg.enableTCPIP then "*" else "localhost"; - port = cfg.port; jit = mkDefault (if cfg.enableJIT then "on" else "off"); }; @@ -524,7 +537,7 @@ in # Wait for PostgreSQL to be ready to accept connections. postStart = '' - PSQL="psql --port=${toString cfg.port}" + PSQL="psql --port=${toString cfg.settings.port}" while ! $PSQL -d postgres -c "" 2> /dev/null; do if ! kill -0 "$MAINPID"; then exit 1; fi diff --git a/nixos/modules/services/misc/forgejo.nix b/nixos/modules/services/misc/forgejo.nix index 08cddc3a0710..2b1700626870 100644 --- a/nixos/modules/services/misc/forgejo.nix +++ b/nixos/modules/services/misc/forgejo.nix @@ -114,11 +114,11 @@ in port = mkOption { type = types.port; - default = if !usePostgresql then 3306 else pg.port; + default = if usePostgresql then pg.settings.port else 3306; defaultText = literalExpression '' if config.${opt.database.type} != "postgresql" then 3306 - else config.${options.services.postgresql.port} + else 5432 ''; description = mdDoc "Database host port."; }; diff --git a/nixos/modules/services/misc/gitea.nix b/nixos/modules/services/misc/gitea.nix index 08feea853e47..13617931c23e 100644 --- a/nixos/modules/services/misc/gitea.nix +++ b/nixos/modules/services/misc/gitea.nix @@ -100,11 +100,11 @@ in port = mkOption { type = types.port; - default = if !usePostgresql then 3306 else pg.port; + default = if usePostgresql then pg.settings.port else 3306; defaultText = literalExpression '' if config.${opt.database.type} != "postgresql" then 3306 - else config.${options.services.postgresql.port} + else 5432 ''; description = lib.mdDoc "Database host port."; }; diff --git a/nixos/modules/services/monitoring/zabbix-proxy.nix b/nixos/modules/services/monitoring/zabbix-proxy.nix index fea5704af6f6..7a0fc77d5b25 100644 --- a/nixos/modules/services/monitoring/zabbix-proxy.nix +++ b/nixos/modules/services/monitoring/zabbix-proxy.nix @@ -103,11 +103,11 @@ in port = mkOption { type = types.port; - default = if cfg.database.type == "mysql" then mysql.port else pgsql.port; + default = if cfg.database.type == "mysql" then mysql.port else pgsql.services.port; defaultText = literalExpression '' if config.${opt.database.type} == "mysql" then config.${options.services.mysql.port} - else config.${options.services.postgresql.port} + else config.services.postgresql.settings.port ''; description = lib.mdDoc "Database host port."; }; diff --git a/nixos/modules/services/monitoring/zabbix-server.nix b/nixos/modules/services/monitoring/zabbix-server.nix index f2fb5fbe7ac6..fc9295d294d1 100644 --- a/nixos/modules/services/monitoring/zabbix-server.nix +++ b/nixos/modules/services/monitoring/zabbix-server.nix @@ -95,11 +95,11 @@ in port = mkOption { type = types.port; - default = if cfg.database.type == "mysql" then mysql.port else pgsql.port; + default = if cfg.database.type == "mysql" then mysql.port else pgsql.settings.port; defaultText = literalExpression '' if config.${opt.database.type} == "mysql" then config.${options.services.mysql.port} - else config.${options.services.postgresql.port} + else config.services.postgresql.settings.port ''; description = lib.mdDoc "Database host port."; }; diff --git a/nixos/modules/services/web-apps/invidious.nix b/nixos/modules/services/web-apps/invidious.nix index 359aaabfe673..ac7937b16e48 100644 --- a/nixos/modules/services/web-apps/invidious.nix +++ b/nixos/modules/services/web-apps/invidious.nix @@ -346,8 +346,8 @@ in port = lib.mkOption { type = types.port; - default = options.services.postgresql.port.default; - defaultText = lib.literalExpression "options.services.postgresql.port.default"; + default = config.services.postgresql.settings.port; + defaultText = lib.literalExpression "config.services.postgresql.settings.port"; description = lib.mdDoc '' The port of the database Invidious should use. diff --git a/nixos/modules/services/web-apps/zabbix.nix b/nixos/modules/services/web-apps/zabbix.nix index 4f6d7e4e6c1c..ac3c85af2a71 100644 --- a/nixos/modules/services/web-apps/zabbix.nix +++ b/nixos/modules/services/web-apps/zabbix.nix @@ -76,11 +76,11 @@ in type = types.port; default = if cfg.database.type == "mysql" then config.services.mysql.port - else if cfg.database.type == "pgsql" then config.services.postgresql.port + else if cfg.database.type == "pgsql" then config.services.postgresql.settings.port else 1521; defaultText = literalExpression '' if config.${opt.database.type} == "mysql" then config.${options.services.mysql.port} - else if config.${opt.database.type} == "pgsql" then config.${options.services.postgresql.port} + else if config.${opt.database.type} == "pgsql" then config.services.postgresql.settings.port else 1521 ''; description = lib.mdDoc "Database host port."; diff --git a/nixos/tests/invidious.nix b/nixos/tests/invidious.nix index e31cd87f6a00..372b47b56c34 100644 --- a/nixos/tests/invidious.nix +++ b/nixos/tests/invidious.nix @@ -18,7 +18,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { host invidious invidious samenet scram-sha-256 ''; }; - networking.firewall.allowedTCPPorts = [ config.services.postgresql.port ]; + networking.firewall.allowedTCPPorts = [ config.services.postgresql.settings.port ]; }; machine = { config, lib, pkgs, ... }: { services.invidious = { diff --git a/nixos/tests/miniflux.nix b/nixos/tests/miniflux.nix index 6d38224448ed..2adf9010051c 100644 --- a/nixos/tests/miniflux.nix +++ b/nixos/tests/miniflux.nix @@ -76,7 +76,7 @@ in systemd.services.postgresql.postStart = lib.mkAfter '' $PSQL -tAd miniflux -c 'CREATE EXTENSION hstore;' ''; - networking.firewall.allowedTCPPorts = [ config.services.postgresql.port ]; + networking.firewall.allowedTCPPorts = [ config.services.postgresql.settings.port ]; }; externalDb = { ... }: { security.apparmor.enable = true; diff --git a/nixos/tests/pg_anonymizer.nix b/nixos/tests/pg_anonymizer.nix index 2960108e37c3..b26e4dca0580 100644 --- a/nixos/tests/pg_anonymizer.nix +++ b/nixos/tests/pg_anonymizer.nix @@ -7,7 +7,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { services.postgresql = { enable = true; extraPlugins = ps: [ ps.anonymizer ]; - settings.shared_preload_libraries = "anon"; + settings.shared_preload_libraries = [ "anon" ]; }; }; diff --git a/nixos/tests/pgmanage.nix b/nixos/tests/pgmanage.nix index 6f8f2f965340..6e72b32eca36 100644 --- a/nixos/tests/pgmanage.nix +++ b/nixos/tests/pgmanage.nix @@ -21,7 +21,7 @@ in pgmanage = { enable = true; connections = { - ${conn} = "hostaddr=127.0.0.1 port=${toString config.services.postgresql.port} dbname=postgres"; + ${conn} = "hostaddr=127.0.0.1 port=${toString config.services.postgresql.settings.port} dbname=postgres"; }; }; }; diff --git a/nixos/tests/web-apps/mastodon/remote-databases.nix b/nixos/tests/web-apps/mastodon/remote-databases.nix index fa6430a99353..55243658ec6a 100644 --- a/nixos/tests/web-apps/mastodon/remote-databases.nix +++ b/nixos/tests/web-apps/mastodon/remote-databases.nix @@ -33,7 +33,7 @@ in extraHosts = hosts; firewall.allowedTCPPorts = [ config.services.redis.servers.mastodon.port - config.services.postgresql.port + config.services.postgresql.settings.port ]; };