Skip to content

Conversation

@ThoSap
Copy link
Contributor

@ThoSap ThoSap commented Jan 22, 2026

No description provided.

@ThoSap ThoSap self-assigned this Jan 22, 2026
@linear
Copy link

linear bot commented Jan 22, 2026

AB-449 PostgreSQL Operator

Based on the research and PoC done in the ticket and PR https://github.com/aboutbits/minio-operator/pull/1

We most likely will use CloudNativePG AB-396 for the DB Setup and this operator to manage the access, e.g. PostgreSQL roles and grants.

The scope of the operator is:

  • Role management
  • Grant management
  • Database management

@ThoSap ThoSap changed the title AB-449 PostgreSQL Operator: Publish workflow + PostgreSQL 15 to 18 test matrix AB-449 PostgreSQL Operator: Publish workflow + PostgreSQL 15 to 18 Test Matrix Jan 22, 2026
Base automatically changed from ab-449-postgresql-operator-default-priviege to main January 22, 2026 21:19
@ThoSap ThoSap changed the title AB-449 PostgreSQL Operator: Publish workflow + PostgreSQL 15 to 18 Test Matrix AB-449 PostgreSQL Operator: Release workflow + PostgreSQL 15 to 18 Test Matrix Jan 23, 2026
@ThoSap ThoSap requested a review from Copilot January 23, 2026 10:16
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the PostgreSQL operator to support PostgreSQL versions 15-18 by implementing a test matrix and introducing a release workflow. The changes remove the MAINTAIN privilege (available only in PostgreSQL 17+) to ensure backward compatibility with PostgreSQL 15 and 16.

Changes:

  • Updated default PostgreSQL version from 17.7 to 18
  • Added test configuration files for PostgreSQL versions 15, 16, 17, and 18
  • Removed MAINTAIN privilege support to maintain compatibility with PostgreSQL 15+
  • Introduced Axion Release Plugin for version management
  • Replaced single test workflow with matrix testing across PostgreSQL versions 15-18

Reviewed changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
operator/src/main/resources/application.yml Updated default PostgreSQL image from 17.7 to 18
operator/src/main/resources/application-test-pg*.yml Added test profile configurations for PostgreSQL 15, 16, 17, and 18
operator/src/main/java/it/aboutbits/postgresql/crd/grant/GrantSpec.java Removed maintain from privilege documentation
operator/src/main/java/it/aboutbits/postgresql/crd/grant/GrantObjectType.java Commented out MAINTAIN privilege and removed import
operator/src/main/java/it/aboutbits/postgresql/crd/defaultprivilege/DefaultPrivilegeSpec.java Removed maintain from privilege documentation
operator/src/main/java/it/aboutbits/postgresql/crd/defaultprivilege/DefaultPrivilegeObjectType.java Commented out MAINTAIN privilege and removed import
operator/src/main/java/it/aboutbits/postgresql/core/Privilege.java Commented out MAINTAIN enum value
operator/src/main/docker/compose-deviservices-test-pg*.yml Added Docker Compose configurations for each PostgreSQL version
gradle/libs.versions.toml Added Axion Release Plugin dependency
gradle.properties Disabled parallel Gradle builds due to Quarkus issue
Makefile Added test targets for each PostgreSQL version
.github/workflows/test.yml Removed standalone test workflow
.github/workflows/release.yml Added comprehensive release workflow with Docker and Helm chart publishing
.github/workflows/main.yml Replaced test workflow with matrix testing across PostgreSQL 15-18

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

image: postgres:18
command: "postgres -c checkpoint_timeout=10min -c fsync=off -c full_page_writes=off -c max_wal_size=2GB -c synchronous_commit=off"
tmpfs:
- /var/lib/postgresql/18/docker:rw,async,noatime
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The tmpfs path includes a version-specific directory '/var/lib/postgresql/18/docker' that differs from the standard PostgreSQL data directory path used in other versions. This inconsistency could lead to confusion. Consider using the standard '/var/lib/postgresql/data' path for consistency with pg15, pg16, and pg17 configurations.

