Skip to content
Open
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ from a trusted, auditable repository
| **[pgAudit](pgaudit)** | PostgreSQL audit extension | [github.com/pgaudit/pgaudit](https://github.com/pgaudit/pgaudit) | CNPG maintainers |
| **[pg_crash](pg-crash)** | **Disruptive** fault injection and chaos engineering extension | [github.com/cybertec-postgresql/pg_crash](https://github.com/cybertec-postgresql/pg_crash) | CNPG maintainers |
| **[pg_ivm](pg-ivm)** | Incremental View Maintenance for PostgreSQL | [github.com/sraoss/pg_ivm](https://github.com/sraoss/pg_ivm) | @shusaan |
| **[pgRouting](pgrouting)** | Geospatial routing and network analysis for PostgreSQL/PostGIS | [pgrouting.org](https://pgrouting.org/) | |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left the Maintained By column empty on purpose as I'm not sure yet who is going to maintain this extension for this project. The CODEOWNER file needs to be updated accordingly as well.

| **[pgvector](pgvector)** | Vector similarity search for PostgreSQL | [github.com/pgvector/pgvector](https://github.com/pgvector/pgvector) | CNPG maintainers |
| **[PostGIS](postgis)** | Geospatial database extension for PostgreSQL | [postgis.net/](https://postgis.net/) | CNPG maintainers |
| **[TimescaleDB Apache-2 Edition](timescaledb-oss)** | Time-series database for PostgreSQL (open source version) | [github.com/timescale/timescaledb/](https://github.com/timescale/timescaledb/) | @shusaan |
Expand Down
30 changes: 30 additions & 0 deletions pgrouting/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SPDX-FileCopyrightText: Copyright © contributors to CloudNativePG, established as CloudNativePG a Series of LF Projects, LLC.
# SPDX-License-Identifier: Apache-2.0

ARG BASE=ghcr.io/cloudnative-pg/postgresql:18-minimal-trixie
FROM $BASE AS builder

ARG PG_MAJOR
ARG EXT_VERSION

USER 0

RUN apt-get update && \
apt-get install -y --no-install-recommends \
"postgresql-${PG_MAJOR}-pgrouting=${EXT_VERSION}" \
"postgresql-${PG_MAJOR}-pgrouting-scripts=${EXT_VERSION}"

FROM scratch
ARG PG_MAJOR

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

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

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

USER 65532:65532
104 changes: 104 additions & 0 deletions pgrouting/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# pgRouting
<!--
SPDX-FileCopyrightText: Copyright © contributors to CloudNativePG, established as CloudNativePG a Series of LF Projects, LLC.
SPDX-License-Identifier: Apache-2.0
-->

[pgRouting](https://pgrouting.org/) extends the [PostGIS](https://postgis.net/)/PostgreSQL geospatial database to
provide geospatial routing and other network analysis functionality.

This image provides a convenient way to deploy and manage `pgRouting` with [CloudNativePG](https://cloudnative-pg.io/).

> [!NOTE]
> `pgRouting` depends on `PostGIS`. When deploying `pgRouting`, you must also include the `postgis` extension image in
> your Cluster definition.
## Usage

### 1. Add the pgRouting and PostGIS extension images to your Cluster

Define the `postgis` and `pgrouting` extensions under the `postgresql.extensions` section of your `Cluster` resource.
For example:

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

storage:
size: 1Gi

postgresql:
extensions:
- name: postgis
image:
# renovate: suite=trixie-pgdg depName=postgresql-18-postgis-3
reference: ghcr.io/cloudnative-pg/postgis-extension:3.6.4-18-trixie
ld_library_path:
- system
env:
- name: GDAL_DATA
value: ${image_root}/share/gdal
- name: PROJ_DATA
value: ${image_root}/share/proj
- name: pgrouting
image:
# renovate: suite=trixie-pgdg depName=postgresql-18-pgrouting
reference: ghcr.io/cloudnative-pg/pgrouting:4.0.1-18-trixie
```
### 2. Enable the extension in a database
You can install `pgrouting` in a specific database by creating or updating a `Database` resource:

```yaml
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: cluster-pgrouting-app
spec:
name: app
owner: app
cluster:
name: cluster-pgrouting
extensions:
- name: postgis
# renovate: suite=trixie-pgdg depName=postgresql-18-postgis-3 extractVersion=^(?<version>\d+\.\d+\.\d+)
version: '3.6.4'
- name: pgrouting
# renovate: suite=trixie-pgdg depName=postgresql-18-pgrouting extractVersion=^(?<version>\d+\.\d+\.\d+)
version: '4.0.1'
```

### 3. Verify installation

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

```sql
\dx
```

You should see `postgis` and `pgrouting` listed among the installed extensions.

---

## Licenses and Copyright

`pgRouting`:

- **Copyright:** pgRouting Contributors
- **License:** GNU General Public License v2.0 or later (`GPL-2.0-or-later`)

All relevant license and copyright information for the `pgrouting` extension
and its dependencies are bundled within the image at:

```text
/licenses/
```

By using this image, you agree to comply with the terms of the licenses
contained therein.
37 changes: 37 additions & 0 deletions pgrouting/metadata.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# SPDX-FileCopyrightText: Copyright © contributors to CloudNativePG, established as CloudNativePG a Series of LF Projects, LLC.
# SPDX-License-Identifier: Apache-2.0
metadata = {
name = "pgrouting"
sql_name = "pgrouting"
image_name = "pgrouting"
licenses = ["GPL-2.0-or-later"]
shared_preload_libraries = []
postgresql_parameters = {}
extension_control_path = []
dynamic_library_path = []
ld_library_path = []
bin_path = []
env = {}
auto_update_os_libs = false
required_extensions = ["postgis"]
create_extension = true

versions = {
bookworm = {
"18" = {
// renovate: suite=bookworm-pgdg depName=postgresql-18-pgrouting
package = "4.0.1-1.pgdg12+1"
// renovate: suite=bookworm-pgdg depName=postgresql-18-pgrouting extractVersion=^(?<version>\d+\.\d+\.\d+)
sql = "4.0.1"
}
}
trixie = {
"18" = {
// renovate: suite=trixie-pgdg depName=postgresql-18-pgrouting
package = "4.0.1-1.pgdg13+1"
// renovate: suite=trixie-pgdg depName=postgresql-18-pgrouting extractVersion=^(?<version>\d+\.\d+\.\d+)
sql = "4.0.1"
}
}
}
}
28 changes: 28 additions & 0 deletions pgrouting/test/chainsaw-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
name: verify-pgrouting-extension
spec:
timeouts:
apply: 5s
assert: 3m
delete: 30s
description: Verify pgrouting extension is properly installed
steps:
- name: Create a Cluster with the extension
try:
- apply:
file: cluster.yaml
- apply:
file: database.yaml
- assert:
file: cluster-assert.yaml
- assert:
file: database-assert.yaml

- name: Verify extension is installed
try:
- apply:
file: check-extension.yaml
- assert:
file: check-extension-assert.yaml
6 changes: 6 additions & 0 deletions pgrouting/test/check-extension-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: batch/v1
kind: Job
metadata:
name: extension-installed
status:
succeeded: 1
28 changes: 28 additions & 0 deletions pgrouting/test/check-extension.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: batch/v1
kind: Job
metadata:
name: extension-installed
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: data-test
env:
- name: PGSSLROOTCERT
- name: EXT_VERSION
value: ($values.version)
- name: DB_URI
valueFrom:
secretKeyRef:
name: (join('-', [$values.name, 'app']))
key: uri
# renovate: datasource=docker depName=alpine/psql versioning=docker
image: alpine/psql:18.4@sha256:b3e4fc061da067813ddc5a8844b1992a50d5f1dce72d46be8ee5d0b964a3e894
command: ['sh', '-c']
args:
- |
set -e
DB_URI=$(echo $DB_URI | sed "s|/\*|/|")
test "$(psql "$DB_URI" -tAc "SELECT EXISTS (SELECT FROM pg_catalog.pg_extension WHERE extname = 'postgis')" -q)" = "t"
test "$(psql "$DB_URI" -tAc "SELECT EXISTS (SELECT FROM pg_catalog.pg_extension WHERE extname = 'pgrouting' AND extversion = '${EXT_VERSION}')" -q)" = "t"
Comment on lines +26 to +28

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test assertions are already covered by generic smoke tests:

test "$(psql "$DB_URI" -tAc "SELECT EXISTS (SELECT FROM pg_catalog.pg_extension WHERE extname = '${EXT_SQL_NAME}' AND extversion = '${EXT_VERSION}')" -q)" = "t"

I believe that adding custom/dedicated tests for an extension should exercise specific aspects of it, like calling a function the extension exposes and verifying the outcome, eg

psql "$DB_URI" -c "DROP TABLE IF EXISTS test_ivm CASCADE;"

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Limited (time) bandwidth here... Do you want me to implement this or are you going to add it?

8 changes: 8 additions & 0 deletions pgrouting/test/cluster-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: ($values.name)
status:
instances: 1
readyInstances: 1
phase: Cluster in healthy state
15 changes: 15 additions & 0 deletions pgrouting/test/cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: ($values.name)
spec:
imageName: ($values.pg_image)
instances: 1

storage:
size: 1Gi

postgresql:
parameters: ($values.postgresql_parameters)
shared_preload_libraries: ($values.shared_preload_libraries)
extensions: ($values.extensions)
5 changes: 5 additions & 0 deletions pgrouting/test/database-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: (join('-', [$values.name, 'app']))
status: ($values.database_assert_status)
10 changes: 10 additions & 0 deletions pgrouting/test/database.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: (join('-', [$values.name, 'app']))
spec:
name: app
owner: app
cluster:
name: ($values.name)
extensions: ($values.database_config.extensions_spec)