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 e2e-tests/run-pr.csv
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ custom-tls
database-init-sql
demand-backup
demand-backup-offline-snapshot
dynamic-configuration
finalizers
init-deploy
huge-pages
Expand Down
1 change: 1 addition & 0 deletions e2e-tests/run-release.csv
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ custom-tls
database-init-sql
demand-backup
demand-backup-offline-snapshot
dynamic-configuration
finalizers
init-deploy
huge-pages
Expand Down
24 changes: 24 additions & 0 deletions e2e-tests/tests/dynamic-configuration/00-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 120
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: perconapgclusters.pgv2.percona.com
spec:
group: pgv2.percona.com
names:
kind: PerconaPGCluster
listKind: PerconaPGClusterList
plural: perconapgclusters
singular: perconapgcluster
scope: Namespaced
---
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
metadata:
name: check-operator-deploy-status
timeout: 120
commands:
- script: kubectl assert exist-enhanced deployment percona-postgresql-operator -n ${OPERATOR_NS:-$NAMESPACE} --field-selector status.readyReplicas=1
13 changes: 13 additions & 0 deletions e2e-tests/tests/dynamic-configuration/00-deploy-operator.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
timeout: 10
commands:
- script: |-
set -o errexit
set -o xtrace

source ../../functions
init_temp_dir # do this only in the first TestStep

deploy_operator
deploy_client
110 changes: 110 additions & 0 deletions e2e-tests/tests/dynamic-configuration/01-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 480
---
kind: StatefulSet
apiVersion: apps/v1
metadata:
labels:
postgres-operator.crunchydata.com/cluster: cluster1
postgres-operator.crunchydata.com/data: postgres
postgres-operator.crunchydata.com/instance-set: instance1
ownerReferences:
- apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
name: cluster1
controller: true
blockOwnerDeletion: true
status:
observedGeneration: 1
replicas: 1
readyReplicas: 1
currentReplicas: 1
updatedReplicas: 1
collisionCount: 0
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: cluster1-pgbouncer
labels:
postgres-operator.crunchydata.com/cluster: cluster1
postgres-operator.crunchydata.com/role: pgbouncer
annotations:
deployment.kubernetes.io/revision: '1'
ownerReferences:
- apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
name: cluster1
controller: true
blockOwnerDeletion: true
status:
observedGeneration: 1
replicas: 3
updatedReplicas: 3
readyReplicas: 3
---
kind: Job
apiVersion: batch/v1
metadata:
labels:
postgres-operator.crunchydata.com/cluster: cluster1
postgres-operator.crunchydata.com/pgbackrest: ''
postgres-operator.crunchydata.com/pgbackrest-backup: replica-create
postgres-operator.crunchydata.com/pgbackrest-repo: repo1
ownerReferences:
- apiVersion: pgv2.percona.com/v2
kind: PerconaPGBackup
controller: true
blockOwnerDeletion: true
status:
succeeded: 1
---
apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: cluster1
ownerReferences:
- apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
name: cluster1
controller: true
blockOwnerDeletion: true
finalizers:
- postgres-operator.crunchydata.com/finalizer
status:
instances:
- name: instance1
readyReplicas: 3
replicas: 3
updatedReplicas: 3
observedGeneration: 1
pgbackrest:
repos:
- name: repo1
stanzaCreated: true
proxy:
pgBouncer:
readyReplicas: 3
replicas: 3
---
apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
metadata:
name: cluster1
status:
pgbackrest:
repos:
- name: repo1
stanzaCreated: true
pgbouncer:
ready: 3
size: 3
postgres:
instances:
- name: instance1
ready: 3
size: 3
ready: 3
size: 3
state: ready
12 changes: 12 additions & 0 deletions e2e-tests/tests/dynamic-configuration/01-create-cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
timeout: 20
commands:
- script: |-
set -o errexit
set -o xtrace

source ../../functions