Suggested change
- /var/lib/postgresql/18/docker:rw,async,noatime
- /var/lib/postgresql/data:rw,async,noatime

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

@ThoSap ThoSap Jan 23, 2026

Choose a reason for hiding this comment

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

No, this is correct, see docker-library/postgres#1259

@ThoSap ThoSap requested a review from Copilot January 23, 2026 10:27
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 20 out of 21 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ThoSap ThoSap marked this pull request as ready for review January 23, 2026 10:30
@ThoSap
Copy link
Contributor Author

ThoSap commented Jan 23, 2026

I will add docs and polish the README.md in a follow-up PR.

I'm using the Gradle Plugin https://github.com/allegro/axion-release-plugin, which is very similar to the way npm version works.
https://axion-release-plugin.readthedocs.io/en/latest/

The first version to be released is v0.1.0 by default (0.1.0 for the Helm chart and container image).
After that, the increment input and prerelases will work.

Copy link
Member

Choose a reason for hiding this comment

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

In the frontend packages we called this file like this. In the backend packages we used the name publish.yml. I think the name release.yml is more appropriate. I will make a note for myself to change it at all other backend packages.

Copy link
Member

Choose a reason for hiding this comment

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

I changed it already for all backend repositories.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I like it.

Comment on lines 70 to 77
**Manually installing CRDs:**
```bash
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/clusterconnections.postgresql.aboutbits.it-v1.yml
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/databases.postgresql.aboutbits.it-v1.yml
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/schemas.postgresql.aboutbits.it-v1.yml
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/roles.postgresql.aboutbits.it-v1.yml
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/grants.postgresql.aboutbits.it-v1.yml
kubectl apply -f https://github.com/${{ github.repository }}/releases/download/v${{ steps.nextVersion.outputs.version }}/defaultprivileges.postgresql.aboutbits.it-v1.yml
Copy link
Member

Choose a reason for hiding this comment

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

When do we need these manual installations? Is this really something that is required? Or will everything be handeled by the Helm chart?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is required if someone is not using the Helm chart, or we add a flag to the Helm chart to not install the CRDs using a simple boolean switch.

Comment on lines 61 to 62
```bash
docker pull ${{ env.DOCKER_IMAGE }}:${{ steps.nextVersion.outputs.version }}
Copy link
Member

Choose a reason for hiding this comment

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

When does a user need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only if you want to inspect the container image with tools like https://github.com/wagoodman/dive or https://github.com/reproducible-containers/diffoci

For the other cases, you most likely always use the Helm chart.

Copy link
Member

Choose a reason for hiding this comment

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

I would remove this, since this is just for debugging reasons. Or at least this is the least important information here. So first the must be the Helm installation instruction.

