Skip to content

Commit 073e863

Browse files
Merge pull request #381 from NuschtOS/pgvector
postgres: add support for pgvector and vectorchord, change extension installing to be per DB, add immich
2 parents 9c1ca82 + 95023d3 commit 073e863

2 files changed

Lines changed: 37 additions & 28 deletions

File tree

modules/postgres.nix

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,19 @@ let
2020

2121
# withJIT installs the postgres' jit output as an extension but that is no shared object to load
2222
cfgInstalledExtensions = lib.filter (x: x != "postgresql") (map (e: lib.getName e) cfg.finalPackage.installedExtensions);
23+
24+
# TODO: upstream, this probably requires a new entry in passthru (passthru.libName ?) to pick if the object name doesn't match the plugin name or there are multiple
25+
# https://github.com/NixOS/nixpkgs/blob/nixos-unstable/nixos/modules/services/databases/postgresql.nix#L81
26+
getExtensionName = ext: {
27+
pgvector = "vector";
28+
postgis = "postgis-3";
29+
vectorchord = "vchord";
30+
}.${ext} or ext;
2331
in
2432
{
2533
options.services = {
2634
postgresql = {
27-
configurePgStatStatements = libS.mkOpinionatedOption "configure and enable pg_stat_statements extension";
35+
configurePgStatStatements = libS.mkOpinionatedOption "configure and enable pg_stat_statements extension in all databases";
2836

2937
databases = lib.mkOption {
3038
type = lib.types.listOf lib.types.str;
@@ -39,14 +47,16 @@ in
3947
'';
4048
};
4149

42-
extensionToInstall = lib.mkOption {
43-
type = lib.types.listOf lib.types.str;
44-
defaultText = lib.literalExpression "config.services.postgresql.finalPackage.installedExtensions";
45-
description = "List of extensions which are going to be installed.";
50+
extensionsToInstall = lib.mkOption {
51+
type = with lib.types; attrsOf (listOf str);
52+
default = { };
53+
example = {
54+
immich = [ "cube" "earthdistance" "pg_trgm" "unaccent" "uuid-ossp" "vector" "vchord" ];
55+
mobilizon = [ "pg_trgm" "postgis" "unaccent" ];
56+
};
57+
description = "A mapping of which database gets which extensions installed.";
4658
};
4759

48-
installAllAvailableExtensions = libS.mkOpinionatedOption "install all extensions installed with `ALTER EXTENSION \"...\" UPDATE` or the extension equivalent custom SQL statements";
49-
5060
ensureUsers = lib.mkOption {
5161
type = lib.types.listOf (lib.types.submodule {
5262
options = {
@@ -193,7 +203,9 @@ in
193203
};
194204

195205
imports = [
196-
(lib.mkRenamedOptionModule ["services" "postgresql" "enableAllPreloadedLibraries"] ["services" "postgresql" "installAllAvailableExtensions"])
206+
(lib.mkRemovedOptionModule ["services" "postgresql" "enableAllPreloadedLibraries"] "Use services.postgresql.extensionsToInstall instead.")
207+
(lib.mkRemovedOptionModule ["services" "postgresql" "installAllAvailableExtensions"] "Use services.postgresql.extensionsToInstall instead.")
208+
(lib.mkRenamedOptionModule ["services" "postgresql" "extensionToInstall"] ["services" "postgresql" "extensionsToInstall"])
197209
(lib.mkRenamedOptionModule ["services" "postgresql" "preloadAllExtensions"] ["services" "postgresql" "preloadAllInstalledExtensions"])
198210
];
199211

@@ -295,20 +307,12 @@ in
295307
databases = [ "postgres" ] ++ config.services.postgresql.ensureDatabases;
296308
enableJIT = lib.mkIf cfg.recommendedDefaults true;
297309
extensions = lib.mkIf cfg.pgRepackTimer.enable (ps: with ps; [ pg_repack ]);
298-
extensionToInstall = lib.mkMerge [
299-
(lib.mkIf cfg.configurePgStatStatements [ "pg_stat_statements" ])
300-
cfgInstalledExtensions
301-
];
310+
extensionsToInstall = {
311+
immich = lib.mkIf config.services.immich.enable [ "cube" "earthdistance" "pg_trgm" "unaccent" "uuid-ossp" "vector" "vchord" ];
312+
};
302313
settings.shared_preload_libraries = lib.mkMerge [
303314
(lib.mkIf cfg.configurePgStatStatements [ "pg_stat_statements" ])
304-
# TODO: upstream, this probably requires a new entry in passthru to pick if the object name doesn't match the plugin name or there are multiple
305-
# https://github.com/NixOS/nixpkgs/blob/nixos-unstable/nixos/modules/services/databases/postgresql.nix#L81
306-
(let
307-
# NOTE: move into extensions passthru.libName when upstreaming
308-
getSoOrFallback = ext:{
309-
postgis = "postgis-3";
310-
}.${ext} or ext;
311-
in lib.mkIf cfg.preloadAllInstalledExtensions (map getSoOrFallback cfgInstalledExtensions))
315+
(lib.mkIf cfg.preloadAllInstalledExtensions (map getExtensionName cfgInstalledExtensions))
312316
];
313317
upgrade.stopServices = with config.services; lib.mkMerge [
314318
(lib.mkIf (atuin.enable && atuin.database.createLocally) [ "atuin" ])
@@ -323,6 +327,7 @@ in
323327
(lib.mkIf (hydra.enable && (!lib.hasInfix ";host=" hydra.dbi)) [
324328
"hydra-evaluator" "hydra-notify" "hydra-send-stats" "hydra-update-gc-roots.service" "hydra-update-gc-roots.timer" "hydra-queue-runner" "hydra-server"
325329
])
330+
(lib.mkIf (immich.enable && immich.database.host == "/run/postgresql") [ "immich-machine-learning" "immich-server" ])
326331
(lib.mkIf mailman.enable [ "mailman" "mailman-uwsgi" ])
327332
(lib.mkIf (mastodon.enable && mastodon.database.host == "/run/postgresql") [ "mastodon-sidekiq-all" "mastodon-streaming.target" "mastodon-web" ])
328333
# assume that when host is set, which is not the default, the database is none local
@@ -404,19 +409,24 @@ in
404409

405410
# install/update pg_stat_statements extension in all databases
406411
# based on https://git.catgirl.cloud/999eagle/dotfiles-nix/-/blob/main/modules/system/server/postgres/default.nix#L294-302
407-
(lib.mkIf (cfg.installAllAvailableExtensions || cfg.configurePgStatStatements) (lib.concatStrings (map (db:
408-
(lib.concatMapStringsSep "\n" (ext: let
412+
(lib.mkIf cfg.configurePgStatStatements (lib.concatStrings (map (db: /* bash */ ''
413+
psql -tAd '${db}' -c 'CREATE EXTENSION IF NOT EXISTS "pg_stat_statements"'
414+
psql -tAd '${db}' -c 'ALTER EXTENSION "pg_stat_statements" UPDATE'
415+
'') cfg.databases)))
416+
417+
# install/update extensions per database as configured in extensionsToInstall
418+
(lib.concatStrings (lib.mapAttrsToList (db: exts:
419+
lib.concatMapStrings (ext: let
409420
extUpdateStatement = name: {
410421
# pg_repack cannot be updated but reinstalling it is safe
411422
"pg_repack" = "DROP EXTENSION pg_repack CASCADE; CREATE EXTENSION pg_repack";
412423
"postgis" = "SELECT postgis_extensions_upgrade()";
413-
}.${name} or ''ALTER EXTENSION "${ext}" UPDATE'';
424+
}.${name} or ''ALTER EXTENSION "${getExtensionName ext}" UPDATE'';
414425
in /* bash */ ''
415-
psql -tAd '${db}' -c 'CREATE EXTENSION IF NOT EXISTS "${ext}"'
426+
psql -tAd '${db}' -c 'CREATE EXTENSION IF NOT EXISTS "${getExtensionName ext}"'
416427
psql -tAd '${db}' -c '${extUpdateStatement ext}'
417-
'') cfgInstalledExtensions
418-
)
419-
) cfg.databases)))
428+
'') exts
429+
) cfg.extensionsToInstall))
420430

421431
(lib.mkIf cfg.refreshCollation (lib.concatStrings (map (db: /* bash */ ''
422432
psql -tAc 'ALTER DATABASE "${db}" REFRESH COLLATION VERSION'

tests/default.nix

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ in toplevel // {
151151
services.postgresql = {
152152
enable = true;
153153
configurePgStatStatements = true;
154-
installAllAvailableExtensions = true;
155154
preloadAllInstalledExtensions = true;
156155
};
157156
};

0 commit comments

Comments
 (0)