-
-
Notifications
You must be signed in to change notification settings - Fork 240
Expand file tree
/
Copy pathpostgres.nix
More file actions
229 lines (217 loc) · 8.13 KB
/
postgres.nix
File metadata and controls
229 lines (217 loc) · 8.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
{ inputs, ... }:
{
perSystem =
{ pkgs, lib, ... }:
let
# Custom extensions that exist in our repository. These aren't upstream
# either because nobody has done the work, maintaining them here is
# easier and more expedient, or because they may not be suitable, or are
# too niche/one-off.
#
# Ideally, most of these should have copies upstream for third party
# use, but even if they did, keeping our own copies means that we can
# rollout new versions of these critical things easier without having to
# go through the upstream release engineering process.
ourExtensions = [
../ext/rum.nix
../ext/timescaledb.nix
../ext/pgroonga
../ext/index_advisor.nix
../ext/wal2json.nix
../ext/pgmq
../ext/pg_repack.nix
../ext/pg-safeupdate.nix
../ext/plpgsql-check.nix
../ext/pgjwt.nix
../ext/pgaudit.nix
../ext/postgis.nix
../ext/pgrouting
../ext/pgtap.nix
../ext/pg_cron
../ext/pgsql-http.nix
../ext/pg_plan_filter.nix
../ext/pg_net.nix
../ext/pg_hashids.nix
../ext/pgsodium.nix
../ext/pg_graphql
../ext/pg_stat_monitor.nix
../ext/pg_jsonschema
../ext/pg_partman.nix
../ext/pgvector.nix
../ext/vault.nix
../ext/hypopg.nix
../ext/pg_tle.nix
../ext/wrappers/default.nix
../ext/supautils.nix
../ext/plv8
];
#Where we import and build the orioledb extension, we add on our custom extensions
# plus the orioledb option
#we're not using timescaledb or plv8 in the orioledb-17 version or pg 17 of supabase extensions
orioleFilteredExtensions = builtins.filter (
x: x != ../ext/timescaledb.nix && x != ../ext/timescaledb-2.9.1.nix && x != ../ext/plv8
) ourExtensions;
orioledbExtensions = orioleFilteredExtensions ++ [ ../ext/orioledb.nix ];
dbExtensions17 = orioleFilteredExtensions ++ [ ../ext/pg_textsearch.nix ];
# CLI extensions - minimal set for Supabase CLI with migration support
cliExtensions = [
../ext/supautils.nix
../ext/pg_graphql
../ext/pgsodium.nix
../ext/vault.nix
../ext/pg_net.nix
../ext/pg_cron
../ext/pg-safeupdate.nix
];
getPostgresqlPackage = version: pkgs."postgresql_${version}";
# Create a 'receipt' file for a given postgresql package. This is a way
# of adding a bit of metadata to the package, which can be used by other
# tools to inspect what the contents of the install are: the PSQL
# version, the installed extensions, et cetera.
#
# This takes two arguments:
# - pgbin: the postgresql package we are building on top of
# not a list of packages, but an attrset containing extension names
# mapped to versions.
# - ourExts: the list of extensions from upstream nixpkgs. This is not
# a list of packages, but an attrset containing extension names
# mapped to versions.
#
# The output is a package containing the receipt.json file, which can be
# merged with the PostgreSQL installation using 'symlinkJoin'.
makeReceipt =
pgbin: ourExts:
pkgs.writeTextFile {
name = "receipt";
destination = "/receipt.json";
text = builtins.toJSON {
psql-version = pgbin.version;
nixpkgs = {
revision = inputs.nixpkgs.rev;
};
extensions = ourExts;
# NOTE this field can be used to do cache busting (e.g.
# force a rebuild of the psql packages) but also to helpfully inform
# tools what version of the schema is being used, for forwards and
# backwards compatibility
receipt-version = "1";
};
};
makeOurPostgresPkgs =
version:
{
variant ? "full",
}:
let
postgresql = getPostgresqlPackage version;
extensionsToUse =
if variant == "cli" then
cliExtensions
else if (builtins.elem version [ "orioledb-17" ]) then
orioledbExtensions
else if (builtins.elem version [ "17" ]) then
dbExtensions17
else
ourExtensions;
extCallPackage = pkgs.lib.callPackageWith (
pkgs
// {
inherit postgresql;
switch-ext-version = extCallPackage ./switch-ext-version.nix { };
overlayfs-on-package = extCallPackage ./overlayfs-on-package.nix { };
}
);
in
map (path: extCallPackage path { }) extensionsToUse;
# Create an attrset that contains all the extensions included in a server.
makeOurPostgresPkgsSet =
version:
{
variant ? "full",
}:
let
pkgsList = makeOurPostgresPkgs version { inherit variant; };
baseAttrs = builtins.listToAttrs (
map (drv: {
name = drv.name;
value = drv;
}) pkgsList
);
# Expose individual packages from extensions that have them in passthru.packages
# This makes them discoverable by nix-eval-jobs --force-recurse
individualPkgs = lib.concatMapAttrs (
name: drv: lib.optionalAttrs (drv ? passthru.packages) { "${name}-pkgs" = drv.passthru.packages; }
) baseAttrs;
in
baseAttrs // individualPkgs // { recurseForDerivations = true; };
# Create a binary distribution of PostgreSQL, given a version.
#
# NOTE: The version here does NOT refer to the exact PostgreSQL version;
# it refers to the *major number only*, which is used to select the
# correct version of the package from nixpkgs. This is because we want
# to be able to do so in an open ended way. As an example, the version
# "15" passed in will use the nixpkgs package "postgresql_15" as the
# basis for building extensions, etc.
makePostgresBin =
version:
{
variant ? "full",
}:
let
# For CLI variant, override PostgreSQL to be portable (no hardcoded /nix/store paths)
postgresql =
if variant == "cli" then
(getPostgresqlPackage version).override { portable = true; }
else
getPostgresqlPackage version;
postgres-pkgs = makeOurPostgresPkgs version { inherit variant; };
ourExts = map (ext: {
name = ext.name;
version = ext.version;
}) postgres-pkgs;
pgbin = postgresql.withPackages (_ps: postgres-pkgs);
in
pkgs.symlinkJoin {
inherit (pgbin) name version;
paths = [
pgbin
(makeReceipt pgbin ourExts)
];
};
# Create an attribute set, containing all the relevant packages for a
# PostgreSQL install, wrapped up with a bow on top. There are three
# packages:
#
# - bin: the postgresql package itself, with all the extensions
# installed, and a receipt.json file containing metadata about the
# install.
# - exts: an attrset containing all the extensions, mapped to their
# package names.
makePostgres =
version:
{
variant ? "full",
}:
lib.recurseIntoAttrs {
bin = makePostgresBin version { inherit variant; };
exts = makeOurPostgresPkgsSet version { inherit variant; };
};
basePackages = {
psql_15 = makePostgres "15" { };
psql_17 = makePostgres "17" { };
psql_orioledb-17 = makePostgres "orioledb-17" { };
};
# CLI packages - minimal PostgreSQL + supautils only for Supabase CLI
cliPackages = {
psql_17_cli = makePostgres "17" { variant = "cli"; };
};
binPackages = lib.mapAttrs' (name: value: {
name = "${name}/bin";
value = value.bin;
}) (basePackages // cliPackages);
in
{
packages = binPackages;
legacyPackages = basePackages // cliPackages;
};
}