|
260 | 260 | recurseForDerivations = true; |
261 | 261 | }; |
262 | 262 |
|
| 263 | + makePostgresDevSetup = { pkgs, name, extraSubstitutions ? {} }: |
| 264 | + let |
| 265 | + paths = { |
| 266 | + migrationsDir = builtins.path { |
| 267 | + name = "migrations"; |
| 268 | + path = ./migrations/db; |
| 269 | + }; |
| 270 | + postgresqlSchemaSql = builtins.path { |
| 271 | + name = "postgresql-schema"; |
| 272 | + path = ./nix/tools/postgresql_schema.sql; |
| 273 | + }; |
| 274 | + pgbouncerAuthSchemaSql = builtins.path { |
| 275 | + name = "pgbouncer-auth-schema"; |
| 276 | + path = ./ansible/files/pgbouncer_config/pgbouncer_auth_schema.sql; |
| 277 | + }; |
| 278 | + statExtensionSql = builtins.path { |
| 279 | + name = "stat-extension"; |
| 280 | + path = ./ansible/files/stat_extension.sql; |
| 281 | + }; |
| 282 | + pgconfigFile = builtins.path { |
| 283 | + name = "postgresql.conf"; |
| 284 | + path = ./ansible/files/postgresql_config/postgresql.conf.j2; |
| 285 | + }; |
| 286 | + supautilsConfigFile = builtins.path { |
| 287 | + name = "supautils.conf"; |
| 288 | + path = ./ansible/files/postgresql_config/supautils.conf.j2; |
| 289 | + }; |
| 290 | + loggingConfigFile = builtins.path { |
| 291 | + name = "logging.conf"; |
| 292 | + path = ./ansible/files/postgresql_config/postgresql-csvlog.conf; |
| 293 | + }; |
| 294 | + readReplicaConfigFile = builtins.path { |
| 295 | + name = "readreplica.conf"; |
| 296 | + path = ./ansible/files/postgresql_config/custom_read_replica.conf.j2; |
| 297 | + }; |
| 298 | + pgHbaConfigFile = builtins.path { |
| 299 | + name = "pg_hba.conf"; |
| 300 | + path = ./ansible/files/postgresql_config/pg_hba.conf.j2; |
| 301 | + }; |
| 302 | + pgIdentConfigFile = builtins.path { |
| 303 | + name = "pg_ident.conf"; |
| 304 | + path = ./ansible/files/postgresql_config/pg_ident.conf.j2; |
| 305 | + }; |
| 306 | + postgresqlExtensionCustomScriptsPath = builtins.path { |
| 307 | + name = "extension-custom-scripts"; |
| 308 | + path = ./ansible/files/postgresql_extension_custom_scripts; |
| 309 | + }; |
| 310 | + getkeyScript = builtins.path { |
| 311 | + name = "pgsodium_getkey.sh"; |
| 312 | + path = ./nix/tests/util/pgsodium_getkey.sh; |
| 313 | + }; |
| 314 | + }; |
| 315 | + |
| 316 | + localeArchive = if pkgs.stdenv.isDarwin |
| 317 | + then "${pkgs.darwin.locale}/share/locale" |
| 318 | + else "${pkgs.glibcLocales}/lib/locale/locale-archive"; |
| 319 | + |
| 320 | + substitutions = { |
| 321 | + SHELL_PATH = "${pkgs.bash}/bin/bash"; |
| 322 | + PGSQL_DEFAULT_PORT = "${pgsqlDefaultPort}"; |
| 323 | + PGSQL_SUPERUSER = "${pgsqlSuperuser}"; |
| 324 | + PSQL15_BINDIR = "${basePackages.psql_15.bin}"; |
| 325 | + PSQL_CONF_FILE = "${paths.pgconfigFile}"; |
| 326 | + PSQL16_BINDIR = "${basePackages.psql_16.bin}"; |
| 327 | + PSQLORIOLEDB17_BINDIR = "${basePackages.psql_orioledb-17.bin}"; |
| 328 | + PGSODIUM_GETKEY = "${paths.getkeyScript}"; |
| 329 | + READREPL_CONF_FILE = "${paths.readReplicaConfigFile}"; |
| 330 | + LOGGING_CONF_FILE = "${paths.loggingConfigFile}"; |
| 331 | + SUPAUTILS_CONF_FILE = "${paths.supautilsConfigFile}"; |
| 332 | + PG_HBA = "${paths.pgHbaConfigFile}"; |
| 333 | + PG_IDENT = "${paths.pgIdentConfigFile}"; |
| 334 | + LOCALES = "${localeArchive}"; |
| 335 | + EXTENSION_CUSTOM_SCRIPTS_DIR = "${paths.postgresqlExtensionCustomScriptsPath}"; |
| 336 | + MECAB_LIB = "${basePackages.psql_15.exts.pgroonga}/lib/groonga/plugins/tokenizers/tokenizer_mecab.so"; |
| 337 | + GROONGA_DIR = "${supabase-groonga}"; |
| 338 | + MIGRATIONS_DIR = "${paths.migrationsDir}"; |
| 339 | + POSTGRESQL_SCHEMA_SQL = "${paths.postgresqlSchemaSql}"; |
| 340 | + PGBOUNCER_AUTH_SCHEMA_SQL = "${paths.pgbouncerAuthSchemaSql}"; |
| 341 | + STAT_EXTENSION_SQL = "${paths.statExtensionSql}"; |
| 342 | + CURRENT_SYSTEM = "${system}"; |
| 343 | + } // extraSubstitutions; # Merge in any extra substitutions |
| 344 | + in pkgs.runCommand name { |
| 345 | + inherit (paths) migrationsDir postgresqlSchemaSql pgbouncerAuthSchemaSql statExtensionSql; |
| 346 | + } '' |
| 347 | + set -x |
| 348 | + mkdir -p $out/bin $out/etc/postgresql-custom $out/etc/postgresql $out/extension-custom-scripts |
| 349 | + |
| 350 | + # Copy config files with error handling |
| 351 | + cp ${paths.supautilsConfigFile} $out/etc/postgresql-custom/supautils.conf || { echo "Failed to copy supautils.conf"; exit 1; } |
| 352 | + cp ${paths.pgconfigFile} $out/etc/postgresql/postgresql.conf || { echo "Failed to copy postgresql.conf"; exit 1; } |
| 353 | + cp ${paths.loggingConfigFile} $out/etc/postgresql-custom/logging.conf || { echo "Failed to copy logging.conf"; exit 1; } |
| 354 | + cp ${paths.readReplicaConfigFile} $out/etc/postgresql-custom/read-replica.conf || { echo "Failed to copy read-replica.conf"; exit 1; } |
| 355 | + cp ${paths.pgHbaConfigFile} $out/etc/postgresql/pg_hba.conf || { echo "Failed to copy pg_hba.conf"; exit 1; } |
| 356 | + cp ${paths.pgIdentConfigFile} $out/etc/postgresql/pg_ident.conf || { echo "Failed to copy pg_ident.conf"; exit 1; } |
| 357 | + cp -r ${paths.postgresqlExtensionCustomScriptsPath}/* $out/extension-custom-scripts/ || { echo "Failed to copy custom scripts"; exit 1; } |
| 358 | + |
| 359 | + echo "Copy operation completed" |
| 360 | + chmod 644 $out/etc/postgresql-custom/supautils.conf |
| 361 | + chmod 644 $out/etc/postgresql/postgresql.conf |
| 362 | + chmod 644 $out/etc/postgresql-custom/logging.conf |
| 363 | + chmod 644 $out/etc/postgresql/pg_hba.conf |
| 364 | +
|
| 365 | + substitute ${./nix/tools/run-server.sh.in} $out/bin/start-postgres-server \ |
| 366 | + ${builtins.concatStringsSep " " (builtins.attrValues (builtins.mapAttrs |
| 367 | + (name: value: "--subst-var-by '${name}' '${value}'") |
| 368 | + substitutions |
| 369 | + ))} |
| 370 | + chmod +x $out/bin/start-postgres-server |
| 371 | + ''; |
| 372 | + |
263 | 373 | # The base set of packages that we export from this Nix Flake, that can |
264 | 374 | # be used with 'nix build'. Don't use the names listed below; check the |
265 | 375 | # name in 'nix flake show' in order to make sure exactly what name you |
|
381 | 491 | supabase_groonga = supabase-groonga; |
382 | 492 | pg_regress = makePgRegress activeVersion; |
383 | 493 | # Start a version of the server. |
384 | | - start-server = |
385 | | - let |
386 | | - migrationsDir = builtins.path { |
387 | | - name = "migrations"; |
388 | | - path = ./migrations/db; |
389 | | - }; |
390 | | - postgresqlSchemaSql = builtins.path { |
391 | | - name = "postgresql-schema"; |
392 | | - path = ./nix/tools/postgresql_schema.sql; |
393 | | - }; |
394 | | - pgbouncerAuthSchemaSql = builtins.path { |
395 | | - name = "pgbouncer-auth-schema"; |
396 | | - path = ./ansible/files/pgbouncer_config/pgbouncer_auth_schema.sql; |
397 | | - }; |
398 | | - statExtensionSql = builtins.path { |
399 | | - name = "stat-extension"; |
400 | | - path = ./ansible/files/stat_extension.sql; |
401 | | - }; |
402 | | - pgconfigFile = builtins.path { |
403 | | - name = "postgresql.conf"; |
404 | | - path = ./ansible/files/postgresql_config/postgresql.conf.j2; |
405 | | - }; |
406 | | - supautilsConfigFile = builtins.path { |
407 | | - name = "supautils.conf"; |
408 | | - path = ./ansible/files/postgresql_config/supautils.conf.j2; |
409 | | - }; |
410 | | - loggingConfigFile = builtins.path { |
411 | | - name = "logging.conf"; |
412 | | - path = ./ansible/files/postgresql_config/postgresql-csvlog.conf; |
413 | | - }; |
414 | | - readReplicaConfigFile = builtins.path { |
415 | | - name = "readreplica.conf"; |
416 | | - path = ./ansible/files/postgresql_config/custom_read_replica.conf.j2; |
417 | | - }; |
418 | | - pgHbaConfigFile = builtins.path { |
419 | | - name = "pg_hba.conf"; |
420 | | - path = ./ansible/files/postgresql_config/pg_hba.conf.j2; |
421 | | - }; |
422 | | - pgIdentConfigFile = builtins.path { |
423 | | - name = "pg_ident.conf"; |
424 | | - path = ./ansible/files/postgresql_config/pg_ident.conf.j2; |
425 | | - }; |
426 | | - postgresqlExtensionCustomScriptsPath = builtins.path { |
427 | | - name = "extension-custom-scripts"; |
428 | | - path = ./ansible/files/postgresql_extension_custom_scripts; |
429 | | - }; |
430 | | - getkeyScript = builtins.path { |
431 | | - name = "pgsodium_getkey.sh"; |
432 | | - path = ./nix/tests/util/pgsodium_getkey.sh; |
433 | | - }; |
434 | | - localeArchive = if pkgs.stdenv.isDarwin |
435 | | - then "${pkgs.darwin.locale}/share/locale" |
436 | | - else "${pkgs.glibcLocales}/lib/locale/locale-archive"; |
437 | | - in |
438 | | - pkgs.runCommand "start-postgres-server" { |
439 | | - inherit migrationsDir postgresqlSchemaSql pgbouncerAuthSchemaSql statExtensionSql; |
440 | | - } '' |
441 | | - set -x |
442 | | - mkdir -p $out/bin $out/etc/postgresql-custom $out/etc/postgresql $out/extension-custom-scripts |
443 | | - cp ${supautilsConfigFile} $out/etc/postgresql-custom/supautils.conf || { echo "Failed to copy supautils.conf"; exit 1; } |
444 | | - cp ${pgconfigFile} $out/etc/postgresql/postgresql.conf || { echo "Failed to copy postgresql.conf"; exit 1; } |
445 | | - cp ${loggingConfigFile} $out/etc/postgresql-custom/logging.conf || { echo "Failed to copy logging.conf"; exit 1; } |
446 | | - cp ${readReplicaConfigFile} $out/etc/postgresql-custom/read-replica.conf || { echo "Failed to copy read-replica.conf"; exit 1; } |
447 | | - cp ${pgHbaConfigFile} $out/etc/postgresql/pg_hba.conf || { echo "Failed to copy pg_hba.conf"; exit 1; } |
448 | | - cp ${pgIdentConfigFile} $out/etc/postgresql/pg_ident.conf || { echo "Failed to copy pg_ident.conf"; exit 1; } |
449 | | - cp -r ${postgresqlExtensionCustomScriptsPath}/* $out/extension-custom-scripts/ || { echo "Failed to copy custom scripts"; exit 1; } |
450 | | - echo "Copy operation completed" |
451 | | - chmod 644 $out/etc/postgresql-custom/supautils.conf |
452 | | - chmod 644 $out/etc/postgresql/postgresql.conf |
453 | | - chmod 644 $out/etc/postgresql-custom/logging.conf |
454 | | - chmod 644 $out/etc/postgresql/pg_hba.conf |
455 | | - substitute ${./nix/tools/run-server.sh.in} $out/bin/start-postgres-server \ |
456 | | - --subst-var-by 'SHELL_PATH' '${pkgs.bash}/bin/bash' \ |
457 | | - --subst-var-by 'PGSQL_DEFAULT_PORT' '${pgsqlDefaultPort}' \ |
458 | | - --subst-var-by 'PGSQL_SUPERUSER' '${pgsqlSuperuser}' \ |
459 | | - --subst-var-by 'PSQL15_BINDIR' '${basePackages.psql_15.bin}' \ |
460 | | - --subst-var-by 'PSQL_CONF_FILE' $out/etc/postgresql/postgresql.conf \ |
461 | | - --subst-var-by 'PSQL16_BINDIR' '${basePackages.psql_16.bin}' \ |
462 | | - --subst-var-by 'PSQLORIOLEDB17_BINDIR' '${basePackages.psql_orioledb-17.bin}' \ |
463 | | - --subst-var-by 'PGSODIUM_GETKEY' '${getkeyScript}' \ |
464 | | - --subst-var-by 'READREPL_CONF_FILE' "$out/etc/postgresql-custom/read-replica.conf" \ |
465 | | - --subst-var-by 'LOGGING_CONF_FILE' "$out/etc/postgresql-custom/logging.conf" \ |
466 | | - --subst-var-by 'SUPAUTILS_CONF_FILE' "$out/etc/postgresql-custom/supautils.conf" \ |
467 | | - --subst-var-by 'PG_HBA' "$out/etc/postgresql/pg_hba.conf" \ |
468 | | - --subst-var-by 'PG_IDENT' "$out/etc/postgresql/pg_ident.conf" \ |
469 | | - --subst-var-by 'LOCALES' '${localeArchive}' \ |
470 | | - --subst-var-by 'EXTENSION_CUSTOM_SCRIPTS_DIR' "$out/extension-custom-scripts" \ |
471 | | - --subst-var-by 'MECAB_LIB' '${basePackages.psql_15.exts.pgroonga}/lib/groonga/plugins/tokenizers/tokenizer_mecab.so' \ |
472 | | - --subst-var-by 'GROONGA_DIR' '${supabase-groonga}' \ |
473 | | - --subst-var-by 'MIGRATIONS_DIR' '${migrationsDir}' \ |
474 | | - --subst-var-by 'POSTGRESQL_SCHEMA_SQL' '${postgresqlSchemaSql}' \ |
475 | | - --subst-var-by 'PGBOUNCER_AUTH_SCHEMA_SQL' '${pgbouncerAuthSchemaSql}' \ |
476 | | - --subst-var-by 'STAT_EXTENSION_SQL' '${statExtensionSql}' \ |
477 | | - --subst-var-by 'CURRENT_SYSTEM' '${system}' |
478 | | -
|
479 | | - chmod +x $out/bin/start-postgres-server |
480 | | - ''; |
| 494 | + start-server = makePostgresDevSetup { |
| 495 | + inherit pkgs; |
| 496 | + name = "start-postgres-server"; |
| 497 | + }; |
481 | 498 |
|
482 | 499 | # Start a version of the client and runs migrations script on server. |
483 | 500 | start-client = |
|
596 | 613 | sqlTests = ./nix/tests/smoke; |
597 | 614 | pg_prove = pkgs.perlPackages.TAPParserSourceHandlerpgTAP; |
598 | 615 | pg_regress = basePackages.pg_regress; |
599 | | - start-postgres-server-bin = basePackages.start-server; |
| 616 | + getkey-script = pkgs.writeScriptBin "pgsodium-getkey" '' |
| 617 | + #!${pkgs.bash}/bin/bash |
| 618 | + set -euo pipefail |
| 619 | + |
| 620 | + # Default to a path in /tmp if no argument is provided |
| 621 | + KEY_FILE=''${1:-"/tmp/pgsodium.key"} |
| 622 | + KEY_DIR=$(dirname "$KEY_FILE") |
| 623 | + |
| 624 | + # Ensure key directory exists with explicit error handling |
| 625 | + if ! mkdir -p "$KEY_DIR" 2>/dev/null; then |
| 626 | + echo "Warning: Could not create key directory $KEY_DIR, using /tmp" >&2 |
| 627 | + KEY_FILE="/tmp/pgsodium.key" |
| 628 | + fi |
| 629 | + |
| 630 | + # Generate key if it doesn't exist |
| 631 | + if [[ ! -f "$KEY_FILE" ]]; then |
| 632 | + # Try dd first, fallback to openssl |
| 633 | + if ! (dd if=/dev/urandom bs=32 count=1 2>/dev/null | od -A n -t x1 | tr -d ' \n' > "$KEY_FILE"); then |
| 634 | + if ! (openssl rand -hex 32 > "$KEY_FILE"); then |
| 635 | + echo "00000000000000000000000000000000" > "$KEY_FILE" |
| 636 | + echo "Warning: Using fallback key" >&2 |
| 637 | + fi |
| 638 | + fi |
| 639 | + fi |
| 640 | + |
| 641 | + if [[ -f "$KEY_FILE" ]]; then |
| 642 | + cat "$KEY_FILE" |
| 643 | + else |
| 644 | + echo "00000000000000000000000000000000" |
| 645 | + echo "Warning: Using default key" >&2 |
| 646 | + fi |
| 647 | + ''; |
| 648 | + # Use the shared setup but with a test-specific name |
| 649 | + start-postgres-server-bin = makePostgresDevSetup { |
| 650 | + inherit pkgs; |
| 651 | + name = "start-postgres-server-test"; |
| 652 | + extraSubstitutions = { |
| 653 | + PGSODIUM_GETKEY = "${getkey-script}/bin/pgsodium-getkey"; |
| 654 | + }; |
| 655 | + }; |
| 656 | + |
600 | 657 | getVersionArg = pkg: |
601 | 658 | let |
602 | 659 | name = pkg.version; |
|
610 | 667 | { |
611 | 668 | nativeBuildInputs = with pkgs; [ |
612 | 669 | coreutils bash pgpkg pg_prove pg_regress procps |
613 | | - start-postgres-server-bin which |
| 670 | + start-postgres-server-bin which getkey-script |
614 | 671 | ]; |
615 | 672 | } '' |
616 | | - set -e |
617 | | - echo "Contents of nativeBuildInputs PATH:" |
618 | | - echo $PATH |
619 | | - echo "Checking start-postgres-server:" |
620 | | - which start-postgres-server |
621 | | - ls -l $(which start-postgres-server) |
622 | | - file $(which start-postgres-server) |
623 | | - # echo "Creating the getKeyScript..." |
624 | | - # cat > getKeyScript.sh <<'EOF' |
625 | | - # #!/usr/bin/env bash |
626 | | - # set -euo pipefail |
627 | | -
|
628 | | - # if [[ ! -f "$KEY_FILE" ]]; then |
629 | | - # head -c 32 /dev/urandom | od -A n -t x1 | tr -d ' \n' > "$KEY_FILE" |
630 | | - # fi |
631 | | - # cat "$KEY_FILE" |
632 | | - # EOF |
633 | | -
|
634 | | - # Make the script executable |
635 | | - ${start-postgres-server-bin}/bin/start-postgres-server ${getVersionArg pgpkg} --daemonize |
636 | | -
|
637 | | - for i in {1..60}; do |
638 | | - if pg_isready -h localhost -p 5435 -U supabase_admin -q; then |
639 | | - echo "PostgreSQL is ready" |
640 | | - break |
641 | | - fi |
642 | | - sleep 1 |
643 | | - if [ $i -eq 60 ]; then |
644 | | - echo "PostgreSQL failed to start" |
645 | | - exit 1 |
646 | | - fi |
647 | | - done |
648 | | -
|
649 | | -
|
650 | | - if ! psql -p 5435 -h localhost --no-password --username=supabase_admin -d postgres -v ON_ERROR_STOP=1 -Xaf ${./nix/tests/prime.sql}; then |
651 | | - echo "Error executing SQL file" |
652 | | - exit 1 |
653 | | - fi |
654 | | -
|
655 | | - mkdir -p $out/regression_output |
656 | | - if ! pg_regress \ |
657 | | - --use-existing \ |
658 | | - --dbname=postgres \ |
659 | | - --inputdir=${./nix/tests} \ |
660 | | - --outputdir=$out/regression_output \ |
661 | | - --host=localhost \ |
662 | | - --port=5435 \ |
663 | | - --user=supabase_admin \ |
664 | | - $(ls ${./nix/tests/sql} | sed -e 's/\..*$//' | sort ); then |
665 | | - echo "pg_regress tests failed" |
666 | | - exit 1 |
667 | | - fi |
668 | | -
|
669 | | - # Copy logs to output |
670 | | - for logfile in $(find /tmp -name postgresql.log -type f); do |
671 | | - cp "$logfile" $out/postgresql.log |
672 | | - done |
673 | | - exit 0 |
| 673 | + set -e |
| 674 | + ${start-postgres-server-bin}/bin/start-postgres-server ${getVersionArg pgpkg} --daemonize |
| 675 | + |
| 676 | + for i in {1..60}; do |
| 677 | + if pg_isready -h localhost -p 5435 -U supabase_admin -q; then |
| 678 | + echo "PostgreSQL is ready" |
| 679 | + break |
| 680 | + fi |
| 681 | + sleep 1 |
| 682 | + if [ $i -eq 60 ]; then |
| 683 | + echo "PostgreSQL failed to start" |
| 684 | + exit 1 |
| 685 | + fi |
| 686 | + done |
| 687 | +
|
| 688 | + if ! psql -p 5435 -h localhost --no-password --username=supabase_admin -d postgres -v ON_ERROR_STOP=1 -Xaf ${./nix/tests/prime.sql}; then |
| 689 | + echo "Error executing SQL file" |
| 690 | + exit 1 |
| 691 | + fi |
| 692 | +
|
| 693 | + mkdir -p $out/regression_output |
| 694 | + if ! pg_regress \ |
| 695 | + --use-existing \ |
| 696 | + --dbname=postgres \ |
| 697 | + --inputdir=${./nix/tests} \ |
| 698 | + --outputdir=$out/regression_output \ |
| 699 | + --host=localhost \ |
| 700 | + --port=5435 \ |
| 701 | + --user=supabase_admin \ |
| 702 | + $(ls ${./nix/tests/sql} | sed -e 's/\..*$//' | sort ); then |
| 703 | + echo "pg_regress tests failed" |
| 704 | + exit 1 |
| 705 | + fi |
| 706 | +
|
| 707 | + # Copy logs to output |
| 708 | + for logfile in $(find /tmp -name postgresql.log -type f); do |
| 709 | + cp "$logfile" $out/postgresql.log |
| 710 | + done |
| 711 | + exit 0 |
674 | 712 | ''; |
675 | 713 | in |
676 | 714 | rec { |
|
0 commit comments