Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 4 additions & 1 deletion .github/workflows/bake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:

defaults:
run:
shell: 'bash -Eeuo pipefail -x {0}'
shell: "bash -Eeuo pipefail -x {0}"

permissions: {}

Expand All @@ -38,6 +38,9 @@ jobs:
pg_repack:
- 'pg_repack/**'
- *shared
plpython3u:
- 'plpython3u/**'
- *shared

- name: Compute matrix
id: get-matrix
Expand Down
2 changes: 1 addition & 1 deletion Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ build ext:
docker buildx bake \
-f {{ ext }}/metadata.hcl \
-f docker-bake.hcl \
--set "*.platforms=linux/{{ arch }}" \
--set "*.platform=linux/{{ arch }}" \
--load

# Build and push to local OCI registry (multi-platform)
Expand Down
64 changes: 64 additions & 0 deletions plpython3u/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
ARG BASE=ghcr.io/cloudnative-pg/postgresql:18-minimal-bookworm
FROM $BASE AS builder

ARG PG_MAJOR
ARG EXT_VERSION

USER 0

RUN set -eux && \
# Initial system libraries
ldconfig -p | awk '{print $NF}' | grep '^/' | sort | uniq > /tmp/base-image-libs.out && \

# Install PL/Python3
apt-get update && apt-get install -y --no-install-recommends \
"postgresql-plpython3-${PG_MAJOR}=${EXT_VERSION}" && \
rm -rf /var/lib/apt/lists/*

# Gather PL/Python3 system libraries and their licenses
RUN mkdir -p /system /licenses && \
# Get libraries
ldd /usr/lib/postgresql/${PG_MAJOR}/lib/plpython3.so \
| awk '{print $3}' | grep '^/' | sort | uniq > /tmp/all-deps.out && \
# Extract all the libs that aren't already part of the base image
comm -13 /tmp/base-image-libs.out /tmp/all-deps.out > /tmp/libraries.out && \
while read -r lib; do \
resolved=$(readlink -f "$lib"); \
dir=$(dirname "$lib"); \
base=$(basename "$lib"); \
# Copy the real file
cp -a "$resolved" /system/; \
# Reconstruct all its symlinks
for file in "$dir"/"${base%.so*}.so"*; do \
[ -e "$file" ] || continue; \
# If it's a symlink and it resolves to the same real file, we reconstruct it
if [ -L "$file" ] && [ "$(readlink -f "$file")" = "$resolved" ]; then \
ln -sf "$(basename "$resolved")" "/system/$(basename "$file")"; \
fi; \
done; \
done < /tmp/libraries.out && \
# Get licenses
for lib in $(find /system -maxdepth 1 -type f -name '*.so*'); do \
# Get the name of the pkg that installed the library
pkg=$(dpkg -S "$(basename "$lib")" | grep -v "diversion by" | awk -F: '/:/{print $1; exit}'); \
[ -z "$pkg" ] && continue; \
mkdir -p "/licenses/$pkg" && cp -a "/usr/share/doc/$pkg/copyright" "/licenses/$pkg/copyright"; \
done

FROM scratch
ARG PG_MAJOR

# Licenses
COPY --from=builder /licenses /licences/
COPY --from=builder /usr/share/doc/postgresql-plpython3-${PG_MAJOR}/copyright /licenses/postgresql-plpython3-${PG_MAJOR}/

# Libraries
COPY --from=builder /usr/lib/postgresql/${PG_MAJOR}/lib/plpython3* /lib/

# Share
COPY --from=builder /usr/share/postgresql/${PG_MAJOR}/extension/plpython3u* /share/extension/

# System libs
COPY --from=builder /system /system

USER 65532:65532
65 changes: 65 additions & 0 deletions plpython3u/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Plpython3u

The `plpython3u` PostgreSQL extension allows writing functions and stored procedures in Python 3.
It is the untrusted variant of PL/Python, meaning it can access the file system and network from within the database.
For more information, see the [official documentation](https://www.postgresql.org/docs/current/plpython.html).

## Usage

### 1. Add the Plpython3u extension image to your Cluster

Define the `plpython3u` extension under the `postgresql.extensions` section of
your `Cluster` resource. For example:

```yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cluster-plpython3u
spec:
imageName: ghcr.io/cloudnative-pg/postgresql:18-minimal-bookworm
instances: 1

storage:
size: 1Gi

postgresql:
extensions:
- name: plpython3u
image:
# renovate: suite=bookworm-pgdg depName=postgresql-plpython3-18
reference: ghcr.io/vshn/plpython3u:1.0-18-bookworm
ld_library_path:
- system
```

### 2. Enable the extension in a database

You can install `plpython3u` in a specific database by creating or updating a
`Database` resource. For example, to enable it in the `app` database:

```yaml
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: cluster-plpython3u-app
spec:
name: app
owner: app
cluster:
name: cluster-plpython3u
extensions:
- name: plpython3u
# renovate: suite=bookworm-pgdg depName=postgresql-plpython3-18
version: '1.0'
```

### 3. Verify installation

Once the database is ready, connect to it with `psql` and run:

```sql
\dx
```

You should see `plpython3u` listed among the installed extensions.
26 changes: 26 additions & 0 deletions plpython3u/metadata.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
metadata = {
name = "plpython3u"
sql_name = "plpython3u"
image_name = "plpython3u"
licenses = [ "BSD-2-clause", "BSD-3-Clause", "Custom-Unicode",
"Custom-pg_dump", "Custom-regex", "PostgreSQL",
"Tcl", "double-metaphone", "nagaysau-ishii" ]
shared_preload_libraries = []
extension_control_path = []
dynamic_library_path = []
ld_library_path = ["system"]
auto_update_os_libs = true
required_extensions = []
create_extension = true

versions = {
bookworm = {
// renovate: suite=bookworm-pgdg depName=postgresql-plpython3-18
"18" = "18.3-1.pgdg12+1"
}
trixie = {
// renovate: suite=trixie-pgdg depName=postgresql-plpython3-18
"18" = "18.3-1.pgdg13+1"
}
}
}
Loading