get_cr "cluster1" ${RANDOM} \
| kubectl -n "${NAMESPACE}" apply -f -
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
metadata:
name: cluster1
spec:
patroni:
dynamicConfiguration:
postgresql:
parameters:
wal_level: "replica"
restore_command: "/bin/true"
7 changes: 7 additions & 0 deletions e2e-tests/tests/dynamic-configuration/03-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: 03-pg-settings
data:
wal_level: 'replica'
restore_command: '/bin/true'
21 changes: 21 additions & 0 deletions e2e-tests/tests/dynamic-configuration/03-verify.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
timeout: 30
commands:
- script: |-
set -o errexit
set -o xtrace
source ../../functions
sleep 30 # wait for the operator to apply it via pod exec
Comment on lines +3 to +12
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

  1. Problem: This KUTTL step sets timeout: 30 but the script itself starts with sleep 30, leaving no time for the remaining commands.
  2. Why it matters: The step will frequently exceed its timeout and flake/fail CI even when the feature works.
  3. Fix: Increase the step timeout (or replace the fixed sleep with a bounded retry loop that waits until SHOW wal_level/SHOW restore_command match the expected values).

Copilot uses AI. Check for mistakes.
uri="postgres:$(get_psql_user_pass cluster1-pguser-postgres)@$(get_psql_user_host cluster1-pguser-postgres)"
uri_replicas="postgres:$(get_psql_user_pass cluster1-pguser-postgres)@cluster1-replicas"
wal_level=$(run_psql_local 'SHOW wal_level;' "$uri" | xargs)
restore_command=$(run_psql_local 'SHOW restore_command;' "$uri_replicas" | xargs)
kubectl create configmap -n "${NAMESPACE}" 03-pg-settings \
--from-literal=wal_level="${wal_level}" \
--from-literal=restore_command="${restore_command}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
delete:
- apiVersion: pgv2.percona.com/v2
kind: PerconaPGCluster
metadata:
name: cluster1
- apiVersion: postgres-operator.crunchydata.com/v1beta1
kind: PostgresCluster
metadata:
name: cluster1
commands:
- script: |-
set -o errexit
set -o xtrace

source ../../functions

remove_all_finalizers
destroy_operator
timeout: 60
15 changes: 8 additions & 7 deletions internal/postgres/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@ func NewParameters() Parameters {
// PostgreSQL must be restarted when changing this value.
parameters.Mandatory.Add("unix_socket_directories", SocketDirectory)

// Enable logical replication in addition to streaming and WAL archiving.
// PostgreSQL must be restarted when changing this value.
// - https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LEVEL
// - https://www.postgresql.org/docs/current/runtime-config-replication.html
// - https://www.postgresql.org/docs/current/logical-replication.html
parameters.Mandatory.Add("wal_level", "logical")

// Always enable SSL/TLS.
// PostgreSQL must be reloaded when changing this value.
// - https://www.postgresql.org/docs/current/ssl-tcp.html
Expand All @@ -36,6 +29,14 @@ func NewParameters() Parameters {
parameters.Mandatory.Add("ssl_key_file", "/pgconf/tls/tls.key")
parameters.Mandatory.Add("ssl_ca_file", "/pgconf/tls/ca.crt")

// Enable logical replication in addition to streaming and WAL archiving.
// Can be overridden via spec.patroni.dynamicConfiguration.postgresql.parameters.
// PostgreSQL must be restarted when changing this value.
// - https://www.postgresql.org/docs/current/runtime-config-wal.html#GUC-WAL-LEVEL
// - https://www.postgresql.org/docs/current/runtime-config-replication.html
// - https://www.postgresql.org/docs/current/logical-replication.html
parameters.Default.Add("wal_level", "logical")

Comment on lines +32 to +39
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure that I fully understand how moving this here allows the overriding, can we elaborate?

Copy link
Member Author

Choose a reason for hiding this comment

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

Its just the way DynamicConfiguration function builds the parameters. Whatever is in Mandatory takes precedence over everything (see this line)

Moving it to Default allows us to configure a parameter with some "default" that can be overridden by dynamicConfiguration

// Just-in-Time compilation can degrade performance unexpectedly. Allow
// users to enable it for appropriate workloads.
// - https://www.postgresql.org/docs/current/jit.html
Expand Down
3 changes: 1 addition & 2 deletions internal/postgres/parameters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ func TestNewParameters(t *testing.T) {
"ssl_key_file": "/pgconf/tls/tls.key",

"unix_socket_directories": "/tmp/postgres",

"wal_level": "logical",
})
assert.DeepEqual(t, parameters.Default.AsMap(), map[string]string{
"jit": "off",

"password_encryption": "scram-sha-256",
"wal_level": "logical",
})
}

Expand Down
Loading