Skip to content

Commit 514fa14

Browse files
committed
Add PG extension build, server-auth, and infra updates
Add end-to-end support for building and publishing the pg_kalam PostgreSQL extension: two GitHub Actions jobs to build extension artifacts for x86_64 and aarch64, package/install scripts, and a docker_pg job to build/push multi-arch PG images. Introduce the pg/ workspace files, tests, Dockerfiles and packaging helpers. Add a new backend crate (kalamdb-server-auth) and make auth crate HTTP integration opt-in; update workspace members and dependencies (including tokio-postgres) and add a compact release profile (release-pg) for smaller extension .so builds. Update backend defaults to enable jemalloc and tweak auth features. Also improve docs/instructions (AGENTS.md and .github/copilot-instructions.md) with performance reminders and workflow tweaks, and apply various repo-wide code/dependency adjustments.
1 parent 1d29933 commit 514fa14

120 files changed

Lines changed: 8073 additions & 792 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/copilot-instructions.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ This file references the main `AGENTS.md` which contains:
1313

1414
Always refer to `AGENTS.md` for the most up-to-date guidelines and best practices.
1515

16+
Priority reminders from `AGENTS.md`:
17+
- Keep performance as a primary constraint, including compile-time and hot-path costs.
18+
- Batch related edits before running `cargo check` or `cargo build`.
19+
- For performance tests, report per-test runtime in seconds.
20+
- When adding dependencies, enable only the minimal required features.
21+
1622
## Active Technologies
1723
- Rust 1.90 (edition 2021) + DataFusion 40, Apache Arrow 52, Apache Parquet 52, Actix-Web 4, `kalamdb-store` EntityStore traits, `kalamdb-commons` system models (007-user-auth)
1824
- RocksDB 0.24 for buffered writes, Parquet files for flushed segments via StorageBackend abstraction (007-user-auth)

.github/workflows/release.yml

