Skip to content

Commit aebebae

Browse files
authored
Merge pull request #2 from NotHimmel/main
Add pg_mooncake.enable_bgworker GUC to control bgworker registration
2 parents 1095906 + 5cc1713 commit aebebae

16 files changed

Lines changed: 1207 additions & 27 deletions

File tree

‎.dockerignore‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Build artifacts
2+
target/
3+
**/target/
4+
*.o
5+
*.so
6+
*.rlib
7+
*.d
8+
9+
# Submodule build artifacts (we rebuild inside the image)
10+
ivy_duckdb/build/
11+
ivy_duckdb/third_party/duckdb/build/
12+
ivy_duckdb/*.so
13+
ivy_moonlink/target/
14+
ivy_duckdb_mooncake/build/
15+
16+
# Cargo
17+
.cargo/
18+
**/.cargo/
19+
20+
# Editor / IDE
21+
.vscode/
22+
.idea/
23+
.devcontainer/
24+
*.swp
25+
*.swo
26+
27+
# OS
28+
.DS_Store
29+
Thumbs.db
30+
31+
# Spec/plan/memory files (untracked, dev-local)
32+
docs/
33+
34+
# Other
35+
.git/
36+
.github/
37+
.gitignore
38+
.gitmodules
39+
40+
# But keep .gitmodules — needed to know submodule layout? No, COPY explicitly
41+
# names submodules; .gitmodules not needed at build time.
42+
43+
# Local test/log
44+
*.log
45+
/tmp/

‎.github/workflows/docker.yml‎

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: docker
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ['v*']
7+
pull_request:
8+
branches: [main]
9+
workflow_dispatch:
10+
11+
env:
12+
REGISTRY: ghcr.io
13+
IMAGE_NAME: ${{ github.repository_owner }}/ivy_mooncake
14+
IVORYSQL_BASE: registry.highgo.com/ivorysql/ivorysql:5.3-ubi8
15+
16+
jobs:
17+
build:
18+
runs-on: ubuntu-latest
19+
permissions:
20+
contents: read
21+
packages: write
22+
steps:
23+
- name: Checkout (with submodules)
24+
uses: actions/checkout@v4
25+
with:
26+
submodules: recursive
27+
28+
- name: Set up Docker Buildx
29+
uses: docker/setup-buildx-action@v3
30+
31+
- name: Login to GHCR
32+
if: github.event_name != 'pull_request'
33+
uses: docker/login-action@v3
34+
with:
35+
registry: ${{ env.REGISTRY }}
36+
username: ${{ github.actor }}
37+
password: ${{ secrets.GITHUB_TOKEN }}
38+
39+
- name: Extract metadata
40+
id: meta
41+
uses: docker/metadata-action@v5
42+
with:
43+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
44+
tags: |
45+
type=ref,event=branch,suffix=-ubi8
46+
type=ref,event=pr,suffix=-ubi8
47+
type=semver,pattern={{version}},suffix=-ubi8
48+
type=semver,pattern={{major}}.{{minor}},suffix=-ubi8
49+
type=sha,prefix=sha-,suffix=-ubi8
50+
type=raw,value=5.3-ubi8,enable={{is_default_branch}}
51+
type=raw,value=latest,enable={{is_default_branch}}
52+
53+
- name: Build and push (amd64)
54+
uses: docker/build-push-action@v5
55+
with:
56+
context: .
57+
file: ./Dockerfile
58+
platforms: linux/amd64
59+
build-args: |
60+
IVORYSQL_BASE=${{ env.IVORYSQL_BASE }}
61+
push: ${{ github.event_name != 'pull_request' }}
62+
tags: ${{ steps.meta.outputs.tags }}
63+
labels: ${{ steps.meta.outputs.labels }}
64+
cache-from: type=gha
65+
cache-to: type=gha,mode=max
66+
67+
smoke-test:
68+
runs-on: ubuntu-latest
69+
if: github.event_name == 'pull_request'
70+
needs: build
71+
steps:
72+
- uses: actions/checkout@v4
73+
with:
74+
submodules: recursive
75+
76+
- name: Build image
77+
run: |
78+
docker build \
79+
--build-arg IVORYSQL_BASE=${{ env.IVORYSQL_BASE }} \
80+
-t ivy_mooncake:test .
81+
82+
- name: Run container
83+
run: |
84+
docker run -d --name test \
85+
-e IVORYSQL_PASSWORD=password \
86+
ivy_mooncake:test
87+
for i in $(seq 1 60); do
88+
docker exec test pg_isready -U ivorysql -d postgres 2>/dev/null && { echo "ready in ${i}s"; break; }
89+
sleep 1
90+
done
91+
92+
- name: Verify CREATE EXTENSION pg_mooncake CASCADE
93+
run: |
94+
docker exec test psql -U ivorysql -d postgres -c "
95+
CREATE EXTENSION pg_mooncake CASCADE;
96+
SELECT extname, extversion FROM pg_extension WHERE extname IN ('pg_duckdb','pg_mooncake');
97+
"
98+
99+
- name: Verify mooncake.create_table E2E
100+
run: |
101+
docker exec test psql -U ivorysql -d postgres <<'SQL'
102+
CREATE TABLE t (id int PRIMARY KEY, v text);
103+
ALTER TABLE t REPLICA IDENTITY FULL;
104+
INSERT INTO t VALUES (1,'a'),(2,'b');
105+
CALL mooncake.create_table('t_mirror', 't');
106+
SELECT count(*) FROM t_mirror;
107+
SQL

