From 9d3defe6e5bd66064d8728a2d322f1e0e74dbee2 Mon Sep 17 00:00:00 2001 From: Itay Grudev Date: Wed, 4 Sep 2024 02:11:12 +0300 Subject: [PATCH 01/10] Added ParadeDB support to the Helm chart --- charts/cluster/templates/_bootstrap.tpl | 24 ++++++++++++++++++++---- charts/cluster/templates/_helpers.tpl | 2 ++ charts/cluster/templates/cluster.yaml | 4 ++++ charts/cluster/values.yaml | 3 +++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/charts/cluster/templates/_bootstrap.tpl b/charts/cluster/templates/_bootstrap.tpl index 81665d2e2..4d95ead8e 100644 --- a/charts/cluster/templates/_bootstrap.tpl +++ b/charts/cluster/templates/_bootstrap.tpl @@ -3,7 +3,7 @@ bootstrap: initdb: {{- with .Values.cluster.initdb }} - {{- with (omit . "postInitApplicationSQL") }} + {{- with (omit . "postInitApplicationSQL" "postInitTemplateSQL") }} {{- . | toYaml | nindent 4 }} {{- end }} {{- end }} @@ -15,11 +15,27 @@ bootstrap: - CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder; {{- else if eq .Values.type "timescaledb" }} - CREATE EXTENSION IF NOT EXISTS timescaledb; + {{- else if eq .Values.type "paradedb" }} + - CREATE EXTENSION IF NOT EXISTS pg_search; + - CREATE EXTENSION IF NOT EXISTS pg_analytics; + - CREATE EXTENSION IF NOT EXISTS pg_ivm; + - CREATE EXTENSION IF NOT EXISTS vector; + - CREATE EXTENSION IF NOT EXISTS vectorscale; + - ALTER DATABASE "{{ default "app" .Values.cluster.initdb.database }}" SET search_path TO public,paradedb; {{- end }} {{- with .Values.cluster.initdb }} - {{- range .postInitApplicationSQL }} - {{- printf "- %s" . | nindent 6 }} - {{- end -}} + {{- range .postInitApplicationSQL }} + {{- printf "- %s" . | nindent 6 }} + {{- end -}} + {{- end }} + postInitTemplateSQL: + {{- if eq .Values.type "paradedb" }} + - ALTER DATABASE template1 SET search_path TO public,paradedb; + {{- end }} + {{- with .Values.cluster.initdb }} + {{- range .postInitTemplateSQL }} + {{- printf "- %s" . | nindent 6 }} + {{- end -}} {{- end -}} {{- else if eq .Values.mode "recovery" -}} bootstrap: diff --git a/charts/cluster/templates/_helpers.tpl b/charts/cluster/templates/_helpers.tpl index 96726fdfe..b6f8a8f83 100644 --- a/charts/cluster/templates/_helpers.tpl +++ b/charts/cluster/templates/_helpers.tpl @@ -76,6 +76,8 @@ If a custom imageName is available, use it, otherwise use the defaults based on {{- printf "ghcr.io/cloudnative-pg/postgresql:%s" .Values.version.postgresql -}} {{- else if eq .Values.type "postgis" -}} {{- printf "ghcr.io/cloudnative-pg/postgis:%s-%s" .Values.version.postgresql .Values.version.postgis -}} + {{- else if eq .Values.type "paradedb" -}} + {{- printf "paradedb/paradedb:%s-v%s" .Values.version.postgresql .Values.version.paradedb -}} {{- else -}} {{ fail "Invalid cluster type!" }} {{- end }} diff --git a/charts/cluster/templates/cluster.yaml b/charts/cluster/templates/cluster.yaml index c1879cfef..fd78ce305 100644 --- a/charts/cluster/templates/cluster.yaml +++ b/charts/cluster/templates/cluster.yaml @@ -55,6 +55,10 @@ spec: shared_preload_libraries: {{- if eq .Values.type "timescaledb" }} - timescaledb + {{- else if eq .Values.type "paradedb" }} + - pg_search + - pg_analytics + - pg_cron {{- end }} {{- with .Values.cluster.postgresql.shared_preload_libraries }} {{- toYaml . | nindent 6 }} diff --git a/charts/cluster/values.yaml b/charts/cluster/values.yaml index 8398c74d1..1a68b953f 100644 --- a/charts/cluster/values.yaml +++ b/charts/cluster/values.yaml @@ -8,6 +8,7 @@ fullnameOverride: "" # * `postgresql` # * `postgis` # * `timescaledb` +# * `paradedb` type: postgresql version: @@ -17,6 +18,8 @@ version: timescaledb: "2.15" # -- If using PostGIS, specify the version postgis: "3.4" + # -- If using ParadeDB, specify the version + paradedb: "0.9.3" ### # -- Cluster mode of operation. Available modes: From 48e03c5e539cbadc08662886aecd500428a0ba38 Mon Sep 17 00:00:00 2001 From: Itay Grudev Date: Wed, 4 Sep 2024 02:11:33 +0300 Subject: [PATCH 02/10] ParadeDB Test suite --- .../00-minio_cleanup-assert.yaml | 6 + .../00-minio_cleanup.yaml | 16 +++ .../01-paradedb_cluster-assert.yaml | 6 + .../01-paradedb_cluster.yaml | 26 ++++ .../02-paradedb_write-assert.yaml | 6 + .../02-paradedb_write.yaml | 35 +++++ .../03-paradedb_test-assert.yaml | 6 + .../03-paradedb_test.yaml | 27 ++++ .../04-data_write-assert.yaml | 6 + .../04-data_write.yaml | 23 +++ .../05-backup.yaml | 8 ++ .../05-backup_completed-assert.yaml | 10 ++ .../05-backup_running-assert.yaml | 10 ++ .../05-checkpoint.yaml | 27 ++++ .../06-post_backup_data_write-assert.yaml | 6 + .../06-post_backup_data_write.yaml | 57 ++++++++ ...7-recovery_backup_pitr_cluster-assert.yaml | 6 + .../07-recovery_backup_pitr_cluster.yaml | 48 +++++++ .../08-data_test-assert.yaml | 6 + .../08-data_test.yaml | 27 ++++ .../chainsaw-test.yaml | 136 ++++++++++++++++++ 21 files changed, 498 insertions(+) create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/00-minio_cleanup-assert.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/00-minio_cleanup.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/01-paradedb_cluster-assert.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/01-paradedb_cluster.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write-assert.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test-assert.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/04-data_write-assert.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/04-data_write.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/05-backup.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/05-backup_completed-assert.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/05-backup_running-assert.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/05-checkpoint.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write-assert.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/07-recovery_backup_pitr_cluster-assert.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/07-recovery_backup_pitr_cluster.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/08-data_test-assert.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/08-data_test.yaml create mode 100644 charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml diff --git a/charts/cluster/test/paradedb-minio-backup-restore/00-minio_cleanup-assert.yaml b/charts/cluster/test/paradedb-minio-backup-restore/00-minio_cleanup-assert.yaml new file mode 100644 index 000000000..9c0f3eb48 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/00-minio_cleanup-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: minio-cleanup +status: + succeeded: 1 diff --git a/charts/cluster/test/paradedb-minio-backup-restore/00-minio_cleanup.yaml b/charts/cluster/test/paradedb-minio-backup-restore/00-minio_cleanup.yaml new file mode 100644 index 000000000..19d550162 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/00-minio_cleanup.yaml @@ -0,0 +1,16 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: minio-cleanup +spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: minio-cleanup + image: minio/mc + command: ['sh', '-c'] + args: + - | + mc alias set myminio https://minio.minio.svc.cluster.local minio minio123 + mc rm --recursive --force myminio/mybucket/paradedb diff --git a/charts/cluster/test/paradedb-minio-backup-restore/01-paradedb_cluster-assert.yaml b/charts/cluster/test/paradedb-minio-backup-restore/01-paradedb_cluster-assert.yaml new file mode 100644 index 000000000..8b243d630 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/01-paradedb_cluster-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: paradedb-cluster +status: + readyInstances: 2 diff --git a/charts/cluster/test/paradedb-minio-backup-restore/01-paradedb_cluster.yaml b/charts/cluster/test/paradedb-minio-backup-restore/01-paradedb_cluster.yaml new file mode 100644 index 000000000..ed0c19c8c --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/01-paradedb_cluster.yaml @@ -0,0 +1,26 @@ +type: paradedb +mode: standalone +cluster: + instances: 2 + storage: + size: 256Mi + +backups: + enabled: true + provider: s3 + endpointURL: "https://minio.minio.svc.cluster.local" + endpointCA: + name: kube-root-ca.crt + key: ca.crt + wal: + encryption: "" + data: + encryption: "" + s3: + bucket: "mybucket" + path: "/paradedb/v1" + accessKey: "minio" + secretKey: "minio123" + region: "local" + scheduledBackups: [] + retentionPolicy: "30d" diff --git a/charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write-assert.yaml b/charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write-assert.yaml new file mode 100644 index 000000000..3fac848be --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: paradedb-write +status: + succeeded: 1 diff --git a/charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write.yaml b/charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write.yaml new file mode 100644 index 000000000..8365921a5 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write.yaml @@ -0,0 +1,35 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: paradedb-write +spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: data-write + env: + - name: DB_URI + valueFrom: + secretKeyRef: + name: paradedb-cluster-app + key: uri + image: alpine:3.19 + command: ['sh', '-c'] + args: + - | + apk --no-cache add postgresql-client + psql "$DB_URI" <<-EOSQL + CALL paradedb.create_bm25_test_table( schema_name => 'public', table_name => 'mock_items' ); + CALL paradedb.create_bm25( + index_name => 'search_idx', + schema_name => 'public', + table_name => 'mock_items', + key_field => 'id', + text_fields => paradedb.field('description', tokenizer => paradedb.tokenizer('en_stem')) || + paradedb.field('category'), + numeric_fields => paradedb.field('rating') + ); + EOSQL + + diff --git a/charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test-assert.yaml b/charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test-assert.yaml new file mode 100644 index 000000000..678c11c9b --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: paradedb-test +status: + succeeded: 1 diff --git a/charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test.yaml b/charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test.yaml new file mode 100644 index 000000000..200ab6b54 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test.yaml @@ -0,0 +1,27 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: paradedb-test +spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: data-test + env: + - name: DB_URI + valueFrom: + secretKeyRef: + name: paradedb-cluster-app + key: uri + image: alpine:3.19 + command: ['sh', '-c'] + args: + - | + apk --no-cache add postgresql-client + RESULT=$(psql "$DB_URI" -t) <<-EOSQL + SELECT description + FROM search_idx.search('description:"bluetooth speaker"~1'); + EOSQL + echo -$RESULT- + test "$RESULT" = " Bluetooth-enabled speaker" \ No newline at end of file diff --git a/charts/cluster/test/paradedb-minio-backup-restore/04-data_write-assert.yaml b/charts/cluster/test/paradedb-minio-backup-restore/04-data_write-assert.yaml new file mode 100644 index 000000000..831f963d9 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/04-data_write-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: data-write +status: + succeeded: 1 diff --git a/charts/cluster/test/paradedb-minio-backup-restore/04-data_write.yaml b/charts/cluster/test/paradedb-minio-backup-restore/04-data_write.yaml new file mode 100644 index 000000000..f39fdb137 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/04-data_write.yaml @@ -0,0 +1,23 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: data-write +spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: data-write + env: + - name: DB_URI + valueFrom: + secretKeyRef: + name: paradedb-cluster-superuser + key: uri + image: alpine:3.19 + command: ['sh', '-c'] + args: + - | + apk --no-cache add postgresql-client kubectl + DB_URI=$(echo $DB_URI | sed "s|/\*|/|" ) + psql "$DB_URI" -c "CREATE TABLE mygoodtable (id serial PRIMARY KEY);" diff --git a/charts/cluster/test/paradedb-minio-backup-restore/05-backup.yaml b/charts/cluster/test/paradedb-minio-backup-restore/05-backup.yaml new file mode 100644 index 000000000..543c9c110 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/05-backup.yaml @@ -0,0 +1,8 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Backup +metadata: + name: post-init-backup +spec: + method: barmanObjectStore + cluster: + name: paradedb-cluster diff --git a/charts/cluster/test/paradedb-minio-backup-restore/05-backup_completed-assert.yaml b/charts/cluster/test/paradedb-minio-backup-restore/05-backup_completed-assert.yaml new file mode 100644 index 000000000..013b0aad5 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/05-backup_completed-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Backup +metadata: + name: post-init-backup +spec: + cluster: + name: paradedb-cluster + method: barmanObjectStore +status: + phase: completed diff --git a/charts/cluster/test/paradedb-minio-backup-restore/05-backup_running-assert.yaml b/charts/cluster/test/paradedb-minio-backup-restore/05-backup_running-assert.yaml new file mode 100644 index 000000000..6610deb8f --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/05-backup_running-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Backup +metadata: + name: post-init-backup +spec: + cluster: + name: paradedb-cluster + method: barmanObjectStore +status: + phase: running diff --git a/charts/cluster/test/paradedb-minio-backup-restore/05-checkpoint.yaml b/charts/cluster/test/paradedb-minio-backup-restore/05-checkpoint.yaml new file mode 100644 index 000000000..bf886cc7b --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/05-checkpoint.yaml @@ -0,0 +1,27 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: backup-checkpoint +spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: create-checkpoint + env: + - name: DB_URI + valueFrom: + secretKeyRef: + name: paradedb-cluster-superuser + key: uri + image: alpine:3.19 + command: ['sh', '-c'] + args: + - | + apk --no-cache add postgresql-client + DB_URI=$(echo $DB_URI | sed "s|/\*|/|" ) + END_TIME=$(( $(date +%s) + 30 )) + while [ $(date +%s) -lt $END_TIME ]; do + psql "$DB_URI" -c "SELECT pg_switch_wal();CHECKPOINT;" + sleep 5 + done diff --git a/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write-assert.yaml b/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write-assert.yaml new file mode 100644 index 000000000..ad9be77a7 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: data-write-post-backup +status: + succeeded: 1 diff --git a/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml b/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml new file mode 100644 index 000000000..405f45e58 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml @@ -0,0 +1,57 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: configmap-creator-sa +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: configmap-creator +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: configmap-creator-binding +subjects: +- kind: ServiceAccount + name: configmap-creator-sa +roleRef: + kind: Role + name: configmap-creator + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: data-write-post-backup +spec: + template: + spec: + serviceAccountName: configmap-creator-sa + restartPolicy: OnFailure + containers: + - name: data-write + env: + - name: DB_URI + valueFrom: + secretKeyRef: + name: paradedb-cluster-superuser + key: uri + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: alpine:3.19 + command: ['sh', '-c'] + args: + - | + apk --no-cache add postgresql-client kubectl coreutils + DB_URI=$(echo $DB_URI | sed "s|/\*|/|" ) + DATE_NO_BAD_TABLE=$(date --rfc-3339=ns) + sleep 30 + psql "$DB_URI" -c "CREATE TABLE mybadtable (id serial PRIMARY KEY);" + kubectl create configmap date-no-bad-table --from-literal=date="$DATE_NO_BAD_TABLE" diff --git a/charts/cluster/test/paradedb-minio-backup-restore/07-recovery_backup_pitr_cluster-assert.yaml b/charts/cluster/test/paradedb-minio-backup-restore/07-recovery_backup_pitr_cluster-assert.yaml new file mode 100644 index 000000000..2b6b9651f --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/07-recovery_backup_pitr_cluster-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: recovery-backup-pitr-cluster +status: + readyInstances: 2 diff --git a/charts/cluster/test/paradedb-minio-backup-restore/07-recovery_backup_pitr_cluster.yaml b/charts/cluster/test/paradedb-minio-backup-restore/07-recovery_backup_pitr_cluster.yaml new file mode 100644 index 000000000..8031e3c2b --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/07-recovery_backup_pitr_cluster.yaml @@ -0,0 +1,48 @@ +type: paradedb +mode: recovery + +cluster: + instances: 2 + storage: + size: 256Mi + +recovery: + method: backup + backupName: "post-init-backup" + provider: s3 + endpointURL: "https://minio.minio.svc.cluster.local" + endpointCA: + name: kube-root-ca.crt + key: ca.crt + wal: + encryption: "" + data: + encryption: "" + s3: + bucket: "mybucket" + path: "/paradedb/v1" + accessKey: "minio" + secretKey: "minio123" + region: "local" + scheduledBackups: [] + retentionPolicy: "30d" + +backups: + enabled: true + provider: s3 + endpointURL: "https://minio.minio.svc.cluster.local" + endpointCA: + name: kube-root-ca.crt + key: ca.crt + wal: + encryption: "" + data: + encryption: "" + s3: + bucket: "mybucket" + path: "/paradedb/v2" + accessKey: "minio" + secretKey: "minio123" + region: "local" + scheduledBackups: [] + retentionPolicy: "30d" diff --git a/charts/cluster/test/paradedb-minio-backup-restore/08-data_test-assert.yaml b/charts/cluster/test/paradedb-minio-backup-restore/08-data_test-assert.yaml new file mode 100644 index 000000000..6f14d5f23 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/08-data_test-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: data-test-backup-pitr +status: + succeeded: 1 diff --git a/charts/cluster/test/paradedb-minio-backup-restore/08-data_test.yaml b/charts/cluster/test/paradedb-minio-backup-restore/08-data_test.yaml new file mode 100644 index 000000000..5fb4faf39 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/08-data_test.yaml @@ -0,0 +1,27 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: data-test-backup-pitr +spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: data-test + env: + - name: DB_URI + valueFrom: + secretKeyRef: + name: recovery-backup-pitr-cluster-superuser + key: uri + image: alpine:3.19 + command: ['sh', '-c'] + args: + - | + apk --no-cache add postgresql-client + DB_URI=$(echo $DB_URI | sed "s|/\*|/|" ) + set -e + test "$(psql $DB_URI -t -c 'SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = $$mygoodtable$$)' --csv -q 2>/dev/null)" = "t" + echo "Good table exists" + test "$(psql $DB_URI -t -c 'SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = $$mybadtable$$)' --csv -q 2>/dev/null)" = "f" + echo "Bad table does not exist" diff --git a/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml b/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml new file mode 100644 index 000000000..a9537ca96 --- /dev/null +++ b/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml @@ -0,0 +1,136 @@ +## +# This test sets up a ParadeDB cluster with MinIO backups and ensured that ParadeDB extensions are installed and +# PITR recovery is enabled and working. +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: paradedb +spec: + timeouts: + apply: 1s + assert: 5m + cleanup: 1m + steps: + - name: Clear the MinIO bucket + try: + - apply: + file: ./00-minio_cleanup.yaml + - assert: + file: ./00-minio_cleanup-assert.yaml + - name: Install a standalone ParadeDB cluster + try: + - script: + content: | + kubectl -n $NAMESPACE create secret generic kube-root-ca.crt --from-literal=ca.crt="$(kubectl -n kube-system get configmaps kube-root-ca.crt -o jsonpath='{.data.ca\.crt}')" --dry-run=client -o yaml | kubectl apply -f - + helm upgrade \ + --install \ + --namespace $NAMESPACE \ + --values ./01-paradedb_cluster.yaml \ + --wait \ + paradedb ../../ + - assert: + file: ./01-paradedb_cluster-assert.yaml + catch: + - describe: + apiVersion: postgresql.cnpg.io/v1 + kind: Cluster + - name: Initialize with ParadeDB sample data + timeouts: + apply: 1s + assert: 10s + try: + - apply: + file: ./02-paradedb_write.yaml + - assert: + file: ./02-paradedb_write-assert.yaml + catch: + - describe: + apiVersion: batch/v1 + kind: Job + - podLogs: + selector: batch.kubernetes.io/job-name=data-write + - name: Verify ParadeDB extensions are installed + timeouts: + apply: 1s + assert: 30s + try: + - apply: + file: 03-paradedb_test.yaml + - assert: + file: 03-paradedb_test-assert.yaml + catch: + - describe: + apiVersion: batch/v1 + kind: Job + - podLogs: + selector: batch.kubernetes.io/job-name=data-test + - name: Write some data to the cluster + timeouts: + apply: 1s + assert: 30s + try: + - apply: + file: 04-data_write.yaml + - assert: + file: 04-data_write-assert.yaml + catch: + - describe: + apiVersion: batch/v1 + kind: Job + - podLogs: + selector: batch.kubernetes.io/job-name=data-test + - name: Create a backup + try: + - apply: + file: ./05-backup.yaml + - assert: + file: ./05-backup_running-assert.yaml + - apply: + file: ./05-checkpoint.yaml + - assert: + file: ./05-backup_completed-assert.yaml + - name: Write more data to the database after the backup + try: + - apply: + file: ./06-post_backup_data_write.yaml + - assert: + file: ./06-post_backup_data_write-assert.yaml + timeouts: + apply: 1s + assert: 10m + catch: + - describe: + apiVersion: postgresql.cnpg.io/v1 + kind: Backup + - name: Create a recovery cluster from backup with a PITR target + try: + - script: + content: | + DATE_NO_BAD_TABLE=$(kubectl -n $NAMESPACE get configmap date-no-bad-table -o 'jsonpath={.data.date}') + helm upgrade \ + --install \ + --namespace $NAMESPACE \ + --values ./07-recovery_backup_pitr_cluster.yaml \ + --set recovery.pitrTarget.time="$DATE_NO_BAD_TABLE" \ + --wait \ + recovery-backup-pitr ../../ + - assert: + file: ./07-recovery_backup_pitr_cluster-assert.yaml + - name: Verify the pre-backup data on the recovery cluster exists but not the post-backup data + try: + - apply: + file: 08-data_test.yaml + - assert: + file: 08-data_test-assert.yaml + catch: + - describe: + apiVersion: batch/v1 + kind: Job + selector: batch.kubernetes.io/job-name=data-test-backup-pitr + - podLogs: + selector: batch.kubernetes.io/job-name=data-test-backup-pitr + - name: Cleanup + try: + - script: + content: | + helm uninstall --namespace $NAMESPACE paradedb From 88bfe597160e0037b1725974f23482372a8d7980 Mon Sep 17 00:00:00 2001 From: Itay Grudev Date: Mon, 9 Sep 2024 03:36:09 +0300 Subject: [PATCH 03/10] Bug Fix: Test suite false positive --- .../04-data_write.yaml | 33 +++++++++++++++++- .../06-post_backup_data_write.yaml | 34 ++----------------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/charts/cluster/test/paradedb-minio-backup-restore/04-data_write.yaml b/charts/cluster/test/paradedb-minio-backup-restore/04-data_write.yaml index f39fdb137..646c7e6de 100644 --- a/charts/cluster/test/paradedb-minio-backup-restore/04-data_write.yaml +++ b/charts/cluster/test/paradedb-minio-backup-restore/04-data_write.yaml @@ -1,3 +1,29 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: configmap-creator-sa +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: configmap-creator +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: configmap-creator-binding +subjects: +- kind: ServiceAccount + name: configmap-creator-sa +roleRef: + kind: Role + name: configmap-creator + apiGroup: rbac.authorization.k8s.io +--- apiVersion: batch/v1 kind: Job metadata: @@ -5,6 +31,7 @@ metadata: spec: template: spec: + serviceAccountName: configmap-creator-sa restartPolicy: OnFailure containers: - name: data-write @@ -18,6 +45,10 @@ spec: command: ['sh', '-c'] args: - | - apk --no-cache add postgresql-client kubectl + apk --no-cache add postgresql-client kubectl coreutils DB_URI=$(echo $DB_URI | sed "s|/\*|/|" ) psql "$DB_URI" -c "CREATE TABLE mygoodtable (id serial PRIMARY KEY);" + sleep 5 + DATE_NO_BAD_TABLE=$(date --rfc-3339=ns) + kubectl create configmap date-no-bad-table --from-literal=date="$DATE_NO_BAD_TABLE" + sleep 5 diff --git a/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml b/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml index 405f45e58..7729a7c62 100644 --- a/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml +++ b/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml @@ -1,29 +1,3 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: configmap-creator-sa ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: configmap-creator -rules: -- apiGroups: [""] - resources: ["configmaps"] - verbs: ["create"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: configmap-creator-binding -subjects: -- kind: ServiceAccount - name: configmap-creator-sa -roleRef: - kind: Role - name: configmap-creator - apiGroup: rbac.authorization.k8s.io ---- apiVersion: batch/v1 kind: Job metadata: @@ -31,7 +5,6 @@ metadata: spec: template: spec: - serviceAccountName: configmap-creator-sa restartPolicy: OnFailure containers: - name: data-write @@ -49,9 +22,6 @@ spec: command: ['sh', '-c'] args: - | - apk --no-cache add postgresql-client kubectl coreutils + apk --no-cache add postgresql-client DB_URI=$(echo $DB_URI | sed "s|/\*|/|" ) - DATE_NO_BAD_TABLE=$(date --rfc-3339=ns) - sleep 30 - psql "$DB_URI" -c "CREATE TABLE mybadtable (id serial PRIMARY KEY);" - kubectl create configmap date-no-bad-table --from-literal=date="$DATE_NO_BAD_TABLE" + psql "$DB_URI" -c "CREATE TABLE mybadtable (id serial PRIMARY KEY);" \ No newline at end of file From d6468b366463d58ee345f0ad2e3cd1d50def9fb6 Mon Sep 17 00:00:00 2001 From: Itay Grudev Date: Mon, 9 Sep 2024 04:08:15 +0300 Subject: [PATCH 04/10] Addressed comments --- charts/cluster/README.md | 3 ++- charts/cluster/templates/_bootstrap.tpl | 12 +++++------- .../03-paradedb_test.yaml | 2 +- charts/cluster/values.schema.json | 3 +++ 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/charts/cluster/README.md b/charts/cluster/README.md index 5b3fcd204..476746d7d 100644 --- a/charts/cluster/README.md +++ b/charts/cluster/README.md @@ -241,7 +241,8 @@ refer to the [CloudNativePG Documentation](https://cloudnative-pg.io/documentat | recovery.s3.secretKey | string | `""` | | | recovery.secret.create | bool | `true` | Whether to create a secret for the backup credentials | | recovery.secret.name | string | `""` | Name of the backup credentials secret | -| type | string | `"postgresql"` | Type of the CNPG database. Available types: * `postgresql` * `postgis` * `timescaledb` | +| type | string | `"postgresql"` | Type of the CNPG database. Available types: * `postgresql` * `postgis` * `timescaledb` * `paradedb` | +| version.paradedb | string | `"0.9.3"` | If using ParadeDB, specify the version | | version.postgis | string | `"3.4"` | If using PostGIS, specify the version | | version.postgresql | string | `"16"` | PostgreSQL major version to use | | version.timescaledb | string | `"2.15"` | If using TimescaleDB, specify the version | diff --git a/charts/cluster/templates/_bootstrap.tpl b/charts/cluster/templates/_bootstrap.tpl index 4d95ead8e..597aacd36 100644 --- a/charts/cluster/templates/_bootstrap.tpl +++ b/charts/cluster/templates/_bootstrap.tpl @@ -15,13 +15,6 @@ bootstrap: - CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder; {{- else if eq .Values.type "timescaledb" }} - CREATE EXTENSION IF NOT EXISTS timescaledb; - {{- else if eq .Values.type "paradedb" }} - - CREATE EXTENSION IF NOT EXISTS pg_search; - - CREATE EXTENSION IF NOT EXISTS pg_analytics; - - CREATE EXTENSION IF NOT EXISTS pg_ivm; - - CREATE EXTENSION IF NOT EXISTS vector; - - CREATE EXTENSION IF NOT EXISTS vectorscale; - - ALTER DATABASE "{{ default "app" .Values.cluster.initdb.database }}" SET search_path TO public,paradedb; {{- end }} {{- with .Values.cluster.initdb }} {{- range .postInitApplicationSQL }} @@ -30,6 +23,11 @@ bootstrap: {{- end }} postInitTemplateSQL: {{- if eq .Values.type "paradedb" }} + - CREATE EXTENSION IF NOT EXISTS pg_search; + - CREATE EXTENSION IF NOT EXISTS pg_analytics; + - CREATE EXTENSION IF NOT EXISTS pg_ivm; + - CREATE EXTENSION IF NOT EXISTS vector; + - CREATE EXTENSION IF NOT EXISTS vectorscale; - ALTER DATABASE template1 SET search_path TO public,paradedb; {{- end }} {{- with .Values.cluster.initdb }} diff --git a/charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test.yaml b/charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test.yaml index 200ab6b54..52a489df5 100644 --- a/charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test.yaml +++ b/charts/cluster/test/paradedb-minio-backup-restore/03-paradedb_test.yaml @@ -24,4 +24,4 @@ spec: FROM search_idx.search('description:"bluetooth speaker"~1'); EOSQL echo -$RESULT- - test "$RESULT" = " Bluetooth-enabled speaker" \ No newline at end of file + test "$RESULT" = " Bluetooth-enabled speaker" diff --git a/charts/cluster/values.schema.json b/charts/cluster/values.schema.json index 9e35d7a90..6b81ab0ac 100644 --- a/charts/cluster/values.schema.json +++ b/charts/cluster/values.schema.json @@ -588,6 +588,9 @@ "version": { "type": "object", "properties": { + "paradedb": { + "type": "string" + }, "postgis": { "type": "string" }, From 36358cf26982d71cfec72a9ce159b4adbab3bf67 Mon Sep 17 00:00:00 2001 From: Itay Grudev Date: Mon, 9 Sep 2024 04:25:33 +0300 Subject: [PATCH 05/10] Bug Fix: Recovery not working if extensions are only specified in template sql --- charts/cluster/templates/_bootstrap.tpl | 7 +++++++ .../test/paradedb-minio-backup-restore/chainsaw-test.yaml | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/charts/cluster/templates/_bootstrap.tpl b/charts/cluster/templates/_bootstrap.tpl index 597aacd36..87f27303f 100644 --- a/charts/cluster/templates/_bootstrap.tpl +++ b/charts/cluster/templates/_bootstrap.tpl @@ -15,6 +15,13 @@ bootstrap: - CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder; {{- else if eq .Values.type "timescaledb" }} - CREATE EXTENSION IF NOT EXISTS timescaledb; + {{- else if eq .Values.type "paradedb" }} + - CREATE EXTENSION IF NOT EXISTS pg_search; + - CREATE EXTENSION IF NOT EXISTS pg_analytics; + - CREATE EXTENSION IF NOT EXISTS pg_ivm; + - CREATE EXTENSION IF NOT EXISTS vector; + - CREATE EXTENSION IF NOT EXISTS vectorscale; + - ALTER DATABASE "{{ default "app" .Values.cluster.initdb.database }}" SET search_path TO public,paradedb; {{- end }} {{- with .Values.cluster.initdb }} {{- range .postInitApplicationSQL }} diff --git a/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml b/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml index a9537ca96..4dd8108ae 100644 --- a/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml +++ b/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml @@ -34,6 +34,8 @@ spec: - describe: apiVersion: postgresql.cnpg.io/v1 kind: Cluster + - podLogs: + selector: cnpg.io/cluster=paradedb-cluster - name: Initialize with ParadeDB sample data timeouts: apply: 1s @@ -116,6 +118,12 @@ spec: recovery-backup-pitr ../../ - assert: file: ./07-recovery_backup_pitr_cluster-assert.yaml + catch: + - describe: + apiVersion: postgresql.cnpg.io/v1 + kind: Cluster + - podLogs: + selector: cnpg.io/cluster=paradedb-cluster - name: Verify the pre-backup data on the recovery cluster exists but not the post-backup data try: - apply: From 8a37c8db506ce4cdcafbcda803a96627f4e21881 Mon Sep 17 00:00:00 2001 From: Itay Grudev Date: Mon, 9 Sep 2024 06:09:03 +0300 Subject: [PATCH 06/10] Missing mention in the chart README --- charts/cluster/README.md.gotmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/charts/cluster/README.md.gotmpl b/charts/cluster/README.md.gotmpl index e1a4d2f05..5f53a129f 100644 --- a/charts/cluster/README.md.gotmpl +++ b/charts/cluster/README.md.gotmpl @@ -69,6 +69,8 @@ Cluster Configuration Currently the chart supports two database types. These are configured via the `type` parameter. These are: * `postgresql` - A standard PostgreSQL database. * `postgis` - A PostgreSQL database with the PostGIS extension installed. +* `timescaledb` - A PostgreSQL database with the TimescaleDB extension installed. +* `paradedb` - A PostgreSQL database with the ParadeDB extension installed. Depending on the type the chart will use a different Docker image and fill in some initial setup, like extension installation. From 3b392dad03c64754653c919b75d9ea560b812094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20No=C3=ABl?= <21990816+philippemnoel@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:04:02 -0700 Subject: [PATCH 07/10] Update chainsaw-test.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Typo Signed-off-by: Philippe Noël <21990816+philippemnoel@users.noreply.github.com> --- .../test/paradedb-minio-backup-restore/chainsaw-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml b/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml index 4dd8108ae..7af6da771 100644 --- a/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml +++ b/charts/cluster/test/paradedb-minio-backup-restore/chainsaw-test.yaml @@ -1,5 +1,5 @@ ## -# This test sets up a ParadeDB cluster with MinIO backups and ensured that ParadeDB extensions are installed and +# This test sets up a ParadeDB cluster with MinIO backups and ensures that ParadeDB extensions are installed and # PITR recovery is enabled and working. apiVersion: chainsaw.kyverno.io/v1alpha1 kind: Test From d4aab97a4eae4b7d7756c8760dbac0a80196f7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20No=C3=ABl?= <21990816+philippemnoel@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:04:47 -0700 Subject: [PATCH 08/10] Extra newlines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Noël <21990816+philippemnoel@users.noreply.github.com> --- .../test/paradedb-minio-backup-restore/02-paradedb_write.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write.yaml b/charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write.yaml index 8365921a5..a2b669e5c 100644 --- a/charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write.yaml +++ b/charts/cluster/test/paradedb-minio-backup-restore/02-paradedb_write.yaml @@ -31,5 +31,3 @@ spec: numeric_fields => paradedb.field('rating') ); EOSQL - - From 49221eeb9f756c7f559be90d13e6e0f81289ff32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20No=C3=ABl?= <21990816+philippemnoel@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:05:14 -0700 Subject: [PATCH 09/10] newline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Noël <21990816+philippemnoel@users.noreply.github.com> --- .../06-post_backup_data_write.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml b/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml index 7729a7c62..8490de2c9 100644 --- a/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml +++ b/charts/cluster/test/paradedb-minio-backup-restore/06-post_backup_data_write.yaml @@ -24,4 +24,4 @@ spec: - | apk --no-cache add postgresql-client DB_URI=$(echo $DB_URI | sed "s|/\*|/|" ) - psql "$DB_URI" -c "CREATE TABLE mybadtable (id serial PRIMARY KEY);" \ No newline at end of file + psql "$DB_URI" -c "CREATE TABLE mybadtable (id serial PRIMARY KEY);" From 1fb0c023958f507d0af0c33b8d2171c990d3ff92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20No=C3=ABl?= <21990816+philippemnoel@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:05:31 -0700 Subject: [PATCH 10/10] Update charts/cluster/README.md.gotmpl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Noël <21990816+philippemnoel@users.noreply.github.com> --- charts/cluster/README.md.gotmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/cluster/README.md.gotmpl b/charts/cluster/README.md.gotmpl index 5f53a129f..2a7fd1023 100644 --- a/charts/cluster/README.md.gotmpl +++ b/charts/cluster/README.md.gotmpl @@ -70,7 +70,7 @@ Currently the chart supports two database types. These are configured via the `t * `postgresql` - A standard PostgreSQL database. * `postgis` - A PostgreSQL database with the PostGIS extension installed. * `timescaledb` - A PostgreSQL database with the TimescaleDB extension installed. -* `paradedb` - A PostgreSQL database with the ParadeDB extension installed. +* `paradedb` - A PostgreSQL database with the ParadeDB extensions (`pg_search` and `pg_analytics`) installed. Depending on the type the chart will use a different Docker image and fill in some initial setup, like extension installation.