|
7 | 7 | cfgb = config.services.postgresqlBackup; |
8 | 8 | cfgu = config.services.postgresql.upgrade; |
9 | 9 |
|
10 | | - # TODO: clean up when dropping support for 25.05 |
11 | | - hasPGdumpAllOptionsAndPostgresqlSetup = lib.versionAtLeast lib.version "25.11pre"; |
12 | 10 | latestVersion = if pkgs?postgresql_18 then "18" else "17"; |
13 | 11 | currentMajorVersion = lib.versions.major cfg.package.version; |
14 | 12 | newMajorVersion = lib.versions.major cfgu.newPackage.version; |
|
156 | 154 | }; |
157 | 155 | }; |
158 | 156 |
|
159 | | - postgresqlBackup = lib.optionalAttrs hasPGdumpAllOptionsAndPostgresqlSetup { |
| 157 | + postgresqlBackup = { |
160 | 158 | backupAll = lib.mkOption { }; |
161 | 159 |
|
162 | 160 | backupAllExcept = lib.mkOption { |
|
169 | 167 | This option also enforces ${optb.backupAll} to be turned on which has the effect that all databases are backed up except the ones listed in this option. |
170 | 168 | ''; |
171 | 169 | }; |
172 | | - } // { |
| 170 | + |
173 | 171 | databases = lib.mkOption { |
174 | 172 | defaultText = lib.literalExpression /* nix */ ''${opt.databases} ++ [ "postgres" ]''; |
175 | 173 | # NOTE: option description cannot be overwritten or merged |
|
338 | 336 | }; |
339 | 337 |
|
340 | 338 | postgresqlBackup = lib.mkMerge [ |
341 | | - ({ |
| 339 | + { |
342 | 340 | databases = lib.mkIf (cfg.recommendedDefaults || cfgb.databasesExcept != [ ]) (lib.subtractLists cfgb.databasesExcept config.services.postgresql.databases); |
343 | | - } // lib.optionalAttrs hasPGdumpAllOptionsAndPostgresqlSetup { |
344 | 341 | backupAll = lib.mkIf (cfgb.backupAllExcept != []) true; |
345 | 342 | pgdumpAllOptions = lib.concatMapStringsSep" " (db: "--exclude-database=${db}") cfgb.backupAllExcept; |
346 | | - }) |
| 343 | + } |
347 | 344 |
|
348 | 345 | (lib.mkIf cfg.recommendedDefaults { |
349 | 346 | compression = "zstd"; |
|
354 | 351 | }; |
355 | 352 |
|
356 | 353 | systemd = { |
357 | | - # TODO: drop the mkMerge when support for 25.05 is removed and we always have postgresql and postgresql-setup |
358 | | - services = lib.mkMerge [ |
359 | | - { |
360 | | - postgresql.preStart = lib.mkIf cfg.preventDowngrade /* bash */ '' |
361 | | - found_current=false |
362 | | - for dir in $(find /var/lib/postgresql/ -mindepth 1 -maxdepth 1 -type d -not -name ".*" | sort --version-sort); do |
363 | | - if [[ $found_current == true ]]; then |
364 | | - echo "Found directory ''${dir} which is newer than the current major postgres version ${currentMajorVersion}, aborting startup due to ${opt.preventDowngrade}" |
365 | | - exit 10 |
366 | | - fi |
367 | | -
|
368 | | - if [[ $(basename "$dir") == ${currentMajorVersion} ]]; then |
369 | | - found_current=true |
370 | | - continue |
371 | | - fi |
| 354 | + services = { |
| 355 | + postgresql.preStart = lib.mkIf cfg.preventDowngrade /* bash */ '' |
| 356 | + found_current=false |
| 357 | + for dir in $(find /var/lib/postgresql/ -mindepth 1 -maxdepth 1 -type d -not -name ".*" | sort --version-sort); do |
| 358 | + if [[ $found_current == true ]]; then |
| 359 | + echo "Found directory ''${dir} which is newer than the current major postgres version ${currentMajorVersion}, aborting startup due to ${opt.preventDowngrade}" |
| 360 | + exit 10 |
| 361 | + fi |
| 362 | +
|
| 363 | + if [[ $(basename "$dir") == ${currentMajorVersion} ]]; then |
| 364 | + found_current=true |
| 365 | + continue |
| 366 | + fi |
| 367 | + done |
| 368 | + ''; |
| 369 | + |
| 370 | + postgresql-setup = { |
| 371 | + preStart = lib.mkIf cfg.refreshCollation /* bash */ '' |
| 372 | + # copied from upstream due to the lack of extensibility # |
| 373 | + check-connection() { |
| 374 | + psql -d postgres -v ON_ERROR_STOP=1 <<-' EOF' |
| 375 | + SELECT pg_is_in_recovery() \gset |
| 376 | + \if :pg_is_in_recovery |
| 377 | + \i still-recovering |
| 378 | + \endif |
| 379 | + EOF |
| 380 | + } |
| 381 | + while ! check-connection 2> /dev/null; do |
| 382 | + if ! systemctl is-active --quiet postgresql.service; then exit 1; fi |
| 383 | + sleep 0.1 |
372 | 384 | done |
373 | | - ''; |
374 | | - } |
| 385 | + ### |
375 | 386 |
|
376 | | - { |
377 | | - "postgresql${lib.optionalString hasPGdumpAllOptionsAndPostgresqlSetup "-setup"}" = { |
378 | | - postStart = lib.mkMerge [ |
379 | | - (lib.mkIf cfg.refreshCollation (lib.mkBefore /* bash */ '' |
380 | | - ### TODO: clean up when dropping support for 25.05 |
381 | | - # copied from upstream due to the lack of extensibility |
382 | | - # TODO: improve this upstream? |
383 | | - PSQL="psql --port=${toString cfg.settings.port}" |
384 | | -
|
385 | | - while ! $PSQL -d postgres -c "" 2> /dev/null; do |
386 | | - if ! kill -0 "$MAINPID"; then exit 1; fi |
387 | | - sleep 0.1 |
388 | | - done |
389 | | - ### |
390 | | -
|
391 | | - $PSQL -tAc 'ALTER DATABASE "template1" REFRESH COLLATION VERSION' |
392 | | - '')) |
393 | | - |
394 | | - (lib.concatMapStrings (user: lib.optionalString (user.ensurePasswordFile != null) /* psql */ '' |
395 | | - # TODO: use psql when dropping support for 25.05 |
396 | | - $PSQL -tA <<'EOF' |
397 | | - DO $$ |
398 | | - DECLARE password TEXT; |
399 | | - BEGIN |
400 | | - password := trim(both from replace(pg_read_file('${user.ensurePasswordFile}'), E'\n', ''')); |
401 | | - EXECUTE format('ALTER ROLE ${user.name} WITH PASSWORD '''%s''';', password); |
402 | | - END $$; |
403 | | - EOF |
404 | | - '') cfg.ensureUsers) |
405 | | - |
406 | | - # install/update pg_stat_statements extension in all databases |
407 | | - # based on https://git.catgirl.cloud/999eagle/dotfiles-nix/-/blob/main/modules/system/server/postgres/default.nix#L294-302 |
408 | | - (lib.mkIf (cfg.installAllAvailableExtensions || cfg.configurePgStatStatements) (lib.concatStrings (map (db: |
409 | | - (lib.concatMapStringsSep "\n" (ext: let |
410 | | - extUpdateStatement = name: { |
411 | | - # pg_repack cannot be updated but reinstalling it is safe |
412 | | - "pg_repack" = "DROP EXTENSION pg_repack CASCADE; CREATE EXTENSION pg_repack"; |
413 | | - "postgis" = "SELECT postgis_extensions_upgrade()"; |
414 | | - }.${name} or ''ALTER EXTENSION "${ext}" UPDATE''; |
415 | | - in /* bash */ '' |
416 | | - # TODO: use psql when dropping support for 25.05 |
417 | | - $PSQL -tAd '${db}' -c 'CREATE EXTENSION IF NOT EXISTS "${ext}"' |
418 | | - $PSQL -tAd '${db}' -c '${extUpdateStatement ext}' |
419 | | - '') cfgInstalledExtensions |
420 | | - ) |
421 | | - ) cfg.databases))) |
422 | | - |
423 | | - (lib.mkIf cfg.refreshCollation (lib.concatStrings (map (db: /* bash */ '' |
424 | | - # TODO: use psql when dropping support for 25.05 |
425 | | - $PSQL -tAc 'ALTER DATABASE "${db}" REFRESH COLLATION VERSION' |
426 | | - '') cfg.databases))) |
427 | | - ]; |
428 | | - |
429 | | - # reduce downtime for dependent services |
430 | | - stopIfChanged = lib.mkIf cfg.recommendedDefaults false; |
431 | | - }; |
| 387 | + psql -tAc 'ALTER DATABASE "template1" REFRESH COLLATION VERSION' |
| 388 | + ''; |
| 389 | + script = lib.mkMerge [ |
| 390 | + (lib.concatMapStrings (user: lib.optionalString (user.ensurePasswordFile != null) /* bash */ '' |
| 391 | + psql -tA <<'EOF' |
| 392 | + DO $$ |
| 393 | + DECLARE password TEXT; |
| 394 | + BEGIN |
| 395 | + password := trim(both from replace(pg_read_file('${user.ensurePasswordFile}'), E'\n', ''')); |
| 396 | + EXECUTE format('ALTER ROLE ${user.name} WITH PASSWORD '''%s''';', password); |
| 397 | + END $$; |
| 398 | + EOF |
| 399 | + '') cfg.ensureUsers) |
| 400 | + |
| 401 | + # install/update pg_stat_statements extension in all databases |
| 402 | + # based on https://git.catgirl.cloud/999eagle/dotfiles-nix/-/blob/main/modules/system/server/postgres/default.nix#L294-302 |
| 403 | + (lib.mkIf (cfg.installAllAvailableExtensions || cfg.configurePgStatStatements) (lib.concatStrings (map (db: |
| 404 | + (lib.concatMapStringsSep "\n" (ext: let |
| 405 | + extUpdateStatement = name: { |
| 406 | + # pg_repack cannot be updated but reinstalling it is safe |
| 407 | + "pg_repack" = "DROP EXTENSION pg_repack CASCADE; CREATE EXTENSION pg_repack"; |
| 408 | + "postgis" = "SELECT postgis_extensions_upgrade()"; |
| 409 | + }.${name} or ''ALTER EXTENSION "${ext}" UPDATE''; |
| 410 | + in /* bash */ '' |
| 411 | + psql -tAd '${db}' -c 'CREATE EXTENSION IF NOT EXISTS "${ext}"' |
| 412 | + psql -tAd '${db}' -c '${extUpdateStatement ext}' |
| 413 | + '') cfgInstalledExtensions |
| 414 | + ) |
| 415 | + ) cfg.databases))) |
| 416 | + |
| 417 | + (lib.mkIf cfg.refreshCollation (lib.concatStrings (map (db: /* bash */ '' |
| 418 | + psql -tAc 'ALTER DATABASE "${db}" REFRESH COLLATION VERSION' |
| 419 | + '') cfg.databases))) |
| 420 | + ]; |
| 421 | + |
| 422 | + # reduce downtime for dependent services |
| 423 | + stopIfChanged = lib.mkIf cfg.recommendedDefaults false; |
| 424 | + }; |
432 | 425 |
|
433 | | - postgresql-pg-repack = lib.mkIf cfg.vacuumAnalyzeTimer.enable { |
434 | | - description = "Repack all PostgreSQL databases"; |
435 | | - serviceConfig = { |
436 | | - ExecStart = "${lib.getExe cfg.package.pkgs.pg_repack} --port=${builtins.toString cfg.settings.port} --all"; |
437 | | - User = "postgres"; |
438 | | - }; |
| 426 | + postgresql-pg-repack = lib.mkIf cfg.vacuumAnalyzeTimer.enable { |
| 427 | + description = "Repack all PostgreSQL databases"; |
| 428 | + serviceConfig = { |
| 429 | + ExecStart = "${lib.getExe cfg.package.pkgs.pg_repack} --port=${builtins.toString cfg.settings.port} --all"; |
| 430 | + User = "postgres"; |
439 | 431 | }; |
| 432 | + }; |
440 | 433 |
|
441 | | - postgresql-vacuum-analyze = lib.mkIf cfg.vacuumAnalyzeTimer.enable { |
442 | | - description = "Vacuum and analyze all PostgreSQL databases"; |
443 | | - serviceConfig = { |
444 | | - ExecStart = "${lib.getExe' cfg.package "psql"} --port=${builtins.toString cfg.settings.port} -tAc 'VACUUM ANALYZE'"; |
445 | | - User = "postgres"; |
446 | | - }; |
| 434 | + postgresql-vacuum-analyze = lib.mkIf cfg.vacuumAnalyzeTimer.enable { |
| 435 | + description = "Vacuum and analyze all PostgreSQL databases"; |
| 436 | + serviceConfig = { |
| 437 | + ExecStart = "${lib.getExe' cfg.package "psql"} --port=${builtins.toString cfg.settings.port} -tAc 'VACUUM ANALYZE'"; |
| 438 | + User = "postgres"; |
447 | 439 | }; |
448 | | - } |
449 | | - ]; |
| 440 | + }; |
| 441 | + }; |
450 | 442 |
|
451 | 443 | timers = let |
452 | 444 | mkTimerConfig = name: lib.mkMerge [ |
|
0 commit comments