diff --git a/e2e-tests/run-pr.csv b/e2e-tests/run-pr.csv index 5253b4a97..6d0dc0189 100644 --- a/e2e-tests/run-pr.csv +++ b/e2e-tests/run-pr.csv @@ -5,6 +5,7 @@ custom-extensions custom-tls database-init-sql demand-backup +dynamic-configuration finalizers init-deploy huge-pages diff --git a/e2e-tests/run-release.csv b/e2e-tests/run-release.csv index 24f64d890..ff0cb68a5 100644 --- a/e2e-tests/run-release.csv +++ b/e2e-tests/run-release.csv @@ -5,6 +5,7 @@ custom-extensions custom-tls database-init-sql demand-backup +dynamic-configuration finalizers init-deploy huge-pages diff --git a/e2e-tests/tests/dynamic-configuration/00-assert.yaml b/e2e-tests/tests/dynamic-configuration/00-assert.yaml new file mode 100644 index 000000000..ae5a062d8 --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/00-assert.yaml @@ -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 diff --git a/e2e-tests/tests/dynamic-configuration/00-deploy-operator.yaml b/e2e-tests/tests/dynamic-configuration/00-deploy-operator.yaml new file mode 100644 index 000000000..1aaca58be --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/00-deploy-operator.yaml @@ -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 diff --git a/e2e-tests/tests/dynamic-configuration/01-assert.yaml b/e2e-tests/tests/dynamic-configuration/01-assert.yaml new file mode 100644 index 000000000..b04ca7d97 --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/01-assert.yaml @@ -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 diff --git a/e2e-tests/tests/dynamic-configuration/01-create-cluster.yaml b/e2e-tests/tests/dynamic-configuration/01-create-cluster.yaml new file mode 100644 index 000000000..7185cfcbf --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/01-create-cluster.yaml @@ -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 - diff --git a/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml b/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml new file mode 100644 index 000000000..578c47fba --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/02-apply-configuration.yaml @@ -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" diff --git a/e2e-tests/tests/dynamic-configuration/03-assert.yaml b/e2e-tests/tests/dynamic-configuration/03-assert.yaml new file mode 100644 index 000000000..c80e19822 --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/03-assert.yaml @@ -0,0 +1,7 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: 03-pg-settings +data: + wal_level: 'replica' + restore_command: '/bin/true' diff --git a/e2e-tests/tests/dynamic-configuration/03-verify.yaml b/e2e-tests/tests/dynamic-configuration/03-verify.yaml new file mode 100644 index 000000000..62155dd69 --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/03-verify.yaml @@ -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 + + 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}" diff --git a/e2e-tests/tests/dynamic-configuration/99-remove-cluster-gracefully.yaml b/e2e-tests/tests/dynamic-configuration/99-remove-cluster-gracefully.yaml new file mode 100644 index 000000000..640eb0968 --- /dev/null +++ b/e2e-tests/tests/dynamic-configuration/99-remove-cluster-gracefully.yaml @@ -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 diff --git a/internal/postgres/parameters.go b/internal/postgres/parameters.go index bbb80b0ac..bd4c62571 100644 --- a/internal/postgres/parameters.go +++ b/internal/postgres/parameters.go @@ -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 @@ -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") + // Just-in-Time compilation can degrade performance unexpectedly. Allow // users to enable it for appropriate workloads. // - https://www.postgresql.org/docs/current/jit.html diff --git a/internal/postgres/parameters_test.go b/internal/postgres/parameters_test.go index 0720d8b42..64538cbc1 100644 --- a/internal/postgres/parameters_test.go +++ b/internal/postgres/parameters_test.go @@ -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", }) }