‎.github/workflows/regression.yml‎

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
name: regression
2+
3+
# Run pgrx regression tests on every PR + manual dispatch.
4+
# Mirrors `make test` (which calls `cargo pgrx regress --resetdb`) inside
5+
# the project's Docker build stage so we exercise the real IvorySQL pg_config,
6+
# pg_duckdb install, and the bgworker codepath end-to-end.
7+
8+
on:
9+
pull_request:
10+
branches: [main]
11+
workflow_dispatch:
12+
13+
env:
14+
IVORYSQL_BASE: registry.highgo.com/ivorysql/ivorysql:5.3-ubi8
15+
TEST_IMAGE: ivy_mooncake:regress-${{ github.run_id }}
16+
17+
jobs:
18+
regress:
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 90
21+
permissions:
22+
contents: read
23+
steps:
24+
- name: Checkout (with submodules)
25+
uses: actions/checkout@v4
26+
with:
27+
submodules: recursive
28+
29+
- name: Set up Docker Buildx
30+
uses: docker/setup-buildx-action@v3
31+
32+
# Build the `build` stage of the project Dockerfile. That stage ends
33+
# with:
34+
# - /ivy_mooncake = source tree (incl. all 3 submodules)
35+
# - /etc/pgconfig = absolute path to IvorySQL pg_config
36+
# - pg_duckdb + libduckdb.so installed into IvorySQL libdir/sharedir
37+
# - rust 1.91.1 + cargo-pgrx 0.16.1 + `cargo pgrx init --pg18=$PG_CONFIG` done
38+
# Stopping at this stage means we can run `cargo pgrx regress` from the
39+
# same container without re-paying any build cost.
40+
- name: Build (Dockerfile target=build)
41+
uses: docker/build-push-action@v5
42+
with:
43+
context: .
44+
file: ./Dockerfile
45+
target: build
46+
load: true
47+
tags: ${{ env.TEST_IMAGE }}
48+
build-args: |
49+
IVORYSQL_BASE=${{ env.IVORYSQL_BASE }}
50+
cache-from: type=gha
51+
cache-to: type=gha,mode=max
52+
53+
- name: Run cargo pgrx regress (pg18)
54+
id: regress
55+
run: |
56+
mkdir -p _artifacts
57+
set -o pipefail
58+
docker run --rm \
59+
-v "$PWD/_artifacts:/out" \
60+
-w /ivy_mooncake \
61+
-e RUST_BACKTRACE=1 \
62+
-e CARGO_TERM_COLOR=always \
63+
"${{ env.TEST_IMAGE }}" \
64+
bash -c '
65+
set -eux
66+
67+
# PG refuses to run as root, so spin up an unprivileged user
68+
# (tester) and have it drive cargo pgrx regress.
69+
useradd -m -u 2000 -s /bin/bash tester
70+
71+
# Share /root/.cargo and /root/.rustup with tester via chmod
72+
# rather than cp -a / chown -R: on overlayfs chown forces a
73+
# copy_up of every file (~1GB doubling), and a full chown of
74+
# the build tree wastes minutes + GBs. chmod only flips
75+
# metadata bits.
76+
chmod o+rx /root
77+
chmod -R o+rX /root/.cargo /root/.rustup
78+
79+
# target/ from the image build is root-owned + stale once
80+
# cargo recompiles with different feature flags during regress,
81+
# so wipe it instead of chown-recursing.
82+
rm -rf /ivy_mooncake/target
83+
chown -R tester:tester /ivy_mooncake
84+
85+
# /out is a host-mounted volume owned by the host user; tester
86+
# would otherwise lack write perms.
87+
chown tester:tester /out
88+
89+
PG_CONFIG="$(cat /etc/pgconfig)"
90+
LIBDIR="$($PG_CONFIG --pkglibdir)"
91+
SHAREDIR="$($PG_CONFIG --sharedir)"
92+
chmod -R a+rwX "$LIBDIR" "$SHAREDIR/extension"
93+
94+
su - tester -c "
95+
set -eux
96+
# Share the root-owned cargo/rustup caches in place; per-user
97+
# pgrx state still goes under tester home.
98+
export CARGO_HOME=/root/.cargo
99+
export RUSTUP_HOME=/root/.rustup
100+
export PGRX_HOME=/home/tester/.pgrx
101+
export PATH=/root/.cargo/bin:\$PATH
102+
103+
cargo pgrx init --pg18=\"$PG_CONFIG\"
104+
cd /ivy_mooncake
105+
# pg_duckdb refuses to load unless it is in
106+
# shared_preload_libraries; the IvorySQL base also expects
107+
# liboracle_parser/ivorysql_ora at preload time.
108+
cargo pgrx regress --resetdb \
109+
--postgresql-conf \"shared_preload_libraries=liboracle_parser,ivorysql_ora,pg_duckdb,pg_mooncake\" \
110+
--postgresql-conf \"wal_level=logical\" \
111+
--postgresql-conf \"duckdb.allow_community_extensions=true\" \
112+
2>&1 | tee /out/regress.log
113+
"
114+
'
115+
116+
- name: Collect regression diffs on failure
117+
if: failure() && steps.regress.outcome == 'failure'
118+
run: |
119+
docker run --rm \
120+
-v "$PWD/_artifacts:/out" \
121+
-w /ivy_mooncake \
122+
"${{ env.TEST_IMAGE }}" \
123+
bash -c '
124+
set -eu
125+
# Best-effort: regression diffs land somewhere under the source
126+
# tree depending on pgrx version, so just grab everything that
127+
# could be useful for triage.
128+
find . -name regression.diffs -exec cp -v {} /out/ \; 2>/dev/null || true
129+
find . -name regression.out -exec cp -v {} /out/ \; 2>/dev/null || true
130+
find . -path "*/pg_regress/results/*" -exec cp -v {} /out/ \; 2>/dev/null || true
131+
# cargo target log (if any)
132+
find . -name "postmaster.log" -exec cp -v {} /out/ \; 2>/dev/null || true
133+
ls -la /out/ || true
134+
' || true
135+
136+
- name: Upload regression artifacts
137+
if: always()
138+
uses: actions/upload-artifact@v4
139+
with:
140+
name: regression-artifacts-${{ github.run_id }}
141+
path: _artifacts/
142+
if-no-files-found: ignore
143+
retention-days: 14

‎.gitignore‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,8 @@
33
/tests/pg_regress/regression.diffs
44
/tests/pg_regress/regression.out
55
/tests/pg_regress/results/
6+
7+
# Local-only: developer notes, machine-specific helpers, alt-base image
8+
docs/
9+
Dockerfile.ivorysql-base
10+
scripts/docker-relocate-data.sh

‎Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pgrx = "0.16.1"
2828
postgres.git = "https://github.com/Mooncake-Labs/rust-postgres.git"
2929
postgres-native-tls.git = "https://github.com/Mooncake-Labs/rust-postgres.git"
3030
regex = "1"
31+
serde_json = "1"
3132
tokio = "1.48"
3233

3334
[profile.release]

0 commit comments

Comments
 (0)