@ThoSap ThoSap requested a review from alexlanz January 23, 2026 12:36
Comment on lines 61 to 62
```bash
docker pull ${{ env.DOCKER_IMAGE }}:${{ steps.nextVersion.outputs.version }}
Copy link
Member

Choose a reason for hiding this comment

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

I would remove this, since this is just for debugging reasons. Or at least this is the least important information here. So first the must be the Helm installation instruction.

strategy:
fail-fast: false
matrix:
postgres-version: [ 15, 16, 17, 18 ]
Copy link
Member

Choose a reason for hiding this comment

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

This is sick! 💯

TRIGGER,
MAINTAIN
TRIGGER
//MAINTAIN // PostgreSQL 17+
Copy link
Member

Choose a reason for hiding this comment

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

General question: Would this break the integration with 15 and 16 if it is not used?

Copy link
Contributor Author

@ThoSap ThoSap Jan 26, 2026

Choose a reason for hiding this comment

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

No, it would not break the integration if it is not used or tested against.

It currently fails as I added a grant all Grant/DefaultPrivileges step for the respective ObjectType in the tests, which then fails as follows in the code block below.

What I could do is retrieve the PostgreSQL major version from the jOOQ DSLContext and add a minimum optional/nullable PG major version to the Privilege enum constants, and then filter out privileges from the List/Set that do not satisfy the minimum database version.

// Returns the major version number (e.g., 17)
int majorVersion = dsl.connectionResult(connection -> 
    connection.getMetaData().getDatabaseMajorVersion()
);

// OR

// Returns an integer, e.g., 170000
Integer versionNum = dsl.fetchValue("show server_version_num", Integer.class);

// OR

// Returns short string, e.g., "17.0"
String version = dsl.fetchValue("show server_version", String.class);

    2026-01-26 08:40:30,201 DEBUG [org.jooq.tools.LoggerListener] (ReconcilerExecutor-defaultprivilegereconciler-196) Executing query          : alter default privileges for role "test-role-75yz5h1v0srm9acoof5a0czky5xru8lpkan2y2zxc894g74ixwcxk" in schema "test-schema-b9igbunxgzg18l95upbnwtasfq01m5tbanecrinm55rv2b27bpv" grant delete, insert, references, truncate, update, maintain, trigger on tables to "test-role-2y69entlxnrljru70a9at1lhq363ro4msi9c7b05omvjxl6lg39az"
    2026-01-26 08:40:30,206 DEBUG [org.jooq.tools.LoggerListener] (ReconcilerExecutor-defaultprivilegereconciler-196) Exception                : org.jooq.exception.DataAccessException: SQL [alter default privileges for role "test-role-75yz5h1v0srm9acoof5a0czky5xru8lpkan2y2zxc894g74ixwcxk" in schema "test-schema-b9igbunxgzg18l95upbnwtasfq01m5tbanecrinm55rv2b27bpv" grant delete, insert, references, truncate, update, maintain, trigger on tables to "test-role-2y69entlxnrljru70a9at1lhq363ro4msi9c7b05omvjxl6lg39az"]; ERROR: unrecognized privilege type "maintain"
    	at org.jooq_3.20.10.POSTGRES.debug(Unknown Source)
    	at org.jooq.impl.Tools.translate(Tools.java:3709)
    	at org.jooq.impl.Tools.translate(Tools.java:3685)
    	at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:869)
    	at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:363)
    	at org.jooq.impl.Tools.attach(Tools.java:1735)
    	at org.jooq.impl.DefaultDSLContext.execute(DefaultDSLContext.java:5338)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeService.grant(DefaultPrivilegeService.java:110)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeReconciler.reconcileInTransaction(DefaultPrivilegeReconciler.java:232)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeReconciler.lambda$reconcile$0(DefaultPrivilegeReconciler.java:99)
    	at org.jooq.impl.DefaultDSLContext.lambda$transactionResult0$3(DefaultDSLContext.java:533)
    	at org.jooq.impl.Tools$3$1.block(Tools.java:6402)
    	at java.base/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:4364)
    	at java.base/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:4310)
    	at org.jooq.impl.Tools$3.get(Tools.java:6399)
    	at org.jooq.impl.DefaultDSLContext.transactionResult0(DefaultDSLContext.java:581)
    	at org.jooq.impl.DefaultDSLContext.transactionResult(DefaultDSLContext.java:504)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeReconciler.reconcile(DefaultPrivilegeReconciler.java:98)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeReconciler.reconcile(DefaultPrivilegeReconciler.java:22)
    	at it.aboutbits.postgresql.crd.defaultprivilege.DefaultPrivilegeReconciler_ClientProxy.reconcile(Unknown Source)
    	at io.javaoperatorsdk.operator.processing.Controller$1.execute(Controller.java:161)
    	at io.javaoperatorsdk.operator.processing.Controller$1.execute(Controller.java:117)
    	at io.javaoperatorsdk.operator.monitoring.micrometer.MicrometerMetrics.lambda$timeControllerExecution$0(MicrometerMetrics.java:151)
    	at io.micrometer.core.instrument.composite.CompositeTimer.record(CompositeTimer.java:69)
    	at io.javaoperatorsdk.operator.monitoring.micrometer.MicrometerMetrics.timeControllerExecution(MicrometerMetrics.java:148)
    	at io.javaoperatorsdk.operator.processing.Controller.reconcile(Controller.java:116)
    	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.reconcileExecution(ReconciliationDispatcher.java:154)
    	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.handleReconcile(ReconciliationDispatcher.java:131)
    	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.handleDispatch(ReconciliationDispatcher.java:98)
    	at io.javaoperatorsdk.operator.processing.event.ReconciliationDispatcher.handleExecution(ReconciliationDispatcher.java:69)
    	at io.javaoperatorsdk.operator.processing.event.EventProcessor$ReconcilerExecutor.run(EventProcessor.java:483)
    	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
    	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
    	at java.base/java.lang.Thread.run(Thread.java:1474)
    Caused by: org.postgresql.util.PSQLException: ERROR: unrecognized privilege type "maintain"
    	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2736)
    	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2421)
    	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:372)
    	at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:525)
    	at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:435)
    	at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:357)
    	at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:342)
    	at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:318)
    	at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:313)
    	at org.jooq.tools.jdbc.DefaultStatement.execute(DefaultStatement.java:102)
    	at org.jooq.impl.SettingsEnabledPreparedStatement.execute(SettingsEnabledPreparedStatement.java:227)
    	at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:459)
    	at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:349)
    	... 29 more
    2026-01-26 08:40:30,206 DEBUG [org.jooq.impl.DefaultConnectionProvider] (ReconcilerExecutor-defaultprivilegereconciler-196) rollback                 
    2026-01-26 08:40:30,207 DEBUG [org.jooq.impl.DefaultConnectionProvider] (ReconcilerExecutor-defaultprivilegereconciler-196) setting auto commit      : true
    2026-01-26 08:40:30,208 ERROR [it.aboutbits.postgresql.core.BaseReconciler] (ReconcilerExecutor-defaultprivilegereconciler-196) Failed to reconcile resource [resource=test-default-privilege-rc5qtair1jkf9ur5tkulnz5k60tb2cke5io6deom]: org.jooq.exception.DataAccessException: SQL [alter default privileges for role "test-role-75yz5h1v0srm9acoof5a0czky5xru8lpkan2y2zxc894g74ixwcxk" in schema "test-schema-b9igbunxgzg18l95upbnwtasfq01m5tbanecrinm55rv2b27bpv" grant delete, insert, references, truncate, update, maintain, trigger on tables to "test-role-2y69entlxnrljru70a9at1lhq363ro4msi9c7b05omvjxl6lg39az"]; ERROR: unrecognized privilege type "maintain"
    	at org.jooq_3.20.10.POSTGRES.debug(Unknown Source)
    	...

Copy link
Contributor Author

@ThoSap ThoSap Jan 26, 2026

Choose a reason for hiding this comment

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

I now check for unsupported privileges and conditionally test these.

@ThoSap ThoSap requested a review from Copilot January 26, 2026 09:49
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 26 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

… not hardcode PostgreSQL 16 in the assertion
@ThoSap ThoSap requested a review from Copilot January 26, 2026 10:15
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 24 out of 25 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

operator/src/test/java/it/aboutbits/postgresql/_support/testdata/persisted/creator/GrantCreate.java:137

  • This line was removed, but the withObjects field is still used later in the method (line 129+). If objects should not be set at this location, ensure that withObjects is properly handled in the conditional logic below. Verify that tests relying on object specification still function correctly.
            spec.setObjects(withObjects);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ThoSap
Copy link
Contributor Author

ThoSap commented Jan 26, 2026

I changed the GitHub workflow structure slightly again, since in the release workflow, we only ran the PostgreSQL 18 tests on build, not across the whole test matrix.

Now I'm using the shared workflow_dispatch trigger workflow test.yml again in both main.yml and release.yml.

@ThoSap ThoSap requested a review from Copilot January 26, 2026 11:12
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 22 out of 23 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ThoSap ThoSap requested a review from Copilot January 26, 2026 11:21
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 22 out of 23 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Member

@alexlanz alexlanz left a comment

Choose a reason for hiding this comment

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

Nice job!

@ThoSap ThoSap merged commit 0d6bc52 into main Jan 26, 2026
8 of 12 checks passed
@ThoSap ThoSap deleted the ab-449-postgresql-operator-publish-workflow-and-pg-15-to-18-test-matrix branch January 26, 2026 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants