Skip to content

feat: multi-ext-versions-pgrcron #1549

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 27 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
054c599
feat: multi-ext-versios-pgrcron
samrose Apr 15, 2025
c8aefa8
feat: add version to drv and patch instead of postPatch rewrite
samrose Apr 15, 2025
45d5fce
chore: newline
samrose Apr 15, 2025
c29cb2d
feat: auto create multi version
samrose Apr 15, 2025
8d64f01
chore: do not re-intro maintainers here not needed
samrose Apr 15, 2025
684420f
chore: bump version
samrose Apr 16, 2025
7ea04ee
feat: pg_cron version switcher in pkg and prestart
samrose Apr 24, 2025
6248e88
test: a tmp test for this branch to test older versions
samrose Apr 24, 2025
e26afc5
test: temp test for ext handling
samrose Apr 24, 2025
de12b8b
test: instead of patch, add prior to start of machine in testinfra
samrose Apr 24, 2025
e7b7245
test: only run on pg 15 for this test, as 1.3.1 limited to 15
samrose Apr 24, 2025
5af1724
feat: use jq from nixpkgs
samrose Apr 24, 2025
fb3fee2
test: handle braces properly
samrose Apr 24, 2025
67a8076
test: propagate errors from any failure
samrose Apr 25, 2025
2bd7b6d
test: more logging for healthcheck
samrose Apr 25, 2025
4535b50
chore: bump version
samrose Apr 25, 2025
66515f8
test: adding even more logging
samrose Apr 25, 2025
7c00cd2
test: extend logging more to see what happens when pg starts
samrose Apr 25, 2025
7990c3c
test: handle lib extension names per system
samrose Apr 28, 2025
90d79b4
chore: bump versions
samrose Apr 28, 2025
1f4f065
test: more debugging
samrose Apr 28, 2025
4e5c3f4
test: move logging here
samrose Apr 28, 2025
4ab837e
test: try direct
samrose Apr 28, 2025
b8c9e31
test: use the right alias on machine
samrose Apr 28, 2025
65ef069
test: do not unpack result
samrose Apr 29, 2025
c2631e8
test: reorg and print logs while waiting continue on other checks whe…
samrose Apr 29, 2025
164752b
test: restructure checks to avoid race
samrose Apr 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/testinfra-nix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,13 @@ jobs:
df -h / # Display available space

- name: Run tests
timeout-minutes: 10
timeout-minutes: 30
env:
AMI_NAME: "supabase-postgres-${{ steps.random.outputs.random_string }}"
run: |
# TODO: use poetry for pkg mgmt
pip3 install boto3 boto3-stubs[essential] docker ec2instanceconnectcli pytest pytest-testinfra[paramiko,docker] requests
pytest -vv -s testinfra/test_ami_nix.py
pytest -vvvv -s testinfra/test_ami_nix.py

- name: Cleanup resources on build cancellation
if: ${{ cancelled() }}
Expand Down
55 changes: 55 additions & 0 deletions ansible/files/postgres_prestart.sh.j2
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,62 @@ update_orioledb_buffers() {
fi
}

check_extensions_file() {
local extensions_file="/root/pg_extensions.json"
if [ ! -f "$extensions_file" ]; then
echo "extensions: No extensions file found, skipping extensions versions check"
return 1
fi
return 0
}

get_pg_cron_version() {
if ! check_extensions_file; then
return
fi

local version
version=$(sudo -u postgres /var/lib/postgresql/.nix-profile/bin/jq -r '.pg_cron // empty' "/root/pg_extensions.json")
if [ -z "$version" ]; then
echo "pg_cron: Not specified in extensions file"
return
fi

if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "pg_cron: Invalid version format: $version"
return
fi

echo "$version"
}

switch_pg_cron_version() {
local version="$1"
local switch_script="/var/lib/postgresql/.nix-profile/bin/switch_pg_cron_version"

if [ ! -x "$switch_script" ]; then
echo "pg_cron: No version switch script available"
return
fi

echo "pg_cron: Switching to version $version"
sudo -u postgres "$switch_script" "$version"
echo "pg_cron: Version switch completed"
}

handle_pg_cron_version() {
local version
version=$(get_pg_cron_version)
if [ -n "$version" ]; then
switch_pg_cron_version "$version"
fi
}

main() {
# 1. pg_cron version handling
handle_pg_cron_version

# 2. orioledb handling
local has_orioledb=$(check_orioledb_enabled)
if [ "$has_orioledb" -lt 1 ]; then
return 0
Expand Down
6 changes: 6 additions & 0 deletions ansible/tasks/stage2-setup-postgres.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@
shell: |
sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:supabase/postgres/{{ git_commit_sha }}#{{postgresql_version}}_src"
when: stage2_nix

- name: Install jq from nix binary cache
become: yes
shell: |
sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install nixpkgs#jq"
when: stage2_nix

- name: Set ownership and permissions for /etc/ssl/private
become: yes
Expand Down
6 changes: 3 additions & 3 deletions ansible/vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ postgres_major:

# Full version strings for each major version
postgres_release:
postgresorioledb-17: "17.0.1.072-orioledb"
postgres17: "17.4.1.022"
postgres15: "15.8.1.079"
postgresorioledb-17: "17.0.1.067-orioledb-pgcron-4"
postgres17: "17.4.1.022-pgcron-4"
postgres15: "15.8.1.079-pgcron-4"

# Non Postgres Extensions
pgbouncer_release: "1.19.0"
Expand Down
31 changes: 31 additions & 0 deletions nix/ext/pg_cron-1.3.1-pg15.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
diff --git a/src/pg_cron.c b/src/pg_cron.c
index e0ca973..4d51b2c 100644
--- a/src/pg_cron.c
+++ b/src/pg_cron.c
@@ -14,6 +14,8 @@
#include <sys/resource.h>

#include "postgres.h"
+#include "commands/async.h"
+#include "miscadmin.h"
#include "fmgr.h"

/* these are always necessary for a bgworker */
@@ -1908,7 +1910,7 @@ CronBackgroundWorker(Datum main_arg)
/* Post-execution cleanup. */
disable_timeout(STATEMENT_TIMEOUT, false);
CommitTransactionCommand();
- ProcessCompletedNotifies();
+ /* ProcessCompletedNotifies removed */
pgstat_report_activity(STATE_IDLE, command);
pgstat_report_stat(true);

@@ -2025,7 +2027,7 @@ ExecuteSqlString(const char *sql)
*/
oldcontext = MemoryContextSwitchTo(parsecontext);
#if PG_VERSION_NUM >= 100000
- querytree_list = pg_analyze_and_rewrite(parsetree, sql, NULL, 0,NULL);
+ querytree_list = pg_analyze_and_rewrite_fixedparams(parsetree, sql, NULL, 0, NULL);
#else
querytree_list = pg_analyze_and_rewrite(parsetree, sql, NULL, 0);
#endif
152 changes: 134 additions & 18 deletions nix/ext/pg_cron.nix
Original file line number Diff line number Diff line change
@@ -1,31 +1,147 @@
{ lib, stdenv, fetchFromGitHub, postgresql }:

stdenv.mkDerivation rec {
pname = "pg_cron";
version = "1.6.4";
let
allVersions = {
"1.3.1" = {
rev = "v1.3.1";
hash = "sha256-rXotNOtQNmA55ErNxGoNSKZ0pP1uxEVlDGITFHuqGG4=";
patches = [ ./pg_cron-1.3.1-pg15.patch ];
};
"1.4.2" = {
rev = "v1.4.2";
hash = "sha256-P0Fd10Q1p+KrExb35G6otHpc6pD61WnMll45H2jkevM=";
};
"1.6.4" = {
rev = "v1.6.4";
hash = "sha256-t1DpFkPiSfdoGG2NgNT7g1lkvSooZoRoUrix6cBID40=";
};
"1.5.2" = {
rev = "v1.5.2";
hash = "sha256-+quVWbKJy6wXpL/zwTk5FF7sYwHA7I97WhWmPO/HSZ4=";
};
};

# Simple version string that concatenates all versions with dashes
versionString = "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings ["."] ["-"] v) (lib.attrNames allVersions));

mkPgCron = pgCronVersion: { rev, hash, patches ? [] }: stdenv.mkDerivation {
pname = "pg_cron";
version = "${pgCronVersion}-pg${lib.versions.major postgresql.version}";

buildInputs = [ postgresql ];
inherit patches;

src = fetchFromGitHub {
owner = "citusdata";
repo = "pg_cron";
inherit rev hash;
};

buildInputs = [ postgresql ];
buildPhase = ''
make PG_CONFIG=${postgresql}/bin/pg_config

# Create version-specific SQL file
cp pg_cron.sql pg_cron--${pgCronVersion}.sql

src = fetchFromGitHub {
owner = "citusdata";
repo = pname;
rev = "v${version}";
hash = "sha256-t1DpFkPiSfdoGG2NgNT7g1lkvSooZoRoUrix6cBID40=";
# Create versioned control file with modified module path
sed -e "/^default_version =/d" \
-e "s|^module_pathname = .*|module_pathname = '\$libdir/pg_cron'|" \
pg_cron.control > pg_cron--${pgCronVersion}.control
'';

installPhase = ''
mkdir -p $out/{lib,share/postgresql/extension,bin}

# Install versioned library
install -Dm755 pg_cron${postgresql.dlSuffix} $out/lib/pg_cron-${pgCronVersion}${postgresql.dlSuffix}

# Install version-specific files
install -Dm644 pg_cron--${pgCronVersion}.sql $out/share/postgresql/extension/
install -Dm644 pg_cron--${pgCronVersion}.control $out/share/postgresql/extension/

# Install upgrade scripts
find . -name 'pg_cron--*--*.sql' -exec install -Dm644 {} $out/share/postgresql/extension/ \;
'';
};

getVersions = pg:
if lib.versionAtLeast pg.version "17"
then { "1.6.4" = allVersions."1.6.4"; }
else allVersions;

allVersionsForPg = lib.mapAttrs mkPgCron (getVersions postgresql);

in
stdenv.mkDerivation {
pname = "pg_cron-all";
version = versionString;

buildInputs = lib.attrValues allVersionsForPg;

dontUnpack = true;
dontConfigure = true;
dontBuild = true;

installPhase = ''
mkdir -p $out/{lib,share/postgresql/extension}
mkdir -p $out/{lib,share/postgresql/extension,bin}

# Install all versions
for drv in ${lib.concatStringsSep " " (lib.attrValues allVersionsForPg)}; do
ln -sv $drv/lib/* $out/lib/
cp -v --no-clobber $drv/share/postgresql/extension/* $out/share/postgresql/extension/ || true
done

# Create default symlinks
latest_control=$(ls -v $out/share/postgresql/extension/pg_cron--*.control | tail -n1)
latest_version=$(basename "$latest_control" | sed -E 's/pg_cron--([0-9.]+).control/\1/')

# Create main control file with default_version
echo "default_version = '$latest_version'" > $out/share/postgresql/extension/pg_cron.control
cat "$latest_control" >> $out/share/postgresql/extension/pg_cron.control

# Library symlink
ln -sfnv pg_cron-$latest_version${postgresql.dlSuffix} $out/lib/pg_cron${postgresql.dlSuffix}

# Create version switcher script
cat > $out/bin/switch_pg_cron_version <<'EOF'
#!/bin/sh
set -e

if [ $# -ne 1 ]; then
echo "Usage: $0 <version>"
echo "Example: $0 1.4.2"
exit 1
fi

VERSION=$1
LIB_DIR=$(dirname "$0")/../lib

# Use platform-specific extension
if [ "$(uname)" = "Darwin" ]; then
EXT=".dylib"
else
EXT=".so"
fi

# Check if version exists
if [ ! -f "$LIB_DIR/pg_cron-$VERSION$EXT" ]; then
echo "Error: Version $VERSION not found"
exit 1
fi

# Update library symlink
ln -sfnv "pg_cron-$VERSION$EXT" "$LIB_DIR/pg_cron$EXT"

echo "Successfully switched pg_cron to version $VERSION"
EOF

cp *${postgresql.dlSuffix} $out/lib
cp *.sql $out/share/postgresql/extension
cp *.control $out/share/postgresql/extension
chmod +x $out/bin/switch_pg_cron_version
'';

meta = with lib; {
description = "Run Cron jobs through PostgreSQL";
homepage = "https://github.com/citusdata/pg_cron";
changelog = "https://github.com/citusdata/pg_cron/raw/v${version}/CHANGELOG.md";
platforms = postgresql.meta.platforms;
license = licenses.postgresql;
description = "Run Cron jobs through PostgreSQL (multi-version compatible)";
homepage = "https://github.com/citusdata/pg_cron";
platforms = postgresql.meta.platforms;
license = licenses.postgresql;
};
}
Loading
Loading