Lines changed: 273 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,178 @@ jobs:
936936
path: dist/${{ needs.read_version.outputs.version }}/*
937937
if-no-files-found: error
938938

939+
# ═══════════════════════════════════════════════════════════════════════════
940+
# PG EXTENSION - Build pg_kalam PostgreSQL extension for Linux
941+
# ═══════════════════════════════════════════════════════════════════════════
942+
build_pg_extension_x86_64:
943+
name: Build PG Extension Linux x86_64
944+
runs-on: ubuntu-latest
945+
needs: read_version
946+
947+
steps:
948+
- name: Checkout
949+
uses: actions/checkout@v6
950+
951+
- name: Build extension in Docker (x86_64 Bookworm)
952+
shell: bash
953+
run: |
954+
set -euo pipefail
955+
956+
# Build the builder image (Debian Bookworm — matches postgres:16-bookworm)
957+
docker build \
958+
-f pg/docker/Dockerfile.builder-base \
959+
-t pg-kalam-builder-x86 \
960+
.
961+
962+
# Compile extension inside the Bookworm container
963+
mkdir -p artifacts
964+
docker run --rm \
965+
-v "$PWD:/src:ro" \
966+
-v "$PWD/artifacts:/artifacts" \
967+
-e CARGO_INCREMENTAL=0 \
968+
-e RUSTFLAGS="-Cdebuginfo=0" \
969+
pg-kalam-builder-x86 \
970+
bash -c '
971+
cd /src && \
972+
cargo pgrx install \
973+
-p kalam-pg-extension \
974+
-c /usr/bin/pg_config \
975+
--no-default-features \
976+
--profile release-pg \
977+
-F pg16 && \
978+
cp /usr/lib/postgresql/16/lib/pg_kalam.so /artifacts/ && \
979+
cp /usr/share/postgresql/16/extension/pg_kalam.control /artifacts/ && \
980+
cp /usr/share/postgresql/16/extension/pg_kalam--*.sql /artifacts/
981+
'
982+
983+
- name: Package extension artifacts
984+
shell: bash
985+
run: |
986+
set -euo pipefail
987+
VERSION="${{ needs.read_version.outputs.version }}"
988+
PKG="pg_kalam-${VERSION}-pg16-linux-x86_64"
989+
mkdir -p "dist/${VERSION}/${PKG}"
990+
991+
cp artifacts/pg_kalam.so "dist/${VERSION}/${PKG}/"
992+
cp artifacts/pg_kalam.control "dist/${VERSION}/${PKG}/"
993+
cp artifacts/pg_kalam--*.sql "dist/${VERSION}/${PKG}/"
994+
995+
cat > "dist/${VERSION}/${PKG}/install.sh" << 'INSTALL_EOF'
996+
#!/usr/bin/env bash
997+
set -euo pipefail
998+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
999+
PG_CONFIG="${1:-pg_config}"
1000+
LIBDIR="$("$PG_CONFIG" --pkglibdir)"
1001+
SHAREDIR="$("$PG_CONFIG" --sharedir)/extension"
1002+
echo "Installing pg_kalam to $LIBDIR and $SHAREDIR ..."
1003+
install -m 755 "$SCRIPT_DIR/pg_kalam.so" "$LIBDIR/"
1004+
install -m 644 "$SCRIPT_DIR/pg_kalam.control" "$SHAREDIR/"
1005+
install -m 644 "$SCRIPT_DIR"/pg_kalam--*.sql "$SHAREDIR/"
1006+
echo "Done. Run: CREATE EXTENSION pg_kalam;"
1007+
INSTALL_EOF
1008+
chmod +x "dist/${VERSION}/${PKG}/install.sh"
1009+
1010+
(cd "dist/${VERSION}" && tar -czf "${PKG}.tar.gz" "${PKG}")
1011+
rm -rf "dist/${VERSION}/${PKG}"
1012+
1013+
ls -lh "dist/${VERSION}/"
1014+
1015+
- name: Upload artifacts
1016+
uses: actions/upload-artifact@v6
1017+
with:
1018+
name: dist-pg-extension-linux-x86_64
1019+
path: dist/${{ needs.read_version.outputs.version }}/*
1020+
if-no-files-found: error
1021+
1022+
build_pg_extension_aarch64:
1023+
name: Build PG Extension Linux ARM64
1024+
runs-on: ubuntu-latest
1025+
needs: read_version
1026+
1027+
steps:
1028+
- name: Checkout
1029+
uses: actions/checkout@v6
1030+
1031+
- name: Setup QEMU
1032+
uses: docker/setup-qemu-action@v3
1033+
1034+
- name: Setup Buildx
1035+
uses: docker/setup-buildx-action@v3
1036+
1037+
- name: Build extension in Docker (ARM64)
1038+
shell: bash
1039+
run: |
1040+
set -euo pipefail
1041+
VERSION="${{ needs.read_version.outputs.version }}"
1042+
1043+
# Build the builder image for ARM64 using QEMU emulation
1044+
docker buildx build \
1045+
--platform linux/arm64 \
1046+
--load \
1047+
-f pg/docker/Dockerfile.builder-base \
1048+
-t pg-kalam-builder-arm64 \
1049+
.
1050+
1051+
# Compile extension inside the ARM64 container
1052+
mkdir -p artifacts
1053+
docker run --rm --platform linux/arm64 \
1054+
-v "$PWD:/src:ro" \
1055+
-v "$PWD/artifacts:/artifacts" \
1056+
-e CARGO_INCREMENTAL=0 \
1057+
-e RUSTFLAGS="-Cdebuginfo=0" \
1058+
pg-kalam-builder-arm64 \
1059+
bash -c '
1060+
cd /src && \
1061+
cargo pgrx install \
1062+
-p kalam-pg-extension \
1063+
-c /usr/bin/pg_config \
1064+
--no-default-features \
1065+
--profile release-pg \
1066+
-F pg16 && \
1067+
cp /usr/lib/postgresql/16/lib/pg_kalam.so /artifacts/ && \
1068+
cp /usr/share/postgresql/16/extension/pg_kalam.control /artifacts/ && \
1069+
cp /usr/share/postgresql/16/extension/pg_kalam--*.sql /artifacts/
1070+
'
1071+
1072+
- name: Package extension artifacts
1073+
shell: bash
1074+
run: |
1075+
set -euo pipefail
1076+
VERSION="${{ needs.read_version.outputs.version }}"
1077+
PKG="pg_kalam-${VERSION}-pg16-linux-aarch64"
1078+
mkdir -p "dist/${VERSION}/${PKG}"
1079+
1080+
cp artifacts/pg_kalam.so "dist/${VERSION}/${PKG}/"
1081+
cp artifacts/pg_kalam.control "dist/${VERSION}/${PKG}/"
1082+
cp artifacts/pg_kalam--*.sql "dist/${VERSION}/${PKG}/"
1083+
1084+
cat > "dist/${VERSION}/${PKG}/install.sh" << 'INSTALL_EOF'
1085+
#!/usr/bin/env bash
1086+
set -euo pipefail
1087+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
1088+
PG_CONFIG="${1:-pg_config}"
1089+
LIBDIR="$("$PG_CONFIG" --pkglibdir)"
1090+
SHAREDIR="$("$PG_CONFIG" --sharedir)/extension"
1091+
echo "Installing pg_kalam to $LIBDIR and $SHAREDIR ..."
1092+
install -m 755 "$SCRIPT_DIR/pg_kalam.so" "$LIBDIR/"
1093+
install -m 644 "$SCRIPT_DIR/pg_kalam.control" "$SHAREDIR/"
1094+
install -m 644 "$SCRIPT_DIR"/pg_kalam--*.sql "$SHAREDIR/"
1095+
echo "Done. Run: CREATE EXTENSION pg_kalam;"
1096+
INSTALL_EOF
1097+
chmod +x "dist/${VERSION}/${PKG}/install.sh"
1098+
1099+
(cd "dist/${VERSION}" && tar -czf "${PKG}.tar.gz" "${PKG}")
1100+
rm -rf "dist/${VERSION}/${PKG}"
1101+
1102+
ls -lh "dist/${VERSION}/"
1103+
1104+
- name: Upload artifacts
1105+
uses: actions/upload-artifact@v6
1106+
with:
1107+
name: dist-pg-extension-linux-aarch64
1108+
path: dist/${{ needs.read_version.outputs.version }}/*
1109+
if-no-files-found: error
1110+
9391111
# ═══════════════════════════════════════════════════════════════════════════
9401112
# SMOKE TESTS - Run against the pre-built Linux x86_64 binary
9411113
# ═══════════════════════════════════════════════════════════════════════════
@@ -1091,11 +1263,14 @@ jobs:
10911263
- build_linux_aarch64
10921264
- build_windows_x86_64
10931265
- build_macos_arm
1266+
- build_pg_extension_x86_64
1267+
- build_pg_extension_aarch64
10941268
- read_version
10951269
- smoke_tests
10961270
- sdk_tests_typescript
10971271
- sdk_tests_dart
10981272
- docker
1273+
- docker_pg
10991274

11001275
if: ${{ github.event_name == 'push' || github.event.inputs.github_release == 'true' }}
11011276

@@ -1396,6 +1571,103 @@ jobs:
13961571
run: |
13971572
echo "::warning::Docker image publish succeeded, but Docker Hub README update failed. Ensure DOCKERHUB_USERNAME is a repo admin and DOCKERHUB_TOKEN has read/write/delete scope."
13981573
1574+
# ═══════════════════════════════════════════════════════════════════════════
1575+
# DOCKER PG - Push PostgreSQL + pg_kalam extension image to Docker Hub
1576+
# ═══════════════════════════════════════════════════════════════════════════
1577+
docker_pg:
1578+
name: Push PG Extension Docker image
1579+
runs-on: ubuntu-latest
1580+
needs:
1581+
- build_pg_extension_x86_64
1582+
- build_pg_extension_aarch64
1583+
- read_version
1584+
1585+
if: ${{ github.event_name == 'push' || github.event.inputs.docker_push == 'true' }}
1586+
1587+
steps:
1588+
- name: Checkout
1589+
uses: actions/checkout@v6
1590+
1591+
- name: Download PG extension artifact (x86_64)
1592+
uses: actions/download-artifact@v4
1593+
with:
1594+
name: dist-pg-extension-linux-x86_64
1595+
path: pg-artifacts-amd64/
1596+
1597+
- name: Download PG extension artifact (aarch64)
1598+
uses: actions/download-artifact@v4
1599+
with:
1600+
name: dist-pg-extension-linux-aarch64
1601+
path: pg-artifacts-arm64/
1602+
1603+
- name: Prepare extension files
1604+
shell: bash
1605+
run: |
1606+
set -euo pipefail
1607+
VERSION="${{ needs.read_version.outputs.version }}"
1608+
1609+
# Extract x86_64 tarball
1610+
mkdir -p pg-ext-amd64
1611+
tar -xzf "pg-artifacts-amd64/pg_kalam-${VERSION}-pg16-linux-x86_64.tar.gz" -C pg-ext-amd64 --strip-components=1
1612+
1613+
# Extract aarch64 tarball
1614+
mkdir -p pg-ext-arm64
1615+
tar -xzf "pg-artifacts-arm64/pg_kalam-${VERSION}-pg16-linux-aarch64.tar.gz" -C pg-ext-arm64 --strip-components=1
1616+
1617+
echo "=== x86_64 ==="
1618+
ls -lh pg-ext-amd64/
1619+
echo "=== aarch64 ==="
1620+
ls -lh pg-ext-arm64/
1621+
1622+
- name: Setup QEMU
1623+
uses: docker/setup-qemu-action@v3
1624+
1625+
- name: Setup Buildx
1626+
uses: docker/setup-buildx-action@v3
1627+
1628+
- name: Login to Docker Hub
1629+
uses: docker/login-action@v3
1630+
with:
1631+
username: ${{ secrets.DOCKERHUB_USERNAME }}
1632+
password: ${{ secrets.DOCKERHUB_TOKEN }}
1633+
1634+
- name: Build and push PG image (amd64)
1635+
uses: docker/build-push-action@v6
1636+
with:
1637+
context: pg-ext-amd64
1638+
file: pg/docker/Dockerfile.release-pg
1639+
push: true
1640+
platforms: linux/amd64
1641+
tags: |
1642+
jamals86/kalamdb-pg:${{ needs.read_version.outputs.version }}-amd64
1643+
1644+
- name: Build and push PG image (arm64)
1645+
uses: docker/build-push-action@v6
1646+
with:
1647+
context: pg-ext-arm64
1648+
file: pg/docker/Dockerfile.release-pg
1649+
push: true
1650+
platforms: linux/arm64
1651+
tags: |
1652+
jamals86/kalamdb-pg:${{ needs.read_version.outputs.version }}-arm64
1653+
1654+
- name: Create and push multi-arch PG manifest
1655+
shell: bash
1656+
run: |
1657+
set -euo pipefail
1658+
REPO="jamals86/kalamdb-pg"
1659+
VERSION="${{ needs.read_version.outputs.version }}"
1660+
1661+
docker buildx imagetools create -t "${REPO}:${VERSION}" \
1662+
"${REPO}:${VERSION}-amd64" \
1663+
"${REPO}:${VERSION}-arm64"
1664+
1665+
docker buildx imagetools create -t "${REPO}:latest" \
1666+
"${REPO}:${VERSION}-amd64" \
1667+
"${REPO}:${VERSION}-arm64"
1668+
1669+
echo "✅ Multi-arch pg_kalam image: ${REPO}:${VERSION} and ${REPO}:latest"
1670+
13991671
# ═══════════════════════════════════════════════════════════════════════════
14001672
# INTEGRATION TESTS - Smoke + TypeScript SDK + Dart SDK against Docker image
14011673
# ═══════════════════════════════════════════════════════════════════════════
@@ -1682,7 +1954,7 @@ jobs:
16821954
continue
16831955
16841956
try:
1685-
parsed = json.loads(line)
1957+
parsed = json.loads(line)
16861958
except json.JSONDecodeError:
16871959
continue
16881960

AGENTS.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,16 @@ use kalamdb_commons::models::UserId;
3636
14. **Tracing Table Field Convention**: In spans/events, log `table_id` (format `namespace.table`) instead of separate `table_namespace` and `table_name` fields.
3737
15. **No SQL Rewrite in Hot Paths**: Do not add SQL/DML/SELECT rewrite passes in execution hot paths. Prefer type-safe coercion at typed boundaries (parameter binding, scalar coercion, provider write path, DataFusion-native casts/UDFs explicitly invoked by query authors) to avoid extra parse/transform overhead.
3838
16. **SDK Changes Must Update Docs**: Any change under `link/sdks/**` or SDK bridge crates (for example `link/kalam-link-dart/**`) must also update the corresponding SDK docs in the `KalamSite` repo (typically `../KalamSite/content/sdk/**`) and include appropriate test coverage.
39+
17. **Performance-First Execution**: Prefer approaches that reduce runtime, allocations, binary size, and compile time; avoid adding abstractions or dependencies that materially slow hot paths or build/test feedback loops without a clear benefit.
40+
18. **Performance Test Timing**: Whenever you run performance tests, benchmarks, or perf-focused e2e cases, record and report how long each relevant test took in seconds.
3941

4042
> **⚠️ IMPORTANT**: Smoke tests require a running KalamDB server! Start the server first with `cargo run` in the `backend` directory before running smoke tests. The tests will fail if no server is running.
4143
4244
**When adding a new dependency:**
4345
1. Add it to `Cargo.toml` (root) under `[workspace.dependencies]` with version
4446
2. Reference it in individual crates using `{ workspace = true }`
4547
3. Add crate-specific features if needed: `{ workspace = true, features = ["..."] }`
48+
4. Enable only the features that are actually required; prefer `default-features = false` when defaults pull in unused code or slow compilation.
4649

4750
**To update a dependency version:**
4851
- Only edit the version in root `Cargo.toml`
@@ -72,6 +75,22 @@ use kalamdb_commons::models::UserId;
7275
- **Actix-Web Middleware**: Custom authentication extractors and guards
7376
- **StorageBackend Abstraction**: `Arc<dyn StorageBackend>` isolates RocksDB dependencies
7477

78+
## Project Navigation
79+
80+
- `backend/`: Main Rust server workspace; most database engine work starts here.
81+
- `backend/crates/`: Core server crates grouped by responsibility; prefer editing the owning crate instead of cross-cutting changes.
82+
- `cli/`: Kalam CLI, smoke tests, and CLI-facing integration flows.
83+
- `link/`: SDK bridge workspace and shared link infrastructure.
84+
- `link/sdks/typescript/`: TypeScript SDK.
85+
- `link/sdks/dart/`: Dart/Flutter SDK. `link/sdks/dart/lib/src/generated` is generated; regenerate with `link/sdks/dart/build_native_libs.sh`.
86+
- `link/kalam-link-dart/`: Rust bridge/native layer used by the Dart SDK.
87+
- `pg/`: PostgreSQL extension workspace for `pg_kalam`; see `pg/pg_kalam.control`, `pg/src/`, `pg/crates/`, and `pg/tests/`.
88+
- `benchv2/`: Benchmark harness, scenarios, templates, and results for performance work.
89+
- `ui/`: Frontend/admin UI.
90+
- `docs/`: Architecture, API, security, and operational documentation.
91+
- `specs/`: Historical and active design specs by feature/phase.
92+
- `docker/`: Container builds and local deployment layouts.
93+
7594
## Project Structure
7695
backend/crates/
7796
- kalamdb-api: HTTP/REST + WebSocket server surface, routes, UI asset serving.
@@ -106,13 +125,15 @@ backend/crates/
106125
- When iterating on multi-file changes, run a single workspace-wide check and capture output to a file, fix all issues, then re-check:
107126
- Example: `cargo check > batch_compile_output.txt 2>&1`
108127
- Parse and address all errors/warnings in one pass; avoid running `cargo check` repeatedly after each tiny edit.
128+
- If a task requires multiple related code changes, finish the full edit batch first and only then run `cargo check` or `cargo build` when validation is actually needed.
109129
- Re-run `cargo check` only after a meaningful batch of fixes. This keeps feedback fast and focused, and prevents thrashing CI and local builds.
110130

111131
## Testing (MUST)
112132

113133
- Use `cargo nextest run` for all test executions unless explicitly told otherwise.
114134
- For CLI e2e tests: run `cargo nextest run --features e2e-tests` **without** `--no-fail-fast`, capture output to a file, then fix failures one-by-one by running only the failing test(s). Re-run the full suite after fixes.
115135
- For e2e test runs, do NOT pass `--no-fail-fast`. Run normally, fix the first failure, re-run until it passes, then move to the next failing issue.
136+
- For performance-focused tests, benchmarks, and perf e2e cases, capture and report the runtime for each relevant test in seconds in the final update.
116137
- Always add `#[ntest::timeout(time)]` to every async test where `time` is the **actual observed runtime** × 1.5 (to cover slower machines).
117138
- Example: if a test took 40s, set `#[ntest::timeout(60000)]`.
118139
- Recalculate and update timeouts after significant changes to test behavior or data size.

0 commit comments

Comments
 (0)