From f167cfb1961a76be0cdea484c3aa5c7355f302a9 Mon Sep 17 00:00:00 2001 From: Lajus Date: Wed, 12 Nov 2025 11:27:21 +0100 Subject: [PATCH 01/49] Updated httpd and redcap configurations --- charts/redcap/configuration/httpd/httpd.conf | 3 ++- .../configuration/redcap/init/redcap-config.sh | 2 +- charts/redcap/templates/_helpers.tpl | 15 ++++++++++++--- charts/redcap/values.schema.json | 2 +- charts/redcap/values.yaml | 4 ++-- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/charts/redcap/configuration/httpd/httpd.conf b/charts/redcap/configuration/httpd/httpd.conf index 0b416ac..58881ad 100644 --- a/charts/redcap/configuration/httpd/httpd.conf +++ b/charts/redcap/configuration/httpd/httpd.conf @@ -377,8 +377,9 @@ EnableSendfile on # Maps the fastcgi server to the root URL space + DirectorySlash On ProxyPassMatch "^/(.*\.php(/.*)?)$" "fcgi://{{ include `redcap.serviceName` . }}:{{ .Values.services.redcap.port }}/var/www/redcap/$1" timeout=3600 enablereuse=on - DirectoryIndex /index.php index.php + DirectoryIndex index.php #/index.php diff --git a/charts/redcap/configuration/redcap/init/redcap-config.sh b/charts/redcap/configuration/redcap/init/redcap-config.sh index c71e02b..8b9c5be 100644 --- a/charts/redcap/configuration/redcap/init/redcap-config.sh +++ b/charts/redcap/configuration/redcap/init/redcap-config.sh @@ -26,7 +26,7 @@ mysql \ --user={{ .Values.redcap.config.database.auth.username }} \ --password=${DB_PASSWD} \ --database={{ .Values.redcap.config.database.auth.databaseName }} < Date: Wed, 12 Nov 2025 14:37:21 +0100 Subject: [PATCH 02/49] Updated values to run bitnamilegacy images --- charts/redcap/values.yaml | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index c45bca0..ec2acb6 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -266,6 +266,21 @@ redcap: # See original documentation @ https://github.com/bitnami/charts/tree/main/bitnami/mysql # @section -- REDCap MySQL Database settings mysql: + + global: + security: + # -- Set to true to enable bitnami charts to use insecure images like bitmani legacy images. + # @section -- REDCap MySQL Database settings + allowInsecureImages: true + + image: + # -- Image repository for MySQL image. + # @section -- REDCap MySQL Database settings + repository: bitnamilegacy/mysql + # -- Image tag for MySQL image. + # @section -- REDCap MySQL Database settings + tag: 9.4.0-debian-12-r1 + # -- Override of the full name of the MySQL Database deployment. # Impacts the name of the services REDCap will use to connect to the Database. # @section -- REDCap MySQL Database settings @@ -359,7 +374,7 @@ backupJob: image: # -- Image repository for the REDCap database backup container. # @section -- REDCap Backup Job's settings - repository: "bitnami/mysql" + repository: "bitnamilegacy/mysql" # -- Image tag for the REDCap database backup container. # @section -- REDCap Backup Job's settings tag: "9.3.0-debian-12-r1" @@ -442,7 +457,7 @@ restoreJob: image: # -- Image repository for the REDCap database restore container. # @section -- REDCap Restore Job's settings - repository: "bitnami/mysql" + repository: "bitnamilegacy/mysql" # -- Image yag for the REDCap application restore container. # @section -- REDCap Restore Job's settings tag: "9.3.0-debian-12-r1" @@ -503,6 +518,23 @@ audit: # @section -- REDCap Audit Log Shipper settings enabled: false + + + global: + security: + # -- Set to true to enable bitnami charts to use insecure images like bitmani legacy images. + # @section -- REDCap Audit Log Shipper settings + allowInsecureImages: true + + + image: + # -- Image repository for Logstash. + # @section -- REDCap Audit Log Shipper settings + repository: bitnamilegacy/logstash + # -- Image tag for Logstash. + # @section -- REDCap Audit Log Shipper settings + tag: 9.1.2-debian-12-r0 + podLabels: # -- Role to set for the networkPolicies. Not to be changed, unless you know exactly what you are doing! # @section -- REDCap Audit Log Shipper settings From 7cb3defafc6716e2ee18838ca0850bbc0023561e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Fri, 14 Nov 2025 14:01:33 +0100 Subject: [PATCH 03/49] Updated redcapBaseUrl format to match DNS --- charts/redcap/templates/_helpers.tpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/redcap/templates/_helpers.tpl b/charts/redcap/templates/_helpers.tpl index d7f02e7..d5f7ab6 100644 --- a/charts/redcap/templates/_helpers.tpl +++ b/charts/redcap/templates/_helpers.tpl @@ -286,8 +286,8 @@ Create the url that redcap will use as redcap_base_url */}} {{- define "redcap.redcapBaseUrl" -}} {{- if .Values.httpd.tls.enabled }} -https://{{ include `httpd.serviceName` . }}:1443 +https://{{ .Values.redcap.config.externalURL }} {{- else }} -http://{{ include `httpd.serviceName` . }}:1080 +http://{{ .Values.redcap.config.externalURL }} {{- end }} {{- end }} \ No newline at end of file From 749de17069d3e87693cd1aeae6340c1a35790ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Mon, 17 Nov 2025 13:55:11 +0100 Subject: [PATCH 04/49] Unpadted sync from main --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0425d59..cce08ae 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![redcap-helmchart-ci](https://github.com/aphp/redcap-helmchart/actions/workflows/chart-ci.yaml/badge.svg)](https://github.com/aphp/redcap-helmchart/actions/workflows/chart-ci.yaml) [![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/aphp-redcap)](https://artifacthub.io/packages/search?repo=aphp-redcap) -## Presentation +## Presentation This repository hosts the REDCap Helm Chart developed by the Greater Paris University Hospitals (`APHP` in French - Assistance Publique des Hôpitaux de Paris). This Chart allows for a cloud-native and cloud-agnostic deployment of REDCap, a secure web application for building and managing online surveys and databases. From 7638f01f25e99ddcd75cea1aa066207fed47aafc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Mon, 17 Nov 2025 16:49:44 +0100 Subject: [PATCH 05/49] Better config architure --- charts/redcap/README.md | 12 +- charts/redcap/configuration/httpd/httpd.conf | 2 +- .../redcap/init/redcap-config.sh | 2 +- charts/redcap/templates/_helpers.tpl | 8 +- charts/redcap/values.schema.json | 489 +++++++++--------- 5 files changed, 265 insertions(+), 248 deletions(-) diff --git a/charts/redcap/README.md b/charts/redcap/README.md index 67ea4ee..e505e73 100644 --- a/charts/redcap/README.md +++ b/charts/redcap/README.md @@ -122,6 +122,9 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | Key | Type | Default | Description | |-----|------|---------|-------------| +| mysql.global.security.allowInsecureImages | bool | `true` | Set to true to enable bitnami charts to use insecure images like bitmani legacy images. | +| mysql.image.repository | string | `"bitnamilegacy/mysql"` | Image repository for MySQL image. | +| mysql.image.tag | string | `"9.4.0-debian-12-r1"` | Image tag for MySQL image. | | mysql.fullnameOverride | string | `"redcap-mysql"` | Override of the full name of the MySQL Database deployment. Impacts the name of the services REDCap will use to connect to the Database. | | mysql.enabled | bool | `true` | If set to `true`, enables the deployment of MySQL as REDCap's database. | | mysql.architecture | string | `"standalone"` | Deployment type for the database, standalone or replicated. | @@ -149,7 +152,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | backupJob.redcap.image.repository | string | `"busybox"` | Image repository for the REDCap application backup container. | | backupJob.redcap.image.tag | string | `"1"` | Image tag for the REDCap application backup container. | | backupJob.redcap.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap application backup container. | -| backupJob.database.image.repository | string | `"bitnami/mysql"` | Image repository for the REDCap database backup container. | +| backupJob.database.image.repository | string | `"bitnamilegacy/mysql"` | Image repository for the REDCap database backup container. | | backupJob.database.image.tag | string | `"9.3.0-debian-12-r1"` | Image tag for the REDCap database backup container. | | backupJob.database.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap database backup container. | | backupJob.uploader.image.repository | string | `"bitnami/rclone"` | Image repository for the REDCap backup uploader container. | @@ -175,7 +178,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | restoreJob.redcap.image.repository | string | `"busybox"` | Image repository for the REDCap application restore container. | | restoreJob.redcap.image.tag | string | `"1"` | Image tag for the REDCap application restore container. | | restoreJob.redcap.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap application restore container. | -| restoreJob.database.image.repository | string | `"bitnami/mysql"` | Image repository for the REDCap database restore container. | +| restoreJob.database.image.repository | string | `"bitnamilegacy/mysql"` | Image repository for the REDCap database restore container. | | restoreJob.database.image.tag | string | `"9.3.0-debian-12-r1"` | Image yag for the REDCap application restore container. | | restoreJob.database.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap application restore container. | | restoreJob.downloader.image.repository | string | `"bitnami/rclone"` | Image repository for the REDCap downloader container. | @@ -195,6 +198,9 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | Key | Type | Default | Description | |-----|------|---------|-------------| | audit.enabled | bool | `false` | If set to `true`, enables the audit log-shipping solution. | +| audit.global.security.allowInsecureImages | bool | `true` | Set to true to enable bitnami charts to use insecure images like bitmani legacy images. | +| audit.image.repository | string | `"bitnamilegacy/logstash"` | Image repository for Logstash. | +| audit.image.tag | string | `"9.1.2-debian-12-r0"` | Image tag for Logstash. | | audit.podLabels."app.kubernetes.io/role" | string | `"redcap-audit"` | Role to set for the networkPolicies. Not to be changed, unless you know exactly what you are doing! | | audit.initContainers[0] | object | A simple container to download the jar JDBC driver on a volume shared with Logstash. | Init container in charge of downloading the JDBC driver needed to connect to the MySQL database. | | audit.initContainers[0].image | string | `"alpine:3.21.3"` | Image used for the pod downloading the driver. | @@ -304,3 +310,5 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | persistence.app.annotations."helm.sh/resource-policy" | string | `"keep"` | | | persistence.modules.annotations."helm.sh/resource-policy" | string | `"keep"` | | +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/charts/redcap/configuration/httpd/httpd.conf b/charts/redcap/configuration/httpd/httpd.conf index 58881ad..ee53600 100644 --- a/charts/redcap/configuration/httpd/httpd.conf +++ b/charts/redcap/configuration/httpd/httpd.conf @@ -122,7 +122,7 @@ PidFile /var/run/supervisor/httpd.pid # as error documents. e.g. admin@your-domain.com # ServerAdmin {{ .Values.redcap.config.adminMail }} -ServerName {{ .Values.redcap.config.externalURL }} +ServerName {{ include `httpd.externalDomain` . }} # # ServerName gives the name and port that the server uses to identify itself. diff --git a/charts/redcap/configuration/redcap/init/redcap-config.sh b/charts/redcap/configuration/redcap/init/redcap-config.sh index 8b9c5be..c71e02b 100644 --- a/charts/redcap/configuration/redcap/init/redcap-config.sh +++ b/charts/redcap/configuration/redcap/init/redcap-config.sh @@ -26,7 +26,7 @@ mysql \ --user={{ .Values.redcap.config.database.auth.username }} \ --password=${DB_PASSWD} \ --database={{ .Values.redcap.config.database.auth.databaseName }} < Date: Mon, 17 Nov 2025 16:53:32 +0100 Subject: [PATCH 06/49] Fix default extrenalURL value --- charts/redcap/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index ec2acb6..7a0c2b9 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -142,7 +142,7 @@ redcap: logAllErrors: "FALSE" # -- The URL on which the application is exposed (useful if the application is behind a reverse-proxy). # @section -- REDCap settings - externalURL: "localhost" + externalURL: "http://localhost" # -- The name of the institution that is presented to the users. # @section -- REDCap settings institutionName: "REDCap Local Institution" From 907b9db940865a2a59ec86d9aa0c0006f7a1c728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Zgrzendek?= <50668672+kzgrzendek@users.noreply.github.com> Date: Wed, 19 Nov 2025 14:18:23 +0000 Subject: [PATCH 07/49] Bumped version to 1.4.6 --- charts/redcap/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/redcap/Chart.yaml b/charts/redcap/Chart.yaml index 74badd6..de4149a 100644 --- a/charts/redcap/Chart.yaml +++ b/charts/redcap/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 name: redcap -version: 1.4.5 +version: 1.4.6 appVersion: 14.5.25 kubeVersion: '>= 1.24.0-0' description: A Helm chart to deploy REDCap on a Kubernetes cluster. From acf556d7e254d6917231897f7182a8eb1b551318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Thu, 20 Nov 2025 11:50:25 +0100 Subject: [PATCH 08/49] Updated rclone image --- charts/redcap/README.md | 4 ++-- charts/redcap/values.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/redcap/README.md b/charts/redcap/README.md index e505e73..617c9eb 100644 --- a/charts/redcap/README.md +++ b/charts/redcap/README.md @@ -155,7 +155,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | backupJob.database.image.repository | string | `"bitnamilegacy/mysql"` | Image repository for the REDCap database backup container. | | backupJob.database.image.tag | string | `"9.3.0-debian-12-r1"` | Image tag for the REDCap database backup container. | | backupJob.database.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap database backup container. | -| backupJob.uploader.image.repository | string | `"bitnami/rclone"` | Image repository for the REDCap backup uploader container. | +| backupJob.uploader.image.repository | string | `"bitnamilegacy/rclone"` | Image repository for the REDCap backup uploader container. | | backupJob.uploader.image.tag | string | `"1.69.3"` | Image tag for the REDCap backup uploader container. | | backupJob.uploader.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap backup uploader container. | | backupJob.uploader.s3.backupPath | string | `"redcap-backup"` | Path of the REDcap backup archive on the S3 bucket. | @@ -181,7 +181,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | restoreJob.database.image.repository | string | `"bitnamilegacy/mysql"` | Image repository for the REDCap database restore container. | | restoreJob.database.image.tag | string | `"9.3.0-debian-12-r1"` | Image yag for the REDCap application restore container. | | restoreJob.database.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap application restore container. | -| restoreJob.downloader.image.repository | string | `"bitnami/rclone"` | Image repository for the REDCap downloader container. | +| restoreJob.downloader.image.repository | string | `"bitnamilegacy/rclone"` | Image repository for the REDCap downloader container. | | restoreJob.downloader.image.tag | string | `"1.69.3"` | Image tag for the REDCap downloader container. | | restoreJob.downloader.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap downloader container. | | restoreJob.downloader.s3.backupPath | string | `"redcap-backup"` | Path of the REDcap backup archive on the S3 bucket. | diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index 7a0c2b9..0fe93e9 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -386,7 +386,7 @@ backupJob: image: # -- Image repository for the REDCap backup uploader container. # @section -- REDCap Backup Job's settings - repository: "bitnami/rclone" + repository: "bitnamilegacy/rclone" # -- Image tag for the REDCap backup uploader container. # @section -- REDCap Backup Job's settings tag: "1.69.3" @@ -469,7 +469,7 @@ restoreJob: image: # -- Image repository for the REDCap downloader container. # @section -- REDCap Restore Job's settings - repository: "bitnami/rclone" + repository: "bitnamilegacy/rclone" # -- Image tag for the REDCap downloader container. # @section -- REDCap Restore Job's settings tag: "1.69.3" From 6fdf440f344fb8857161ed44a1090821fb3d232e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Mon, 24 Nov 2025 15:18:16 +0100 Subject: [PATCH 09/49] link dev ci with dev branch --- .github/workflows/chart-ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/chart-ci.yaml b/.github/workflows/chart-ci.yaml index 2c8ee94..b1bfc11 100644 --- a/.github/workflows/chart-ci.yaml +++ b/.github/workflows/chart-ci.yaml @@ -9,7 +9,7 @@ on: jobs: aphp-chart-ci-workflow: - uses: aphp/ci-workflows/.github/workflows/chart-ci.yml@main + uses: aphp/ci-workflows/.github/workflows/chart-ci.yml@dev with: kubernetes-version: "1.24.2" chart-dir: "charts/redcap" From ff165b1dda3ddb5469a4bf9d2b9f3479d40daa75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Thu, 4 Dec 2025 14:24:28 +0100 Subject: [PATCH 10/49] Change MySQL to MariaDB --- NOTICE | 2 +- charts/redcap/Chart.lock | 10 +- charts/redcap/Chart.yaml | 8 +- charts/redcap/README.md | 47 +++-- .../mysql/templates/secondary/configmap.yaml | 6 +- .../mysql/templates/tls-secret.yaml | 14 +- .../update-password/previous-secret.yaml | 10 +- charts/redcap/charts/mariadb-0.8.0.tgz | Bin 0 -> 32515 bytes charts/redcap/charts/mysql-13.0.2.tgz | Bin 67973 -> 0 bytes charts/redcap/ci/ct-values.yaml | 2 +- .../configuration/audit/redcap-log-event.conf | 6 +- .../audit/redcap-log-event2.conf | 6 +- .../audit/redcap-log-event3.conf | 6 +- .../audit/redcap-log-event4.conf | 6 +- .../audit/redcap-log-event5.conf | 6 +- .../audit/redcap-log-event6.conf | 6 +- .../audit/redcap-log-event7.conf | 6 +- .../audit/redcap-log-event8.conf | 6 +- .../audit/redcap-log-event9.conf | 6 +- .../configuration/audit/redcap-log-view.conf | 6 +- charts/redcap/configuration/mysql/my.cnf | 55 ++--- .../database-conf/creds/credentials.php | 6 +- .../redcap/init/redcap-config.sh | 4 +- .../configuration/redcap/php-conf/php.ini | 92 ++++----- charts/redcap/templates/_helpers.tpl | 8 +- .../configmaps/mysql/mysql-config.yaml | 4 +- .../templates/cronjobs/backup-cronjob.yaml | 2 +- .../templates/cronjobs/restore-cronjob.yaml | 2 +- .../redcap/templates/deployments/redcap.yaml | 24 +-- .../templates/networkpolicies/app-egress.yaml | 4 +- .../networkpolicies/audit-egress.yaml | 4 +- .../networkpolicies/backup-job-egress .yaml | 4 +- .../templates/networkpolicies/db-ingress.yaml | 4 +- .../networkpolicies/restore-job-egress.yaml | 4 +- .../secrets/mysql/database-password.yaml | 6 +- charts/redcap/tests/values.yaml | 4 +- charts/redcap/values.schema.json | 5 +- charts/redcap/values.yaml | 194 ++++++++++-------- examples/local/values.yaml | 2 +- examples/production/README.md | 2 +- examples/production/values.yaml | 16 +- 41 files changed, 320 insertions(+), 285 deletions(-) create mode 100644 charts/redcap/charts/mariadb-0.8.0.tgz delete mode 100644 charts/redcap/charts/mysql-13.0.2.tgz diff --git a/NOTICE b/NOTICE index 6ea0bdd..d640cd4 100644 --- a/NOTICE +++ b/NOTICE @@ -1,7 +1,7 @@ This software contains the following dependencies developed by Broadcom : - Helm Charts: - - mysql : https://github.com/bitnami/charts/tree/main/bitnami/mysql + - mariadb : https://github.com/bitnami/charts/tree/main/bitnami/mariadb - logstash : https://github.com/bitnami/charts/tree/main/bitnami/logstash Those dependencies are present in the "bitnami/charts" github repository provided by Broadcom under the Apache 2.0 license, diff --git a/charts/redcap/Chart.lock b/charts/redcap/Chart.lock index e1317f8..82cea67 100644 --- a/charts/redcap/Chart.lock +++ b/charts/redcap/Chart.lock @@ -1,9 +1,9 @@ dependencies: -- name: mysql - repository: https://charts.bitnami.com/bitnami - version: 13.0.2 +- name: mariadb + repository: oci://registry-1.docker.io/cloudpirates + version: 0.8.0 - name: logstash repository: https://charts.bitnami.com/bitnami version: 7.0.4 -digest: sha256:9acead3f00befe50145d27d120a6795203cc65d72bc6578d1903642884fe1a48 -generated: "2025-06-19T15:34:43.900600074+02:00" +digest: sha256:dc9763292e407c0ac831ca4999083e516bb9778644fadd05e43075ed05c166cc +generated: "2025-12-03T15:34:36.056346225+01:00" diff --git a/charts/redcap/Chart.yaml b/charts/redcap/Chart.yaml index 74badd6..c695f09 100644 --- a/charts/redcap/Chart.yaml +++ b/charts/redcap/Chart.yaml @@ -14,10 +14,10 @@ home: https://www.project-redcap.org/ sources: - https://github.com/aphp/redcap-helmchart dependencies: - - condition: mysql.enabled - name: mysql - repository: https://charts.bitnami.com/bitnami - version: 13.0.2 + - condition: mariadb.enabled + name: mariadb + repository: oci://registry-1.docker.io/cloudpirates + version: 0.8.0 - condition: audit.enabled name: logstash alias: audit diff --git a/charts/redcap/README.md b/charts/redcap/README.md index 67ea4ee..2c2b70f 100644 --- a/charts/redcap/README.md +++ b/charts/redcap/README.md @@ -23,7 +23,7 @@ Kubernetes: `>= 1.24.0-0` | Repository | Name | Version | |------------|------|---------| | https://charts.bitnami.com/bitnami | audit(logstash) | 7.0.4 | -| https://charts.bitnami.com/bitnami | mysql | 13.0.2 | +| https://charts.bitnami.com/bitnami | mariadb | 13.0.2 | ## Deployment Architecture @@ -98,7 +98,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | redcap.config.database.salt.value | string | `"UjtNfDs2ELs2v6p"` | The value of the salt used by the application to cypher sensitive data. | | redcap.config.database.salt.secretKeyRef.name | string | `""` | The name of the secret holding the value of the salt used by the application to cypher sensitive data. If set, the value of that secret will override the `redcap.config.database.salt.value` value. | | redcap.config.database.salt.secretKeyRef.key | string | `""` | The key of the secret holding the value of the salt used by the application to cypher sensitive data. If set, the value of that secret will override the `redcap.config.database.salt.value` value. | -| redcap.config.database.auth.hostname | string | `"redcap-mysql"` | The hostname of REDCap's database instance. | +| redcap.config.database.auth.hostname | string | `"redcap-mariadb"` | The hostname of REDCap's database instance. | | redcap.config.database.auth.databaseName | string | `"redcap"` | The name of REDCAP's database. | | redcap.config.database.auth.username | string | `"redcap"` | The username used to connect to REDCAP's database. | | redcap.config.database.auth.password.value | string | `""` | The password used to connect to REDCAP's database, as a clear string. Don't use the option for a production-grade deployment, refer to an external secret instead! | @@ -122,21 +122,24 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | Key | Type | Default | Description | |-----|------|---------|-------------| -| mysql.fullnameOverride | string | `"redcap-mysql"` | Override of the full name of the MySQL Database deployment. Impacts the name of the services REDCap will use to connect to the Database. | -| mysql.enabled | bool | `true` | If set to `true`, enables the deployment of MySQL as REDCap's database. | -| mysql.architecture | string | `"standalone"` | Deployment type for the database, standalone or replicated. | -| mysql.initdbScriptsConfigMap | string | `""` | Name of a configmap holding an SQL script to initialize the database with. | -| mysql.networkPolicy.enabled | bool | `true` | Enable creation of NetworkPolicy resources | -| mysql.auth.createDatabase | bool | `true` | Automatically create a database at the first run. | -| mysql.auth.database | string | `"redcap"` | Name of the database automatically created at the first run, if `mysql.auth.createDatabase` has been set to `true` | -| mysql.auth.username | string | `"redcap"` | Name of the database user automatically created at the first run, if `mysql.auth.createDatabase` has been set to `true` | -| mysql.auth.password | string | `"Redcap*!"` | Name of the database user automatically created at the first run, if `mysql.auth.createDatabase` has been set to `true` Not secure in production, use secret reference instead! | -| mysql.primary.existingConfigmap | string | `"redcap-database-config"` | Name of existing ConfigMap with MySQL Primary configuration. | -| mysql.primary.podLabels."app.kubernetes.io/role" | string | `"redcap-mysql"` | Role to set for the networkPolicies. Not to be changed, unless you know exactly what you are doing! | -| mysql.primary.service.port.mysql | int | `3306` | Port exposed by the MySQL service. | -| mysql.primary.persistence.storageClass | string | `"standard"` | StorageClass used for database persistence. | -| mysql.primary.persistence.accessModes | list | `["ReadWriteOnce"]` | AccessMode used for database persistence. | -| mysql.primary.persistence.size | string | `"10G"` | Size of the storage used for database persistence. | +| mariadb.global.security.allowInsecureImages | bool | `true` | Set to true to enable bitnami charts to use insecure images like bitmani legacy images. | +| mariadb.image.repository | string | `"docker.io/mariadb"` | Image repository for MySQL image. | +| mariadb.image.tag | string | `"9.4.0-debian-12-r1"` | Image tag for MySQL image. | +| mariadb.fullnameOverride | string | `"redcap-mariadb"` | Override of the full name of the MySQL Database deployment. Impacts the name of the services REDCap will use to connect to the Database. | +| mariadb.enabled | bool | `true` | If set to `true`, enables the deployment of MySQL as REDCap's database. | +| mariadb.architecture | string | `"standalone"` | Deployment type for the database, standalone or replicated. | +| mariadb.initdbScriptsConfigMap | string | `""` | Name of a configmap holding an SQL script to initialize the database with. | +| mariadb.networkPolicy.enabled | bool | `true` | Enable creation of NetworkPolicy resources | +| mariadb.auth.createDatabase | bool | `true` | Automatically create a database at the first run. | +| mariadb.auth.database | string | `"redcap"` | Name of the database automatically created at the first run, if `mariadb.auth.createDatabase` has been set to `true` | +| mariadb.auth.username | string | `"redcap"` | Name of the database user automatically created at the first run, if `mariadb.auth.createDatabase` has been set to `true` | +| mariadb.auth.password | string | `"Redcap*!"` | Name of the database user automatically created at the first run, if `mariadb.auth.createDatabase` has been set to `true` Not secure in production, use secret reference instead! | +| mariadb.primary.existingConfigmap | string | `"redcap-database-config"` | Name of existing ConfigMap with MySQL Primary configuration. | +| mariadb.primary.podLabels."app.kubernetes.io/role" | string | `"redcap-mariadb"` | Role to set for the networkPolicies. Not to be changed, unless you know exactly what you are doing! | +| mariadb.primary.service.port.mariadb | int | `3306` | Port exposed by the MySQL service. | +| mariadb.primary.persistence.storageClass | string | `"standard"` | StorageClass used for database persistence. | +| mariadb.primary.persistence.accessModes | list | `["ReadWriteOnce"]` | AccessMode used for database persistence. | +| mariadb.primary.persistence.size | string | `"10G"` | Size of the storage used for database persistence. | ### REDCap Backup Job's settings @@ -149,7 +152,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | backupJob.redcap.image.repository | string | `"busybox"` | Image repository for the REDCap application backup container. | | backupJob.redcap.image.tag | string | `"1"` | Image tag for the REDCap application backup container. | | backupJob.redcap.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap application backup container. | -| backupJob.database.image.repository | string | `"bitnami/mysql"` | Image repository for the REDCap database backup container. | +| backupJob.database.image.repository | string | `"docker.io/mariadb"` | Image repository for the REDCap database backup container. | | backupJob.database.image.tag | string | `"9.3.0-debian-12-r1"` | Image tag for the REDCap database backup container. | | backupJob.database.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap database backup container. | | backupJob.uploader.image.repository | string | `"bitnami/rclone"` | Image repository for the REDCap backup uploader container. | @@ -175,7 +178,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | restoreJob.redcap.image.repository | string | `"busybox"` | Image repository for the REDCap application restore container. | | restoreJob.redcap.image.tag | string | `"1"` | Image tag for the REDCap application restore container. | | restoreJob.redcap.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap application restore container. | -| restoreJob.database.image.repository | string | `"bitnami/mysql"` | Image repository for the REDCap database restore container. | +| restoreJob.database.image.repository | string | `"docker.io/mariadb"` | Image repository for the REDCap database restore container. | | restoreJob.database.image.tag | string | `"9.3.0-debian-12-r1"` | Image yag for the REDCap application restore container. | | restoreJob.database.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap application restore container. | | restoreJob.downloader.image.repository | string | `"bitnami/rclone"` | Image repository for the REDCap downloader container. | @@ -200,12 +203,12 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | audit.initContainers[0].image | string | `"alpine:3.21.3"` | Image used for the pod downloading the driver. | | audit.initContainers[0].imagePullPolicy | string | `"Always"` | Image pullPolicy used for the pod downloading the driver. | | audit.initContainers[0].env[0] | object | URL of the JDBC driver to download. | Env var to set the URL of the JDBC driver to download. | -| audit.initContainers[0].env[0].value | string | `"https://downloads.mysql.com/archives/get/p/3/file/mysql-connector-j-8.4.0.tar.gz"` | URL of the JDBC driver to download. | +| audit.initContainers[0].env[0].value | string | `"https://downloads.mariadb.com/archives/get/p/3/file/mariadb-connector-j-8.4.0.tar.gz"` | URL of the JDBC driver to download. | | audit.initContainers[0].command | list | Using `wget` do download the driver, and moving it to the shared persistent volume. | Command to be run to download and extract the JDBC driver. | | audit.initContainers[0].volumeMounts[0] | object | Mounted to `/driver` | Definition of the volumeMount used to persist the JDBC driver. | | audit.initContainers[0].volumeMounts[0].mountPath | string | `"/driver"` | Mount path of the volume used to persist the JDBC driver. | | audit.enableMultiplePipelines | bool | `true` | If set to `true`, allows the use of multiple pipelines. Needed for audit concurrent pipelines for performance reasons. | -| audit.existingConfiguration | string | `"redcap-mysql-audit-logstash-pipeline"` | Name of an existing ConfigMap holding the pipeline(s)'s configuration. | +| audit.existingConfiguration | string | `"redcap-mariadb-audit-logstash-pipeline"` | Name of an existing ConfigMap holding the pipeline(s)'s configuration. | | audit.extraEnvVars[0] | object | Empty external secret reference to REDCap DB password | Extra environment variables related to REDCap MySQL DB's password. | | audit.extraEnvVars[1] | object | Empty external secret reference to the API token to reach the audit stack API | Extra environment variables related to the API token to reach the audit stack API. | | audit.persistence.enabled | bool | `true` | If set to `true`, enables persistence for Logstash. Useful for disaster recovery purposes, as the pipeline(s)'s cache is stored persisted by Logstash. | @@ -300,7 +303,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | Key | Type | Default | Description | |-----|------|---------|-------------| -| redcap.config.database.auth.password | object | `{"secretKeyRef":{"key":"","name":""},"value":""}` | The password used to connect to REDCAP's database. Automatically retrieved from the default mysql secret name if you enbaled the MySQL database embedded in this chart. If you specified a reference to an secret for your MySQL database password, you have to set it here also, in the `secretKeyRef` section. | +| redcap.config.database.auth.password | object | `{"secretKeyRef":{"key":"","name":""},"value":""}` | The password used to connect to REDCAP's database. Automatically retrieved from the default mariadb secret name if you enbaled the MySQL database embedded in this chart. If you specified a reference to an secret for your MySQL database password, you have to set it here also, in the `secretKeyRef` section. | | persistence.app.annotations."helm.sh/resource-policy" | string | `"keep"` | | | persistence.modules.annotations."helm.sh/resource-policy" | string | `"keep"` | | diff --git a/charts/redcap/charts/.helm_ls_cache/mysql/templates/secondary/configmap.yaml b/charts/redcap/charts/.helm_ls_cache/mysql/templates/secondary/configmap.yaml index dd9fdd1..9d4544d 100644 --- a/charts/redcap/charts/.helm_ls_cache/mysql/templates/secondary/configmap.yaml +++ b/charts/redcap/charts/.helm_ls_cache/mysql/templates/secondary/configmap.yaml @@ -3,14 +3,14 @@ Copyright Broadcom, Inc. All Rights Reserved. SPDX-License-Identifier: APACHE-2.0 */}} -{{- if (include "mysql.secondary.createConfigmap" .) }} +{{- if (include "mariadb.secondary.createConfigmap" .) }} apiVersion: v1 kind: ConfigMap metadata: - name: {{ include "mysql.secondary.fullname" . }} + name: {{ include "mariadb.secondary.fullname" . }} namespace: {{ include "common.names.namespace" . | quote }} labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} - app.kubernetes.io/part-of: mysql + app.kubernetes.io/part-of: mariadb app.kubernetes.io/component: secondary {{- if .Values.commonAnnotations }} annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} diff --git a/charts/redcap/charts/.helm_ls_cache/mysql/templates/tls-secret.yaml b/charts/redcap/charts/.helm_ls_cache/mysql/templates/tls-secret.yaml index f5fef25..813303c 100644 --- a/charts/redcap/charts/.helm_ls_cache/mysql/templates/tls-secret.yaml +++ b/charts/redcap/charts/.helm_ls_cache/mysql/templates/tls-secret.yaml @@ -5,11 +5,11 @@ SPDX-License-Identifier: APACHE-2.0 {{- $secretName := printf "%s-crt" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} {{- if and .Values.tls.enabled (eq .Values.tls.autoGenerated.engine "helm") }} -{{- $ca := genCA "mysql-ca" 365 }} +{{- $ca := genCA "mariadb-ca" 365 }} {{- $releaseNamespace := include "common.names.namespace" . }} {{- $clusterDomain := .Values.clusterDomain }} -{{- $primaryServiceName := include "mysql.primary.fullname" . }} -{{- $secondaryServiceName := include "mysql.secondary.fullname" . }} +{{- $primaryServiceName := include "mariadb.primary.fullname" . }} +{{- $secondaryServiceName := include "mariadb.secondary.fullname" . }} {{- $headlessServiceName := printf "%s-headless" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} {{- $altNames := list (printf "*.%s.%s.svc.%s" $primaryServiceName $secondaryServiceName $releaseNamespace $clusterDomain) (printf "%s.%s.svc.%s" $releaseNamespace $clusterDomain) (printf "%s.%s.svc.%s" $secondaryServiceName $releaseNamespace $clusterDomain) (printf "*.%s.%s.svc.%s" $headlessServiceName $releaseNamespace $clusterDomain) (printf "%s.%s.svc.%s" $headlessServiceName $releaseNamespace $clusterDomain) (include "common.names.fullname" .) "localhost" "127.0.0.1" }} {{- $cert := genSignedCert $primaryServiceName nil $altNames 365 $ca }} @@ -19,8 +19,8 @@ metadata: name: {{ $secretName }} namespace: {{ include "common.names.namespace" . | quote }} labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} - app.kubernetes.io/part-of: mysql - app.kubernetes.io/component: mysql + app.kubernetes.io/part-of: mariadb + app.kubernetes.io/component: mariadb {{- if .Values.commonAnnotations }} annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} {{- end }} @@ -36,8 +36,8 @@ metadata: name: {{ $secretName }} namespace: {{ include "common.names.namespace" . | quote }} labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} - app.kubernetes.io/part-of: mysql - app.kubernetes.io/component: mysql + app.kubernetes.io/part-of: mariadb + app.kubernetes.io/component: mariadb {{- if .Values.commonAnnotations }} annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} {{- end }} diff --git a/charts/redcap/charts/.helm_ls_cache/mysql/templates/update-password/previous-secret.yaml b/charts/redcap/charts/.helm_ls_cache/mysql/templates/update-password/previous-secret.yaml index dc76999..8319986 100644 --- a/charts/redcap/charts/.helm_ls_cache/mysql/templates/update-password/previous-secret.yaml +++ b/charts/redcap/charts/.helm_ls_cache/mysql/templates/update-password/previous-secret.yaml @@ -3,7 +3,7 @@ Copyright Broadcom, Inc. All Rights Reserved. SPDX-License-Identifier: APACHE-2.0 */}} -{{- if and .Values.passwordUpdateJob.enabled (eq ( include "mysql.createPreviousSecret" . ) "true") }} +{{- if and .Values.passwordUpdateJob.enabled (eq ( include "mariadb.createPreviousSecret" . ) "true") }} {{- $rootPassword := .Values.passwordUpdateJob.previousPasswords.rootPassword }} {{- $password := .Values.passwordUpdateJob.previousPasswords.password }} {{- $replicationPassword := .Values.passwordUpdateJob.previousPasswords.replicationPassword }} @@ -13,17 +13,17 @@ metadata: name: {{ printf "%s-previous-secret" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} namespace: {{ include "common.names.namespace" . | quote }} labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} - app.kubernetes.io/part-of: mysql + app.kubernetes.io/part-of: mariadb {{- $defaultAnnotations := dict "helm.sh/hook" "pre-upgrade" "helm.sh/hook-delete-policy" "hook-succeeded" }} {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.commonAnnotations $defaultAnnotations ) "context" . ) }} annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $ ) | nindent 4 }} type: Opaque data: - mysql-root-password: {{ required "The previous root password is required!" $rootPassword | b64enc | quote }} + mariadb-root-password: {{ required "The previous root password is required!" $rootPassword | b64enc | quote }} {{- if .Values.auth.username }} - mysql-password: {{ required "The previous user password is required!" $password | b64enc | quote }} + mariadb-password: {{ required "The previous user password is required!" $password | b64enc | quote }} {{- end }} {{- if eq .Values.architecture "replication" }} - mysql-replication-password: {{ required "The previous replication password is required!" $replicationPassword | b64enc | quote }} + mariadb-replication-password: {{ required "The previous replication password is required!" $replicationPassword | b64enc | quote }} {{- end }} {{- end }} diff --git a/charts/redcap/charts/mariadb-0.8.0.tgz b/charts/redcap/charts/mariadb-0.8.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..81e20f54cad5e549dafe27e6959aecdff469e9ce GIT binary patch literal 32515 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 literal 0 HcmV?d00001 diff --git a/charts/redcap/charts/mysql-13.0.2.tgz b/charts/redcap/charts/mysql-13.0.2.tgz deleted file mode 100644 index e25e6459033c386427de189db8ea84258824786a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67973 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�aA}I{r7Q6b1 zWfdgkr1POGm6q-u<@-$q>HEWR*>pqUg=Itlbgn65+W+Y87@8fIewjb(H+`} z#)v>uBEzJ_IIuJ=bT;axhm-lKiw6y3-C2^2z34(D^RAHxD55G2b5|`j-|e5FMsh~Y zLKXARk_UUebiNzcFKQI(A!jUgiG;$Vt{|;H8hE#USfYA5pyg8rVgGYMI_X}@89h&f zsf!RNXBK{l1NYjq3KjO19&TqpUU_ab>A}`N=TpMjd1+|d65E?t9N6;5m!Q;_Q%HV! ze{NN^9^Pqd8R7B)B3ueZ<7u3mWT;I}ON?Kh=ov}2Ez6S;i|1RJy<>&=VRdd6XN+8F z&R$pCN^|LRM6EOzI9JR{bCGjLtTY$kJ^UN|Z2jFfd!-y`sf_hJclIPL7#F zQd$bAEg+?({CUDrT8f-67^S7q`9o1!3Vx_Slp70}DAEiO?zbPp5uP>Xn@d0w^1@iM znm7V=MKf~o(sVdV&D6wGC6i%~A)j@XujEAN=`?a7TDVXd6DJ@%bX7vp$CRMtV9xSGP?@HrBm+97g`{7?9`%e>;xS?M45TX@ z@w4v;(K{0hZAfwC+*mjSbDY4DY!{RX6Sb75i{3s2^;hYsqa#J{aGtQ= z?B-mYK(*2B64gOt=%EW#)&D4e#B|76OgncZ(M#Ca*l-ciJuuzAR&RtCBX0LUBn)f8`APft$IPg99Zr^s*7V8hN6i*qA#J8u_;I* z+D-10fzwQAVUc?(kZ(|w=pp%hOXJ+q!P!*3Laf6QZ=FmL1v7(z-5^>To7SMF(zFIN zft9F!g<8LG8}Gv^P0lq>z;k}UbdEY22Vu5UPl5W*Rb>7$dWKd^s!<#zzl70FqdifC zRt6HHG$sU5Mcw3*A{4U9s2Uno>5bX!HK0J6IejT!FZ8QMa0&0|gxMjc^eJ=BD{>6c0D1{IUa>}3`Em~b`}&nUXJoYGFJHgn7aHaaTKqz#VLD_cbge+1SWyKMRNg=Qjvm@C?bekS z44GN>9_m=@tgUTtZj!aNwa)9U4*nM(@!z$r*K4G+wYI*ozV^DazCqSHn;Yv}e;{l3 zKuhMC;$6`{tRan^ymaWNl=oe06seWS`+Hzfb0-MoONA|C0S0;4oB9Dg7XZ=v837Ml zjc3e+kC-A95t-hbA$a=EFgPLgE2>gc6bTwTH+>I_4HPi)E}5&{${17z|5hL*{BgBK z(A$X~L5vwmXe6MAC9OtlzkAk&_0DS`E&)BD_+hV$!A{~v3)GD^{g;v7X!ZUbwdud& z#nojS{}F%2*Q0h?P!HNS9Wx)a#>-ZGGlqYA?q~RSGKAm%50d`iMig}KaQ^@*1PP5U zGL4o$@Z2^_2d^NVKfJ`#o`DxN;3utwUiS;a%f{aKyGQR1-hX@ty3M1JF>L;)2OS7N z+q!dyL5+13%>T~z=C(Hfx8aZF{9nZL<%>hwFB^N|_zq^v)r7o_LU#a~`zvxd>bDRv zoSfhX+|tv~1A|thd%XWo=RK_Lqu6r}DL%`Ek3N>W$GdyqA2{o+wZ_Z#*RPER7VlqB zMN{}=nIlpppXI0lPy%cPe!$zXc#`+!3!du+(}72t?1WBruccYj3{BF)5fZ9 z@Uo1Hhw`X(FaV4|bH7L-Ly=USOkzp!LKH32nkh+xxqc(RPD9oRX~Tm3q2=W&jR<1h zBr71-VBgi`=nV98GwC3fi|egT?h)T4&&euOIYR%7(S&TWYH3X4mTLM3Wpm<$7pYpt z$4D(-zIRTGQa40~W=zJxH6KDWJ4Isgz}nDt0RBj#IA{SJ@NrUnQt4ci zeG%JjrYt8B8`wt{tU>DrDa1rV#LP{W3bVC!J=0d{=l#upUH&u7X-8lYv`5~J!!G;G zzA6;R|Ba3=|JT>ox0d?fLY~FTe>?v9N;1D#JRi0SuscaGmsT;H-~^_aF_}PdPLh*V zp21#m5g7BTn1;_4;Ow0@NtqZ7M@7{ZImWisV?Ct_lR8s{A&s^=UU&FX$7nY%cH;6 z6<@Wl!tisGG=Z<2>G(2o2hdLCqr)Pxvxqx)_z_>y15R(?4Vvj9@Z41^vadZuFS_)! zr6C{--9tY*?e;b{x4PF0Rd%d-})c+Ro zEJpt;*8MbHriaJI?L?!2l*Q@{FWX@(yi{ij)EQGEywe$uprjohe9~bM%S+W~VX6y3u+2>Zfn7u2<{@kw8Q9p(if8BSGe&Bft*8Hz zR#C=rL#NhS=wRM z@XWMHudvtKJ-n{s##h>Vhu>7N3}LB0qEJvu78YZ=-rk|L%+)n+0#%Z>|2O6DOk=09 zCyWIY)J`oBABr0?^4MJ#yp@a~d?Hc7I^Dpo%Ktoh(MYb|xdcjdVQ;GnpfaU3xeP-3emKZqbgniMyixj=LK z7L&4giBumG;PIb+BF+UtlZnGXh1!a-(&6#9$HMb>W{EnB~QPzxdM&^nX4&J^b$QV4uAG z7kTmg!@s)!=l$8y!H;JrA3vU+9q)F#KYl#ffAO~_bTS=`GX%1kcxT=%XhqO<&*i~a zG#Nf<8jK~oxbgKXX*L<@yw2m3gC7n*e(I_f8=5l-5yGc%R7ws8zl)BXm5hkqi5I?E z22$@OSbryXW~=h5fe%ewRh^+eDfZ`@8A>s3mt!bChWJMjU)?iHNt9$bs}fU{<|lP5 zX6C1iRv|uAJ04KzGm0?7$w384W;#cxTc8>0sKkaR2gmOZ_jXSYKOU80Njd#u*i)yF zWTl{irgFkCXMC#-Ye`l%C~7{_(qiD-HSC~x+LNveaL_w(1inYZ=yjljY${tGA3M+e zGTfVKDtYdg=Ud8cX5PhzlVVeU(iUq9&~qO(pmHjZv5<;NklGQ+d=tpH>AB!YGzogi z)EBfr=Ro$loYrKja_PAUfq9+YKA`ZJf~QND4-cdsLcS zr?%dmtV)?}OS@@qv#~Q+V~(?GKf!C)@s+2FJGptrGGU*kZ(e8)Cv;Bj& zpWbOi@NnkTY6A))OgZNAM4I#hep55a47}d-QayjljIQhtFLck`{kWjBg3?XN{w@lK zI~f*bd+vXDcNkmKz`)75o^GZ}t?P+zR2s!3W4;p4XHVSxR^3K&T39rr@40a!@20MH zS$KQay@=XPsDxO#)$B5}7{+``JXw+*p9m*bWkNe|&a{0|`%PDv%kipIKHa4)NR}3> z?vIjvO*@Ao$@<_;tuA1TS~(Mo7w9qvqw62sD8oSapf!n_N}dDcpJ>2Vu3U9{A4(=< zW0ldRviwo0U!nTU)MUU-AKbB#xf0fzwSqd>!PFT@I-3`D&~2{4I^@+)whDu?DaAd| z5x$McN{40DyM{Tj$PmP82`V~q-AAQ{+85B=69q_CEkXmCy_W`S^)H~s^h{|wHncaE zzT8i1mAdC?D+~Jj0WEQv17Id{=+?p+_>m@(sAtNtJGt7C%^_N%c-mu0Foj-5#RFwQ z5LZ&gofos8gifLH#5lPVms1a3uAZj~$X|NZEfDQLNMp4Cg+i(BUguL96G0OjX;1+u zViNw#9R{U}DdGNrYQI;eFdlWIiQzJuxdiI{pGKNsAvlu$M?ZzU?$_$B)ZuJG8{CRa z^O(Nd_fw=)X}IK@eubN&N^_G<4OQC2i7H>q76*2k!&q0MoO0$Ce8zN2S1^@1g&SyV zv6d3&I{|bm?R@M_F5c!DrhHimIv*nxZ2;@!fg)pK_2JL42R-D-m)zSM20int%Ayu) z+3sT{tLTmT)b6+G_rGY%9U2<2HWa`j{LhW`O%4C=b!T&XdH-t>&jRj$MR>fKOg743 z`ygOK>N)H*_mzHB59)+r?*V+Q;EKra@rKMhZ-fZ?&>9wjnB7v8&_wz!5_{>5_I9}z>Ga(u z+1TDnl0*!aJ_WWn+@v$y5KU@ekrwttjC>*Efv6uua_)A+Z}o`YEaf_#3}Uw>BuzJG#0ayH)Clf#<&@TeK$a7t0rl7)?c^Q;Qu=5`1ZYM!Y5nTzZ`jkJ$zvr z%aI>Q?0|C-=jqoOaByUy^!vW({S;w<89t2KB#`V0R7~G(^`nV#B)NsP6@=mE=~zA) zq8LarUo>G$3>?b}gCG35_z(O_H@v5es%xTz;389B{k${-0Z@A$33Nwa8wu=}iG+W6 zcV=~*TTHF%vg|=&T9|3FRozdC7NOy^I!hU_lmV&?(Aq+0k;_Vv#Dn%ZAHT@S%XMMT>pEPD;K2@?N@X%AYmd7st(KE+`sT0p_3eK1RTd%h^H+A{H zxxU2zTgbB*`Cs}_x=OewnL#a4pSnCr*R};*t{LC#njx^tIE%%~cF%IFn3gdP2Or## zd+A|7VgmqDn%9sryK$@+X-}!VGQyr38=J;vd|%9&Qo1=X_aykYl8Aey*)mQ|#5yWy z{WqkwIgl2^oQ%2?v|e3uSS`JaRm6dUkzklWRKgZKyTTz%4 zdB_eI$n(}IC$II^MF+si6=_=cmd#ZvF5@eAeQO)a&-D)~;~|v2OTYrnx45${jZB_^ z9RzMX;h?d!Eu-)TsG%2ro9pa&dL7i0&9$wj=|)&Fh02^YLO#ytzho_cCXl%&i@+&M z1Ors1X*{Si%5ga8LgIRS$t-1CMq*p7R2c^~PUewSW6@J7K8;FKDuQ&D#-L2wJQMb0 zn*Dw;C(ZTDfHi5Q-@Twg*(FFs@un`ylNw5rtw8oA#3b_x6D9PM7AhcAv={Tl^#w1i7r_x z2TN>gXZgv1MR&QrnI@Ot)-@@Vn(Ca-lQ8fieXW*W*3|&Ho;v9VWh|uk7eU2|(_>CL zuk=s0El#G0j0#kq9#E_&{?Id!qkpk&*7O4AASMQNb})sGS1D0mTgXte&OyT@9EU-8 zdDk7|Wk*oFW6&9V<)W4~Nqx*`qe0q0&d-XE1+hDiqz zP=Qa%O=jW0l0|1|wSi=dn>X~rS#<3=zz?w#-wgwQ^x2FfZBi=dgON6ZZCHEv5nd!O zCa%u=kg^4<_#UL)=rG6iM?)d^e(lj(XXXB^fa`6-xmIz$O~}{J{+O1feX;{4U&L8> zWr~R1565>D?i%MNxd;Q`PSW%G?i9ymLayAHh#8B>*zsf#PAAm&3VwQ#ei0jn@{h!i z&jx;U#{8=klGwQr)@8v+?2m~P+47J!EfUIZ!G%(&$Tz;5atntpt zqT8RdZYn*I)U!j@?CVsP=VrRMpI1!fg)679dtbl`>%Ipt4m=si5t<4oYw7F?y(H{7 zUWZB+_Wpw9!CSA25mfFElKYZLjFca5|1NT}B zSEQEnVYhpFaB}wj$L^`MedX?_7S?h6@#OUE=+lR{C7@hI9sFptHI^XUOZ5-0lOng+ z!DE}~5t!FKNOK{vhIQpQOK<7ntR3rCt?J-t_wDQxjWPV=F4 ztvALrc7ktvyLbamcU8%fzW4s{;OO*hZ};rG!}k`J&+@BWK_1P;(4I3O1j~FV5OwmY z=eP4@)S8;% zisL+dD)!8PZ2v&m%M}|l2imgT!{@ue)s>=*Wc%mo35bUGyYIRdac>mbO7YG4DZK~a zXG;z90X~<(U^Z7g2ljHkJphDcuT9r8eBC*Kn(J*Or=)U2sm^59YfV-nMR%#9-<0lM zssMbrgQ@yY+eD@%-qu9fZ7uvj3%tk4%*w9?yIsDEUuFwzH{L7|$2z~(TK3ZlwdSs< zp+PI*&^I~x2Wo?O_084tV~#E}A^t$wzHk660T-0AI`=JPLh zb!x}?YKml)gmBBvOw~&)p(vD_LeKLRP%xn2f^wUyhQcxtw(y|>!yOF$5n*uF#FWxEwfFg)pCw9cWZ1jEmm5yoM*q|dA4+GyJxqy-=#NzMwe_d zwrmy=cqyk7vIa@a5N9g2(;^?>jQq)<*JVzAd&1UX{%oa}E(;E(b-24=4*7$y|JjQi z3JNt2{n5l>m9(lD)1($q0iM$Y^?N}ZXyTa~!K<0M6&Az~)8?AN%k7DKs@5ja1l1S` zva}hHiEVxuzUDWwIO@hqCR(AvU~WA^;rO?u0@~PZ`DGe(PkudBi#89Ntv2*=#qTv& znbSV3vHmuqpKe}_MnB$s3)p={AIhs{9($P9nxQv|{JwEDN#+JiA{A_Pq!Oi7cc@Zw zR&}frnIEBBRS{|Rx@OFOBwNo}?7;DE(ZcRU_i!p(?r8I=o@stV-gA$`iR^wI{mpym zqRn%5<6M2moU>alu}#iwk!jBTvx9%4R}VTQ@$7H3-7)JcHp|b%EGLe`-n87o0Je4U zn*Y3beCHkWWtKI3?8j*t zNzM+_t|pVQak9>N-XyAK=r8#jvDWTMe@)|L%H0Dj_lg*B_dCQ#)r$@=jO_ zXg+ns`}iuIQ)AP?o}GkN+RQ{T3ysLBDffdSSqLV>0C8iN6fm2xm zxK=c+6socc_*MyyQj!|R1zP4w3A|OKF9$sIxtwbbpy66*GlCEEKARgHT4`x1Xugcd zm%%}Sq(1DLVq7UQ8z0sBV(F4JyUHF8v&dLY^x7(vZU>b;;;&G%ZlnPYj>H*5!AZLR zZv#S^c|qc(w)zOKmaIlnX+{*S^fPH*24T+)(q!!K+~uj*ogjlDDB)Pww6GfMtHfH4 zF5#q~4~_Ak_vFNXxbD{!0=OXl&+Cn~O#I*NW&Gd8JjkYxH2#AW!;fC%T}E)IFM@+n z2N4&hE9f6}Y98|vWK=p9qi)!vPp~M3W)xB0ItuAqyh9Voc>vzSV@^hWb4S z?ze8>f)W!oS4(9%0;Ltt=>&5CS$O^!oJNRM-OmkvB1$smF~`r;nS7R3;g((t2%F6s zNSV4+sXjqPK3?VRw0$oK&{0&pJe&{T@WW$Ma|)3u>)PyUN>#X-M) z0;7IA_pskS$henb14&|N7qe@ZNCg+OH;trIRr)c;3Y*iyS|S)w&R)m3jd>!rm8bCJ z+JBPhY4aI^3hX}{osCTV=gswvrTu3S&y%L{EbR>R#cb2P>+Eh0pz7PXeT%HYES_R*8k4twtoJzwzalg{}=KsX8qUCV?>A^wyRGror)+f##5l=N^Yq= zx;4KkNvX@_!-E;`e_Vkb-K|GJ`P8yeLS{0SYWb)*mZf5Zpo9nA%&8k~tdr}(S%T1YiZiOAi*^7^0S>9DQrX%*qNLc5$iZwa`S)>{|xvnE%h zX)*huHwLsczH-;MwxM*n#$p600UGs*_T2x3JrmeY|H?(zJ&xu_4{=03CvfA5!}^`J zWE9@u=`@AeT1Um91De9t+UD9;(*|)-Kw&ydbC6YLRRt}j&jiRP@0~M?opsG6vgfl`3Qm6JWdjKEgug0Ke(U6l^l3B^vv(2(UZgL@(#v{?musnycKB~d!&e}L7D|8llCbv4yjRH-kkM?)(gIrY#HSE@ zIw|@WBPE&aGZPYnb~>0scdJw=uZ<+A8E3A45{|sinpQ;HP};!0%na##j#n z`;7eP0lDKlj2%O8K9Y+t0G=d0ukTKAOeW;Yjft40FwP{N48rMzo@ByLFVdq0z%c%i z`0?4mkIooMk0rpGC1Oo~Oq|G;hqP&tPKH{Vg~rNy0Vjo(!)Rs&I^(p&G7>dQMs*o$DWg#8)*fPM_!-8BIAhXO8AlJQ)V~UE zMx<$2@~jdcRKVT%6D(WMgdMYCUC(k6ze8tK$j~ez2zEY$Od8@0QRs{(SEK{K-P`0h z`UyBV>ZI9zZ$jmZS$72@>m;px%thr_e|gSVgFX=@E7i=VYcBcKShfd~n0Ubrx# zO$wr@3eSPpn_d<$=c-w*W_tX=f&?!^1EacyM%jwzr$lQaKgm(QN2B-V_7yu$UAy zR&4>-rvluds0@Ik5jgloMApb+NoG&7M7Zv7+blJRWkadj7r8ir+7}X zaiUID`>?a?xv{5y8;G~L6z}hz?!Mja+Ih)b=1lXjG>D>|+>?Xj_lJACr-vVp&OUtH zw~*Z&x(F`UELl+b2`&*zEi3o80!!r8z7QMYB9>W?dA4vyDPU^Sqmu}QK_;t7hdd{- z?*dm>+cRtZKTl6!v3$S#u4`d*gIG}tZ_Z2Q!RY!2ExvD(r4ENSQGQ9S+^&~r*``FZ z_C90>pf7G@89B|0PB2gFfefYn^D`GOn0e%7+sG!x;u^^5sN6^i@-rpgY{0@tSy9Wc zx%vH?kHc>y>$VoUZfoEJ1twm}P>(li4oG~-sVnK|Rg5t<^C9!U^RK;;7stm@*wa>} zK>k#dIm%FH4OSh6QgbKN(3q8Q=x1+z1Zrb=<;~UdW9{9_0V>5bFq|B+$zwh}WZ(1? zMD|ucMZ`y}*k|ta_D%Eo7lS!q$N8!s}{L*;=x82TfEm&~Ryai-Kh;*5b{xl*NdRSa^BixGO+w@jT#`BvxL z(Q2(>@~E_$XHOmNF;AaJYtM52Jf8V8_D7dFvj+y{5;g&R_b?!SOk9+P^G&NRUaFps z4U;OCzSKFTlp1T8P%@pCv$(liVxCN~(vsy=`h85LrI+J9c{wf}MRM9!!BM1Y(OIh; z8X9c1p_3$juer*c_F;|nw-FsZ^J+9Yf@)kOpFUZ}w(mugYJCqG;!LIX&9!_&JMs+( zKjzO?dg&VNU|NCblSBR>?0@zm2c~#*HxB*L#9@`RN}DD%jBYbXk>z_q8x&ZgN{!&v z%-RYw2wK)o0dfP@spR6hwK+6FJ{LWPhV=gjrv)Nq#0KIdL5J2I1Z@(A}FL?7IQNN$hNFtZk>? zg;UWRw$FBMyk0Ayn;}PJ-7%~R+KJNDWP+*>9pngOy=Rv*Tr+opU&JcPlGCYKVV|CN zWS3bL@v$F{ z*>7cJq#$}$+qtm^Y^Lx>)CJ}HWrizD+02z~O_?I@-PUBOu{K-NQ`qYm^s%DmK7vb0 zu|M$oZvEGhl5%Idh{X6HixpSzZr-|+Pds{5IZ}kVnLx=IR8;$j)Lkm!6sGXA~c_)l|nok|+KE6tk7suHn zNjm|pw1J6^7#i?;%fU`)v}=PeS5mesR|=_-o3pA6mo=N*l_ws)fa%MuoNDXJXr%-y^F89u!EnsSXPEK*n+jM(|iH|mkWO<1JFxM!(0M_wFCyU zXjm!SZx!CK0@A7^d<;sW%vKT>u|``CBJOiJ*BofsHBe?m(B{20H*~qu&QcJRnN>r^ zyakf_up5kVvB_-cRI8G)L(dPXrIc z3eQokD!Iuj8V(mMuDM=Hc=umkd8NO50A-;w3{~;+1wLp zo4hNM%(?WWRb+KxoAr}tjXjF0wX2}0YcF%_HWn}k1jo~U1`&*KafTyM0P!SGumg~UC!E1)gy`n|oH#h59Al1bL>!Y1@O|Fu=8`d2Hu4$lnY8tW@&C# zWt&xN>JcxLw?*3HiZ8j{pk+^U%Vw$ytB|Ss5ol*}sp*E(W&$!tyyMBQ7CzfA+WA=0~X0urQjhWrsPa`+UZua%kD&gyi zn$=F8TElP2RmqNp*hjcxQl|VS!rj;Jrg3kNZT+WVa^1lHH*@*zD{>#sc%4 zB&ghJiOx$e?>!+QpY!PQpKtBmejo4J)w2aGlK-z?Z))-%a&(sRe-Y1O_kWzbb~$&M zw}85xn5Qnaky9%;`h9HW3|9@+etuw6?o8A?Dg&-Ng>gjURhB#rKYJr(Po_6DC!bhD z(DR`5bxD4g8mEAhPJ+Uq4N_CIWy>P}p)Y;dlPyI4Z)VT`);b&OOZmTuXYu;Kj{l{< z=N$NfbD(rjOmdqgwogQT3OwM+ejhGNd(Aq*awDD3D@TCdZd1 zuo(+{j8*}Z0xw+Y1XH{zLtZv_=AK+RGU9&Zj=fWV=!H`WHcok6h9FBhGg5UGj>3q~ z=_IT4vJ6GWGG?TQy*}}%7yywim6-W7r}dyT1;uycXKZX_YG!ob4UA@QTCxmvvzB<& zA(K0y&MX_Jdo%A>+D_#f`X#g1ETSlTeRLiJR8b|C!QD0vZn2F@*Z-q1@On@tDpm_R z|L<(;_W#c7jjg5qXCcqx^?$PsNPLZYZeOwsF>U??nDQ-S%1X`xw6Kh;Kz*BmZ_tSJ zB+UHrwD${0Lv98!8Vj-2m5qcb{5T3PaLv0YoQ`)0W1{Kg3U-_9G_>{kFW85WDrL`V zyyQHZ^8;P}1B2Xz(P!>vQ_l*JFaJB8P2K*}dHs5Odnx}H@hsN<&$%lLLBuA~k^EVg z^r?~4B?@Qbo63%8ii-=b(0T`ZH}8P3-5h76!z5#%SBVjoMU775))*j~0al2`Jr z$xr*oWs`~vmZEm(un~+7;*U;35>BqXNVvJ<*u{wl_w&U0o3)tT*V}nxb}ciyuctbt z2r`@J{j@hr{u(v}0WbhVdW zxK?ERLz6%JkwL;pbNnI-hvjBD7mSa0nkxhvW|8v!fhPJ)G|o2FE!Hm$7PAKON(3q> zi7H^cRIW>>a=B(~6RSpTN=_r@y)a+Yw*1`lwQ)Ra(%NNG^V(QXMB&8>~h`Cn&g|6Rzl zSo^PG4>1=)2rsW`bH`g==rMRU6nfA-GS|7M>@$~vjn&(h3mdB^Hp9jmi!2KpYp)_} z3Q~|qGLRm6N%B5JL-J6ZY)nvndcecFP&KMgzHeOv$ol`&3kJ2V{rD8&zi++ zt<9zX&qAIBtpCq3Dyyqv=V~3|P zwIdqZF)x-FEH<#0YVvP-km+XNjV>owO^oHx1o?LD54^z-VzHxZU6Wq(k%!kgjHH2=4Wu|RvkO-sz|vs`wYTPA6M;X_I5G%6jgSaR4gJB^xRl6rcnZu517<(ocoas zXj4JgYRY~~G4ZIx1ZN%L`3{X@Z4m>_**lWvdy~gIZd&Ghvi0N1X@R!HG;qBnOQ_0Z zPMU1IgxEn<$((c=gbl9)3KM6YwPw)9fA}n^NqK$5Nuk zzCR#$;gozHg*ODf1wG=z|9f~58zwPKx@(p?CgBApAa9v4C9rXDgYfdd$ai4`>8~)3 z$^fH&&NYp+r9=t5=L>GFCF9pN*#vKAb$iuhwQ#lqw(@3ISxFO zO+63evZJ#Jxw-NKkM>m`yPWtje1*k|3}C|*-a(^ZzRV~&1K+(Ifzb2&7)e&%Bb_D% zUAb72H%beFPE9icfsm7$24NNKc`; z)lLHsCs?ZaB2Q^e6E)`_+PG1LE7@hL#R7BdY`pU(v}@=V8Mqz&Wl8Ujc(=gR7~`9E z32IdRNkA?kHBI3-DPTxB_3-Og;sgfu%paj5*!SMxbUpDXV0=XUh+_`~PNp$vU^qjinXzLS>6@9lvC-h?<}szh>tBT+tfYixme*6 zK}pDZi>MvSr=Hl)l9kAF2W?z{z15`07@s;3^f;nE()XaVaTiqSfh4y&rRb138d6A$f zL!Yr_3bi+8b*kzo{f3>v-T0tFfnF;H(K|3Lt<^=oWGGAARC}RizzP^b(kl>DS(;8_f56oUesjq)ie^5|V$LW+yr778KuL%F$6&Sz4?NMH%b~4=|IJQu67nCk zU9h1F=#~X`ES>e&tu^?+PKoToXS9*wQFRW1+U$d5_ry^TKke6(^{>4C=M(6B==xLl zGEJx+`)J(*gD|3pK6vpJqx{D5u@^M~CWlf|F`VaItjAaulNqJlHYl-l?Of? zBq?M^S5vA>*!+XQ0j_nJw?ov-#EX!>qWL3@9|0eLaB`oB0zw z@DtA3>6UiB!DpWh<+R{`xDWVKNd>PG$gsYn07783o_Y~Sw6d_Z>#$T6+9z~Jlr)}kQ_b=xlZj{z{2<+>pK49_Qvbw{%;}Ax4Qom zrv}6Eh4~Rnsp_{) zxJ&cI?}4eT=83A~Z?#ZBQ5A~u{}UK|3AC(f-x{Oc1T@1W`Y0r_V(I(=KlW@ z|7S7JmoN9K{kLC|Yk!EhX(r^t4?MgA^Ja*B-oFB-Pd5o5n5iajvnV=WtGfwedTCCT zwYuw0i}-=wJ)e&HWP5{OL+?&6F8o{4bW+-=A80~or63UcZ$qD$jDF7itxSt8-_Dds zV4f2XdVj>+g`*H;2lu;SE&^C6Qn|An|T-!S*NS)P9U=Lj&&~VZls2r&>gd9I`uNA{~0UqKW}U zQJ+$=&6|Y8^C>nxYoKTt)^ChM*1*yz1_j7YQ3^%3zwzUofj2~yl7}D*QlW)E6Ny=d zqA0_bg@Bw^gA+&Kj9q>jR}M=o>)hm0 zOks!8tVt`CE|u-|>HvsiIK{Et+I6ck)6fPPb>#)JlM)J{fT3i(`I%TMuYg&Z%6Rtw z2-r&M*aF5{DYbz!?ND-9FsG~QWI}$4igF<980mUePS+$?r7Wug#U~Jyb467Z);Vlu z%FNj-NBY~?%)Zhn1(xSC-e<*3X6ru{!cFHUnF|a(v1&-cESLf@<~z_R;v6PfcuS8X z@7fQiv8Ba{)aCSl8sn{s{|S2_hgrts1OZGz#!+Qkhrt^zL zXSaA-Rc~ZwlC)ovQ;mA6d3rYqZVBp)%6R8^X#0i*jR-h z?zO4Xu0xRFQ~{tXGDPJ{wu&w3-OHkFJ}&AgzGF4qjCW_idI!Wjftv+uV0a--7VrF>CDzJ&c-vzht`zOLBU3HA$@>Zp@NXwJ^_8g3UZ{oc?>^aEx$7 zAYq6o75#%l)QjN{_ym(DhWxMS($dF-7p@;zjcWRRVbOojc{yniN#hrkh~ac1y=-R7 zz=XeqFrdx<9W|w-$rMGjJCRmDZTsKR54-O_9drr&=Wu`b6cMogcSI2>MV8-a6LTfO z!=C@Lxy4-{Vqn^#+d>$RI_oGn|6kwQex1R8+gSSlF68+FVz~L74SaJ4RuOjpA6dZR z><~tmZT9n7^A#q?Lwroj_POjGGy7vGcKGsz%J!yg+)3U_`C|}Jqf45fz4s>p{lN4G zC3}(xQPG;r=`49S@Ys`dor$=+y+CI8e+ zlQ&h8#jmev%b+=BD;uQM$nP%1yWU`DS5TZu3Zk~0k5 z+xHC8eTQss8tF(_Z*Dr0l8p6?=N~d&Pg0Vx9%*tTq}Dtfl9p7^HWM6vJ@w|dH8b0d zRrbO#@Z3>;*Rmb7#!=1e^i;&909&adF~!+V!nGA-rcET!sGP9V_a}FI+;h{?7aCcn zt`P8A$05fgg;I%d2vss#B_myW=!PuwpEFgcnr( z93VkaK6*ZgrlZ~1An=r$9s?)X#;Y!VKv!qjL3*RURUqcFzyT$LNX2k~&tvgsLVlpz zXtEc${xDuNFUS%xOFp{MU;+lEXe0U+y4$c3qY0^rW#5mQxjcrKg!70utZgcBS!(bG zaW;cN_9x%CGe1@rAX|>324+mU^Jy)^DHkjkV*a^aZdfkG%cc0+Uy3E^cQ1=^1ONY_jsDWZ z?EfreM-cWu-$xw<_#bNu%Zdf{&N2N$nlj5as> z>;1;1ILd|@yS}!*<*dQ~wof~2JDXcOoxisJvc9>#x%HR7{N>MU>pN>}&Brs}9^1pu z*6F~t*|2kIP#*$N!Tj%Z*7f*L+uN^~^M4_ad@;U(H`77Yq_h2SbP>5Q(WmtM4L$|z z#&5hscE@;om)`SLq9d-upW`3&sh=K?Ku+@B??tGje~&&{l+mbH>?Q7q1lD>uB0+fR z_esy2++fHc5gduJX$y!srBPi()FV7PVUbp-3fQ|N{sbXdT8*m^#hHl1#LK}u{0+a4 z1c@($yI}I`@Gki4UpH>9Tm2xM4lbe)Z@zew_8`0&1))2L+dx*B#Avv;Xhm~oN=alhG|wyNcp##ly5wHMo!=VZU3avI6pr}b)=zcs|dKM>8pzBdE2_B zuVzwWp-NgWEE6$o?HkmIIH~`RFhA-f870pcD>%8NJA1fbDSSQM$AZ=igA#<~$1nqeWpds~I97o|`N*AF2BBwBzKmG8522ZqxF-!+qS~}Zl(8kqQ zNhC8b>icd$yn#;(Fb8pDgL*icB!n~?(o)W2>e7%-j6;&3G8~o$V;=UeX!NHZ_0S)% zuyog65RR$uGaEi``k}m=;nr0G3e0D8&l6xxjfTp6N(I!l`lo+Pdmi*>oR;>PziC1B zZN}hIxHt51WX01zp+8cUhYkkEz~YR49C_5o2l&*B8?ZY6BLO}lo!0uspWziPV59Yy z*4m$09ybCO!7>^&c%u|djOsz?8yO1^c-njJwd)7;8~0)5bCq{14W!u*$0Fe4#f2ws zK2QLGKz_d-qNF|}yB8M}SpW(B4XL8Q6A2KEW?K1;?58TAZg;UizmbF6G1LpR9FE4* zN%@>CJ5c82Kcp~4o!QdtK-oE;>~7MNtx-5Y56tjla*mDX-t;bwa7yqa@AW(8CF`4d z6AESs6rhkcN%OmpADi6rl?K0gyL-~afB$cD_1w^BR?2{H2P$Rw<`GbKo>Y-gR+1={ zGHMJZP3-Sxc{(kW!BQB4yu15{cXuvRCcQ5rOrk8!#A(v|$C%wr8Ak3BY?k3O_$c}f zPk(k{Mw|LEp)A2;OZqCsLbKDDM;T|c44*wXWl1K9vXVsA!)H|V?zv;P=Le;QZw`CR zCYH-TNS$%KfxXua`_UTI_MNtg7W_X^{VbT>U*py(zLO-6j&biTr&xV{4F*YRCaB-@plfu#velwZ|HBE9-U>6p48+c=uCz(sU zPhgt#FywCgx}!~WYeVq!o)G)5f6MhlS1BkaABCgB#*}S{ zDC{8`GH^Y32b`MMl(G#;3tN0czMTA0aCg=((e4?clY>E6jq@X^)%#a?AA9& zz7He+-{^`KP-XBMyUFv=*=TM2xpF&dnd}38$$n4vuGR)A z+mKyjwwZ_J{u-iAo6=ItT-ZVyqIy4Dno_nQ$F{=iYzVUug~KrvO`CC7*+g{jR-s4o z%z3&%i>PR|x_3j>BYA3Qr#dNRhHm-s$FVnxuY6{}PRG+=avFFOHpF;@h_1;f7nAHY zanfR+^5Vc=gtc#(hqmV4&tx2aV5hP)ec&Z`D|j*q+d1S|?7Y)k?% z;6Q3VY`4Q5PJoMzs1zJLC^+e5`AOs9Q zjP8ZEDNYvb7ZD!^*u%N*knY}IYE^`$iTfy0*cbEd2i@FAW$-~1g;6E@{F9NpH3&{q zspVzqlM$o$L#Q%+J<4aT>G(2o2VR1&7q{rO5S+P(91tC*5F+df7?A`iAf{*jm;SXk zA~#p~55v1+MdECB1#;fu1v%%COu(az#m~h714G>s@avPSD7>Kn@0g0ZLeTf|Bpfr{ zn^8>MK2w5HgT7XQI1GEPeOOz|zUr(JyYZiQl|Q0#%cG$oD^)XGW@~Vn@p%j1|&LXK^s~^bhcdd*ErNj znuK%_vuTD&SDB+s;60YsBy2%_tt8^cYT@Z87hH^na)N8&BI|xckG;AwGHKz`Xu%aK zb4U*Ba;^oh-qa~Od0}0Y~s0t)ylG<^UD5h z-5O*j8EQi>WQaSTxfeXt;9Ppr%~UzWUlnobR!j53{Jl^pDl@%sowYofdVw*cur}5F zRGblXQHK{A5(|^igLoKLG8yAe}}g zJNR!zfaapN7n{YLt3TeXaA?_S)-q=Pzw{>^o9!4725QoX&Pz5(0Oi z4c{i-!F`a_rcM=>`D2hhr*~sXVfYOrwv1pMYoeap6xNzCPe?#^1cUjVg!E3G*KV@t zC$CfaK<@>x&p^fM+}5eSmax{&{YE-f3iNye`(rOoEQ^LtO?J?7uxB~EFr6m|eIC>J z?=&5c%N-i+(H3m3Kng%oO)OnYuvZ4S57gji_h*`%TjnH4H$oJ>{aA| zB=90PtFyaXAoY-u&V{7H6dyqWieSXg)pG84)yOtST&B~=*b{L;#AyPiyCc6&-2fSM zfakd^-e+!g3vUknckK3+_WVXD>NP*w2t0xCOB3QO@4uBk9qFd5eF~+w zb+AQzqm$;OnAsDD-GgOmL@Wp)W%R_xvK=!m^f8UdXS}YgbzCwcJklJbse|0PMugp(g@38e@T9su=P`{)>eIn&P3MLY zNy7a>`y!0`Yu6S_XmSsu?5XpBb$zRkr##XQ zO7=bA!$asvP|C(K=(cg?mEp9rZZyZ~S6FYQw0S-Qr{jQCv{19~BiTW;yTiS} z=yQxpZa5vbw0_9-o}#Zh_D?08rz+12OFuYh%f5;H2~~){`F@~s^V7sHK3=8iAC(~! zpW1}){lU83<5L?&%8ZyIJGAJwhn!XAFQl9oVT* z$E!s&pY4r=v}Au(5tGK|L#wgz@BLT-w2OhcBM{$d)3K%W@|VlQjPv-wxahL9+|WqH zKDC?#WE74Zk-CQFXN@HAvZHniHI10MCEI)&Vm_V@Px;D559atg#2QQ%JYHc_EQah} z&r24T{bhR2vXWrczUoRgGd$PFbCGZ$dn&zxtu#W{iZfV&ZcA2hYw)b|myOrkl8ZVc zpxI{8!-npd1{f&M0(=qtA-VK31ODBEER2tMf6#*Us)%CG}9ixAtC=% zPkNa7kU7+%Em@qb8L=d?y>`=+wGS60>8_{rvZF4O7$d7J>s#G~eqz>I)t;;#GyyZY*6&#|Ec?HbndmjETWw5wQ@K@TU@Qir+gG z$+`HT9;5UcB*>s3q&IINr+4eZh6&0_LV`3JQs|I^s!o!WR0gG&p5>B77^M-6_idvA zoLW>YD+dzF#dKPo?N$eNraj*sIh{2p+TLh1@J2F&Wh*L_cJ>7j%8EZuGPYi@Vz^^l zT8mADoYhQ= zyomr#z`Z+NAn1BRA!OhSP90#p2%0=Xa2a+vj>Vvf<-TPxdyyq~N6fDnkG^jB;(73q;-5lg+h3Sqv}{l6httbF)LL)gY_yqZoEeKgW)j%Zk% zW|Idb8Tc{M8I!>s4b8(M#GvCekf2ZuB{dpuALLs6Asl!``_$z^B3I&9FNDZ|0~ z^%;>mR_g#rk3B$%enw4+Qnd-ss;*fn+tMgV1+6@ioB%cF4W+TeJ6`%{@9u*;#yC?u zdRhE^5^{=_$yF+}5VDH}hD$E^(I44}VDz&UGPko?*r$ZlXGA9U8Aw&3w_~DX{u}nQ zNmpWD(gq`8QAlYIL62_|K%7G8xwcfxOL1J{DrINhO`-;8?JsB;-R3u z(e+LeA6kSkJKpVffBbl|F9ngl7N-3j=_TPE4NP(3U8rAjx=Z%C1??=~^-_1YOm}gs zte52nI5@XPYUr<6p*Skw_83|#_8;^v-;O5Ts?8{M@)yk}qSy=g1Uve8deCi6ZYN6o zw=Z8Dvu$GMjcA?C__Vf`H9sAx)+a%z18G-@1I@M6*C|t9r$T)lUSGp7goXB_WMJ#D z;?QxXV*@I}4PBY>@*1cXi9L!fcMNU}Wfp}M1Ko~_GQ>~D>lk|2K7Kun-u?hiV3q>M ziK*|bGEi@t%~x7q!Yj)0FSMjDvbM2TWXx{fxq|_DVXol0nCNF%1nR6jfF7(mEpp1N ze)QcmirCpLM*M3evkum)5XhH`dGmY)Q62h|fM(`roQ{)TgA-niDK8KwB)`Pr2+4cX z{L(^+*OIvKYZJvAv}JpfID^%OsS7$YbwNk&f=)eM(7A^$=;&R*g$DT~u<^J%TL`NC zT5GM*`03+_9EI23um>7;XX6!FUt3>$#WAMW1>yp%vlJv?NVi8ABr3l01}Q*?6pj~} zm&ay(hG8eBu@hc6&@&F`!KiD{_=^-!^A}j?B^+zMbH@gA1ttY9xN=7n#16wfviOPk zT?)v|<`~@|z)uhgVFZMWOBrcczzfesLqm*X&8|+drfx6|ik5=&kgL22^d?QkTfieV zaTne#TSt>zbU+3#h>gPgQPW4)|lX{T0gg%QP7MOGpCUb_IRh^C&(ecee}1SD^J# zF#X_;X}DM6FvJ5D9QhmfPBCbUP@hsfPR?U{$gBe|;!qqE1u{j#q!YzYI0?DykeeE~ z<}6?>wUpfVJiQY@?`AMg5b;I%%y~u2V-AI*7tkpvy4(@^494g&Te?c7qw{&h88z<1 zUN7>)Bq~?}0fR;tIrkv+Vys?>EHNK}5*)~sjIS z@I)JchU*Q^EihkT4*_#!^qEF%{ky1p;`Ohv-d2x?ai_w38n?Ys`+A5Gcby4F+-*zo zc^w`hw@tq|rY{`(37X^f9Vj2O$IfI5`#$K6*g;EeaP2wR^mY30h66jdiIX;yaghTP z(z|V4O@_gL%5<0MGh+sdBE`~p4)zzV-ML-WSs$-LVc<#R!Nvfsn0{|M zQMyOa1nra);QBEl&D}0J>^8~U-R@!cRpZCQ)9*iiIwe2uo}BC+ogN-^$;T72_wi`| z@bvKG5&ZQX***Ff`N!eW{ww17%=CCWrl3bSU_+{cv>IKGU?wV04l}6n*zZG&Mwe4G zAzq^6FFmdp19Pz85cDcngI*5jk~`C!R^y=qtv}Ldco+W~2(^N3``XeLyOuiEI%{j& zo10{9ZLRZqtAqc=NBnnfqq9XiTWjkZ>uaw&>l*}8b=F`1fvnY1d%*)67&rRE8q(Ow zONXaydEd20ky?qozXz2bA&7-geZ{2eF6c`q_#s9F4Oo0|ramLx4u)Vhr0xAsHbxhb4prIK>H>CgX__IG223}^N zdG@R!|GmSpa+&J6oa5CW)BL9@zJECaO|O&lN!oL;!pFhI>_akhB>E39}NWvu^)oWP2Tl?KJJS)Qkr#;H0Fcv8~+i1#@C~ES`Y%cPRCTMiyJRn@y!_i?YW=f-^mbu z|Gx&>i6gqPIov;h3c2l~(SpsQ+h*zDRikws_rrmQW&1#}FJIa( z8`V^RG77-UHak*iza-cGaEG4v;{-$V(i=1y;|6Dkq{$j(VxO~O@nnQu%190>Y{Ax> z$x(_h|E`E1tvxxNp(5Vbp|!=*Jay z+GDC1#v>_F8BZxq>w7mQ0-~Q4j%Ns10UeNJ$f&pJ1+_1VN1QDpZ-z#m5Pf?-|Apd{&r2?b zPA^BK8nHb?S~{KPAxA`WFGo@~ko-N7HE=zsJTA>`Y5E+}&^kFkWogv-lBAhp*540p zav=C}#F^vJ-w$;H9lRW6*}(D(n4DVN_HvYJk>fLDvhUN$6~>8XM@==6OQW-wowWT;L%u^yYZEUnQ{@iNpQZJlINGN87B{h0aVdqJXUDMIT z50V5>R%?yfi`DHu7Q?&m6~8)?;6CBSBiL5+o2Jb#U%xhqbW5&5P1=ksKbGruV~Rn3 z>D_+7U6u&Dh==!Rp1H8oK)!w@J+JT5V2)Ta^&{bD+IW*dPV0}z-=SgLT`y+-OHH7| zi>UVx_Q*vz9f1_3mve#rU!GFmIu;Cjz|8g3Uy^x>yokxrANj-S$TS)+UzXgga4Ww= zYg6WRsb`vBR<3_qbN>4C>dT-0zpp>P{QC8IldLG+LwSf#i=4idU(ky`1=**azsjR#^grLY7$+XR+(3U~x4_s< zraz-U?+!6It|z`9Os-5K&ub51HEyd;AsRwE?bFO~z&k@fGGCG@3ju;&zx2Y$m3xhi zfCbMD^d61T;;QiYb~r{w4~x6E3Ati%>1l?hFIKs4X1#hPLplo2{*?zEMU zU$7J`ix4cRcT1uqo#^rfW9gc&xZPVcz3Et{`$#ANCU=Y0CQn<#tYIp!b>65s)RW6> ziLLbJW0I1kr8MD|cHrIS<$9hFEpm#Hiz?^?)h5e^mnl7-! zWmBk?V{B&x)+^$*E_YBpgH21)`^^^l5wC%ceb~Y?D9(Tzk=;5sN^MBPb6+QZZE)Re<(2WO~c4+!t3&E0SwQN?w7il@}y> zf0*B2u;FYEB6~r+4BY_RGuVUa?A9;gSXvsS2P*N-)?CXrcPFw66q&c>O@=$u= zg@qUuJuLbo<~eivfuWwb6GJtrEj4XfS{Lhimt8u30SR)enFwR0)NOtSMkHOGOg*<{0^45WewfIKDJ= zF}5uwuTY83DsPE;`8=Tv^y+3)sG!diI7#(&x@byHiA~&1Cm%#oQ7~WcrSzb~wRrQB z#GD5t7!lJ!kqMYQ(L@;pcuSMQlB$<(`EAv*kR*8(%Yg85%}sL~a%*S9vyVtZXt7{{ zwn&qDm5TkY#g366FUW=rKHjSoYeCcklT@xq-Wb8`KpN%Gbdw_OQBw90TbxX4iqkXj z`f1U^*OML9{YqM?MnfgTs$7HE-~8`L08VuO|Ms4=yNx5c@A?(<#&Sfgg(1OH%RFtO z%U&fq7?HN$ZnW7Q0z-0E00y1`DA8;Gk$lQ;%P&dS(dYCWxG2iOJU@$=>7%;3y1Kf$ zj^M?+cW>VvqYTUI=e;=pybsZH8k=RFsf1Az@8b5Jco- zbE-`fN7KnL*s5qn-_dlmX^0;d7@}_0oU@9yE2eA_aEv*0j>L|2F^4t_?BlRv9FI+I z;W_r2O*c{sH!i)~P7J2yM(gpfLwQV<!@p3#@?cq#+#K*i6 zB?8V$H?vWar+x7v*qTiy%)eezXc| z#TrFFO-ox>brrazeMf<3pA3hu(kZIO!}srhG*A?T{|d2gz;|8@=b(M_TJ?jegDP!TgeRUFM)FTKU{Mt~qr(jbgf-eWmWc zmf~n=yj-u;=$KoXy=_&9q4gIp;ry6!-cJ;e|YV-8Zmj<^LcPq05Vn_c*)x3l zy7Vw8jz6c`DPU}kt=8DG~_e9!}lonyfdkHuuUVS@`hGBAuPhxh{lpYGf^zFq9X zjAZOqS5kHmd`y5Qj)PvcZFd|9mNHms9-)Et&Li~zRpimM{WL-gr^ztsiwQVOa+wvO z`z6g~&Fn2Paca(Bv4gaLt7R=S7}|Cepr1ke6YkU04z=SNrk9D70ClTGFY~lYHLO;f zydq*DK~Az^c6kG$Y-`jTmGlId?-0wa(Q8#DcmwmLpf06c|DXajfd2p_g0M~ADu#)S zev%C&nQg=0Vl$ba>_kO}?SoNKHWpixBDucUbh6Pa3=eM@X=MX?1$JE1JVtwVw~+hA zhghzEqKAV_!D+<(%(dP~iBT^JB}9V2seU-gL0iwJfgmN_DioD2O4J8k)a3BZ(WqEygsM`O6M1*6E~JG%{qD5%!=ZPK_gmJkU@5uDb4gJ_$1SQ(s_|qJ*=t`_ zIu7s{t4XQUogq%R+Zq^=Jv4L+WkPZxx=;Hl?yX$UyZeK^<%iOzRViRwcu=s#>J79Y@4`^as%G+yh4!O6T?9Ol_!%o3fl ztY}TKf6-!{ySR+*{}$F!nc1#-9ckT1nE6`UO%AD1yD-D6ANn823udFuD3ZJI<&z5uMf>*!|@!$7%_x9cR&-+K4{13PC z+?D&^z!xNWAS3`x%?soRsl&hmbbDn+D zZY6mF9?meW-RoX(`s`Wzc_ew})JA}5o}^w$B>-FDmnyYC)VG2_oqgj$46cK+7Z5cy zSe8ThR&_9JtILiiqK+*+VEDkFN=EP0iUYSMM1-(}4a~F}c7iPmxV@rQA&4V1I?w8q z7E`84wqOtMi2fiMrCJFsh%g-+Wb9BR&bSnf+?jhEWFxUY+}Ghn@f~z1q`!PNeo}m2 zfP77V^9RRGpNx(b4TwKqrQ_Kra^fuPLB71;bqbcecwC~C;t!1#C<>slug>rZOJ5$v zWYjTH3jZjS$tn7#LH4)B#%+UbkFp#lpv>9y6w<&PG|)H!Uw%RpFuj0!r*<_k2-M!L zfm*{d6kq!_=I@|G(fq3C&$29C0+m(B;-r{J*AOxg!oy>xRO#m}C~qvYrYdGfuD z=jhOp|96g#Hu2wX<+%g$KZ0aFe5#&n{0Pf0%f8Eha9fPyrNgDyChnaUvb0&@9TC8QpZ1 zZ%p&lI87Ow9Dc!=XcMu8!3-7f$17CxbwfE|qXxR~Jrg7Uwp10BgX}qKD4(4^Owp;b zwZ{+{84y}oVk;m=!YJr?q%ZubeF`gE@g6(B16Q%wbS-1?iDs~I=4!prRrDnKHP;d= zHLQI#U^MKLZ_Hp6+Fm_=hb7$Xrf<*xj`w4Z$f%0(Y^t70A-s%s%sG}98!DOgb((yn z7;S=e=IkLR4ki!2E*`LV4oGlP=X}53QQUDy+LDe<8W@{Gj1Q0N9F3Ge(sih_W`)u> z30n+mJd(&sP2$i9VPUzc!6BAP^1%$35JmulxIE)7mu^FH)e#q*P+sC?&!)rDHGdmQ zwE9!D!~x)V_!vz@eaj&-WdTm$cq`67xs*+1W>I&N7mNN7`S0#*-+fIEibGNKxTx8~ z))xoPMXDPJ4xIQ7re@@#LY5iwEHZ@yt7h zDOI;!I_xw{6nzHxjGnm0d24O-_*&e3AvRFe1M-B-2EDF+T0{pDNBmeA5{L8-z)Rj?~*&^)+An)LYG9I9y zHcH~L3|Y%@ZXu4?fKHyijXcKS`7{}wR!MUc~gi`jMq2M!08E{hV;^09LgdnH| zzbbMwM*43{*3phdAUpfZk#%%n5y;L_TeAMN z1k|ZK-qt%Nl7l$bW1my4(do zll@QcXxEkh#2*{^?>3%0BmWuM-o@AP0DM)5`h4;j)1@q_d4kvJgesLSnCk_$QXfv_ zAsKBba=PtUU$`@!1mnKcrK!k(Ws7G{YE!MpH$%&WSIKY`6<6CFAh4nue>Lir`-S_L zcx>JfSfoRky#2}fBY!b# z>b&Lkakyjjy$nl5jXJS)eg7!-A?Lt8<}$mirfK{^`EreG@|ts#n8{|fBaD5`w~ z0g9u7Js?bv22d^+*L}M{4L7l!A?g^4;l<{1lY2iV!5|wym}$ z6at2*{*W3@>i& z9Bg4+yb|MU^n_^e?&=u&Q!l^dJLDQh+L2u@%jD;0)*UUSu98#D%XKzx1b6vq%Ku15 zr*-Ck+z}$bYyZ>R-N^s9^V}KvpY^|F!Jb1ntl*UOn$L!D;XMUN>g+=S?Y}qy5u}(V z#2Y>7*o*=}NEV?@S9MNT+U|hfBZwF&QdyW1{w3<=-NSn$O8QKq8lRWsjSI2MvY2g1K;~cKym(u_> z#Q*GxmoER`Kiu5^-O6(Z_&?>;7TmI`SHoSH!t6OcO1Oaqt}jbTOeWUe!xc^1M|g@nxOMAU>mbBoz-IL z_eI$Y#OX0lV3=?i!t6%zb(Rjw*ybek`brecI8)ICCCq>WH+xMOtO2+AZzk0_lf7Sf;9cEi88L*GU26LhH5IO1vvauB*E` zJZ*CoG1_daN%O6=yqyiHL7A+HMTjkJN4EWSaf}xtV$}$E1-+ZJ4^;2C#Nnb-Yt!k% z8HSbP$HkB~zjZz=1f5K6VPg5Q_5p27Tw&J)y8Yk({-5CV#k23rXI6AcH3pIvN(GjYbDIDd zv%(CNPb_vO1Z;o|G!hR3!IVCTvC|+gl2{xvKsN^EMrnbd8@vrn)l*P47SX+Xry5_9 z7f3#QY?^916!I&@WkL0)F`bQCPn!z?B@0AOrRk!wijkgjV>FR9RDbQZNNI#(x<#-b znqeg?&11nXR+Y&wok2;|;igYqL>8Bm_>=~bT1F3IU$$ORa3ei{suYrI?$ zQu|Oq3Z9?9Vltb{FsxA^*Lx60=TTpisRNgs{o}`K&P)XAC`^T;H&8Xrge>?Xs+a;V zoybaFLebvUoWci-Lgr2OL48ci1{0Cv7WFI>_<6kZQ2LTfMkjEt#;xEmFE2D8(!JFL zLsfC1R=%)iSq59es6Cv`0&^|_Lwqq=PSh#&+^{Ts^J2##@}tE>u)vMe9ue?3f%p_+ zk0+~5L7QOpE?wKlv(dSb40eFiz}!qJM?9vs9#csj_QJxKREAx8>BfLdoYPVWP_|P> z%l7Xq8VUX&0QpiTrG#slK3ZT}h)R&4Je^8bAfeQ3tAxun46?-#ecYf;1cC}lS_#i* z$iIPioBM5VSDkM7TxWWf{jBenQ zUgCZ~%LlwXZbau8?_wxU;JADWuY{^5qgqC_&-V5`ADr^R*9FXv3wC;$5(UMDIE#%*#UO;b;d$KufRO}9C%U+^f}6GO zy@%D`b~{x|yv>rfpfYse#(Slk`PB&@;Vx+dA+|0=5EnS{zAS=p6i-aefTuStshe-n z&dZjp%UAtv+9^rrrFChI(Y_wAzL?G0aMX==!4X#;mgXGwJf{@HO2dqkZ8XfW@Z8xy zcGW8;EWZS^ar%=K^p$mA*ylHw#kFD}&=;$5QI;`3G%X;hTX3J7^Q;5?%ki&OPr+}S z3zFQ=?hb&v%Pda{ehoo>;Qh7`aB?z;4p6i5PxZ%=I?+b?yUcemng0NyI#Pl@emE17 zdZU!j8q&+;(}XN1q$=q$onFn((Kh6DT#$4*D7K4aB)Z!^7ff$^ckkk$H%Rs##XFA< z5Bmqn#m@Ofe}DIU@8W3hpntU2+c`Qv+S!plCedZ~)vNtp_tpNs72XoN$K(#d-~Mas zKXt@jcC^)Ke1UHtx}`{%g(^ZV{!zTt2BMdx=NsPRp!a`*pc;L18UNIF5k zCKz%>K_#OPBK$8@RioGO-$5`}Khv@K^909RFZ+AWPPL-_=T=T^p0z&>`ait`tTX=0 z{!uCZ%fZ1$|92bD-O>M{J)ep?h;|#wl1n*rijDUwo)qMfSoFn4EFIPOM?oQAz)Z2) z9L6Kp1h!z~*-r75DewgB0lKc{LmZO$ONa;c`*yiQ+lB;o9l$&YtOf4XA?FTjBfmGjv1+T=fBZuXYMT990T=Zg5YW=%(R5gXpnx*i>O-VA_(eIrz*|fl z6R(p~EZ>E=q6~AW`yc?p9hhgbvh?TF<2v?bSy@bc zjZnsP63i~Fxb$UejxPlA1DZ4G2O4o3pczXB=%ONsTGS<{ktrb#q$(j)jkF{cv4E9k z+lAQdFSh|x1zNv;g}Cd&vctbxtqkcT9eBN@s|dJP{mDLiwL(%h~(2nzt6_a6i zqKcLyCC+uGQ6!?)q9ipVu--51go+)Oe{?WK+yZH_A;|6OektW_rimU z72?2a;wJcM77x*x1hi9p4gX_8t#ia)(FZ_YDAT+m6CfIad=Nz(v;(f{F@P6&9!#Vu3$?V0lVXk6XC)-B%4v=3+5AtywX(rB<+P z6ngBg+AbY$=oAgS@9WY_$=m9xmlOsUWUGEny_6$_Lf>YD9x=seoQf_BMj{czw+O6X z1#O&T;C>Po+ic35ZKSj_m(v}a3=iKdze~rJ8yQ$SOTQ}9?Dj#SQPg((@Qu@%?urOM zdQC;16nW*8EuFbg(N_LzkpIObWcixyKX(s$ZvNL^Z+|2I-^z1WB+ww*6`pf?!RVfuRP?^if%pPC5VPY+p`i;EeAtgD`$U9I z+9&ycw=&sCsCIV3Ql6zy>&s@n*+k04zuQh!hC@yDN)TAWk}3n zDP50eM#?BC+v?nVm;5wKb4Uox9R^^pI4a1E)9p>Xk~h7{1C{92=NRLsMHwOqd>k-RLvCphd|Y=n_<3dX?i$0tutPk(&-?)hoJ!H)lw&1gNcBP}_n z^k+F@L9btDksESK6jpc2Q3C9j0*t_Y-lzx|3FaJQm8rSiKMb;=kY@4(Sy()T^vE|r z0N_AFGQ5E5M!x+3LH8k1fQ;WXW&huxKaA5+u@bPqo#p8F4z?osh^Vt4k5O7XmzkTV zN{>r%H^|W*O)D;wF@(I{zREs!r`h&2&t~AwekC@qE`%86Qv+p!-Tq1szDwlS{dgs~ zbXUy_m*<&r{bt(?@oT3N3rAM5GC@{myDE!&rJW-yMM046`*7});XN>81Xp7WpWgs^ zk_N~0y=TMUNTv0TL9~83#@~qyw!ukgF`qV`DAB9#UL3HGcQ9hFGkH)Hv+{8)ZJNy; ztBTvEPLJ!1DN@m;;YBda&~m#fq=>|G_4jFfd0G9PaIUONA+%a$GT$m!hqc5lsdUFs zP8criMrA7^$(xK#sw~rg*X-Z*$!G|l5^_`$Usq_bWo-v_0aK_>DQb#ih3d3mdn{Dd zRj9OyNSh_PU!38V?M+LNm}qN;!=hCa4C_NJ6kfB&3N&pwlT{8JQ;T+Y@t6QxAN&B< z@Kf#34%y|wQF>DGb*Z-{8}0b`s2R|QHWaakydV4H-TaW`>BS93 zi>c)K5ZI>pkP7^OEM|qr+C;#qjezrh?5MNAICn|1Fc_FCOSTSPL<#@K;9Gq;PJhN} z5#R>TQC~%yb}F^AckYWP*M)BExF<}it(kIiP-i2$6kg;-c-o9-Me zAfa{xZQ$-@Z9o#*GH8I#Az)6RBjc5rSzY-_o{W5T8bMc#f=?o$U2N{5zaPK6fYS?# zjfI$G{2`;di{nin;#AZT*h8!V(j{;pmp8%1A+QT#2ae3i?xT3TP2lYEpoI|nKnbA> z2hGk zyUKM7H@+cw6zujixY~6brC+NK$~4Sl&*7sa)Y1W1#!uoAK%VS}K@wextr=O6(szgV zDBL1C6B}KDYVaev5#VqGBuBhA{N7SsER8l}ftHlZ61_6gBrx z#dvHC4CKY}cM(>q+dPvj_wTa)pH)+G-ffM{(sxFYnrKD65syp~ZbZZOn6h@NWG72y ztEfzRd(^J><}p>@e~sYqH8|JQ)wCo>H(j&r?3``$%s)4a=5`kij*ZdpYhCO&9f0wCX?z1XT|xm%*n_! za$w-j!(KaKXhqh8waTSB(uvx5^Q-A-4eO2Jwp~?)w97hWSPs0ESw+Nfp3#lo4|3e0 zU4+$$l5;S}aP+RSrz)&rrL*kC`1*%9_ry4G!O%+Z;4BjqOtUZV9&sSYaITQIZC@9l z<0{$SQ0D|W%$&5{uL>?;d+t*6nCP{{)>K?Sh_(2j+Xb-*V(~n_|1}@puP6$Rz+Hrj zVMQ8x_KkNEfhA1Tb74dNn?wE=Odwsz6sSS|-#s{T?f>_74>tBcxALr2{-5Un@MQKW z9j3t2E@op2i8!Z^Kf8MtXzt@Px0g zLpO#uH!26>D8Q;3!QdEfOWZ~~*{cnnCwT&Pg(#W;wzUk>8q;E9i>MhL0$xi{prb4c zQYVJsWbF4(vrI6}u_aFYc$J{C68nVBTv}bLdID^Lt4PMU0bmE8_&ui3= ztEZXjm~+-(WNNB<+&^Rzd5&m$lW21Vif18cK;`;W!?g; zB(f`4@xlc*qt`d5|M6-Sn^7~&Eo2W@N}xtPt*Ip4H8P0XSj%RXl0wST9u1-OY%eJ7 z`P*1h+M`DAq_n5;9OwP36fzvm@}&KmGAgZA)?3r^vcO+_T^Y^HwU8?6t!PH!ose?^ zSg);T6l8Z2y1uyC)Sx%aq~?acnKIwsVc~5B&ph%U>(b|z02}1Lqoc!JSN=OV*xSf| zxAEK+`A^-Uyap(>dok<}!NPt9#9vCXP)ZMH1{vP1*B zB?0RRX~~+~(VLRhhE(H&W5$WRm$H;4QEq$+tzJFtd|xE$;>KuW#;+UeSHLi7+yA>n z*^gBXr(B}ks_mfQ(X{k;zxhG6M}t6`gtCartVD2?*Os>X1IKi>VDO~>az|E+ z?Kv=AM)IZPCd0cVW17%iyWo7*)Lm3#er;bM$M9ZbcvW;XWH}hBn|L}|3*%k$ove8J>WIi?1ZsUV4ov&>C;s4Mr| zw(Ds7%yItj3k1gFK_1U*0n+6EbGYl~f7|cv9B$74xAENV^ZyFYewu3MI{GcZH=oI# zR>3wK!CpY^tJ@r$gABNWE0)#`t@s$Hhce&XFLsElZf8j;M>qV19N}ob=fXK`_f&1I zQpo;D++gQ4ti+EgWPyZ=T zF8_HA>#hB5ys@AbxQ$<{<%`2YZq4##y;HNi`HP&g^_#zZ?(MztX~_R1xH?=-ESCVP zDgNWmj%)wX+dbOf$bYx-+yVKISm1XYZ!9>E`yXKWh<5WEis6NstVa`Z5D_~aMO=;r zWJY$!Cnqmu9@ct$5J}M7i{S*6UyC8J^ACTOu0ZtdBttgI-}sjs3(j^6Qf(@05$zBp zn5Pt+WJx)8vo`djYHztsy2^e(@DN3fvWl~CZ^c=HfJK^l)XDL3Yq~&Z4gSTZ>jJ`BE zz(RRIfKnLqvEa2}$gWX~40s}Na%^5q0;Rny#N^>fLRAHk$IQLdp7~L21svjBHYl)R zx7N|$E{0h=J=}M{%kFTd${qd!7`D0<`Afj~cJVhA!aA8geVz-TgPv6Q%Mal);Dn^TQQU0qFX zo)Z&HzreI4BHm$&uYv-#Fd`VPXT!KCbh6k*k@3=LZBC?=tIvTP8l4(kKgp-vQ9Kr) z=i03@)~RoBv7Ws;4Ji4=J*Yr|>7`#{GL_*P88EZD=TS_=J1khl?Z;I(JJx?TzKk~Lh#1%%_Xnhsq= zh#?izB&Xb4dDv-Lt)ch_wFg4s>9FX={Si338SF%bBl=>c)XlSbHqYkSJga{G4+2KU I=Kz!k0Oli)=Kufz diff --git a/charts/redcap/ci/ct-values.yaml b/charts/redcap/ci/ct-values.yaml index 317e2af..2dc2d90 100644 --- a/charts/redcap/ci/ct-values.yaml +++ b/charts/redcap/ci/ct-values.yaml @@ -11,7 +11,7 @@ redcap: install: enabled: false -mysql: +mariadb: primary: resources: requests: diff --git a/charts/redcap/configuration/audit/redcap-log-event.conf b/charts/redcap/configuration/audit/redcap-log-event.conf index 9c7a05d..2a3adac 100644 --- a/charts/redcap/configuration/audit/redcap-log-event.conf +++ b/charts/redcap/configuration/audit/redcap-log-event.conf @@ -1,9 +1,9 @@ input { jdbc { - jdbc_driver_library => "/driver/mysql-connector-j-8.4.0.jar" - jdbc_driver_class => "com.mysql.jdbc.Driver" - jdbc_connection_string => "jdbc:mysql://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mysql.primary.service.ports.mysql }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" + jdbc_driver_class => "com.mariadb.jdbc.Driver" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event2.conf b/charts/redcap/configuration/audit/redcap-log-event2.conf index bd6fa03..4f69730 100644 --- a/charts/redcap/configuration/audit/redcap-log-event2.conf +++ b/charts/redcap/configuration/audit/redcap-log-event2.conf @@ -1,9 +1,9 @@ input { jdbc { - jdbc_driver_library => "/driver/mysql-connector-j-8.4.0.jar" - jdbc_driver_class => "com.mysql.jdbc.Driver" - jdbc_connection_string => "jdbc:mysql://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mysql.primary.service.ports.mysql }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" + jdbc_driver_class => "com.mariadb.jdbc.Driver" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event3.conf b/charts/redcap/configuration/audit/redcap-log-event3.conf index 050369b..d9fc846 100644 --- a/charts/redcap/configuration/audit/redcap-log-event3.conf +++ b/charts/redcap/configuration/audit/redcap-log-event3.conf @@ -1,9 +1,9 @@ input { jdbc { - jdbc_driver_library => "/driver/mysql-connector-j-8.4.0.jar" - jdbc_driver_class => "com.mysql.jdbc.Driver" - jdbc_connection_string => "jdbc:mysql://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mysql.primary.service.ports.mysql }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" + jdbc_driver_class => "com.mariadb.jdbc.Driver" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event4.conf b/charts/redcap/configuration/audit/redcap-log-event4.conf index 5e1a7d8..4724396 100644 --- a/charts/redcap/configuration/audit/redcap-log-event4.conf +++ b/charts/redcap/configuration/audit/redcap-log-event4.conf @@ -1,9 +1,9 @@ input { jdbc { - jdbc_driver_library => "/driver/mysql-connector-j-8.4.0.jar" - jdbc_driver_class => "com.mysql.jdbc.Driver" - jdbc_connection_string => "jdbc:mysql://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mysql.primary.service.ports.mysql }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" + jdbc_driver_class => "com.mariadb.jdbc.Driver" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event5.conf b/charts/redcap/configuration/audit/redcap-log-event5.conf index 388cb59..4b59986 100644 --- a/charts/redcap/configuration/audit/redcap-log-event5.conf +++ b/charts/redcap/configuration/audit/redcap-log-event5.conf @@ -1,9 +1,9 @@ input { jdbc { - jdbc_driver_library => "/driver/mysql-connector-j-8.4.0.jar" - jdbc_driver_class => "com.mysql.jdbc.Driver" - jdbc_connection_string => "jdbc:mysql://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mysql.primary.service.ports.mysql }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" + jdbc_driver_class => "com.mariadb.jdbc.Driver" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event6.conf b/charts/redcap/configuration/audit/redcap-log-event6.conf index 7b78053..56a7557 100644 --- a/charts/redcap/configuration/audit/redcap-log-event6.conf +++ b/charts/redcap/configuration/audit/redcap-log-event6.conf @@ -1,9 +1,9 @@ input { jdbc { - jdbc_driver_library => "/driver/mysql-connector-j-8.4.0.jar" - jdbc_driver_class => "com.mysql.jdbc.Driver" - jdbc_connection_string => "jdbc:mysql://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mysql.primary.service.ports.mysql }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" + jdbc_driver_class => "com.mariadb.jdbc.Driver" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event7.conf b/charts/redcap/configuration/audit/redcap-log-event7.conf index bf75fcc..6c4a379 100644 --- a/charts/redcap/configuration/audit/redcap-log-event7.conf +++ b/charts/redcap/configuration/audit/redcap-log-event7.conf @@ -1,9 +1,9 @@ input { jdbc { - jdbc_driver_library => "/driver/mysql-connector-j-8.4.0.jar" - jdbc_driver_class => "com.mysql.jdbc.Driver" - jdbc_connection_string => "jdbc:mysql://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mysql.primary.service.ports.mysql }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" + jdbc_driver_class => "com.mariadb.jdbc.Driver" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event8.conf b/charts/redcap/configuration/audit/redcap-log-event8.conf index 10a0418..4bb92d3 100644 --- a/charts/redcap/configuration/audit/redcap-log-event8.conf +++ b/charts/redcap/configuration/audit/redcap-log-event8.conf @@ -1,9 +1,9 @@ input { jdbc { - jdbc_driver_library => "/driver/mysql-connector-j-8.4.0.jar" - jdbc_driver_class => "com.mysql.jdbc.Driver" - jdbc_connection_string => "jdbc:mysql://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mysql.primary.service.ports.mysql }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" + jdbc_driver_class => "com.mariadb.jdbc.Driver" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event9.conf b/charts/redcap/configuration/audit/redcap-log-event9.conf index eaf0630..7a93fc1 100644 --- a/charts/redcap/configuration/audit/redcap-log-event9.conf +++ b/charts/redcap/configuration/audit/redcap-log-event9.conf @@ -1,9 +1,9 @@ input { jdbc { - jdbc_driver_library => "/driver/mysql-connector-j-8.4.0.jar" - jdbc_driver_class => "com.mysql.jdbc.Driver" - jdbc_connection_string => "jdbc:mysql://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mysql.primary.service.ports.mysql }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" + jdbc_driver_class => "com.mariadb.jdbc.Driver" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-view.conf b/charts/redcap/configuration/audit/redcap-log-view.conf index 70e6b61..58b01d2 100644 --- a/charts/redcap/configuration/audit/redcap-log-view.conf +++ b/charts/redcap/configuration/audit/redcap-log-view.conf @@ -1,9 +1,9 @@ input { jdbc { - jdbc_driver_library => "/driver/mysql-connector-j-8.4.0.jar" - jdbc_driver_class => "com.mysql.jdbc.Driver" - jdbc_connection_string => "jdbc:mysql://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mysql.primary.service.ports.mysql }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" + jdbc_driver_class => "com.mariadb.jdbc.Driver" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/mysql/my.cnf b/charts/redcap/configuration/mysql/my.cnf index ae31175..582f3fc 100644 --- a/charts/redcap/configuration/mysql/my.cnf +++ b/charts/redcap/configuration/mysql/my.cnf @@ -1,19 +1,19 @@ -[mysqld] -skip_name_resolve -explicit_defaults_for_timestamp -basedir=/opt/bitnami/mysql -port=3306 -tmpdir=/opt/bitnami/mysql/tmp -socket=/opt/bitnami/mysql/tmp/mysql.sock -pid_file=/opt/bitnami/mysql/tmp/mysqld.pid -max_allowed_packet=16M -bind_address=0.0.0.0 -log_error=/opt/bitnami/mysql/logs/mysqld.log -slow_query_log=0 -long_query_time=10.0 -character_set_server=utf8mb4 -plugin_dir=/opt/bitnami/mysql/lib/plugin -datadir=/bitnami/mysql/data +# [mariadbd] +# skip_name_resolve +# explicit_defaults_for_timestamp +# basedir=/opt/bitnami/mariadb +# port=3306 +# tmpdir=/opt/bitnami/mariadb/tmp +# socket=/opt/bitnami/mariadb/tmp/mariadb.sock +# pid_file=/opt/bitnami/mariadb/tmp/mariadbd.pid +# max_allowed_packet=16M +# bind_address=0.0.0.0 +# log_error=/opt/bitnami/mariadb/logs/mariadbd.log +# slow_query_log=0 +# long_query_time=10.0 +# character_set_server=utf8mb4 +# plugin_dir=/opt/bitnami/mariadb/lib/plugin +# datadir=/bitnami/mariadb/data # REDCap recommendations max_allowed_packet=1G @@ -28,14 +28,15 @@ innodb_flush_log_at_trx_commit=1 sync_binlog=0 -[client] -port=3306 -socket=/opt/bitnami/mysql/tmp/mysql.sock -default_character_set=utf8mb4 -plugin_dir=/opt/bitnami/mysql/lib/plugin - - -[manager] -port=3306 -socket=/opt/bitnami/mysql/tmp/mysql.sock -pid_file=/opt/bitnami/mysql/tmp/mysqld.pid +#[client] +#port=3306 +#socket=/opt/bitnami/mariadb/tmp/mariadb.sock +#default_character_set=utf8mb4 +#plugin_dir=/opt/bitnami/mariadb/lib/plugin +# +# +#[manager] +#port=3306 +#socket=/opt/bitnami/mariadb/tmp/mariadb.sock +#pid_file=/opt/bitnami/mariadb/tmp/mariadbd.pid +# \ No newline at end of file diff --git a/charts/redcap/configuration/redcap/database-conf/creds/credentials.php b/charts/redcap/configuration/redcap/database-conf/creds/credentials.php index 60dfe13..7ad670f 100644 --- a/charts/redcap/configuration/redcap/database-conf/creds/credentials.php +++ b/charts/redcap/configuration/redcap/database-conf/creds/credentials.php @@ -13,9 +13,9 @@ // You may optionally utilize a database connection over SSL/TLS for improved security. To do so, at minimum // you must provide the path of the key file, the certificate file, and certificate authority file. -$db_ssl_key = ''; // e.g., '/etc/mysql/ssl/client-key.pem' -$db_ssl_cert = ''; // e.g., '/etc/mysql/ssl/client-cert.pem' -$db_ssl_ca = ''; // e.g., '/etc/mysql/ssl/ca-cert.pem' +$db_ssl_key = ''; // e.g., '/etc/mariadb/ssl/client-key.pem' +$db_ssl_cert = ''; // e.g., '/etc/mariadb/ssl/client-cert.pem' +$db_ssl_ca = ''; // e.g., '/etc/mariadb/ssl/ca-cert.pem' $db_ssl_capath = NULL; $db_ssl_cipher = NULL; $db_ssl_verify_server_cert = false; // Set to TRUE to force the database connection to verify the SSL certificate diff --git a/charts/redcap/configuration/redcap/init/redcap-config.sh b/charts/redcap/configuration/redcap/init/redcap-config.sh index c71e02b..550f684 100644 --- a/charts/redcap/configuration/redcap/init/redcap-config.sh +++ b/charts/redcap/configuration/redcap/init/redcap-config.sh @@ -20,9 +20,9 @@ set -e # #################################################################################### -mysql \ +mariadb \ --host={{ .Values.redcap.config.database.auth.hostname }} \ - --port={{ default 3306 .Values.mysql.primary.service.ports.mysql }} \ + --port={{ default 3306 .Values.mariadb.service.port }} \ --user={{ .Values.redcap.config.database.auth.username }} \ --password=${DB_PASSWD} \ --database={{ .Values.redcap.config.database.auth.databaseName }} <.so' and ; 'extension='php_.dll') is supported for legacy reasons and may be @@ -928,12 +928,12 @@ default_socket_timeout = 60 ;extension=ldap ;extension=mbstring ;extension=exif ; Must be after mbstring as it depends on it -;extension=mysqli +;extension=mariadbi ;extension=oci8_12c ; Use with Oracle Database 12c Instant Client ;extension=odbc ;extension=openssl ;extension=pdo_firebird -;extension=pdo_mysql +;extension=pdo_mariadb ;extension=pdo_oci ;extension=pdo_odbc ;extension=pdo_pgsql @@ -1055,10 +1055,10 @@ cli_server.color = On ;pdo_odbc.db2_instance_name -[Pdo_mysql] +[Pdo_mariadb] ; Default socket name for local MySQL connects. If empty, uses the built-in ; MySQL defaults. -pdo_mysql.default_socket= +pdo_mariadb.default_socket= [Phar] ; http://php.net/phar.readonly @@ -1141,85 +1141,85 @@ odbc.defaultbinmode = 1 [MySQLi] ; Maximum number of persistent links. -1 means no limit. -; http://php.net/mysqli.max-persistent -mysqli.max_persistent = -1 +; http://php.net/mariadbi.max-persistent +mariadbi.max_persistent = -1 ; Allow accessing, from PHP's perspective, local files with LOAD DATA statements -; http://php.net/mysqli.allow_local_infile -;mysqli.allow_local_infile = On +; http://php.net/mariadbi.allow_local_infile +;mariadbi.allow_local_infile = On ; Allow or prevent persistent links. -; http://php.net/mysqli.allow-persistent -mysqli.allow_persistent = On +; http://php.net/mariadbi.allow-persistent +mariadbi.allow_persistent = On ; Maximum number of links. -1 means no limit. -; http://php.net/mysqli.max-links -mysqli.max_links = -1 +; http://php.net/mariadbi.max-links +mariadbi.max_links = -1 -; Default port number for mysqli_connect(). If unset, mysqli_connect() will use -; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the +; Default port number for mariadbi_connect(). If unset, mariadbi_connect() will use +; the $MYSQL_TCP_PORT or the mariadb-tcp entry in /etc/services or the ; compile-time value defined MYSQL_PORT (in that order). Win32 will only look ; at MYSQL_PORT. -; http://php.net/mysqli.default-port -mysqli.default_port = 3306 +; http://php.net/mariadbi.default-port +mariadbi.default_port = 3306 ; Default socket name for local MySQL connects. If empty, uses the built-in ; MySQL defaults. -; http://php.net/mysqli.default-socket -mysqli.default_socket = +; http://php.net/mariadbi.default-socket +mariadbi.default_socket = -; Default host for mysqli_connect() (doesn't apply in safe mode). -; http://php.net/mysqli.default-host -mysqli.default_host = +; Default host for mariadbi_connect() (doesn't apply in safe mode). +; http://php.net/mariadbi.default-host +mariadbi.default_host = -; Default user for mysqli_connect() (doesn't apply in safe mode). -; http://php.net/mysqli.default-user -mysqli.default_user = +; Default user for mariadbi_connect() (doesn't apply in safe mode). +; http://php.net/mariadbi.default-user +mariadbi.default_user = -; Default password for mysqli_connect() (doesn't apply in safe mode). +; Default password for mariadbi_connect() (doesn't apply in safe mode). ; Note that this is generally a *bad* idea to store passwords in this file. -; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw") +; *Any* user with PHP access can run 'echo get_cfg_var("mariadbi.default_pw") ; and reveal this password! And of course, any users with read access to this ; file will be able to reveal the password as well. -; http://php.net/mysqli.default-pw -mysqli.default_pw = +; http://php.net/mariadbi.default-pw +mariadbi.default_pw = ; Allow or prevent reconnect -mysqli.reconnect = Off +mariadbi.reconnect = Off -[mysqlnd] -; Enable / Disable collection of general statistics by mysqlnd which can be +[mariadbnd] +; Enable / Disable collection of general statistics by mariadbnd which can be ; used to tune and monitor MySQL operations. -mysqlnd.collect_statistics = Off +mariadbnd.collect_statistics = Off -; Enable / Disable collection of memory usage statistics by mysqlnd which can be +; Enable / Disable collection of memory usage statistics by mariadbnd which can be ; used to tune and monitor MySQL operations. -mysqlnd.collect_memory_statistics = Off +mariadbnd.collect_memory_statistics = Off -; Records communication from all extensions using mysqlnd to the specified log +; Records communication from all extensions using mariadbnd to the specified log ; file. -; http://php.net/mysqlnd.debug -;mysqlnd.debug = +; http://php.net/mariadbnd.debug +;mariadbnd.debug = ; Defines which queries will be logged. -;mysqlnd.log_mask = 0 +;mariadbnd.log_mask = 0 -; Default size of the mysqlnd memory pool, which is used by result sets. -;mysqlnd.mempool_default_size = 16000 +; Default size of the mariadbnd memory pool, which is used by result sets. +;mariadbnd.mempool_default_size = 16000 ; Size of a pre-allocated buffer used when sending commands to MySQL in bytes. -;mysqlnd.net_cmd_buffer_size = 2048 +;mariadbnd.net_cmd_buffer_size = 2048 ; Size of a pre-allocated buffer used for reading data sent by the server in ; bytes. -;mysqlnd.net_read_buffer_size = 32768 +;mariadbnd.net_read_buffer_size = 32768 ; Timeout for network requests in seconds. -;mysqlnd.net_read_timeout = 31536000 +;mariadbnd.net_read_timeout = 31536000 ; SHA-256 Authentication Plugin related. File with the MySQL server public RSA ; key. -;mysqlnd.sha256_server_public_key = +;mariadbnd.sha256_server_public_key = [OCI8] diff --git a/charts/redcap/templates/_helpers.tpl b/charts/redcap/templates/_helpers.tpl index 6cd4041..a9c3a10 100644 --- a/charts/redcap/templates/_helpers.tpl +++ b/charts/redcap/templates/_helpers.tpl @@ -235,12 +235,12 @@ Secrets names {{ .Release.Name }}-db-audit-credentials {{- end }} -{{- define "mysql.secrets.password.name" -}} -{{ .Release.Name }}-mysql +{{- define "mariadb.secrets.password.name" -}} +{{ .Release.Name }}-mariadb {{- end }} -{{- define "mysql.secrets.password.key" -}} -mysql-password +{{- define "mariadb.secrets.password.key" -}} +mariadb-password {{- end }} {{/* diff --git a/charts/redcap/templates/configmaps/mysql/mysql-config.yaml b/charts/redcap/templates/configmaps/mysql/mysql-config.yaml index 8936dba..09b641e 100644 --- a/charts/redcap/templates/configmaps/mysql/mysql-config.yaml +++ b/charts/redcap/templates/configmaps/mysql/mysql-config.yaml @@ -1,6 +1,6 @@ apiVersion: v1 kind: ConfigMap metadata: - name: {{ .Values.mysql.primary.existingConfigmap }} + name: {{ .Values.mariadb.config.existingConfigmap }} data: -{{ tpl (.Files.Glob "configuration/mysql/my.cnf").AsConfig . | nindent 2 }} \ No newline at end of file +{{ tpl (.Files.Glob "configuration/mariadb/my.cnf").AsConfig . | nindent 2 }} \ No newline at end of file diff --git a/charts/redcap/templates/cronjobs/backup-cronjob.yaml b/charts/redcap/templates/cronjobs/backup-cronjob.yaml index 64ae1b5..fc409ea 100644 --- a/charts/redcap/templates/cronjobs/backup-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/backup-cronjob.yaml @@ -75,7 +75,7 @@ spec: - "sh" - "-c" - "mkdir -v /backup-data/redcap-db && \ - mysqldump \ + mariadbdump \ --host={{ .Values.redcap.config.database.auth.hostname }} \ --user={{ .Values.redcap.config.database.auth.username }} \ --password=${DB_PASSWD} \ diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 03c1a24..07f1a07 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -114,7 +114,7 @@ spec: command: - "sh" - "-c" - - "mysql \ + - "mariadb \ --host={{ .Values.redcap.config.database.auth.hostname }} \ --database={{ .Values.redcap.config.database.auth.databaseName }} \ --user={{ .Values.redcap.config.database.auth.username }} \ diff --git a/charts/redcap/templates/deployments/redcap.yaml b/charts/redcap/templates/deployments/redcap.yaml index d14adfd..e6ce278 100644 --- a/charts/redcap/templates/deployments/redcap.yaml +++ b/charts/redcap/templates/deployments/redcap.yaml @@ -89,22 +89,22 @@ spec: {{- end }} - name: wait-for-db - image: "{{ .Values.mysql.image.repository }}:{{ .Values.mysql.image.tag }}" - imagePullPolicy: {{ .Values.mysql.image.pullPolicy }} + image: "{{ .Values.mariadb.image.repository }}:{{ .Values.mariadb.image.tag }}" + imagePullPolicy: {{ .Values.mariadb.image.pullPolicy }} env: - name: DB_PASSWD valueFrom: secretKeyRef: - name: {{ default (include "mysql.secrets.password.name" .) .Values.redcap.config.database.auth.password.secretKeyRef.name }} - key: {{ default (include "mysql.secrets.password.key" .) .Values.redcap.config.database.auth.password.secretKeyRef.key }} + name: {{ default (include "mariadb.secrets.password.name" .) .Values.redcap.config.database.auth.password.secretKeyRef.name }} + key: {{ default (include "mariadb.secrets.password.key" .) .Values.redcap.config.database.auth.password.secretKeyRef.key }} command: - "sh" - "-c" - - "mysql \ + - "mariadb \ --host={{ .Values.redcap.config.database.auth.hostname }} \ - --port={{ default 3306 .Values.mysql.primary.service.ports.mysql }} + --port={{ default 3306 .Values.mariadb.service.port }} --user={{ .Values.redcap.config.database.auth.username }} \ --password=${DB_PASSWD} \ --database={{ .Values.redcap.config.database.auth.databaseName }} \ @@ -158,8 +158,8 @@ spec: - name: DB_PASSWD valueFrom: secretKeyRef: - name: {{ default (include "mysql.secrets.password.name" .) .Values.redcap.config.database.auth.password.secretKeyRef.name }} - key: {{ default (include "mysql.secrets.password.key" .) .Values.redcap.config.database.auth.password.secretKeyRef.key }} + name: {{ default (include "mariadb.secrets.password.name" .) .Values.redcap.config.database.auth.password.secretKeyRef.name }} + key: {{ default (include "mariadb.secrets.password.key" .) .Values.redcap.config.database.auth.password.secretKeyRef.key }} {{- if .Values.redcap.install.enabled }} startupProbe: @@ -221,7 +221,7 @@ spec: mountPath: /app/redcap/temp - name: server-tmp mountPath: /tmp - - name: redcap-mysql-creds + - name: redcap-mariadb-creds mountPath: /var/run/secrets/credentials.php subPath: credentials.php - name: redcap-config-script @@ -231,7 +231,7 @@ spec: mountPath: /tmp/redcap-setup.sh subPath: redcap-setup.sh {{- if .Values.redcap.config.database.auth.password.secretKeyRef.key }} - - name: mysql-password + - name: mariadb-password mountPath: /var/run/secrets/DB_PASSWD subPath: {{ .Values.redcap.config.database.auth.password.secretKeyRef.key }} {{- end }} @@ -316,11 +316,11 @@ spec: - name: database-conf configMap: name: {{ .Release.Name }}-database-conf - - name: redcap-mysql-creds + - name: redcap-mariadb-creds secret: secretName: {{ include "redcap.secrets.database.creds.name" . }} {{- if .Values.redcap.config.database.auth.password.secretKeyRef.name }} - - name: mysql-password + - name: mariadb-password secret: secretName: {{ .Values.redcap.config.database.auth.password.secretKeyRef.name }} {{- end }} diff --git a/charts/redcap/templates/networkpolicies/app-egress.yaml b/charts/redcap/templates/networkpolicies/app-egress.yaml index 0daad6d..ed5dd47 100644 --- a/charts/redcap/templates/networkpolicies/app-egress.yaml +++ b/charts/redcap/templates/networkpolicies/app-egress.yaml @@ -25,12 +25,12 @@ spec: - to: - podSelector: matchLabels: - {{- range $labelKey, $labelValue := .Values.mysql.primary.podLabels }} + {{- range $labelKey, $labelValue := .Values.mariadb.primary.podLabels }} {{ $labelKey | nindent 12 }}: {{ $labelValue }} {{- end }} ports: - protocol: TCP - port: {{ default 3306 .Values.mysql.primary.service.ports.mysql }} + port: {{ default 3306 .Values.mariadb.primary.service.ports.mariadb }} # allow DNS resolution - to: diff --git a/charts/redcap/templates/networkpolicies/audit-egress.yaml b/charts/redcap/templates/networkpolicies/audit-egress.yaml index 14c8a58..af3d390 100644 --- a/charts/redcap/templates/networkpolicies/audit-egress.yaml +++ b/charts/redcap/templates/networkpolicies/audit-egress.yaml @@ -26,12 +26,12 @@ spec: - to: - podSelector: matchLabels: - {{- range $labelKey, $labelValue := .Values.mysql.primary.podLabels }} + {{- range $labelKey, $labelValue := .Values.mariadb.primary.podLabels }} {{ $labelKey | nindent 12 }}: {{ $labelValue }} {{- end }} ports: - protocol: TCP - port: {{ default 3306 .Values.mysql.primary.service.ports.mysql }} + port: {{ default 3306 .Values.mariadb.primary.service.ports.mariadb }} # allow DNS resolution - to: diff --git a/charts/redcap/templates/networkpolicies/backup-job-egress .yaml b/charts/redcap/templates/networkpolicies/backup-job-egress .yaml index 9ad089b..844f081 100644 --- a/charts/redcap/templates/networkpolicies/backup-job-egress .yaml +++ b/charts/redcap/templates/networkpolicies/backup-job-egress .yaml @@ -17,12 +17,12 @@ spec: - to: - podSelector: matchLabels: - {{- range $labelKey, $labelValue := .Values.mysql.primary.podLabels }} + {{- range $labelKey, $labelValue := .Values.mariadb.primary.podLabels }} {{ $labelKey | nindent 12 }}: {{ $labelValue }} {{- end }} ports: - protocol: TCP - port: {{ default 3306 .Values.mysql.primary.service.ports.mysql }} + port: {{ default 3306 .Values.mariadb.primary.service.ports.mariadb }} # allow DNS resolution - to: diff --git a/charts/redcap/templates/networkpolicies/db-ingress.yaml b/charts/redcap/templates/networkpolicies/db-ingress.yaml index e0b921d..8c2a718 100644 --- a/charts/redcap/templates/networkpolicies/db-ingress.yaml +++ b/charts/redcap/templates/networkpolicies/db-ingress.yaml @@ -6,7 +6,7 @@ metadata: spec: podSelector: matchLabels: - {{- range $labelKey, $labelValue := .Values.mysql.primary.podLabels }} + {{- range $labelKey, $labelValue := .Values.mariadb.primary.podLabels }} {{ $labelKey | nindent 6 }}: {{ $labelValue }} {{- end }} policyTypes: @@ -39,5 +39,5 @@ spec: ports: - protocol: TCP - port: {{ default 3306 .Values.mysql.primary.service.ports.mysql }} + port: {{ default 3306 .Values.mariadb.primary.service.ports.mariadb }} {{- end }} \ No newline at end of file diff --git a/charts/redcap/templates/networkpolicies/restore-job-egress.yaml b/charts/redcap/templates/networkpolicies/restore-job-egress.yaml index 7fda8cd..65d2f1c 100644 --- a/charts/redcap/templates/networkpolicies/restore-job-egress.yaml +++ b/charts/redcap/templates/networkpolicies/restore-job-egress.yaml @@ -17,12 +17,12 @@ spec: - to: - podSelector: matchLabels: - {{- range $labelKey, $labelValue := .Values.mysql.primary.podLabels }} + {{- range $labelKey, $labelValue := .Values.mariadb.primary.podLabels }} {{ $labelKey | nindent 12 }}: {{ $labelValue }} {{- end }} ports: - protocol: TCP - port: {{ default 3306 .Values.mysql.primary.service.ports.mysql }} + port: {{ default 3306 .Values.mariadb.primary.service.ports.mariadb }} # allow DNS resolution - to: diff --git a/charts/redcap/templates/secrets/mysql/database-password.yaml b/charts/redcap/templates/secrets/mysql/database-password.yaml index b87e6b0..5c653f4 100644 --- a/charts/redcap/templates/secrets/mysql/database-password.yaml +++ b/charts/redcap/templates/secrets/mysql/database-password.yaml @@ -1,9 +1,9 @@ -{{- if and (not .Values.mysql.enabled) (empty .Values.redcap.config.database.auth.password.secretKeyRef.name ) }} +{{- if and (not .Values.mariadb.enabled) (empty .Values.redcap.config.database.auth.password.secretKeyRef.name ) }} apiVersion: v1 kind: Secret metadata: - name: {{ include "mysql.secrets.password.name" . }} + name: {{ include "mariadb.secrets.password.name" . }} type: Opaque data: - {{ include "mysql.secrets.password.key" . }}: {{ required "You need to specify REDCap database password, as you didn't enabled the MySQL database embedded in this chart, nor provided a reference to an external Secret containing your database password!" .Values.redcap.config.database.auth.password.value }} + {{ include "mariadb.secrets.password.key" . }}: {{ required "You need to specify REDCap database password, as you didn't enabled the MySQL database embedded in this chart, nor provided a reference to an external Secret containing your database password!" .Values.redcap.config.database.auth.password.value }} {{- end }} diff --git a/charts/redcap/tests/values.yaml b/charts/redcap/tests/values.yaml index f100afd..5d7d79a 100644 --- a/charts/redcap/tests/values.yaml +++ b/charts/redcap/tests/values.yaml @@ -70,7 +70,7 @@ redcap: affinity: {} -mysql: +mariadb: enabled: true primary: existingConfigmap: "redcap-ext-qual-database-config" @@ -163,7 +163,7 @@ audit: valueFrom: secretKeyRef: name: "test" - key: "mysql-password" + key: "mariadb-password" - name: AUDIT_TOKEN valueFrom: secretKeyRef: diff --git a/charts/redcap/values.schema.json b/charts/redcap/values.schema.json index 24f821a..bc7dd0f 100644 --- a/charts/redcap/values.schema.json +++ b/charts/redcap/values.schema.json @@ -484,7 +484,8 @@ }, "type": "object" }, - "mysql": { + "mariadb": { + "type": "object", "properties": { "architecture": { "type": "string" @@ -557,7 +558,7 @@ "properties": { "port": { "properties": { - "mysql": { + "mariadb": { "type": "integer" } }, diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index 20f0a65..0f92e53 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -190,15 +190,15 @@ redcap: auth: # -- The hostname of REDCap's database instance. # @section -- REDCap settings - hostname: "redcap-mysql" + hostname: "redcap-mariadb" # -- The name of REDCAP's database. # @section -- REDCap settings databaseName: "redcap" # -- The username used to connect to REDCAP's database. # @section -- REDCap settings username: "redcap" - # -- The password used to connect to REDCAP's database. Automatically retrieved from the default mysql secret name if you enbaled - # the MySQL database embedded in this chart. If you specified a reference to an secret for your MySQL database password, you + # -- The password used to connect to REDCAP's database. Automatically retrieved from the default MariaDB secret name if you enbaled + # the MariaDB database embedded in this chart. If you specified a reference to an secret for your MariaDB database password, you # have to set it here also, in the `secretKeyRef` section. password: # -- The password used to connect to REDCAP's database, as a clear string. Don't use the option for a production-grade deployment, @@ -238,7 +238,7 @@ redcap: password: # -- The password used to connect to the mail server. # @section -- REDCap settings - value: "" + value: "Redcap*!" # -- Reference to an existing secret holding the password used to connect to the mail server. # If set, the value of that secret will override the `redcap.config.mail.auth.password.value` value. # @section -- REDCap settings @@ -261,71 +261,85 @@ redcap: affinity: {} -# REDCap MySQL Database settings -# @default -- Settings for a standalone MySQL deployment compatible with REDCap. -# See original documentation @ https://github.com/bitnami/charts/tree/main/bitnami/mysql -# @section -- REDCap MySQL Database settings -mysql: - # -- Override of the full name of the MySQL Database deployment. +# REDCap MariaDB Database settings +# @default -- Settings for a standalone MariaDB deployment compatible with REDCap. +# See original documentation @ https://github.com/bitnami/charts/tree/main/bitnami/MariaDB +# @section -- REDCap MariaDB Database settings +mariadb: + + image: + # # -- Image repository for MariaDB image. + # # @section -- REDCap MariaDB Database settings + # repository: bitnamilegacy/MariaDB + # # -- Image tag for MariaDB image. + # # @section -- REDCap MariaDB Database settings + # tag: 9.4.0-debian-12-r1 + ## @param image.registry MariaDB image registry + registry: docker.io + ## @param image.repository MariaDB image repository + repository: mariadb + ## @param image.tag MariaDB image tag (immutable tags are recommended) + tag: "12.1.2@sha256:e1bcd6f85781f4a875abefb11c4166c1d79e4237c23de597bf0df81fec225b40" + ## @param image.pullPolicy MariaDB image pull policy + imagePullPolicy: Always + + # -- Override of the full name of the MariaDB Database deployment. # Impacts the name of the services REDCap will use to connect to the Database. - # @section -- REDCap MySQL Database settings - fullnameOverride: "redcap-mysql" - # -- If set to `true`, enables the deployment of MySQL as REDCap's database. - # @section -- REDCap MySQL Database settings + # @section -- REDCap MariaDB Database settings + fullnameOverride: "redcap-mariadb" + # -- If set to `true`, enables the deployment of MariaDB as REDCap's database. + # @section -- REDCap MariaDB Database settings enabled: true - # -- Deployment type for the database, standalone or replicated. - # @section -- REDCap MySQL Database settings - architecture: "standalone" - # -- Name of a configmap holding an SQL script to initialize the database with. - # @section -- REDCap MySQL Database settings - initdbScriptsConfigMap: "" networkPolicy: # -- Enable creation of NetworkPolicy resources - # @section -- REDCap MySQL Database settings + # @section -- REDCap MariaDB Database settings enabled: true auth: + # -- Enbled authentification system in mariadb. + # @section -- REDCap MariaDB Database settings + enabled: true # -- Automatically create a database at the first run. - # @section -- REDCap MySQL Database settings + # @section -- REDCap MariaDB Database settings createDatabase: true - # -- Name of the database automatically created at the first run, if `mysql.auth.createDatabase` has been set to `true` - # @section -- REDCap MySQL Database settings + # -- Name of the database automatically created at the first run, if `MariaDB.auth.createDatabase` has been set to `true` + # @section -- REDCap MariaDB Database settings database: "redcap" - # -- Name of the database user automatically created at the first run, if `mysql.auth.createDatabase` has been set to `true` - # @section -- REDCap MySQL Database settings + # -- Name of the database user automatically created at the first run, if `MariaDB.auth.createDatabase` has been set to `true` + # @section -- REDCap MariaDB Database settings username: "redcap" - # -- Name of the database user automatically created at the first run, if `mysql.auth.createDatabase` has been set to `true` + # -- Name of the database user automatically created at the first run, if `MariaDB.auth.createDatabase` has been set to `true` # Not secure in production, use secret reference instead! - # @section -- REDCap MySQL Database settings + # @section -- REDCap MariaDB Database settings password: "Redcap*!" - - primary: - # -- Name of existing ConfigMap with MySQL Primary configuration. - # @section -- REDCap MySQL Database settings + config: + # -- Name of existing ConfigMap with MariaDB Primary configuration. + # @section -- REDCap MariaDB Database settings existingConfigmap: "redcap-database-config" - podLabels: - # -- Role to set for the networkPolicies. Not to be changed, unless you know exactly what you are doing! - # @section -- REDCap MySQL Database settings - app.kubernetes.io/role: redcap-mysql - - service: - port: - # -- Port exposed by the MySQL service. - # @section -- REDCap MySQL Database settings - mysql: 3306 - - persistence: - # -- StorageClass used for database persistence. - # @section -- REDCap MySQL Database settings - storageClass: "standard" - # -- AccessMode used for database persistence. - # @section -- REDCap MySQL Database settings - accessModes: - - "ReadWriteOnce" - # -- Size of the storage used for database persistence. - # @section -- REDCap MySQL Database settings - size: "10G" + + + podLabels: + # -- Role to set for the networkPolicies. Not to be changed, unless you know exactly what you are doing! + # @section -- REDCap MariaDB Database settings + app.kubernetes.io/role: redcap-mariadb + + service: + # -- Port exposed by the MariaDB service. + # @section -- REDCap MariaDB Database settings + port: 3306 + + persistence: + # -- StorageClass used for database persistence. + # @section -- REDCap MariaDB Database settings + storageClass: "standard" + # -- AccessMode used for database persistence. + # @section -- REDCap MariaDB Database settings + accessModes: + - "ReadWriteOnce" + # -- Size of the storage used for database persistence. + # @section -- REDCap MariaDB Database settings + size: "10G" # REDCap Backup Job's settings # @section -- REDCap Backup Job's settings @@ -357,15 +371,23 @@ backupJob: database: image: - # -- Image repository for the REDCap database backup container. - # @section -- REDCap Backup Job's settings - repository: "bitnami/mysql" - # -- Image tag for the REDCap database backup container. - # @section -- REDCap Backup Job's settings - tag: "9.3.0-debian-12-r1" - # -- Image pullPolicy for the REDCap database backup container. - # @section -- REDCap Backup Job's settings - pullPolicy: "Always" + # # -- Image repository for the REDCap database backup container. + # # @section -- REDCap Backup Job's settings + # repository: "bitnamilegacy/MariaDB" + # # -- Image tag for the REDCap database backup container. + # # @section -- REDCap Backup Job's settings + # tag: "9.3.0-debian-12-r1" + # # -- Image pullPolicy for the REDCap database backup container. + # # @section -- REDCap Backup Job's settings + # pullPolicy: "Always" + ## @param image.registry MariaDB image registry + registry: docker.io + ## @param image.repository MariaDB image repository + repository: mariadb + ## @param image.tag MariaDB image tag (immutable tags are recommended) + tag: "12.1.2@sha256:e1bcd6f85781f4a875abefb11c4166c1d79e4237c23de597bf0df81fec225b40" + ## @param image.pullPolicy MariaDB image pull policy + imagePullPolicy: Always uploader: image: @@ -440,15 +462,23 @@ restoreJob: database: image: - # -- Image repository for the REDCap database restore container. - # @section -- REDCap Restore Job's settings - repository: "bitnami/mysql" - # -- Image yag for the REDCap application restore container. - # @section -- REDCap Restore Job's settings - tag: "9.3.0-debian-12-r1" - # -- Image pullPolicy for the REDCap application restore container. - # @section -- REDCap Restore Job's settings - pullPolicy: "Always" + # # -- Image repository for the REDCap database restore container. + # # @section -- REDCap Restore Job's settings + # repository: "bitnamilegacy/MariaDB" + # # -- Image yag for the REDCap application restore container. + # # @section -- REDCap Restore Job's settings + # tag: "9.3.0-debian-12-r1" + # # -- Image pullPolicy for the REDCap application restore container. + # # @section -- REDCap Restore Job's settings + # pullPolicy: "Always" + ## @param image.registry MariaDB image registry + registry: docker.io + ## @param image.repository MariaDB image repository + repository: mariadb + ## @param image.tag MariaDB image tag (immutable tags are recommended) + tag: "12.1.2@sha256:e1bcd6f85781f4a875abefb11c4166c1d79e4237c23de597bf0df81fec225b40" + ## @param image.pullPolicy MariaDB image pull policy + imagePullPolicy: Always downloader: image: @@ -509,7 +539,7 @@ audit: app.kubernetes.io/role: "redcap-audit" initContainers: - # -- Init container in charge of downloading the JDBC driver needed to connect to the MySQL database. + # -- Init container in charge of downloading the JDBC driver needed to connect to the MariaDB database. # @default -- A simple container to download the jar JDBC driver on a volume shared with Logstash. # @section -- REDCap Audit Log Shipper settings - name: "init-driver-download" @@ -527,7 +557,7 @@ audit: - name: "JDBC_DRIVER_URL" # -- URL of the JDBC driver to download. # @section -- REDCap Audit Log Shipper settings - value: "https://downloads.mysql.com/archives/get/p/3/file/mysql-connector-j-8.4.0.tar.gz" + value: "https://downloads.MariaDB.com/archives/get/p/3/file/MariaDB-connector-j-8.4.0.tar.gz" # -- Command to be run to download and extract the JDBC driver. # @default -- Using `wget` do download the driver, and moving it to the shared persistent volume. @@ -536,11 +566,11 @@ audit: - "sh" - "-c" - "cd driver/ && \ - wget -O - ${JDBC_DRIVER_URL} | tar xzvf - mysql-connector-j-8.4.0/mysql-connector-j-8.4.0.jar && \ - mv mysql-connector-j-8.4.0/mysql-connector-j-8.4.0.jar . && \ - chown 1001:1001 mysql-connector-j-8.4.0.jar && \ - chmod 755 mysql-connector-j-8.4.0.jar && \ - rm -rf mysql-connector-j-8.4.0/" + wget -O - ${JDBC_DRIVER_URL} | tar xzvf - MariaDB-connector-j-8.4.0/MariaDB-connector-j-8.4.0.jar && \ + mv MariaDB-connector-j-8.4.0/MariaDB-connector-j-8.4.0.jar . && \ + chown 1001:1001 MariaDB-connector-j-8.4.0.jar && \ + chmod 755 MariaDB-connector-j-8.4.0.jar && \ + rm -rf MariaDB-connector-j-8.4.0/" securityContext: runAsUser: 1001 @@ -562,12 +592,12 @@ audit: enableMultiplePipelines: true # -- Name of an existing ConfigMap holding the pipeline(s)'s configuration. # @section -- REDCap Audit Log Shipper settings - existingConfiguration: "redcap-mysql-audit-logstash-pipeline" + existingConfiguration: "redcap-mariadb-audit-logstash-pipeline" extraEnvVars: - # -- Extra environment variables related to REDCap MySQL DB's password. + # -- Extra environment variables related to REDCap MariaDB DB's password. # @section -- REDCap Audit Log Shipper settings # @default -- Empty external secret reference to REDCap DB password - - name: "MYSQL_PASSWD" + - name: "MariaDB_PASSWD" valueFrom: secretKeyRef: name: "" diff --git a/examples/local/values.yaml b/examples/local/values.yaml index d52a8af..561db5e 100644 --- a/examples/local/values.yaml +++ b/examples/local/values.yaml @@ -34,7 +34,7 @@ redcap: memory: "4Gi" cpu: "2" -mysql: +mariadb: primary: resources: requests: diff --git a/examples/production/README.md b/examples/production/README.md index 216bcb9..0e4a77b 100644 --- a/examples/production/README.md +++ b/examples/production/README.md @@ -32,7 +32,7 @@ kubectl -n redcap create secret generic redcap-prod-database-salt --from-literal ``` - Database credentials : ```sh -kubectl -n redcap create secret generic redcap-prod-mysql-passwd --from-literal mysql-password='generated-mysql-password' +kubectl -n redcap create secret generic redcap-prod-mariadb-passwd --from-literal mariadb-password='generated-mariadb-password' ``` - Email server password: ```sh diff --git a/examples/production/values.yaml b/examples/production/values.yaml index 884607b..33f5eea 100644 --- a/examples/production/values.yaml +++ b/examples/production/values.yaml @@ -39,13 +39,13 @@ redcap: key: "salt" auth: - hostname: "redcap-prod-mysql" + hostname: "redcap-prod-mariadb" databaseName: "redcap" username: "redcap" password: secretKeyRef: - name: "redcap-prod-mysql-passwd" - key: "mysql-password" + name: "redcap-prod-mariadb-passwd" + key: "mariadb-password" mail: auth: @@ -68,15 +68,15 @@ redcap: cpu: "10" -mysql: +mariadb: enabled: true - fullnameOverride: "redcap-prod-mysql" + fullnameOverride: "redcap-prod-mariadb" architecture: "standalone" auth: createDatabase: true database: redcap username: redcap - existingSecret: "redcap-prod-mysql-passwd" + existingSecret: "redcap-prod-mariadb-passwd" primary: existingConfigmap: "redcap-prod-database-config" persistence: @@ -163,8 +163,8 @@ audit: - name: MYSQL_PASSWD valueFrom: secretKeyRef: - name: "redcap-prod-mysql-passwd" - key: "mysql-password" + name: "redcap-prod-mariadb-passwd" + key: "mariadb-password" - name: AUDIT_TOKEN valueFrom: secretKeyRef: From 213e4be3d0827133d73480e423937289cf9c92e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Mon, 8 Dec 2025 15:17:13 +0100 Subject: [PATCH 11/49] WIP MySQL to MariaDB --- .../redcap/templates/cronjobs/backup-cronjob.yaml | 14 ++++++++++++-- .../redcap/templates/cronjobs/restore-cronjob.yaml | 2 +- charts/redcap/templates/deployments/redcap.yaml | 4 ++++ charts/redcap/values.yaml | 8 ++++---- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/charts/redcap/templates/cronjobs/backup-cronjob.yaml b/charts/redcap/templates/cronjobs/backup-cronjob.yaml index fc409ea..2818ec3 100644 --- a/charts/redcap/templates/cronjobs/backup-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/backup-cronjob.yaml @@ -47,6 +47,11 @@ spec: securityContext: allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 999 + runAsGroup: 999 + runAsNonRoot: true + volumeMounts: - name: edocs @@ -75,7 +80,7 @@ spec: - "sh" - "-c" - "mkdir -v /backup-data/redcap-db && \ - mariadbdump \ + mariadb-dump \ --host={{ .Values.redcap.config.database.auth.hostname }} \ --user={{ .Values.redcap.config.database.auth.username }} \ --password=${DB_PASSWD} \ @@ -88,6 +93,11 @@ spec: securityContext: allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 999 + runAsGroup: 999 + runAsNonRoot: true + volumeMounts: - name: backup-data @@ -127,7 +137,7 @@ spec: - mountPath: /backup-data name: backup-data - name: rclone-conf - mountPath: /.rclone.conf + mountPath: /config/rclone/rclone.conf subPath: rclone.conf - name: upload-script mountPath: /tmp/backup-upload.sh diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 07f1a07..0c46229 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -66,7 +66,7 @@ spec: - mountPath: /backup-data name: backup-data - name: rclone-conf - mountPath: /.rclone.conf + mountPath: /config/rclone/rclone.conf subPath: rclone.conf - name: download-script mountPath: /tmp/backup-download.sh diff --git a/charts/redcap/templates/deployments/redcap.yaml b/charts/redcap/templates/deployments/redcap.yaml index e6ce278..78103ce 100644 --- a/charts/redcap/templates/deployments/redcap.yaml +++ b/charts/redcap/templates/deployments/redcap.yaml @@ -115,6 +115,10 @@ spec: securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true + runAsUser: 999 + runAsGroup: 999 + runAsNonRoot: true + - name: msmtp-config-injector image: "busybox:1" diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index 0f92e53..9c26b70 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -393,10 +393,10 @@ backupJob: image: # -- Image repository for the REDCap backup uploader container. # @section -- REDCap Backup Job's settings - repository: "bitnami/rclone" + repository: "rclone/rclone" # -- Image tag for the REDCap backup uploader container. # @section -- REDCap Backup Job's settings - tag: "1.69.3" + tag: "drime" # -- Image pullPolicy for the REDCap backup uploader container. # @section -- REDCap Backup Job's settings pullPolicy: "Always" @@ -484,10 +484,10 @@ restoreJob: image: # -- Image repository for the REDCap downloader container. # @section -- REDCap Restore Job's settings - repository: "bitnami/rclone" + repository: "rclone/rclone" # -- Image tag for the REDCap downloader container. # @section -- REDCap Restore Job's settings - tag: "1.69.3" + tag: "drime" # -- Image pullPolicy for the REDCap downloader container. # @section -- REDCap Restore Job's settings pullPolicy: "Always" From dd110044b6735df76360cf94a0ee8691393acf70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Mon, 8 Dec 2025 16:10:31 +0100 Subject: [PATCH 12/49] Quoting chart dependency --- .github/workflows/chart-ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/chart-ci.yaml b/.github/workflows/chart-ci.yaml index b1bfc11..1ddfd04 100644 --- a/.github/workflows/chart-ci.yaml +++ b/.github/workflows/chart-ci.yaml @@ -9,7 +9,7 @@ on: jobs: aphp-chart-ci-workflow: - uses: aphp/ci-workflows/.github/workflows/chart-ci.yml@dev + uses: "aphp/ci-workflows/.github/workflows/chart-ci.yml@dev" with: kubernetes-version: "1.24.2" chart-dir: "charts/redcap" From 5c4445c5aa0ec25b3dfc0bbb92f7551a4e020e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Mon, 8 Dec 2025 16:16:31 +0100 Subject: [PATCH 13/49] Updated dependencies --- charts/redcap/Chart.lock | 4 ++-- charts/redcap/charts/mariadb-0.8.0.tgz | Bin 32515 -> 32516 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/redcap/Chart.lock b/charts/redcap/Chart.lock index 82cea67..3060aea 100644 --- a/charts/redcap/Chart.lock +++ b/charts/redcap/Chart.lock @@ -5,5 +5,5 @@ dependencies: - name: logstash repository: https://charts.bitnami.com/bitnami version: 7.0.4 -digest: sha256:dc9763292e407c0ac831ca4999083e516bb9778644fadd05e43075ed05c166cc -generated: "2025-12-03T15:34:36.056346225+01:00" +digest: sha256:f08d201367526ff2189bcba7f2fa3ec712a842dabbd716490414560faeb7b935 +generated: "2025-12-08T16:16:04.913596174+01:00" diff --git a/charts/redcap/charts/mariadb-0.8.0.tgz b/charts/redcap/charts/mariadb-0.8.0.tgz index 81e20f54cad5e549dafe27e6959aecdff469e9ce..942aa3c4a7081ac45b250c56e4cb00710558d03c 100644 GIT binary patch delta 31273 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 delta 31289 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𝔗SxatDLJ}az-a+FWS+!`G5lxPP~xF^&%C#EE`WQC0UA+FJ}fWnr&B` z!`4}I{0k*p)OG(S(JG$Y59KGm`MhhAFJNu<{JZJ9jLRbWf*|J(2EbPMPI`rW<#ujl{1 z#Pi#4+s_-P4+)M#IKt}Z?t@z}+l}YjzyIF&?Y9;R$(Y8(Tze3XAmLvVwaix<2T>Xl zW%hWNed;o8SBk_T`u+Dt1MnW}tbf>MFf$io{gUE{jwuNdP7fbtUU z?ErNGjYxn~L6BfGg1m$L(2g-BQK)ZYf}E1XBs!!5ZH(s7#*_1*DhnCr5)y2-8)svC zj#mS*H#}>0n7o8pdI88SfCa)pyrH(1Wi|+Z8QZdQi&^KnQY4W< zx~Mgx%}E>*o~!0JQ2m57gt>NZ>XTpOK}p^w^4g|RZa;6lCenZ88+Dfh=JHeLFMwJg zE2{c=euR!4HB}dHE$l;?MCN3@Zn$f$PQJMiaAlh#K}s0Q%B79+{a+G=A8D{TLlQ2&X$z}^v|(+3T9`+NIMk44{5|A%W% zermFR|C7-eHMg2R-pVPgu6qFsBXC~run0}5`dCA{Z}tczdm2&Df@r4 z5i`TdlU)YC#Q)Rnb^1mB&+h)$``^FFWAqh{L$rUvc+rxrx*WDJ{~2%kCfbOZTxtn} z{Z>eLUd(l#r8&15&izGYjj4>Xta4DkVmg3Q+F76z99Ej(nb+YXifJ5@SfX8BSCxmU zJ8Na}%5*4K%I&BsO7;_;MRj0}(zVU5UXWDv20)n2+d(`YppORIDis%zQ6ivlPc9Vc zbc}z=?&JPX%g=2hgKfA#bvrAS$CCZ|uO0;dAAZXE9}fpr>?$wV|NVEbmT|RQD;B?~>XQopSGyX7@dUk?DBcaWx0gb5{-6TDn1y5+L7BU& zs8=UGzv0sg@@CvgZ+vBR07nGd{!e#pSyn;jQtYT$@PrYZ6arOkRKJ zYqz0of)x-M-)^ za?@S|QfJJ%P8f@>1^t!O!z$b?o@bkp+=OsoP#h2>(^%hPZ@WiC_>Nplof@G|RQ>b` z1zFSiNv>lSUwmIz-A`hYuRg;M*Y|(onzQ>_+%6SIWz8DyWL*V&c(b=8Zv z_ve79>eudK{cCfvejTXFEBbTrLP(c#-8<;@`~B;C#&0oaX&lx;^zPx$!BJx9Zq2W& zoV#Z~FET?3*ILFn5mP47700m{6OJ~9!>i5w*fa7Y&>P|%yECpxnfmzm(e%2 zMh-pPh#WZB_UbCQFviw}qTY7!i*GgniGzqfq6sGnYBBWfhfeG8=jY#i>l1UC13p0C z_YeTVsWL`T}?t(!;3=mYvs z)Cy7a8(Y$RM?e3MVsd}%0>m|uCwa6M*Ou!TjAC++Xe=a-Oh$4C;{5c->*F`?hgYYU zFU(Cs2sVZnBhhW!LV;>KTvcpjMkoue8oa#{386793(|yRsM`*)%-JXK7K*;UJQ`jd zU7cRPI(u{a!eftLSK}TYy*jFH3c4%Yss$NU>KlovxKRDrr4jJt2gsMbWonyF&CjRWG~S-S8}UXI?)I#Qdz#uD{*m58`&C>OBcThvolT-&Jur4)#8yQ_MS8+pe3+N=y$25 z6Q$XdDCQ?dHxmLu&gzt~O%N3E8cE8u5t3do?A z0cPJsL`VWRz*dkDqE-vmhOL;~x9k{de)G4CWGJra*oKHIFfKxf>CW39^^odjiN7-% zE1tOv;1_=|E>Cohz-KE{=&EIU&R9}5E%~R}Q5K4^q81oUu4KYlK!nJfON;0HM@(!v z8)4zozm*E9~dP|W01H9;~@6c|5ZBwx7XYKdjH=SdAxu4uNoh~B9~|`=BqaFzdqnIx4lVM|bX z7ZWT%=Y*#U<<~jm3qK3=KLm?E#RRZS|L=8niu!-IxARs1e~G8&nAb7~ut{99p5~qs z97cco`tQ%LyOCN`w(~iwkNL|5Kg*SgQYby1RSD^B=v=*Z99L@)Xp+?R=~Mb4Op#A9eIq+y!cs z!THrHrPM0SEhhgkjVJBf15nd$wmH*ORnImVY5%HYAeL$P>1K-6XQMTypNch~ZGwNh zF9K}{GP@)En9UN*32OfJMYr8OXmy&XeT)-4q7jvpi1zpCh?qWXzoydsxv7yGu*Vi^ zZi*`7TzU@0R*{iuz4SXVAIDxQtEL0EVq)N2V_q%zlFgK=u%b1;9?EKY(K!fZStE1< zv)`3LL%AP3jmXkA|F;7q~)7Oh)ecZz!@2Urh=4QN9bpSgIf}ZgWO9;con6GD^ps;h3v`UBDQ)Bm4CoM zDZNE*qgvIss+TiLf9>vkUH^ZX2XZ1@{BVq{03a$*%BkYfTYWN%9G#tD@Gs1tpS>C%*A!kD_vHYBc_|2ci@bvC?sIz!-yvT}YwojE& zmN%$ul4*^ClV4Ke8GYs~N6r%UkqY`NDLcVE8#GtgyP_ahc!T_cnyu#2O2+W^5-w=^&CK(YERQq@_wu&1YfOzKjKrK|DSN<*F1mA=Kr12`R{(` z>-_&^9zXwwznNQ+kZ`l`ap@Mp+IzeI?wh*b6cXbNUZ9PLvD-93&AV210V>&;60z{{QkU{gVO>?e$axB1g# zIbOaOgnzDn%E4Z%pHdIPqx-2`Ip0q?^6L62`NTf@YKK%jRrCLoZTy>O+5F$zDeeDs z_rK2nU*vi6-Tgnvn%YY7zj{5L-}0~6pqI|CU7b3z?Lq@|DKCFgpaNQ41UU z%(cNdEQ%|e59bWvN~6sMh2Ah6zQhrZ1Hzk|rM#GJdoNN(y?s;J&~ot#Pxg`=XkViu zaz%3te2O56f3-_&Eo|Wi0)tLO*5 z9sd~PZO=q!8Kq(Xds3mED2L+_oq13U#>#J8*^8iyr7C~=uLLO<-BJa*VjHwVTvkI_ zKxjn=WidJ49Qo+E6bM^z(P-78$W3|+>e)#NI8*jUm#>A&E^R4^NL3`Ae+PHI(YeI4 z<|3)`wcU%jy>vN;AXUn-zVeN5uRB}$C67*v)KaCrSSV-O?kl#;~7c)AwKAHmMvw}QfpkA*O@_42rQ^dx9o&XVnX zS8(QK8m}yHpHD^ZKPK-&Q*3+0ZTmSdwkOTU0u81!7NWh~-N#ha!8UKza1%w2!;rjy z=u8E%fKJP&oFy#{qfog*dkbwo`uk3&_atNOsu9M#3mvf^Q5c&Utq5f)^XeKj0K?EZ9? z$a!whFPGH(G`{-*bFmW3NPIV_4STNH2Co_cHfhb}yLVUD7e~Y4kMAx|3Znp0rN82A zR*ruIc6(@-WLy~~yudQZu5)Ww1s)@GOY)+<($;K=Bh_8DgdHbGS4S_8hNo4WDAVMi zRs`eMN?J96PI{IQ_Zj#nYk->F<{I=ZQV?a5OkOIJnW%;i$W4Fs2r$>mC|W9r{#|q{ilISs{_f z!mY|Rq6pvggl?C6ZI{1q6;h5)PA*S}!zZUkNGwxW!JS>K(B)N$f0vLy9A2%aHOi?M z9@Ak8&6iXm<;y`=R3xk9h*)Jz*6^V+{oAU%A2S}1As&+}=2C>MF}dWN1343;qHuqO zFQ91Bt#-mjKi+O`kyH5uWcqOyv)<#|+3D;RN>uIgW%wVh70WxHHKceur^`ucRqtpn z0)DVAaIqA4wtu=B6YH#D%h`zDk(dZ^!P$sZGdNcy-~Hqv^B-jtS1jFiTT6C7sI>=-qimlEsW+E-_l+gP#x2f1ZX+SV3LGJ`3FOKw|lA^E2WzY^mk} zq;H!N9LXu9fJI|WBN7g>yI>{4O6qFrD;{<$=iW*=sy?j$T zh!hUUTunIbySb+63;wU8MGELSLM!)vIfhgvf@kxT1gS4&~ z=74;H5a!@~k_hG?tuKI?M4J+T$WCH1q;fq##g1R!qHF@nh8K%PlGVQ9_|W_D`l;2X>4l=Kv1*g z)3%#xmyF3*G$LXyB$?HuDYG}eLAo#s?_iBO%yU@=2=)fG8v3a?J8 zR=^cosg>Fpt|U33e1Lw-$Ij3(@(m{c0C|O?tC?VGp%<9@bmOUdEIpErFE&%v&QgH| zlAp)x9lNeVg;#eu!E!k_bXI>(Eav#)TNaW5>g@OX zk6`@rDQ>mtZCUeH$5%u1qoc1*Yls#@(I6b1VEK293 zOB6$fQI*k96VzP}0yY81sPWrxe*5i$xwCu-)Mm&j9r!RkT@@Hyza6-E6#DVO6}gnM zT93-8q@Vg^mzBJzbWId9Eg7mGoo^|_x^mW~T$M-WUdn%wS=f?*?e_Nfzvln`A`j-0 zj&UHT>8Qm?!r;hXLn=MK{dLIy`#*O4AAfgr{`&OIyVvbm_|!NSkN@6IXSY)v|GWLK zxd(Z`r@9YQrBwU;0y82qpKIrXr_7Bz`c&7S#dbZOW?~m4QwW;onc{kH_ zTD^m{#{Bp&*cp%47JXBFEpCLPUU<-1f7E~J>W&-z_O8c`^)z6o-^Jm<&f0UZuD%vG zy13uj>FlpWnbiU0+;v^)+Y5?zq!kdtx@#*FrrGcK3gS z{@NT97M^>>5aad%zRruuqfhI=IJtu5iE z`g+#z?qNuJYxlLOzMdI$aM0V^S>FuO)jd_y%~Vad531&6IvLZ4ZB9bCog_y7DSDJ} zGNun`z%$FbyUqcjBPwhL)SN#eTaoPS!kT!rkN0-gx6MuUwYU)+j>o$sSQoXa zzMg5mH|~bLwZ+d=cO9`?(GmXYP_G64Jr!-!cc~f?} zeVD)YyPfWMZAO{uz$m3QVKaXR_`(trizyvTwDGLh+f%rLgHCXGu(mvy>VWGzCe<{o z-4(+6D|);8(5AyqXMC{sxHr|k9`IIY9ldftD)^{tLO)g0VTuUCQU74H_N-;9dn9>F zq|RQpVB82vA~v10>NxT?WmXsl-Cn!X?x7R-fI>PULL$jfX9st7@ScC7xC2Zi{Vq8? zTw9Dyb&uk1iQ-fcB$G&?=R~GFM&&5gjc2_s&=c$jz47k)Go7yP(PO8Z&S9%}2=vVG zEpa1+r!iu2PK>+zAjYH@?BMa*y4_TFl=RyB87194e<0_S&Blk(=x{IWudT{Wbr?S{ z(^;bR1iCYqjc$A(_@IB^>8#X z>x2Hm!Op?jcD<<%yikfNxeHo4Bn)kQzu=KlHn!AndL0 zqSw_;S3-!Fm#P<92^v_U<2ab`JK|9x#8Vy4Q*Q6+4mig99>N zyAw@y*NFudWY<`3d>HL@I(xmf9fGF1*TmhdiJij*P24~1?{~&)?}3`?(8RM@5|NoQ zq-jhg(qY_aY{5+|`Bz8fEQ_7B6+`bLPU?s0EtRqpk>`?$BZ zrC_RO8uhJGY$ty&3!2r8%N?}wq1zdCNBe6_q^Vx7!o%Ld-VR>h7pANGTXU;xZQRG> zes>=X|6Xt0S%05QSNHm}=k=#H!1SCFmKZSJAMNcPu8rDM2L@P6AZGW76OoWWnYO7~ zZ^3DYEJcgU!U(U(gG7QzWyc6KBeMVpQxbxSI3r4tkZ^ws$te|xC2&;d9t)lN;ttaY zk0PZ|_V+sk@2&05H`P5Bc0CsEE;2HLup6##q?_t)K>+7rP()+J4!D3`O|Bzy*js<+ z##9F!ujm7sk|-fuw3RKn@uAo0k|0=H6`Sh*5GZiy5RZF@owY4vQ@x;a?fD3o2uv-P z`UiOZY14mH_e8+6csqKN3G}b?AlPA~7jQAT*PAQvM*q~JPcU4htPB|3-yg3noThpv zBN-NiImdI*CYfJj8ZFHRZw=4xzh*WQK?(PKpWNll~R0n^=YRzggEM$RL!t(mq@_O%J-0iHt zonoqcyzYCv*2|kSLxseX31~)0zW+4@^xyok4yiY1$EWAR)6arqN&M$tw-o=~-P`+m z|IZhB(6Z+!QKk}lLjw}mWJNQNIpBqQ?amhZJC0M#=cw1|6m#TdkJ4s??d|*f`!)tN zZN`5m+mS{kwi~MA)#>HiAv!ugLC5dTPtLB+-klH8t9O^^{qS@PU7lWCzB_q;tX^+H zsgtwe)#cgC_v#G*=(f=bfdhAH8f`ZWHBHl^CK6MnYi9(RK@S zq=IZAP7=<-G*GX%?0LR8L?IQD(@_e>BNl(kcAzl{(P)l_B+x**NKQFRCsTBY*jSsJ zAq!GvY!vBYyhK>Qk~yc7sYL8v8Muri5=&*_;#5u01X3b2YGsLY7HuKSiTx1)(OZA2 zHR^2|hlCq%g@I%W>d+E^qY<{zE5?D2B;^ScL}Xlb9d7%mX`nQrDFSWKOnaDby3j`2iWifoKT8cYpgTj+jDp!p-c`rsH~`<%I_ zN}3o)8j%8~x6IZ2~&RiDA42lu99S9I8GLQ_P955a}iw zk(i8Wpr-U3bdS!g%YR~N6Rv1ffAQv~-|ILAp4`zeRj@en<--6V4}=F)C_)m#XH;mD z735400_c{Ks14y1VN(sSSy9pwPR4|D66&vdm-kkon6Z$KX`s(l+78yo@zsClQ7U2S z7SS11*d;@Pjpe-(FO$eVU?JIZV-En?LzYlr%Z`69dBd1S#8V&IHZGHn;Z6F`3AaE%eiI-Y?e?ppqMt?bu(=| zX_#-Yue|~myLE~d8&SeeFIepsGf4yD)SJo7pe$=pD^lv!zGRMC17ZWmh&*7m z;!_n9&hDtGs7f9s35i4cfJP)@_nR3PP6(%WSkgO!6hlO_C;kTB$155Y_ z3)Ois48>64P}0xYOzSFz3c5>;h5IQDrk*k&A(f1);m*k&g|6K4&mV6g65$c!_7~%} zoBh#bfT>xI2og)+K1TOb7QvuEjME8?aa7UgWqoY*)HpZ%w@{INhI>kyZB~tYcn^%> zWQM65pCrK?Bt`KBnlXPPoJ8QyxCO?IXbf@^;~Cksolav(_!tK;No;v@q+@D{D8(JZ z##yf)D^+gh_{ttHjsZ7hJ$#OV)<0(EQb&gZmg^Ic;m}wj?p(j-4b)=1miR4iP)Mcq zS&XB|s%?>uW>gyGVeJkR!VyF%kY|PhAObyJGAnE^!*sWBw(x%q6{VE{y^{A4nc`@S z*tp(!S#7pQP1mNT%ORlVd#9G!7{SSC&SDyDsa_c22;}IVt9mgQA8Bm3kJKpenNBiB zDLzS&4Hn?P*jhLhIo;*sV6jINnqeBL$`KV(Z241`Glle4w(wOrcqh~p62Kg3O6cxa zGoQ9roUP?EeanASBRMJXxUKjWQW2yAW_iFk1AS@C$R9!DWm6M*uuRCe)yiYQVv*1w zWvPhfXomT%QhhwLj;zT=1f9g7`)Le)1dOeeM5U~n=S(7u{IS|@mWOb`zIM&FBXFt7 z<1nqq-Qgv5xGfPf|+&2xCNK`6*CDT!sI&<1~uCrnS*%HZ{epH@V@HhQhh zDuwpgHQ!oRXqf8B)yQh)V#XV0zE&nUm?DosNU4y~Tw8Hq7yQIhgq4Mt5Sil0ir+os zQFu?4tr4@h1wAk59sC4O)I=?u*c?Z4-Wqd4wh-l<+_69@^3rT>)_*z#L9e#RmNEwu zCC4RAm#KgABppRGh~`RAlL*hZvNs9gda4!h#uygZ*&q)ANu(NJu;Xe>Br1^53!+Vw=(c*jH^aAN3r+DI0V~fE1nX!v9xFSK zAwi;O%lx0t62_(O7^eq}p=_)|P&2k=iUqolELMM~88Kk95sjTy57mklY=iU) z*UYw(86z)GoI!D~y28$NZFDwP{qNR7LQ<(@+I5Pg6HNl1VD%Z4oLRVUWD}ONtvM5- z1q^>v&45$BgzMilMi@o-UZhm2rbc9t1T>*UDJ|dh zb*n@5lp2a*ekiUa{s*Q}i*w}R)Q+3Xlve8~wSL!59j-)(vl)$*oaoh~pBqo9I46J7 z3Z{;?33bC2oIK{h!_0}qG~Tjyv$uqY)j>QjHO@oq5M~0grFY%z?6_s5drPUskSM!p z%QGfGL}fPIOxv^zqJo~HO3hntT6D>@NGWj^`pW}lm!25H0$`1q z2_30qtBp4B*>98@Xa?O7Xu{SieD%OobGVYPAZ%Eoh+v_XQ@)qpRLMqb5~)S-z>!GJjm>9Z-mlGd-iG%t3NDQc zBLxhIJ2*-Lz7)#CmTKhO^-aw9Of8s|VL>o&qpPW2g(>}2X0zAdU_9uhv~%*|$XmQB z3nfpE8C#&S<~iTIn>KJ5s=v8f@AwkwL9wJ84y`g0wlwzz4RfLc>nR*7q$Cd0nKfH; z5@QvMUjNzdEb261uytbKsCs`efwu~ch_(ZGT9iM{n7Vz7N)~0S3NTy2S+5O%g5%5U z3I)Wp!zY<>6jEii=B(Tb3qEu0Rcsk)Fy3Af8&^=Xl?@v>PZG~-mLk4)&J87ir%-#| zyo`X-ZdGm;c2;-5X4;fia+Gt+xRpv_C6McoJ}h?3PJmvkW>%nRqxXMtM1+7&BM(VL z1FDw40MXkZasG{Y(Ten(S)LoK)^(Lx`U+#wk)ut$k?(ze%+k!5SwN;IFdBq5T|>M3 zsOz6IsVceM8<<~4OfSmRu${p2PE8{~nn)AE1qq4X2vWnq>k@-VTNm0vDoM5^nsA~8 ze{MzytjNd%2|N`Kir0TJgpdS9uy_Aq+^du?=O4G^K!qGv~kjOgGwFuA=QA;oyJ zp{C6jyN!WoM0ggB*s=+Rkon0tGBT_STcNcSZ)IL5vrOgWmz0{_BQ>E52DwUgmqM%{ z=5wHi#wa8r;B;iV!Yw-JgqHoYb~M?3GqXX(6ree^-$o}?z|wz-a8>F@%oSheZV)(9 zM{~V^g_XBjVr6OodJz^cnHOv;>o7C+MMmm|qLtuaT3n*~rKuG8&fP=|cKn)0Lv%K5 zqL)X*v!P|~k7rlky?cL!emuIoJUYKRI~}5Tm;Sc=yI1Jw{3rDN+4;#9B2@1HKO|f= z(zS$wUI{%nX*Pd?z)y;;o|>b3%_>+B@v@3#V{~$G*addfgcKrU$(IvWge|hn4c&cYx zy;~TOXbypV69@+ zH5H)Q1q-NKCTpc`_F2Ij>uLlrTQ`TrGAdOENBfmqAP>5uK1YAe&omw|gt+%5|QfrSiU^4F!Qh648-PgQJL> za3+M?x3GUGCBlIeusdEoKD74CO&^S-k?pdG0%GG4fUdbgakBm zve7u8p)zdsR)R8Mv`?4f$O5$*I+$X`BEk{ode2(AadQ zr&oQC!N$TpaZ8nIcEq&6P8bXCY2^D3Z;_BJN$`J!Y=KRXD#Fd3M>+~38mDn)+`uGQ z5eWhp9r7T@4~>|J%`K2aWuO-waR!ESrsMFA!Y1k1gl`Bz4HIl|g8{Ecz+oF51!_)E zT(Fu~VLr+xYHv{dI8~;5ez+Dl3m0y;St~S{GN!$t;OWe5wu8?VVKgS7PqrYJb0Q&` z3N(Kr(QZ(q{pKKdWENBD#-rQ4jV$emjUwZP0=s2fsU2nc>a7-?VcV{+sK{;ikT&{` z-K&+5UP?NK0Y5#!S^FTOC62t^5NC6nZ4q$dn%7E^W@;4Z1xqK}MaeXJ<|*>T!1#pK znu(6JepUlsk9XkB*zqPLV-knD23*KhcAbA?J_Ai;jcdonY&fT!XS-#_bBu)`Tn!)N zMBOU;jYo51Y-A0ZD-L8lb;kU?Cyk!j=xEUbe0qMO=GCe&IQV{aadCQna`wLi)rH_K zNRnu7!WaC|J@pMpxp#X>2%)PLD{PrCio7?$n$?U(gzIxxdNsF|t>obnZh=S~L`;8Z zr9a|0xFu4c=7*n~*&-#vft~H8_wB%SLdF| zoE(@3Q+j7LWwx34VLqSFe?}jGZZ7+hZ9_tGBv>H_vt~>K6ybQ1;t4?$c1L(zjO;Vs zlFVKg<#x5d9v=APKQ{jV^7QEB?dfMo{=78)f3Mds=YQ_*?0${^{}Rt%5`-f`Eyis2KJVt*ZXGx33)@lKJ zLFv%9^Wi_<7|kU?5DVyFdz+JqnyBZkZaX`J?MtGSdIc{>j_y)@Mp=KKG<}#sDEql&z_<8F|F&5)PC9yNknv*RgU?d z)D#JDbv>pS&Z+^%$&B48p*7v@jUY96SgZxH;7H2^L!0CgRPf|O3z)q~68$$CLI7gQ ziLz*&MQw=iMmc{KDB$x%vI)n@lm>cpf=*(K`k1L-%1|V+Q1Eanr)um4R@@V=9dZ)S z62fUbX*U|rpI<=G8v35h2hX1aj~XrYygYqHhDN z*FXNFG5fz?fBN;{m%ktKy?;z!?VLY+f51LA~=tNx!goTP+18tB6(}UW31wknO)Zx%XB0 zD}5AO7`a$Y@o$+BFXxdLWjg@qTG|)AsOh{0K8>BsHZ=oC0%2wxp#{1E|*#tE2cu3Ux=fsUw z1^{sYb5*O`^kSuGv%ShTLVi zpbPZq9^trGY zJt!dL-tOw@!s@kZ_KZlv-M(W!sSF4^#C6(~5oQk7jCdWf5suJ>gVJbx%zmNb^AVkR zexg+#RYT+b*!YNAbq`wbZCMR~d^3TTwCM~_$fePnH<|*|NRxr)OqFn|wVLLeW>eQK zLcU0UqsZJ3dsBk!V490%^>(lcRDnblAJNT+pABT-|1q2YMZLdDC7i+r~4J*YlJ^?4Drik|at+jKO(aS6yE1Eo%9 zp(jIkJW=?v@Z0Z2h)3DkH6;b!&lSM>5J3ii?10sRxl|M$KL&H+@PtpbWIcW;uUlz3 zP}OBHZrj{b2_GHH=~7+baq!03U^h?6K}VqVAKX+BXumBc(5+jZ?C}Vccyg2B$`dH@ z1Z~jSEY)+B#1n0NxjhIHZo=T~_S)Tc?{8v?d;Pru>5hVMZ+y_-Kj@Bk@xgu{kH~m` z)a?el-Mzh_8}1*H-QLcA(Ax<~|8Rda?u6rm?wAC z0v{K0@N9g}tpgTL%}+2!>uc)%Q)^9o zVRJRtv;M?+{@H7ub?l=4yHN9{DS1kNnkB#)YR;IvFqyQ<#T;r?EX%mH3d8MeRFB%4 zkk!R9V@|tgoWc1Ns8d0>nmJcPtx6*|(S9Q8q>kD3s8`|pDyVJFU~R?S6ak!@jYV6` z+Hxk01stiCI!;0zMk7{3t^cRY`qNn=A^CGAbsy1@`l7u(Om90vOrAw2nU0Qsj9JDD zLF8(vbt}FnbCDDF@5%heZ}lyitM%}L#^=XCHs`d|hgR0Fm8eyd)<>Ne0}pjUnhIuB zZf*4#eY>uvU2)0t2^zI%i|Z9(TMw69dzD-ryY!QO$`DVGYg$n-r2$1L+qiTC?|>J^;V3yH*#MT9&g5zbC7nu^|H7{UexgoX)1&Vh5&FSS)dlvq@QGB!6ZZ!UiKK$p8N0;Yk=dXW8sPWhA?9_}-z`p>_X^bE|S|6qK z#;4s$z?{HprHxMXxe4P;FyHkqdM4=^ET`XX)TwtkhO>llLkFDxmn2bt%lMV7hEFgX zszrNIp_QzOCo=h0f@0S3!2N}G#z%CT>nSUVGZrqNb3G_GV;t4Y={}b%Nwu@Ec3-I3Vt~*xk8#jSvV3G62ab@iDa_07f4ce*o^3QuU|)>sriaZNYBJB)uha$|_A+_>lSSk%)03rcAn{>;i4T zygI_cZJKPM*K2x{Qv=Op*vf{_Z)I zL=ewcR3xeUcv(6oT+;FUoW&R4=SaHLVO}WV6i$aIb4ec`fkCm7R)6$})3SsgeiWDN zUfdLby~Pi7md;Rr?6}3*y|9611Z>k4Na{SEOF+_){z~dd67*NFM;swEMx(hTHGNei zsoUA#+28FR^mc2ta*?DHGD;`q(oR)s9T2Kgkdok0&wAp0NhF^irIP7XyV;1##9Pvt zK6uVmS=jQ?g;ybI4e?ggoW%i$sFY)!G3dtQk|F?6TfpUi6k3@}Yl!y=PZJz{hlAUj zJTOC&{tmnLSlW30DGqK|Bx#L~d&9uKj%XnBdg%>=lm_|>?A3D)ClwwcPmd;v#xV;= z?QxWf=^HjVl2`oU*hthzbQZ_#l#a)QUoaMVy1?JS-ro&H?igofg*qCWV1|qo~dKTb`7pf{Q}CCN!5cC3d!T{rH&YBf1en zw(6u~DM^X%F{vc!5kAQrNekU@1=~AdcZAQYR!=#9?X3giZ1Kl&>9NZJLz1!WebdsB zWbOWJr2>(Wt5LTiN#MG$fds4gm)2Q}=U3jfOYC(P)%iM_$0ll_E$0cT*!8i&5bE<% z9v<7Uhnqa?gmJk5He8ms4ED}WXV1C)JlJXtcwymxMCWQP>TcgFVyc1d>5&}lAZw4_ zp$3tEw~}^tffzUO9Xfcl7(ucKHZJTeXJ@aBFWf6o*_Lc~8D+xhqJdTvP$zM#OKG)d zXt68kal%?%TC*?78d%U!P7_#0g;-+bl{Y7$FMc?#9q}a;CRph>!UDQURkmSE@G{pm zfYC&V)lE<(6gUWo5N}yX1n4t`;t1Y>uVvwXLgpj7`Ov&1IQ&s9f8NCbY5sgu(Tdyx zD&GpV+$2KQw&NqZIe1M=Rz;~5zBsQW&vHt#zVIZuzAqp>DdTp=_E4A`()jH*Oo zG`fkhJvNs#J$kFQqGLYQ3A_55PuQ{uA4QabdI=M<%_^l{^ zv)cfvgK%?rczEOOPUx$(ij?p)J`(S%EU!Eb4nP$p4#+3aaL(dO#$?f9@i-a`kUR}W zVJ)Tsb{#J`y`vGCkW&%h$n6i+(U92Uh`91KePLFVOZZTE>Fv!U`A~gxu1^Du-b{YGze1d}gEHP}4#+|b#O&7Fv6mwSCBkJ> z!Oo(@8isdH-NsZu4Zm~Bqd<4wekj+ij=Y4^!UgJ|`YDX20^N%?^z87pN7$=>sMS#q zkUBSJa6P0>&!L0xsX$8UZy~IKP~oK*)aERlWU`^LH}2}$c5z$3$ZxfRSAPw2@2}V` zfvMt0BOUg5fF^cI(C`RJRS3~o(2%%T{io!2UcsL}NRA&9-0>N-$|7a)8MHxhki$iY zr}5nnm={-z-tkIw2b*;!!|Y0byD}crUAVf%=S9CC!J!05jN)O=JMm0X$9t-?*nz~r zp&K(!vrAEH@aZ020bgK4PF6=*h3^M_tYtYqd;aAU+h?xJti|V@9JE2?l9|BrEH`HE z5NT!qsX=2$jltPyKmuVLyUce5lHBc@7F{J-nU&yDWSKKx5RFTT*vjI6fy5RfGH7pB zlWvX;QGvWuHhQH6i%VT`Zw=C%F2u)T{Osj6NM>4lBb+ zMmQ~L6s5jX(;g?*hs5BT4oadBu9DCvJME3$CY1%uLl7=BBIuWtNfNf7KZn~v%vC;H zex5=9(62}^q^40Tc73>i0^STz^S9qn`_i!I+`dP@|K7X-vQIVOfjR$%aE|$NbFkDk z%N){#qe*^e4;l!y5KgGcj54rCuxUJL-yXnW_`5C~z`vz&ILKpx_cJ1Kh$S9)sS^hX zRvxX;CB|E+X;4-qB(Shxk*OE@1N7VP?yW+8HBX2bxO}WFbUIOgong~1!VmwmWP^sU z|ozAc`qUNZ9w#qXMMsA?l?$kBwI9gq+tQ414)QB{;5-< z&j@UWOQr{G<(S@VyJLfqoTB3?32xVM2d(Q;U3Dq4u0vH%M-jb)^pF>vjf!s6j3(nw z%@sy0u3U5$yc2l@=5FB=65;uf1S}4%s8>$b=icnvFbSl6cPGoifI@yGpN01Os z!8c_<+ZJ5F`z4TF>6>mX0!e3trLutGBf8S>SHh6RQB)u>xeTwSoQNrlLhIvvWpW%! z`(Xi!ET*jjfk?rnTtYC^?^i|Ow}2BI(j{W#q$ppwMvMwlR6tNEMvJ7VfK#`iU*CdC zF{+fJGURH1DJmeS6r*Y>s>86j4=Tl|PKv5g6r`wtpi+$Lq^K5w-vT%?pC*e`Q6@!x z;W|}Ray0k|s#VcKDazrj(nUE0)vBmkipr3yr6`A>S{2nuQ5}XweNe56YNePRLq2IZxt$J^0)+`ic{M!orLvnkA(%mIZax z@DO}aOL$Qjb5(d}G(NI7tm-lMmd0L4X~IIYpo4Xlkj9eCu4TnzX_EVqI~v%7CB7h6 z;>8c|W1L}z*wIS7flkYj#tTu}_T~??oW-#E_-s)js|nlFJWm>PvYNO)6+Ad2th*vF z=uXOi%~uEw;-Ph?u5?f;&+`?6D<8>oM>%9{JvW}^k5;yHyg|+hHG(wUI_u{wiOkg^ zQ{u#N!&^yp+ueizx4Bx}+`5$4N3~RK|DUn%4mni@6TT?-44p7r3w1BK<%`Mb_1fb0U`tTe4smg5I_gC|Ts23NUjOj!3 z_n&{a5gwLu8RZO(t2e`n6M#OuA4~bqPs(#pmo`LDbzQd^aUZ;D=c(g zS3R#mtfm*b1w;rzCwe!lP+zjh%+ywYVy?0`HTC^H7}c9Gm2*$Wn>SUJ3-mW&M+N-v zLihJeENEaefSPPx$9mTmqZ=>%^zww^R89vCg#6?AYF3y-2n?~WnhoSm3Bzam zLw&Fr9pD2T6lfq991btvdnfRljfNLUr*I4UD;c0}=QY(%-LqoC(iIYenk<}uUf$1A z(oYx|St{5ek!iA&5qE?eR`_`n3hc-d%wC710!MI?TvzZ!0L;aFFU^3WU9#X*Hi=4 zZ8V;tcZnX718eYB<`m4**sYX*w(c2v55WfR+=kg3F85{r%m+xK6_}RZCkE!ZGY^^- zg-jI#)XXKB(7Qy1oDu`nRByaOj#!fip^$6OlB$g(Xm2@8} z%6ozOoeq4_=aa7W38d?UvFI93AiY4{*HGY>l<@g=fP*PFJi0tPI(d10^#1DI_4|w0mq#b3xzgPxB)^8h5pO%$1Pe6$5Cfk8A);15 zxVhNU47j%}Bm>mh-PK%whrRa;ET;psO=PewM6|8zRAJQpjb=D8SWTdTk5x-TOV7tu zsQ3H*5^9|#tVLqU=a4(RrKXc`)DA1@Fku7@Kls3>L7%d2+5DJAZ2B|2PVRzpsA5N! zshZpcF45!_XQ}GxDPwSdkV!&lg&3U)k*c|@+eXiy>wPXiWhh*KJZ}_+kXWYT`Ez}< zvYi&pUT7dAG$GO@hZRJkR)lbpwDVh~s*x{j{^VliyWsJaz;UxuE#OH{HS~%I=~=JZ zxHGqs811*9oji>l%Z*LkYVjFrwWOS*7FEA=4%ippo|8MmzeTN|wW@tX{$~?_74G=g-jwwKv__xDTypHtQN~5`mioh<`B~(wd-_Cp*v3 zdq^kj8#mf15R?1tJRW4BNhbC_Nu4=d|1JPuVmJ8=uxB)XD#q%?565O)q78rC>h+&c z-$g#L@8*&LoUA$qpFx<5hg57CbX-TcgafeDT7U6$f?@1m5*D^-9Fm8>R^f+gPE7Jc zSGPNJ%^E$auQwvg)f1G4!ue6;b58^~G7)BihIVmL9y!m@(3A|}4&R|YuT59F@pQji)gXOt)a?!-ryr|FL3h54%*En{Skv5>{y zMH|E6NefVKHd@-WRb^*HavJF6-;BjnGHxb2^oGWNw?Z}QgC*vjTF+CR#W%YF{O1jO z+lTebF+SPOT@t>%>4PyjfWJ#eS=DJevWeRRHru|ou%M#ngRQ}wA8;WHghpu>lrf_J zfA+q1xouoo@V}k{tITX9FGYXbiDq-_YHUwNJ03e_Ig_2rnMxoMl5j#13_x1ZNlw*1 z%|6(FKFJok0T84p+0JB=J5|57y(O>9p0Nq*zlrKy<)Fjbkog|`&Uzi#sTtG3D zp3yPzmg;`%`YyM9s`Y=$L|tEUjLr3bb`K7Y4r}#)_ID5W9_s&mjn7IxI6sw~DP>>< zvaC|zQp9m6)E>F2lVq%|yiC#vYr12Bnk*52ODuf|IpQfKXQ570)gUMj*L$@!%EiZ) z8!z+qhV>qxM2}jg(M*a|6v`B$nNxV`XY)}aDe5~=ex;n|qBL+*%N1#S`}Xae$vNe5 z3o7d6EXoVXdSjMjJ-{hkv7;G(y=KOvaAW>Wt& zbz7Q~m0rxlz4}9h!aUutKh@n=!H3TJ z=epTdQz!nL{VUz`;%Tjz-sSe2ic;3_EDZBGe~)@Ti)9&8JV= zd(YczG5=Mg!MKe>)13FHzd4{XJj*sUDF;o#mzYoBIC72~#4Y=do(62UYTw&dF8A`^+2E+O<urJ7S88seVo5=A!I2sAHnVTKku7sbl`<_yH z&&w)gt{v2((8x9zTDEz7Y-QlA5_tAg>HymqLmhAUK}5mUsY#ao)+6WbnR|Vv4IDn< z5ordJ{G;_qlfO5SV%|%5&LmBqS-_qd(Olok0{BcjYCVHS`=duHtGus&OtKvG7Oh5h zDRflCQYyJnL0L1`xT%o#@t(@MDODssgqVwBrqFiU00Hm-{@A3%VRNOHD#$$YW^ICi zSaPJkOnIR-KdWgzlcJd76^1$GX;~{s`@qClByrcwKg`-v5lKt#Up;pjV=H!+Ca&aN@N}vc=B3^zEdZfmY^^7kkAGPE+>8Nx zAsd>((U><7KYC+IVL$!>C-VziS_mum9gX|nZ}rIA)v@08oASngnil0N4dcG;laV`K z(H<=|fnC0zB%dv@yRr{JLG`W6i?%xvZQD25PfbDlN9GoaZ>JYF82B63lcPyuS0>4b zEYcJ%fUS#t-Y_Goz2q2-`NOCqMG@|%=GHpD_JG^)}^`{$&WlKq_>vVB7_w=ocH+si8) zn*S0pbpRZCyHYk2pI7>O6$(^|SA&b|5&7xziaa*Uqkz1)x;!}>jRJCY_Tqea zGPoXIUXYXX;n~GCxx64-;TE~RtN~MYIXFKjFRq5a4bRV>pN*Pd0KU=&7QW~&U{FvD z_XZ#$Ffws}1h-RQohmrY1sgb|qq2nOy|IMV%Pgo3dqY<1RMIkwwA3`WkUpY$o#cL3 z`fazD;M)#*3|L)-%CY`r#9|onzS}B2t)n*NrG92@g-2unr@TGYBy$zmDl>KK=8MAt z2lT4C@&Xl50cwf-Q($ULz}|XNX+hD_>Qe@!*Q3mTCzOO9*CumG1hb4dQS+?Ol@(yq zhFK5iNqT}*HnVV}B@qjgi`=CkFK1)hmlh*2UMglXx94V2S+s$5s4>cDS|%^Y7ky83 zjmL>k9ude=OcnFf$W|4hJ*;Z?jc>GDh@tf+YE<@^q3xLE3&v7dbDQO67lbB_Nbg@a z_{&~@Z}L7)|AQPH9vy$iJ5TQY&cVS!RsC9j02k><%rn@|a$+(o@>nd=CKUX{u^458 z7?aM7PiGoMioH)o_e<#!*uHB>Ex%EpY#3OvSc}PHwY}17pX@aKxV!!MZlGRDTj{2v z`6daS{$)yT#WVj=li-Dokz*a-L9(Dr$jCr{L>zl}WI*F@ZIRA?Kn??P+=XMZH-g8+ zTTh@5bLuRs$5FPn@SK9SMK(uKbT7s^DVdG`i*0QY$)-g@WnxlQ6zAe*Qba7)GuhhGsy`KJZ%r-zZ@p>r1wVHGkII}+Xq3;2aZj>Lgv)vI zrN-F2|EC}B*Y^Joj`ofp_W!=dr`$ywp7zQ96E==xdej@oPshE3XlJ)aCkL!|c=+UL z%;L%3@zW=*Zw>Op=L>$U{F~JcOYd%fpXk5fP}G+g;}-ef-QU@%$^YU0!R~|ne~piK z^F-T{-ZBt!p}8WRGSw%a_S|Mf&*Ub;XR)`T5to;0`lKxxuv2$ zk3WC%d_Mk}{C9F9Lh{S=mciP8rV-6KZh*h#Ze#SwJrSKt#woW5>=zj0Hv4b)@Tji;k9HpHzpwIns!j@s5`^QC+VpWwVm9Ha zOBANLqxFaklEfwg(>@oriCsZLk*Z=2hkAj#!Ut*nFZXGdf42y2zrhuMNQHU!*{Wc( z{O|1@9v|1_|M>XuLH@tW=i|rit=8FxjGCySpD-DCB5ZAK|NGyqj~{zh1+**czkZ=j zdSw&10TQAI0VRvW-%wxZmX|k7N**)viR7|KBXYD4U-^7gOeXvTY4_U1^u^Lxe{BJX z?tZTw0c!t}_XSP(gtM4`&@2Ps!`3T?eM9?PkDw=_$e2a6P>d)sXMUPPm@*_CMJ)y~ zCuWjdb45BPtLf>*NVkRUfQ&`mur-`i(u>+$Sjt#+m^Zpi83Or2sMfR^cmwTb?Aq+o zC5HLLA=Ex}NHtB?KEDgn6Xp8(4kpllc6X|lFgjFVCzTAO4$jJdkM{&FlRV8Qr2W0> zeXrWJzHrdH^H}p&LZ+*NLxW?AEZoDNT;q=?r`Uf5mN#_K%nZbU@S!$hx+3Qt>THEcW_ttmib81;j# z;E>^MvxlZ@CtQ(Y{BC?z@(B+3X?nN+N1L?YwC_({^kOl!#4TWABZN~sf}xtB9nvQs zKaysYo2i93_?kwxT+z81AoLWIneo6m==#~}VH)RVe*D;f@X9BX$F_=r)n4GT1B-j( zC3a-x%ATb+@5APVl`u5HOiC7t1)Z2uQ#Eyf0+8`f)RBl#;$?SrzhhOum+|N2C7 zG0Ncvp>JwT6EUWVMhGE{uPh}0{>)P>; z<2rwYXWFLFv#tCZ-pX_q94*o~q>o_R&nl3sZT?d5tdd(n$|_{*TK=W*byAU&4x4BB zveHF=x2qwn!_se+@P1drv+3|1PvfB??K#cNnp1}U^$L^vD~s_Jsx9th_pivvZ#3aC zUdV>5Y_V|{Z;^u=^V*ep%aeo1R9fplBXA|3gk-0D3cdT!cFSjTrj%w#@9CbeDK*Yb z2lm$qEhOgxkHyLW84X7VPU zxH9|CxWLmhw|;DjDR&v?tSmd=7p-{5&`tyBJjozLD@F=+F@~x4Gs0Tki}JYGOr_G3 z9tSwlvmxuR8|H&!c=rC$COXZijK36}bYFjpPF6{w>nTS_pDiZTdq%2*hRvMJfpAoI*dvI%R!TERK0B>tt>bg^6f!6MIs-aGE zvb$3ygtZaN`BxsV`X#O*a?qOhYLa-jYk2pQ*}sGvZO?Oimf>L}H0Hqm!j9-2Nf$s!g*xgxGG(~inrF|%2Jo@bDC zM&(S-c^a$G98%z7TV;|@w__gVDxBr>9bpBYZk7U+A0!%8PmVO7cJrwDdrHB`9uIz9Cp=Q#osLlZ(Mxu<<%0V zA;!9Nc2m3LHnpDK;K|tOSNvW}cxunJr{2=w3wg^o zoH`xb%z}=tdUwUy>{cAdRd=rRMepc|u31KIWk_%nJ!INtrV5}75PcPCnC<|NVesl- ztkUJ1)b2y~e7!Rp=DE_=Yks{^qo8ucRX3WMV z_Y|*kaNP3Gse~KK3C$-$&h^@PnXz;<)VMLJL~6_WveeXfxjkcs_*31ZKAT6{41hczln zI&oz#=&<;9N|^Ow1)e*RW&O*}bbs(Dhc3n)*a3GMy}%!PU+t)^aql)DHR8&Ja|IaE zb_i{o?|{fQX;0j@Dn8q*=7o3kz-}I`AMw^*C13(qI_=)9@E35v$r@np!3XQR_-5R& z4#gXI;!kkG+R@hX!?!;Eb^G~0lQjIVJO8({x3hP!a{lk&=;8d|*Z3HHRDURNvrVdH zysAOddY$rv}w-O=XV!1KGOtAv{rH5w>+V9vB z|GmJ!&1kiVEB-J2VPY}`$n{OU?FQ~*TJm?g*Zasxk z<$>z{f?g!r-jCS&l;%`F>EKJGeY4vp?U7-dI~>+>fkiWXH;i?co_}GfS6F|v&Wx&G z*s}6l_>L{RtKm2sN3A!l9zEa_5>|=5+E2BCcS7S686O?6G+KLH;>LCPv2whjU4PWH z3;3;d(!=NLeb(In{CRNk{OtVl`4`CqecS!dO?mIE>eb7b-EM1(L^B~-pA=Xs!slE( zG|l7`&qSwFrby@YlY?k-bUgmtq0Q@e8JZ@EIg1U4ys@Hyc4nqiCQ0Y@(bMCDr$+~$ z3yFEX+XcGqhP&aON4FiI+l0})PiP!#dkBbCE`xzJHrAY1|9^k~=l^Pg?d@xVJw4n# zJ~)g%7gqDS2kWkZb?0es?+9R}Sq51rbG;6gW|p}E%gt%%&ZFIRq{eM0@IlCC0eIXrl%l)sT-Tiw0|AT}5 z2mkM@e8_DdyyH&J@y>f|LrZ%&elOe!$p6yHPA2P#?HT?0V{slVN z4auoHN}qUZ7W7p$?ajD}Y5JTS`cWFBU12L`cHY9BL92`AkUuFBs1r zR%v(x_J7g2B2!7z++MLUc<=yVQ<{)7=z0Z+BGnT#J}ku~z7~o!)=Qr02Ftd>BkphE zOOXU{&CdLh0MLP+jsCSTkx{t$k3E@&s8gXI9594pNZ^SVG82la6045jmPT#UOB<%5 zNQZavRk2_)ATgIL$~6!?#qR-VbGR^=&n(~LBY(hv#7Y)e_ghSeDx#SIEO5nw$4i8s zLf<}S7F=_akfg(T7s;b$Jkvc*_#|JFjLArM-8tO(z6-+%X@dv0qas&1P2sYXno-G= z?U8rMn5E3r+^O{L!C8|0cTu!SM@aZ4+g+dPH1+ed3Q2taFdeWDOhz2)c6g~mk&N3Fhf}cLJx(Pi`9iao z3F1T|W&x=b8ZzBrgTTtaU&@;&%u^qic0wI#OkG7YWiq60Bbs4c8tH1%y<0)qkUD1Y-0 zWXuw==$2SGWs={}oZm2_5u)044$xyXjomHacR-9}bIP53LT-P^4J*YQrZH!dB}+&P z1c)2+6!=7YI$cY2s7o_}`r%>{cx$9X>IzUAJ4{SUs-I|8Zr1oliq~bpiL5uCL!iCp zY1UE)hwiLG6X0P}%T&3esE8YQOUSjr2cA&mTI-9{R>9NAEXH%58|7i`4u9Y-fE>Ux zq5uQgo2XT@!crNQyN#=bZ>VUk48v=FAF~-vCPYlu8!vZT?Md6s$tHio_1>vvF(Giw zREm^Gfu_QkCcsAvso#Tp)bk>B6{1+0`$%UcqBNdzRSFB>Uj-YNBB#6jF+}RYMCO!3 zfxU#QTm}A;2Q$sbE1IrU=UFjMc$6$Pqh<+R2IVg% z<7}X@ojAk7_uG6k-|1p7mRCk>Sk6JWAc6Kh0==Mc=J@YVoeujDu`JgD23eJ3SB6ia zL)0Z1&efydoW5fLnb8{tR-Oe2{Ad9Qzx5)(k|Z$y@_8m?j(>zHcbaX+@>0#%nL&&Y zXkmbLCOphXGgb7k6klN&Fw6Cb-yZ>B6_N>Rx{Iwz8+QJh=nGFUF$+JoM`$xUr6OV*F5cr zlJhBoK&Mnc27e`I9QRJSU^&}b3Z;60Fao&=3vEB)-#jIhBy^z)p6jV5Y>JBj%^mQi zO;FQ{n-mx>#nv5rP5V`j;-Ru!%e zct3#VmRG2<1{=iu4f8qdas_^3jH=)uBv;Ij427=Duz%BRbuAQ$j9c5LqK`IMc|a0v zHnNx(^T0%(aSva(6}jp*;}X6`lLe(K1PCcvYt9%_c_NZTEKJ2_qr3Vo=T~)criIGM zRKu&mLw`fEh-Vy<*7&Bc^A7cAWug?;hq@>611zI<%&|8n25w4I8m{b`YDE#1nC^Sd z;r0)DkAKP=UaL6A(z;KR>l7!h`>Bo`c_T}fQ=SIaZuVSw@D9@D%H+I(-GC)S1h|c4 zSI59`cc9f`%(UGUc*X>68sMp`)T-r%+SB#{z{LU#+Kfp(O*r-g5-0O= z;UdO@uTQj!w79F4mZQJRm_bSV;_`ZUa@HoW*?*$(t;Noap-paY9ACOT70@6lE0_g( zd0ko8lR~X1@G(oKV~uFF2mXBY8>I%C0Ve`e2=0PcubXBJH{unTjpig_RB3n0kJ6i0 zN@<1kKB{lQq!z{!*CmE3T%|U`@Pn_+D@^9gbu|EmSy7Ch(M#sETme`67cyAIGPSmz z7k}ll>DpGYG^t4n7!Ws1BC+xrmvK)|a_MN33OR==@HER9l_4Cyf^ERG!iEMb9=*YM zKv&uY`Do%fui8SXf@5S0G}f{bn|I3wjbr^?5~zJ&a-`Rb1>IoiE|L%+_7#sStONcO zP4%EGjf=T8TPqx66$|=*mYj8+1_-u641bz53ll`E$QToc=CY{sA0lSmzC|O7O0NRU zRtVOk0Z=8EI@PSXmWcy zLN;w80IlD)+Zc4tlxNYXz*YA&e+o$q4`XA?v=-u^j5--NwM^B5#UGWx>Nr5sLgivk zMPsZ6Ab zn~HRBwMKh|Rd%6SCPgN>HqT+g6H-8|6!@>yxL&*zqm4=xkonPyw14CZG`kWJcWyE& zb+gY3(O7?@b=8?g-g^>~bB9v>(mBV=Zp)Ai^~y`|h@OT6`$z>zAlRADn2<{^)M9tC zav^g+WRS9H!lx{aST}IH-9aUk>mon5@_Ppj1w~?(@G%&40NhjxrQE)S9Wp00$`$O6 zH_HcV&&u*4BpF+hC4W%D)z(X8q^M6SYD9kFO3O;aPrn&(Z z>Ee@>K%D8r1=DGK!(o$jVvcVp#SIed;Re$^O2E^Q3?jWIXe?OG3%6Cvh1wH}S2Jz8 zSH-oyS-5e#&03++ObCpELZq{@*$y#RLdk@IJ_!f~2x%HIoJ59UP^0~pz;|q(^4!Uz z+r3RJ>_m(c6MuyQyJcIe9c}rpX1~y!RoU)gA^BM>v?qkFq(d0s)9bjLADn1O6K^-f z+1zGZ1cJEcXRSy}H45;8rBm*rlp4K^6nSi5V!}|Ce1iH}3p~m@;AY}*6SE0RV|-&K zlDHvsPURdlku|Oz7E5t1q%3#KOyrm<#iSM=6GRPGlW5~t3XUwGW; znT-w>WZ<)lQ@yS>9fO1CgBLH(E>4I4yRS(I(E>O|i^muIqkH<9E1u`Prt3St5SU{W z)o6k>s|8P(#H1|f%>|_=Z!)X1G)ja?XFQfPddG4_+OPj;mrhDTBfHuyEi-{uHC~_R zNr$9!3V)?_P0+@ZQQP@{>k{zR!A(`J*s_Decn99H?d{EKSy9V0rytx#C^+>9KuBIO zLK7vRdZ2D?;-prKLtEqIcHh;7XUZT4mC=mfSWQ`OCV#$OE|<$c$ZJ~*ptj5U2Q)WK5_>*V zm3;#LKq%?x2JXyd7YZs{e?%(+T)s^B+?w&2)I3W#s7A+8&cyM&eldn<8LfouEF;t0 zviogEPR+q*DCwkMxr>Fq&h{{8&RTwyvVt!Q9#@qH>n!j;X?|P78_+gltO9~%axiNq zJbxkyO{WE&GBOo6Os4gdeI{B`+Usg{UJvD7{sy1s^Z!?8gVSHnzR2aTJKX;|*sb6H zJ~-Zaxc~K4KCYPk&n%e}NOTXyipiNd7Kw*oK|z%HB}{pH)zS;>TfauoTa$PKZL7D9 z`BUE762jVvW=(l#ptQ<{d^FHm;O%O7<$qhoj6voMHWxQ~nFj+5)|a=Hi|BYA>MqGI z-fHc+{^fPKQ{Gw=1F(w6S)7iny%Dx-9d?tFq~CH0D$G~&b2U9hzXjE$EwKu`aButa zixSc-Q` Date: Mon, 8 Dec 2025 16:18:36 +0100 Subject: [PATCH 14/49] Updated workflow call --- .github/workflows/chart-ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/chart-ci.yaml b/.github/workflows/chart-ci.yaml index 1ddfd04..b1bfc11 100644 --- a/.github/workflows/chart-ci.yaml +++ b/.github/workflows/chart-ci.yaml @@ -9,7 +9,7 @@ on: jobs: aphp-chart-ci-workflow: - uses: "aphp/ci-workflows/.github/workflows/chart-ci.yml@dev" + uses: aphp/ci-workflows/.github/workflows/chart-ci.yml@dev with: kubernetes-version: "1.24.2" chart-dir: "charts/redcap" From b5aca5c3ce17fe1c4aa9a431b475d795d2004043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Mon, 8 Dec 2025 16:55:44 +0100 Subject: [PATCH 15/49] Trying agai with adding write permissions --- .github/workflows/chart-ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/chart-ci.yaml b/.github/workflows/chart-ci.yaml index b1bfc11..b73900c 100644 --- a/.github/workflows/chart-ci.yaml +++ b/.github/workflows/chart-ci.yaml @@ -7,6 +7,9 @@ on: - "dev" - "main" +permissions: + contents: write + jobs: aphp-chart-ci-workflow: uses: aphp/ci-workflows/.github/workflows/chart-ci.yml@dev From 138f4d1b2cad9f31d7e2113b205098cb9fce441a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Mon, 8 Dec 2025 17:00:06 +0100 Subject: [PATCH 16/49] Added missing content write permission --- .github/workflows/chart-ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/chart-ci.yaml b/.github/workflows/chart-ci.yaml index b73900c..e82d5a8 100644 --- a/.github/workflows/chart-ci.yaml +++ b/.github/workflows/chart-ci.yaml @@ -9,6 +9,7 @@ on: permissions: contents: write + security-events: write jobs: aphp-chart-ci-workflow: From ce62ff3abf0b4e58c500dfd563916e7157a7929a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Tue, 9 Dec 2025 09:40:23 +0100 Subject: [PATCH 17/49] Updated network policies and audit templates --- charts/redcap/configuration/audit/redcap-log-event.conf | 2 +- charts/redcap/configuration/audit/redcap-log-event2.conf | 2 +- charts/redcap/configuration/audit/redcap-log-event3.conf | 2 +- charts/redcap/configuration/audit/redcap-log-event4.conf | 2 +- charts/redcap/configuration/audit/redcap-log-event5.conf | 2 +- charts/redcap/configuration/audit/redcap-log-event6.conf | 2 +- charts/redcap/configuration/audit/redcap-log-event7.conf | 2 +- charts/redcap/configuration/audit/redcap-log-event8.conf | 2 +- charts/redcap/configuration/audit/redcap-log-event9.conf | 2 +- charts/redcap/configuration/audit/redcap-log-view.conf | 2 +- charts/redcap/templates/networkpolicies/app-egress.yaml | 2 +- charts/redcap/templates/networkpolicies/audit-egress.yaml | 2 +- charts/redcap/templates/networkpolicies/backup-job-egress .yaml | 2 +- charts/redcap/templates/networkpolicies/db-ingress.yaml | 2 +- charts/redcap/templates/networkpolicies/restore-job-egress.yaml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/charts/redcap/configuration/audit/redcap-log-event.conf b/charts/redcap/configuration/audit/redcap-log-event.conf index 2a3adac..fdbc819 100644 --- a/charts/redcap/configuration/audit/redcap-log-event.conf +++ b/charts/redcap/configuration/audit/redcap-log-event.conf @@ -3,7 +3,7 @@ input { jdbc { jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" jdbc_driver_class => "com.mariadb.jdbc.Driver" - jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.service.port }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event2.conf b/charts/redcap/configuration/audit/redcap-log-event2.conf index 4f69730..f43b9cb 100644 --- a/charts/redcap/configuration/audit/redcap-log-event2.conf +++ b/charts/redcap/configuration/audit/redcap-log-event2.conf @@ -3,7 +3,7 @@ input { jdbc { jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" jdbc_driver_class => "com.mariadb.jdbc.Driver" - jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.service.port }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event3.conf b/charts/redcap/configuration/audit/redcap-log-event3.conf index d9fc846..0878ddd 100644 --- a/charts/redcap/configuration/audit/redcap-log-event3.conf +++ b/charts/redcap/configuration/audit/redcap-log-event3.conf @@ -3,7 +3,7 @@ input { jdbc { jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" jdbc_driver_class => "com.mariadb.jdbc.Driver" - jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.service.port }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event4.conf b/charts/redcap/configuration/audit/redcap-log-event4.conf index 4724396..a135cbb 100644 --- a/charts/redcap/configuration/audit/redcap-log-event4.conf +++ b/charts/redcap/configuration/audit/redcap-log-event4.conf @@ -3,7 +3,7 @@ input { jdbc { jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" jdbc_driver_class => "com.mariadb.jdbc.Driver" - jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.service.port }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event5.conf b/charts/redcap/configuration/audit/redcap-log-event5.conf index 4b59986..8cb843f 100644 --- a/charts/redcap/configuration/audit/redcap-log-event5.conf +++ b/charts/redcap/configuration/audit/redcap-log-event5.conf @@ -3,7 +3,7 @@ input { jdbc { jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" jdbc_driver_class => "com.mariadb.jdbc.Driver" - jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.service.port }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event6.conf b/charts/redcap/configuration/audit/redcap-log-event6.conf index 56a7557..cb5eb5b 100644 --- a/charts/redcap/configuration/audit/redcap-log-event6.conf +++ b/charts/redcap/configuration/audit/redcap-log-event6.conf @@ -3,7 +3,7 @@ input { jdbc { jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" jdbc_driver_class => "com.mariadb.jdbc.Driver" - jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.service.port }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event7.conf b/charts/redcap/configuration/audit/redcap-log-event7.conf index 6c4a379..305e2db 100644 --- a/charts/redcap/configuration/audit/redcap-log-event7.conf +++ b/charts/redcap/configuration/audit/redcap-log-event7.conf @@ -3,7 +3,7 @@ input { jdbc { jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" jdbc_driver_class => "com.mariadb.jdbc.Driver" - jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.service.port }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event8.conf b/charts/redcap/configuration/audit/redcap-log-event8.conf index 4bb92d3..c504269 100644 --- a/charts/redcap/configuration/audit/redcap-log-event8.conf +++ b/charts/redcap/configuration/audit/redcap-log-event8.conf @@ -3,7 +3,7 @@ input { jdbc { jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" jdbc_driver_class => "com.mariadb.jdbc.Driver" - jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.service.port }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-event9.conf b/charts/redcap/configuration/audit/redcap-log-event9.conf index 7a93fc1..1c4c89e 100644 --- a/charts/redcap/configuration/audit/redcap-log-event9.conf +++ b/charts/redcap/configuration/audit/redcap-log-event9.conf @@ -3,7 +3,7 @@ input { jdbc { jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" jdbc_driver_class => "com.mariadb.jdbc.Driver" - jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.service.port }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/configuration/audit/redcap-log-view.conf b/charts/redcap/configuration/audit/redcap-log-view.conf index 58b01d2..14f7ba7 100644 --- a/charts/redcap/configuration/audit/redcap-log-view.conf +++ b/charts/redcap/configuration/audit/redcap-log-view.conf @@ -3,7 +3,7 @@ input { jdbc { jdbc_driver_library => "/driver/mariadb-connector-j-8.4.0.jar" jdbc_driver_class => "com.mariadb.jdbc.Driver" - jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.primary.service.ports.mariadb }}/{{ .Values.redcap.config.database.auth.databaseName }}" + jdbc_connection_string => "jdbc:mariadb://{{ .Values.redcap.config.database.auth.hostname }}:{{ default 3306 .Values.mariadb.service.port }}/{{ .Values.redcap.config.database.auth.databaseName }}" jdbc_user => "{{ .Values.redcap.config.database.auth.username }}" jdbc_password => "{{ default .Values.redcap.config.database.auth.password `${MYSQL_PASSWD}` }}" schedule => "{{ .Values.audit.logsApi.config.pollingSchedule }}" diff --git a/charts/redcap/templates/networkpolicies/app-egress.yaml b/charts/redcap/templates/networkpolicies/app-egress.yaml index ed5dd47..0c721fb 100644 --- a/charts/redcap/templates/networkpolicies/app-egress.yaml +++ b/charts/redcap/templates/networkpolicies/app-egress.yaml @@ -30,7 +30,7 @@ spec: {{- end }} ports: - protocol: TCP - port: {{ default 3306 .Values.mariadb.primary.service.ports.mariadb }} + port: {{ default 3306 .Values.mariadb.service.port }} # allow DNS resolution - to: diff --git a/charts/redcap/templates/networkpolicies/audit-egress.yaml b/charts/redcap/templates/networkpolicies/audit-egress.yaml index af3d390..fcc6616 100644 --- a/charts/redcap/templates/networkpolicies/audit-egress.yaml +++ b/charts/redcap/templates/networkpolicies/audit-egress.yaml @@ -31,7 +31,7 @@ spec: {{- end }} ports: - protocol: TCP - port: {{ default 3306 .Values.mariadb.primary.service.ports.mariadb }} + port: {{ default 3306 .Values.mariadb.service.port }} # allow DNS resolution - to: diff --git a/charts/redcap/templates/networkpolicies/backup-job-egress .yaml b/charts/redcap/templates/networkpolicies/backup-job-egress .yaml index 844f081..d7dafdd 100644 --- a/charts/redcap/templates/networkpolicies/backup-job-egress .yaml +++ b/charts/redcap/templates/networkpolicies/backup-job-egress .yaml @@ -22,7 +22,7 @@ spec: {{- end }} ports: - protocol: TCP - port: {{ default 3306 .Values.mariadb.primary.service.ports.mariadb }} + port: {{ default 3306 .Values.mariadb.service.port }} # allow DNS resolution - to: diff --git a/charts/redcap/templates/networkpolicies/db-ingress.yaml b/charts/redcap/templates/networkpolicies/db-ingress.yaml index 8c2a718..adaecc2 100644 --- a/charts/redcap/templates/networkpolicies/db-ingress.yaml +++ b/charts/redcap/templates/networkpolicies/db-ingress.yaml @@ -39,5 +39,5 @@ spec: ports: - protocol: TCP - port: {{ default 3306 .Values.mariadb.primary.service.ports.mariadb }} + port: {{ default 3306 .Values.mariadb.service.port }} {{- end }} \ No newline at end of file diff --git a/charts/redcap/templates/networkpolicies/restore-job-egress.yaml b/charts/redcap/templates/networkpolicies/restore-job-egress.yaml index 65d2f1c..02c125d 100644 --- a/charts/redcap/templates/networkpolicies/restore-job-egress.yaml +++ b/charts/redcap/templates/networkpolicies/restore-job-egress.yaml @@ -22,7 +22,7 @@ spec: {{- end }} ports: - protocol: TCP - port: {{ default 3306 .Values.mariadb.primary.service.ports.mariadb }} + port: {{ default 3306 .Values.mariadb.service.port }} # allow DNS resolution - to: From c77a9b9808b5d1d9a07f6e229431b7f52ff5b85b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Wed, 10 Dec 2025 11:09:17 +0100 Subject: [PATCH 18/49] Fix networkpolicies for MariaDB --- charts/redcap/templates/networkpolicies/app-egress.yaml | 2 +- charts/redcap/templates/networkpolicies/audit-egress.yaml | 2 +- charts/redcap/templates/networkpolicies/backup-job-egress .yaml | 2 +- charts/redcap/templates/networkpolicies/db-ingress.yaml | 2 +- charts/redcap/templates/networkpolicies/restore-job-egress.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/charts/redcap/templates/networkpolicies/app-egress.yaml b/charts/redcap/templates/networkpolicies/app-egress.yaml index 0c721fb..e376afa 100644 --- a/charts/redcap/templates/networkpolicies/app-egress.yaml +++ b/charts/redcap/templates/networkpolicies/app-egress.yaml @@ -25,7 +25,7 @@ spec: - to: - podSelector: matchLabels: - {{- range $labelKey, $labelValue := .Values.mariadb.primary.podLabels }} + {{- range $labelKey, $labelValue := .Values.mariadb.podLabels }} {{ $labelKey | nindent 12 }}: {{ $labelValue }} {{- end }} ports: diff --git a/charts/redcap/templates/networkpolicies/audit-egress.yaml b/charts/redcap/templates/networkpolicies/audit-egress.yaml index fcc6616..633f73b 100644 --- a/charts/redcap/templates/networkpolicies/audit-egress.yaml +++ b/charts/redcap/templates/networkpolicies/audit-egress.yaml @@ -26,7 +26,7 @@ spec: - to: - podSelector: matchLabels: - {{- range $labelKey, $labelValue := .Values.mariadb.primary.podLabels }} + {{- range $labelKey, $labelValue := .Values.mariadb.podLabels }} {{ $labelKey | nindent 12 }}: {{ $labelValue }} {{- end }} ports: diff --git a/charts/redcap/templates/networkpolicies/backup-job-egress .yaml b/charts/redcap/templates/networkpolicies/backup-job-egress .yaml index d7dafdd..f09b3ed 100644 --- a/charts/redcap/templates/networkpolicies/backup-job-egress .yaml +++ b/charts/redcap/templates/networkpolicies/backup-job-egress .yaml @@ -17,7 +17,7 @@ spec: - to: - podSelector: matchLabels: - {{- range $labelKey, $labelValue := .Values.mariadb.primary.podLabels }} + {{- range $labelKey, $labelValue := .Values.mariadb.podLabels }} {{ $labelKey | nindent 12 }}: {{ $labelValue }} {{- end }} ports: diff --git a/charts/redcap/templates/networkpolicies/db-ingress.yaml b/charts/redcap/templates/networkpolicies/db-ingress.yaml index adaecc2..10746d7 100644 --- a/charts/redcap/templates/networkpolicies/db-ingress.yaml +++ b/charts/redcap/templates/networkpolicies/db-ingress.yaml @@ -6,7 +6,7 @@ metadata: spec: podSelector: matchLabels: - {{- range $labelKey, $labelValue := .Values.mariadb.primary.podLabels }} + {{- range $labelKey, $labelValue := .Values.mariadb.podLabels }} {{ $labelKey | nindent 6 }}: {{ $labelValue }} {{- end }} policyTypes: diff --git a/charts/redcap/templates/networkpolicies/restore-job-egress.yaml b/charts/redcap/templates/networkpolicies/restore-job-egress.yaml index 02c125d..8f528ce 100644 --- a/charts/redcap/templates/networkpolicies/restore-job-egress.yaml +++ b/charts/redcap/templates/networkpolicies/restore-job-egress.yaml @@ -17,7 +17,7 @@ spec: - to: - podSelector: matchLabels: - {{- range $labelKey, $labelValue := .Values.mariadb.primary.podLabels }} + {{- range $labelKey, $labelValue := .Values.mariadb.podLabels }} {{ $labelKey | nindent 12 }}: {{ $labelValue }} {{- end }} ports: From db1af13208b3ae03b38eb3599bcf576cef564282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Wed, 10 Dec 2025 17:36:48 +0100 Subject: [PATCH 19/49] Fix mail configmap --- charts/redcap/templates/configmaps/redcap/mail-conf.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/redcap/templates/configmaps/redcap/mail-conf.yaml b/charts/redcap/templates/configmaps/redcap/mail-conf.yaml index 6085f81..be70f87 100644 --- a/charts/redcap/templates/configmaps/redcap/mail-conf.yaml +++ b/charts/redcap/templates/configmaps/redcap/mail-conf.yaml @@ -3,4 +3,4 @@ kind: ConfigMap metadata: name: {{ .Release.Name }}-mail-conf data: -{{ tpl (.Files.Glob "configuration/redcap/mail-conf/*").AsConfig . | nindent 2 }} \ No newline at end of file +{{ tpl (.Files.Glob "configuration/redcap/mail-conf/creds/*").AsConfig . | nindent 2 }} \ No newline at end of file From a3f2d730921edf0132de02d010097007966e40d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Wed, 10 Dec 2025 18:09:49 +0100 Subject: [PATCH 20/49] Fixed tls and starttls params in msmtprc configuration --- charts/redcap/configuration/redcap/mail-conf/creds/msmtprc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/redcap/configuration/redcap/mail-conf/creds/msmtprc b/charts/redcap/configuration/redcap/mail-conf/creds/msmtprc index 0625e89..ba037d3 100644 --- a/charts/redcap/configuration/redcap/mail-conf/creds/msmtprc +++ b/charts/redcap/configuration/redcap/mail-conf/creds/msmtprc @@ -16,8 +16,8 @@ auth on password {{ .Values.redcap.config.mail.auth.password.value }} {{- end }} -tls {{ default "on" .Values.redcap.config.mail.auth.password.value }} -tls_starttls {{ default "off" .Values.redcap.config.mail.auth.password.value }} +tls {{ ternary "on" "off" .Values.redcap.config.mail.auth.tls }} +tls_starttls {{ ternary "on" "off" .Values.redcap.config.mail.auth.starttls }} ###Set a default account account default : mail From 0a8ff0c1ccb4425c1e866b7de6a7ebbe3eb5963a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Wed, 10 Dec 2025 18:49:30 +0100 Subject: [PATCH 21/49] Adapting the puging method of the backup restore process --- charts/redcap/configuration/redcap/mail-conf/creds/msmtprc | 2 +- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/redcap/configuration/redcap/mail-conf/creds/msmtprc b/charts/redcap/configuration/redcap/mail-conf/creds/msmtprc index ba037d3..fc997ee 100644 --- a/charts/redcap/configuration/redcap/mail-conf/creds/msmtprc +++ b/charts/redcap/configuration/redcap/mail-conf/creds/msmtprc @@ -17,7 +17,7 @@ password {{ .Values.redcap.config.mail.auth.password.value }} {{- end }} tls {{ ternary "on" "off" .Values.redcap.config.mail.auth.tls }} -tls_starttls {{ ternary "on" "off" .Values.redcap.config.mail.auth.starttls }} +tls_starttls {{ ternary "on" "off" .Values.redcap.config.mail.auth.starttls }} ###Set a default account account default : mail diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 0c46229..4a43667 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -78,10 +78,10 @@ spec: command: - "sh" - "-c" - # Purging the edocs (user's uploaded files) and redcap (application codebase, except database.php which is a custom mount from a secret) befre restoring them, to have idempotent backups + # Purging the edocs (user's uploaded files) and redcap (application codebase) - "rm -f -r -v /edocs/* && \ cp -f -r -v /backup-data/redcap-edocs/* /edocs && \ - find /redcap -mindepth 1 -name \"*\" -not \\( -name \"database.php\" \\) -prune -exec rm -r -f -v {} \\; && \ + rm -f -r -v /redcap/* && \ cp -f -r -v /backup-data/redcap-app/* /redcap" securityContext: From 2b5b9c35605bf6364f0bb57962f60b91e8152ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Thu, 11 Dec 2025 11:26:17 +0100 Subject: [PATCH 22/49] WIP : Testing redcap update to desired version mechanism after restore --- .../templates/cronjobs/restore-cronjob.yaml | 72 ++++++++++++++++++- .../redcap/templates/deployments/redcap.yaml | 2 - 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 4a43667..97db0ba 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -95,7 +95,6 @@ spec: - name: backup-data mountPath: /backup-data - containers: - name: db-restore image: "{{ .Values.restoreJob.database.image.repository }}:{{ .Values.restoreJob.database.image.tag }}" imagePullPolicy: {{ .Values.restoreJob.database.image.pullPolicy }} @@ -132,6 +131,62 @@ spec: - name: backup-data mountPath: /backup-data + + containers: + - name: redcap-update + image: "{{ .Values.restoreJob.redcap.image.repository }}:{{ .Values.restoreJob.redcap.image.tag }}" + imagePullPolicy: {{ .Values.restoreJob.redcap.image.pullPolicy }} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 2000 + runAsGroup: 2000 + + env: + - name: XDG_CONFIG_HOME + value: "/var/run/secrets" + - name : REDCAP_VERSION + value: {{ .Values.redcap.install.version }} + - name : REDCAP_INSTALL_PATH + value: "/app/redcap" + - name: REDCAP_COMMUNITY_USERNAME + valueFrom: + secretKeyRef: + name: {{ default (include "redcap.secrets.community.creds.name" .) .Values.redcap.install.communityAuth.existingSecret }} + key: USERNAME + - name: REDCAP_COMMUNITY_PASSWORD + valueFrom: + secretKeyRef: + name: {{ default (include "redcap.secrets.community.creds.name" .) .Values.redcap.install.communityAuth.existingSecret }} + key: PASSWORD + - name: DB_PASSWD + valueFrom: + secretKeyRef: + name: {{ default (include "mariadb.secrets.password.name" .) .Values.redcap.config.database.auth.password.secretKeyRef.name }} + key: {{ default (include "mariadb.secrets.password.key" .) .Values.redcap.config.database.auth.password.secretKeyRef.key }} + + command: + - | + sh -c /tmp/scripts/redcap-install.sh && \ + sh -c /tmp/scripts/redcap-setup.sh && \ + sh -c /tmp/scripts/redcap-config.sh + + volumeMounts: + - name: redcap-app + mountPath: /app/redcap + - name: database-conf + mountPath: /tmp/conf/database.php + subPath: database.php + - name: redcap-install-script + mountPath: /tmp/scripts/redcap-install.sh + subPath: redcap-install.sh + - name: redcap-setup-script + mountPath: /tmp/scripts/redcap-setup.sh + subPath: redcap-setup.sh + - name: redcap-config-script + mountPath: /tmp/scripts/redcap-config.sh + subPath: redcap-config.sh + volumes: - name: redcap-code persistentVolumeClaim: @@ -148,6 +203,21 @@ spec: - name: rclone-conf secret: secretName: {{ include "redcap.secrets.restore.rclone.conf.name" . }} + - name: database-conf + configMap: + name: {{ .Release.Name }}-database-conf + - name: init-install-script + configMap: + name: {{ .Release.Name }}-init-install-script + defaultMode: 0777 + - name: redcap-setup-script + configMap: + name: {{ .Release.Name }}-init-setup-script + defaultMode: 0777 + - name: redcap-config-script + configMap: + name: {{ .Release.Name }}-init-config-script + defaultMode: 0777 {{- with .Values.redcap.nodeSelector }} diff --git a/charts/redcap/templates/deployments/redcap.yaml b/charts/redcap/templates/deployments/redcap.yaml index 78103ce..f51c494 100644 --- a/charts/redcap/templates/deployments/redcap.yaml +++ b/charts/redcap/templates/deployments/redcap.yaml @@ -50,8 +50,6 @@ spec: env: - name : REDCAP_INSTALL_PATH value: "/app/redcap" - - name : OVERRIDE_INSTALL - value: {{ .Values.redcap.install.override | toString | quote }} - name : REDCAP_VERSION value: {{ .Values.redcap.install.version }} - name: REDCAP_COMMUNITY_USERNAME From 2c5c89a85e80341ad2a05585390d5caa44c3fb80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Thu, 11 Dec 2025 11:45:23 +0100 Subject: [PATCH 23/49] Updated scalar bloc indicator --- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 97db0ba..b268ff7 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -166,9 +166,9 @@ spec: key: {{ default (include "mariadb.secrets.password.key" .) .Values.redcap.config.database.auth.password.secretKeyRef.key }} command: - - | - sh -c /tmp/scripts/redcap-install.sh && \ - sh -c /tmp/scripts/redcap-setup.sh && \ + - >- + sh -c /tmp/scripts/redcap-install.sh + sh -c /tmp/scripts/redcap-setup.sh sh -c /tmp/scripts/redcap-config.sh volumeMounts: From ee0cac2e6e0e115208b1f4bddf4f95b7a3734bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Thu, 11 Dec 2025 12:49:32 +0100 Subject: [PATCH 24/49] Fixed command separator for restore scripts --- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index b268ff7..d15dc0c 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -167,9 +167,9 @@ spec: command: - >- - sh -c /tmp/scripts/redcap-install.sh - sh -c /tmp/scripts/redcap-setup.sh - sh -c /tmp/scripts/redcap-config.sh + sh -c /tmp/scripts/redcap-install.sh && + sh -c /tmp/scripts/redcap-setup.sh && + sh -c /tmp/scripts/redcap-config.sh && volumeMounts: - name: redcap-app From d9d1b81b070b5cbf7e3896c6e2fc96ff457cc794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Thu, 11 Dec 2025 12:49:52 +0100 Subject: [PATCH 25/49] Removed uneeded separator --- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index d15dc0c..1cbf204 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -169,7 +169,7 @@ spec: - >- sh -c /tmp/scripts/redcap-install.sh && sh -c /tmp/scripts/redcap-setup.sh && - sh -c /tmp/scripts/redcap-config.sh && + sh -c /tmp/scripts/redcap-config.sh volumeMounts: - name: redcap-app From 66a29d72c91504a670191f9febaa9393aceb95b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Thu, 11 Dec 2025 13:53:01 +0100 Subject: [PATCH 26/49] Try to fix init script mounting point --- .../templates/cronjobs/restore-cronjob.yaml | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 1cbf204..a2e92db 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -171,21 +171,21 @@ spec: sh -c /tmp/scripts/redcap-setup.sh && sh -c /tmp/scripts/redcap-config.sh - volumeMounts: - - name: redcap-app - mountPath: /app/redcap - - name: database-conf - mountPath: /tmp/conf/database.php - subPath: database.php - - name: redcap-install-script - mountPath: /tmp/scripts/redcap-install.sh - subPath: redcap-install.sh - - name: redcap-setup-script - mountPath: /tmp/scripts/redcap-setup.sh - subPath: redcap-setup.sh - - name: redcap-config-script - mountPath: /tmp/scripts/redcap-config.sh - subPath: redcap-config.sh + volumeMounts: + - name: redcap-app + mountPath: /app/redcap + - name: database-conf + mountPath: /tmp/conf/database.php + subPath: database.php + - name: redcap-install-script + mountPath: /tmp/scripts/redcap-install.sh + subPath: redcap-install.sh + - name: redcap-setup-script + mountPath: /tmp/scripts/redcap-setup.sh + subPath: redcap-setup.sh + - name: redcap-config-script + mountPath: /tmp/scripts/redcap-config.sh + subPath: redcap-config.sh volumes: - name: redcap-code From 4ad5939c3e8d6724f3eb9ecb41f4cff04b75cc69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Thu, 11 Dec 2025 14:16:49 +0100 Subject: [PATCH 27/49] Fixed bad volume naming --- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index a2e92db..7f73981 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -188,7 +188,7 @@ spec: subPath: redcap-config.sh volumes: - - name: redcap-code + - name: redcap-app persistentVolumeClaim: claimName: {{ .Release.Name }}-app-pvc - name: edocs @@ -206,7 +206,7 @@ spec: - name: database-conf configMap: name: {{ .Release.Name }}-database-conf - - name: init-install-script + - name: redcap-install-script configMap: name: {{ .Release.Name }}-init-install-script defaultMode: 0777 From 332f488639dc33d64d0b94b0ee90a37d523e7dce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Thu, 11 Dec 2025 14:29:06 +0100 Subject: [PATCH 28/49] Fixed bad pvc ref --- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 7f73981..ca68fbd 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -90,7 +90,7 @@ spec: volumeMounts: - name: edocs mountPath: /edocs - - name: redcap-code + - name: redcap-app mountPath: /redcap - name: backup-data mountPath: /backup-data From 91c408945675601126ee5e9358d44ddfde15dd4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Thu, 11 Dec 2025 14:45:41 +0100 Subject: [PATCH 29/49] Fixed scripts call --- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index ca68fbd..0419f09 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -166,10 +166,12 @@ spec: key: {{ default (include "mariadb.secrets.password.key" .) .Values.redcap.config.database.auth.password.secretKeyRef.key }} command: - - >- - sh -c /tmp/scripts/redcap-install.sh && - sh -c /tmp/scripts/redcap-setup.sh && - sh -c /tmp/scripts/redcap-config.sh + - sh + - -c + - > + /tmp/scripts/redcap-install.sh && + /tmp/scripts/redcap-setup.sh && + /tmp/scripts/redcap-config.sh volumeMounts: - name: redcap-app From 8446ae93bd15d01f2c4f4ca407b12294844b2ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Thu, 11 Dec 2025 15:05:39 +0100 Subject: [PATCH 30/49] Added custom redcap app rzstore image (curl) and updated docs --- charts/redcap/README.md | 9 ++- .../templates/cronjobs/restore-cronjob.yaml | 6 +- charts/redcap/values.yaml | 75 +++++++++++-------- 3 files changed, 53 insertions(+), 37 deletions(-) diff --git a/charts/redcap/README.md b/charts/redcap/README.md index b490237..56708ad 100644 --- a/charts/redcap/README.md +++ b/charts/redcap/README.md @@ -168,9 +168,6 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | restoreJob.imagePullSecrets | list | `[]` | ImagePullSecret used to pull the images for the restore pod's containers | | restoreJob.schedule | string | `"0 0 1 1 *"` | Schedule for the restore Cronjob. CronJob resources needs a valid schedule, but this one will never be used since it will always be suspended (see spec.suspend field). | | restoreJob.archiveName | string | `"redcap-backup.tar.gz"` | Name of the backup archive to restore. | -| restoreJob.redcap.image.repository | string | `"busybox"` | Image repository for the REDCap application restore container. | -| restoreJob.redcap.image.tag | string | `"1"` | Image tag for the REDCap application restore container. | -| restoreJob.redcap.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap application restore container. | | restoreJob.downloader.image.repository | string | `"rclone/rclone"` | Image repository for the REDCap downloader container. | | restoreJob.downloader.image.tag | string | `"drime"` | Image tag for the REDCap downloader container. | | restoreJob.downloader.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap downloader container. | @@ -181,6 +178,12 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | restoreJob.downloader.s3.config.auth.accessKeyID | string | `""` | AccessKeyID needed for authentication on the S3 bucket. | | restoreJob.downloader.s3.config.auth.secretAccessKey | string | `""` | SecretAccessKey needed for authentication on the S3 bucket. | | restoreJob.downloader.s3.config.auth.existingSecret | string | `""` | Reference to an existing secret holding the AccessKeyID and SecretAccessKey needed for authentication on the S3 bucket. If set, overrides the AccessKeyID and SecretAccessKey values. | +| restoreJob.file.image.repository | string | `"busybox"` | Image repository for the REDCap application restore container. | +| restoreJob.file.image.tag | string | `"1"` | Image tag for the REDCap files application container. | +| restoreJob.file.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap application restore container. | +| restoreJob.redcap.image.repository | string | `"alpine/curl"` | Image repository for the REDCap application restore container. | +| restoreJob.redcap.image.tag | string | `"8.12.1"` | Image tag for the REDCap application restore container. | +| restoreJob.redcap.image.pullPolicy | string | `"Always"` | Image pullPolicy for the REDCap application restore container. | | restoreJob.resources | object | `{}` | Resources for backup job's pod. | ### REDCap Audit Log Shipper settings diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 0419f09..87f6cef 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -73,8 +73,8 @@ spec: subPath: backup-download.sh - name: files-restore - image: "{{ .Values.restoreJob.redcap.image.repository }}:{{ .Values.restoreJob.redcap.image.tag }}" - imagePullPolicy: {{ .Values.restoreJob.redcap.image.pullPolicy }} + image: "{{ .Values.restoreJob.files.image.repository }}:{{ .Values.restoreJob.files.image.tag }}" + imagePullPolicy: {{ .Values.restoreJob.files.image.pullPolicy }} command: - "sh" - "-c" @@ -133,7 +133,7 @@ spec: containers: - - name: redcap-update + - name: redcap-restore image: "{{ .Values.restoreJob.redcap.image.repository }}:{{ .Values.restoreJob.redcap.image.tag }}" imagePullPolicy: {{ .Values.restoreJob.redcap.image.pullPolicy }} securityContext: diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index ffb4a23..6e64093 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -448,37 +448,6 @@ restoreJob: # -- Name of the backup archive to restore. # @section -- REDCap Restore Job's settings archiveName: "redcap-backup.tar.gz" - redcap: - image: - # -- Image repository for the REDCap application restore container. - # @section -- REDCap Restore Job's settings - repository: "busybox" - # -- Image tag for the REDCap application restore container. - # @section -- REDCap Restore Job's settings - tag: "1" - # -- Image pullPolicy for the REDCap application restore container. - # @section -- REDCap Restore Job's settings - pullPolicy: "Always" - - database: - image: - # # -- Image repository for the REDCap database restore container. - # # @section -- REDCap Restore Job's settings - # repository: "bitnamilegacy/MariaDB" - # # -- Image yag for the REDCap application restore container. - # # @section -- REDCap Restore Job's settings - # tag: "9.3.0-debian-12-r1" - # # -- Image pullPolicy for the REDCap application restore container. - # # @section -- REDCap Restore Job's settings - # pullPolicy: "Always" - ## @param image.registry MariaDB image registry - registry: docker.io - ## @param image.repository MariaDB image repository - repository: mariadb - ## @param image.tag MariaDB image tag (immutable tags are recommended) - tag: "12.1.2@sha256:e1bcd6f85781f4a875abefb11c4166c1d79e4237c23de597bf0df81fec225b40" - ## @param image.pullPolicy MariaDB image pull policy - imagePullPolicy: Always downloader: image: @@ -519,6 +488,50 @@ restoreJob: # @section -- REDCap Restore Job's settings existingSecret: "" + file: + image: + # -- Image repository for the REDCap application restore container. + # @section -- REDCap Restore Job's settings + repository: "busybox" + # -- Image tag for the REDCap files application container. + # @section -- REDCap Restore Job's settings + tag: "1" + # -- Image pullPolicy for the REDCap application restore container. + # @section -- REDCap Restore Job's settings + pullPolicy: "Always" + + database: + image: + # # -- Image repository for the REDCap database restore container. + # # @section -- REDCap Restore Job's settings + # repository: "bitnamilegacy/MariaDB" + # # -- Image yag for the REDCap application restore container. + # # @section -- REDCap Restore Job's settings + # tag: "9.3.0-debian-12-r1" + # # -- Image pullPolicy for the REDCap application restore container. + # # @section -- REDCap Restore Job's settings + # pullPolicy: "Always" + ## @param image.registry MariaDB image registry + registry: docker.io + ## @param image.repository MariaDB image repository + repository: mariadb + ## @param image.tag MariaDB image tag (immutable tags are recommended) + tag: "12.1.2@sha256:e1bcd6f85781f4a875abefb11c4166c1d79e4237c23de597bf0df81fec225b40" + ## @param image.pullPolicy MariaDB image pull policy + imagePullPolicy: Always + + redcap: + image: + # -- Image repository for the REDCap application restore container. + # @section -- REDCap Restore Job's settings + repository: "alpine/curl" + # -- Image tag for the REDCap application restore container. + # @section -- REDCap Restore Job's settings + tag: "8.12.1" + # -- Image pullPolicy for the REDCap application restore container. + # @section -- REDCap Restore Job's settings + pullPolicy: "Always" + # -- Resources for backup job's pod. # @section -- REDCap Restore Job's settings resources: {} From 126e33ae01c816d3253270a25642583f11a80796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Thu, 11 Dec 2025 15:07:09 +0100 Subject: [PATCH 31/49] Updated schema --- charts/redcap/values.schema.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/charts/redcap/values.schema.json b/charts/redcap/values.schema.json index 14e87aa..7b13b57 100644 --- a/charts/redcap/values.schema.json +++ b/charts/redcap/values.schema.json @@ -1021,6 +1021,25 @@ "enabled": { "type": "boolean" }, + "file": { + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + } + } + }, "imagePullSecrets": { "type": "array" }, From 4595dde66b2dcffe57f8339a4ffb05d535cb6027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20ZGRZENDEK?= Date: Thu, 11 Dec 2025 15:12:29 +0100 Subject: [PATCH 32/49] Fixed typo --- charts/redcap/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index 6e64093..3e6c07d 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -488,7 +488,7 @@ restoreJob: # @section -- REDCap Restore Job's settings existingSecret: "" - file: + files: image: # -- Image repository for the REDCap application restore container. # @section -- REDCap Restore Job's settings From 7624d20815a1d43aaba9dc351721866daa52757e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Fri, 12 Dec 2025 10:51:34 +0100 Subject: [PATCH 33/49] Added ephemeral volume for Redcap restore service --- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 87f6cef..7f50826 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -174,6 +174,8 @@ spec: /tmp/scripts/redcap-config.sh volumeMounts: + - name: redcap-archive-cache + mountPath: /tmp/redcap - name: redcap-app mountPath: /app/redcap - name: database-conf @@ -190,6 +192,9 @@ spec: subPath: redcap-config.sh volumes: + - name: redcap-archive-cache + emptyDir: + sizeLimit: 500Mi - name: redcap-app persistentVolumeClaim: claimName: {{ .Release.Name }}-app-pvc From 56414e5b34f0e0bd21ecdedaa03f3fad5a62d799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Fri, 12 Dec 2025 14:27:06 +0100 Subject: [PATCH 34/49] Updated redcap image for restore backup job --- charts/redcap/values.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index 3e6c07d..f19f379 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -524,10 +524,10 @@ restoreJob: image: # -- Image repository for the REDCap application restore container. # @section -- REDCap Restore Job's settings - repository: "alpine/curl" + repository: "ghcr.io/aphp/redcap-httpd-shibd" # -- Image tag for the REDCap application restore container. # @section -- REDCap Restore Job's settings - tag: "8.12.1" + tag: "1.2.0" # -- Image pullPolicy for the REDCap application restore container. # @section -- REDCap Restore Job's settings pullPolicy: "Always" From d45feba9e8a010e479e703689dccb82e888ae036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Fri, 12 Dec 2025 15:48:38 +0100 Subject: [PATCH 35/49] WIP Add extra init container --- .../templates/cronjobs/restore-cronjob.yaml | 45 ++++++++++++++++++- charts/redcap/values.yaml | 4 +- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 7f50826..135adf7 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -130,11 +130,53 @@ spec: volumeMounts: - name: backup-data mountPath: /backup-data + + - name: init-download-redcap + image: "{{ .Values.restoreJob.redcap.image.repository }}:{{ .Values.restoreJob.redcap.image.tag }}" + imagePullPolicy: {{ .Values.redcap.install.image.pullPolicy }} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 2000 + runAsGroup: 2000 + + env: + - name : REDCAP_INSTALL_PATH + value: "/app/redcap" + - name : REDCAP_VERSION + value: {{ .Values.redcap.install.version }} + - name: REDCAP_COMMUNITY_USERNAME + valueFrom: + secretKeyRef: + name: {{ default (include "redcap.secrets.community.creds.name" .) .Values.redcap.install.communityAuth.existingSecret }} + key: USERNAME + - name: REDCAP_COMMUNITY_PASSWORD + valueFrom: + secretKeyRef: + name: {{ default (include "redcap.secrets.community.creds.name" .) .Values.redcap.install.communityAuth.existingSecret }} + key: PASSWORD + + command: + - "sh" + - "-c" + - "/home/curl_user/redcap-install.sh" + + volumeMounts: + - name: redcap-archive-cache + mountPath: /tmp/redcap + - name: redcap-app + mountPath: /app/redcap + - name: database-conf + mountPath: /tmp/conf/database.php + subPath: database.php + - name: redcap-install-script + mountPath: /home/curl_user/redcap-install.sh + subPath: redcap-install.sh containers: - name: redcap-restore - image: "{{ .Values.restoreJob.redcap.image.repository }}:{{ .Values.restoreJob.redcap.image.tag }}" + image: "{{ .Values.redcap.image.repository }}:{{ .Values.redcap.image.tag }}" imagePullPolicy: {{ .Values.restoreJob.redcap.image.pullPolicy }} securityContext: allowPrivilegeEscalation: false @@ -169,7 +211,6 @@ spec: - sh - -c - > - /tmp/scripts/redcap-install.sh && /tmp/scripts/redcap-setup.sh && /tmp/scripts/redcap-config.sh diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index f19f379..3e6c07d 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -524,10 +524,10 @@ restoreJob: image: # -- Image repository for the REDCap application restore container. # @section -- REDCap Restore Job's settings - repository: "ghcr.io/aphp/redcap-httpd-shibd" + repository: "alpine/curl" # -- Image tag for the REDCap application restore container. # @section -- REDCap Restore Job's settings - tag: "1.2.0" + tag: "8.12.1" # -- Image pullPolicy for the REDCap application restore container. # @section -- REDCap Restore Job's settings pullPolicy: "Always" From 18b1139b500ce9e02bd6a5bc947c4b54ce9f82ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Fri, 12 Dec 2025 16:07:08 +0100 Subject: [PATCH 36/49] Remove setup and config script in backup restore job --- .../templates/cronjobs/restore-cronjob.yaml | 59 +++---------------- 1 file changed, 8 insertions(+), 51 deletions(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 135adf7..41326ce 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -130,53 +130,11 @@ spec: volumeMounts: - name: backup-data mountPath: /backup-data - - - name: init-download-redcap - image: "{{ .Values.restoreJob.redcap.image.repository }}:{{ .Values.restoreJob.redcap.image.tag }}" - imagePullPolicy: {{ .Values.redcap.install.image.pullPolicy }} - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsUser: 2000 - runAsGroup: 2000 - - env: - - name : REDCAP_INSTALL_PATH - value: "/app/redcap" - - name : REDCAP_VERSION - value: {{ .Values.redcap.install.version }} - - name: REDCAP_COMMUNITY_USERNAME - valueFrom: - secretKeyRef: - name: {{ default (include "redcap.secrets.community.creds.name" .) .Values.redcap.install.communityAuth.existingSecret }} - key: USERNAME - - name: REDCAP_COMMUNITY_PASSWORD - valueFrom: - secretKeyRef: - name: {{ default (include "redcap.secrets.community.creds.name" .) .Values.redcap.install.communityAuth.existingSecret }} - key: PASSWORD - - command: - - "sh" - - "-c" - - "/home/curl_user/redcap-install.sh" - - volumeMounts: - - name: redcap-archive-cache - mountPath: /tmp/redcap - - name: redcap-app - mountPath: /app/redcap - - name: database-conf - mountPath: /tmp/conf/database.php - subPath: database.php - - name: redcap-install-script - mountPath: /home/curl_user/redcap-install.sh - subPath: redcap-install.sh containers: - name: redcap-restore - image: "{{ .Values.redcap.image.repository }}:{{ .Values.redcap.image.tag }}" + image: "{{ .Values.restoreJob.redcap.image.repository }}:{{ .Values.restoreJob.redcap.image.tag }}" imagePullPolicy: {{ .Values.restoreJob.redcap.image.pullPolicy }} securityContext: allowPrivilegeEscalation: false @@ -211,8 +169,7 @@ spec: - sh - -c - > - /tmp/scripts/redcap-setup.sh && - /tmp/scripts/redcap-config.sh + /tmp/scripts/redcap-install.sh && volumeMounts: - name: redcap-archive-cache @@ -225,12 +182,12 @@ spec: - name: redcap-install-script mountPath: /tmp/scripts/redcap-install.sh subPath: redcap-install.sh - - name: redcap-setup-script - mountPath: /tmp/scripts/redcap-setup.sh - subPath: redcap-setup.sh - - name: redcap-config-script - mountPath: /tmp/scripts/redcap-config.sh - subPath: redcap-config.sh + # - name: redcap-setup-script + # mountPath: /tmp/scripts/redcap-setup.sh + # subPath: redcap-setup.sh + # - name: redcap-config-script + # mountPath: /tmp/scripts/redcap-config.sh + # subPath: redcap-config.sh volumes: - name: redcap-archive-cache From 499fe3661562a4eafaf0e5e0a173932bfe173045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Mon, 15 Dec 2025 14:59:09 +0100 Subject: [PATCH 37/49] Clean PVC --- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 41326ce..3817a2c 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -182,12 +182,6 @@ spec: - name: redcap-install-script mountPath: /tmp/scripts/redcap-install.sh subPath: redcap-install.sh - # - name: redcap-setup-script - # mountPath: /tmp/scripts/redcap-setup.sh - # subPath: redcap-setup.sh - # - name: redcap-config-script - # mountPath: /tmp/scripts/redcap-config.sh - # subPath: redcap-config.sh volumes: - name: redcap-archive-cache From 23cba36437cfb5762d0bc7be8bedec0439fa4624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Mon, 15 Dec 2025 15:28:23 +0100 Subject: [PATCH 38/49] Add setup script in restore backup job --- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 3817a2c..00c3e44 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -170,6 +170,7 @@ spec: - -c - > /tmp/scripts/redcap-install.sh && + /tmp/scripts/redcap-setup.sh volumeMounts: - name: redcap-archive-cache @@ -182,6 +183,9 @@ spec: - name: redcap-install-script mountPath: /tmp/scripts/redcap-install.sh subPath: redcap-install.sh + - name: redcap-setup-script + mountPath: /tmp/scripts/redcap-setup.sh + subPath: redcap-setup.sh volumes: - name: redcap-archive-cache From 53a42c0c1c2a52d6053aca5cdf00207476a5aa59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Wed, 17 Dec 2025 16:25:11 +0100 Subject: [PATCH 39/49] Check if database.php is present even if Redcap is already installed --- charts/redcap/configuration/redcap/init/redcap-install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/charts/redcap/configuration/redcap/init/redcap-install.sh b/charts/redcap/configuration/redcap/init/redcap-install.sh index ccdd8ed..cfe6082 100644 --- a/charts/redcap/configuration/redcap/init/redcap-install.sh +++ b/charts/redcap/configuration/redcap/init/redcap-install.sh @@ -58,7 +58,6 @@ update_database_config () { echo "[INFO] Injecting REDCap database configuration" cp -f /tmp/conf/database.php "${REDCAP_INSTALL_PATH}/database.php" - echo "[INFO] REDCap Database configuration updated!" } @@ -80,6 +79,11 @@ if [ -n "$(find "$REDCAP_INSTALL_PATH" -mindepth 1 -maxdepth 1 -not -path "$RED if [ "$REDCAP_VERSION_SANITIZED" -eq "$REDCAP_CURRENT_VERSION_SANITIZED" ]; then echo "[INFO] REDCap version ${REDCAP_VERSION} files are already present in ${REDCAP_INSTALL_PATH}. Skipping installation process." + if [ -f "${APP_INSTALL_PATH}/database.php" ]; then + echo "database.php founded" + else + update_database_config + fi exit 0 elif [ "$REDCAP_VERSION_SANITIZED" -gt "$REDCAP_CURRENT_VERSION_SANITIZED" ]; then From 191213d6d1c1228d2186373361f6444a97737cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Thu, 18 Dec 2025 11:15:51 +0100 Subject: [PATCH 40/49] Remove redcap-setup script from restore cron-job --- charts/redcap/templates/cronjobs/restore-cronjob.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/charts/redcap/templates/cronjobs/restore-cronjob.yaml b/charts/redcap/templates/cronjobs/restore-cronjob.yaml index 00c3e44..3e377c2 100644 --- a/charts/redcap/templates/cronjobs/restore-cronjob.yaml +++ b/charts/redcap/templates/cronjobs/restore-cronjob.yaml @@ -169,8 +169,7 @@ spec: - sh - -c - > - /tmp/scripts/redcap-install.sh && - /tmp/scripts/redcap-setup.sh + /tmp/scripts/redcap-install.sh volumeMounts: - name: redcap-archive-cache @@ -183,9 +182,9 @@ spec: - name: redcap-install-script mountPath: /tmp/scripts/redcap-install.sh subPath: redcap-install.sh - - name: redcap-setup-script - mountPath: /tmp/scripts/redcap-setup.sh - subPath: redcap-setup.sh + # - name: redcap-setup-script + # mountPath: /tmp/scripts/redcap-setup.sh + # subPath: redcap-setup.sh volumes: - name: redcap-archive-cache From ad8d4d4e29e12406e20ee169341bab5e01971a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Tue, 6 Jan 2026 09:45:08 +0100 Subject: [PATCH 41/49] Try new MariaDB config --- charts/redcap/configuration/mysql/my.cnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/redcap/configuration/mysql/my.cnf b/charts/redcap/configuration/mysql/my.cnf index 582f3fc..7d742af 100644 --- a/charts/redcap/configuration/mysql/my.cnf +++ b/charts/redcap/configuration/mysql/my.cnf @@ -1,4 +1,4 @@ -# [mariadbd] +[mariadbd] # skip_name_resolve # explicit_defaults_for_timestamp # basedir=/opt/bitnami/mariadb From b751ca868604a05275ae03a31edaada779a2104e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Tue, 6 Jan 2026 11:02:58 +0100 Subject: [PATCH 42/49] Add Redcap settings for MariaDB --- charts/redcap/configuration/mysql/my.cnf | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/charts/redcap/configuration/mysql/my.cnf b/charts/redcap/configuration/mysql/my.cnf index 7d742af..84182ce 100644 --- a/charts/redcap/configuration/mysql/my.cnf +++ b/charts/redcap/configuration/mysql/my.cnf @@ -15,8 +15,16 @@ # plugin_dir=/opt/bitnami/mariadb/lib/plugin # datadir=/bitnami/mariadb/data -# REDCap recommendations + +# REDCap recommendations : Maximum paquet size during communication with client (client must have the same value) max_allowed_packet=1G +# REDCap recommendations : Optimize some querrys with index: https://mariadb.com/docs/server/ha-and-performance/optimization-and-tuning/query-optimizations/rowid-filtering-optimization +optimizer_switch='rowid_filter=off' +# REDCap recommendations : Store result of select command. +query_cache_size=16777216 +# REDCap recommendations : Enabling cache type : https://mariadb.com/docs/server/server-management/variables-and-modes/server-system-variables#query_cache_type +query_cache_type=1 + sort_buffer_size=1M read-rnd-buffer-size=1M From 878cb6f72ce08b164e9301a349b69d85c8fda1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Thu, 8 Jan 2026 11:59:29 +0100 Subject: [PATCH 43/49] Fix path in MariaDB configmap --- charts/redcap/templates/configmaps/mysql/mysql-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/redcap/templates/configmaps/mysql/mysql-config.yaml b/charts/redcap/templates/configmaps/mysql/mysql-config.yaml index 09b641e..5a74611 100644 --- a/charts/redcap/templates/configmaps/mysql/mysql-config.yaml +++ b/charts/redcap/templates/configmaps/mysql/mysql-config.yaml @@ -3,4 +3,4 @@ kind: ConfigMap metadata: name: {{ .Values.mariadb.config.existingConfigmap }} data: -{{ tpl (.Files.Glob "configuration/mariadb/my.cnf").AsConfig . | nindent 2 }} \ No newline at end of file +{{ tpl (.Files.Glob "configuration/mysql/my.cnf").AsConfig . | nindent 2 }} \ No newline at end of file From 925667c90aa78636af06be73e0894ed69c149868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Mon, 19 Jan 2026 17:33:38 +0100 Subject: [PATCH 44/49] Fix my.cnf in config map --- charts/redcap/configuration/mysql/my.cnf | 1 + charts/redcap/values.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/charts/redcap/configuration/mysql/my.cnf b/charts/redcap/configuration/mysql/my.cnf index 84182ce..aee1cb0 100644 --- a/charts/redcap/configuration/mysql/my.cnf +++ b/charts/redcap/configuration/mysql/my.cnf @@ -24,6 +24,7 @@ optimizer_switch='rowid_filter=off' query_cache_size=16777216 # REDCap recommendations : Enabling cache type : https://mariadb.com/docs/server/server-management/variables-and-modes/server-system-variables#query_cache_type query_cache_type=1 +query_cache_limit=16777216 sort_buffer_size=1M read-rnd-buffer-size=1M diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index 3e6c07d..4fe1909 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -316,7 +316,7 @@ mariadb: config: # -- Name of existing ConfigMap with MariaDB Primary configuration. # @section -- REDCap MariaDB Database settings - existingConfigmap: "redcap-database-config" + existingConfigMap: "redcap-database-config" podLabels: From 4e5845ff84e2470229c090542e41193cb0c2c25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Tue, 20 Jan 2026 11:07:43 +0100 Subject: [PATCH 45/49] Fix typo on existingConfigMap --- charts/redcap/README.md | 2 +- charts/redcap/templates/configmaps/mysql/mysql-config.yaml | 2 +- charts/redcap/tests/values.yaml | 2 +- charts/redcap/values.schema.json | 2 +- examples/production/values.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/charts/redcap/README.md b/charts/redcap/README.md index 56708ad..92883f5 100644 --- a/charts/redcap/README.md +++ b/charts/redcap/README.md @@ -130,7 +130,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | mariadb.auth.database | string | `"redcap"` | Name of the database automatically created at the first run, if `MariaDB.auth.createDatabase` has been set to `true` | | mariadb.auth.username | string | `"redcap"` | Name of the database user automatically created at the first run, if `MariaDB.auth.createDatabase` has been set to `true` | | mariadb.auth.password | string | `"Redcap*!"` | Name of the database user automatically created at the first run, if `MariaDB.auth.createDatabase` has been set to `true` Not secure in production, use secret reference instead! | -| mariadb.config.existingConfigmap | string | `"redcap-database-config"` | Name of existing ConfigMap with MariaDB Primary configuration. | +| mariadb.config.existingConfigMap | string | `"redcap-database-config"` | Name of existing ConfigMap with MariaDB Primary configuration. | | mariadb.podLabels."app.kubernetes.io/role" | string | `"redcap-mariadb"` | Role to set for the networkPolicies. Not to be changed, unless you know exactly what you are doing! | | mariadb.service.port | int | `3306` | Port exposed by the MariaDB service. | | mariadb.persistence.storageClass | string | `"standard"` | StorageClass used for database persistence. | diff --git a/charts/redcap/templates/configmaps/mysql/mysql-config.yaml b/charts/redcap/templates/configmaps/mysql/mysql-config.yaml index 5a74611..1fb5ae3 100644 --- a/charts/redcap/templates/configmaps/mysql/mysql-config.yaml +++ b/charts/redcap/templates/configmaps/mysql/mysql-config.yaml @@ -1,6 +1,6 @@ apiVersion: v1 kind: ConfigMap metadata: - name: {{ .Values.mariadb.config.existingConfigmap }} + name: {{ .Values.mariadb.config.existingConfigMap }} data: {{ tpl (.Files.Glob "configuration/mysql/my.cnf").AsConfig . | nindent 2 }} \ No newline at end of file diff --git a/charts/redcap/tests/values.yaml b/charts/redcap/tests/values.yaml index 5d7d79a..43750d2 100644 --- a/charts/redcap/tests/values.yaml +++ b/charts/redcap/tests/values.yaml @@ -73,7 +73,7 @@ redcap: mariadb: enabled: true primary: - existingConfigmap: "redcap-ext-qual-database-config" + existingConfigMap: "redcap-ext-qual-database-config" persistence: annotations: helm.sh/resource-policy: keep diff --git a/charts/redcap/values.schema.json b/charts/redcap/values.schema.json index 7b13b57..503e206 100644 --- a/charts/redcap/values.schema.json +++ b/charts/redcap/values.schema.json @@ -533,7 +533,7 @@ "config": { "type": "object", "properties": { - "existingConfigmap": { + "existingConfigMap": { "type": "string" } } diff --git a/examples/production/values.yaml b/examples/production/values.yaml index 33f5eea..700a8e2 100644 --- a/examples/production/values.yaml +++ b/examples/production/values.yaml @@ -78,7 +78,7 @@ mariadb: username: redcap existingSecret: "redcap-prod-mariadb-passwd" primary: - existingConfigmap: "redcap-prod-database-config" + existingConfigMap: "redcap-prod-database-config" persistence: annotations: helm.sh/resource-policy: keep From 0c4fcb84044ae81ff64f9c8356a16f5d93f8d78c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Thu, 22 Jan 2026 10:26:52 +0100 Subject: [PATCH 46/49] Update doc --- NOTICE | 2 +- charts/redcap/configuration/mysql/my.cnf | 29 ------------- .../redcap/init/redcap-install.sh | 2 +- charts/redcap/values.schema.json | 2 +- charts/redcap/values.yaml | 42 +++++++------------ 5 files changed, 18 insertions(+), 59 deletions(-) diff --git a/NOTICE b/NOTICE index d640cd4..15a35de 100644 --- a/NOTICE +++ b/NOTICE @@ -1,7 +1,7 @@ This software contains the following dependencies developed by Broadcom : - Helm Charts: - - mariadb : https://github.com/bitnami/charts/tree/main/bitnami/mariadb + - mariadb : https://github.com/CloudPirates-io/helm-charts/tree/main/charts/mariadb - logstash : https://github.com/bitnami/charts/tree/main/bitnami/logstash Those dependencies are present in the "bitnami/charts" github repository provided by Broadcom under the Apache 2.0 license, diff --git a/charts/redcap/configuration/mysql/my.cnf b/charts/redcap/configuration/mysql/my.cnf index aee1cb0..23955de 100644 --- a/charts/redcap/configuration/mysql/my.cnf +++ b/charts/redcap/configuration/mysql/my.cnf @@ -1,20 +1,4 @@ [mariadbd] -# skip_name_resolve -# explicit_defaults_for_timestamp -# basedir=/opt/bitnami/mariadb -# port=3306 -# tmpdir=/opt/bitnami/mariadb/tmp -# socket=/opt/bitnami/mariadb/tmp/mariadb.sock -# pid_file=/opt/bitnami/mariadb/tmp/mariadbd.pid -# max_allowed_packet=16M -# bind_address=0.0.0.0 -# log_error=/opt/bitnami/mariadb/logs/mariadbd.log -# slow_query_log=0 -# long_query_time=10.0 -# character_set_server=utf8mb4 -# plugin_dir=/opt/bitnami/mariadb/lib/plugin -# datadir=/bitnami/mariadb/data - # REDCap recommendations : Maximum paquet size during communication with client (client must have the same value) max_allowed_packet=1G @@ -36,16 +20,3 @@ max_connections=400 innodb_flush_log_at_trx_commit=1 sync_binlog=0 - -#[client] -#port=3306 -#socket=/opt/bitnami/mariadb/tmp/mariadb.sock -#default_character_set=utf8mb4 -#plugin_dir=/opt/bitnami/mariadb/lib/plugin -# -# -#[manager] -#port=3306 -#socket=/opt/bitnami/mariadb/tmp/mariadb.sock -#pid_file=/opt/bitnami/mariadb/tmp/mariadbd.pid -# \ No newline at end of file diff --git a/charts/redcap/configuration/redcap/init/redcap-install.sh b/charts/redcap/configuration/redcap/init/redcap-install.sh index cfe6082..1910300 100644 --- a/charts/redcap/configuration/redcap/init/redcap-install.sh +++ b/charts/redcap/configuration/redcap/init/redcap-install.sh @@ -80,7 +80,7 @@ if [ -n "$(find "$REDCAP_INSTALL_PATH" -mindepth 1 -maxdepth 1 -not -path "$RED if [ "$REDCAP_VERSION_SANITIZED" -eq "$REDCAP_CURRENT_VERSION_SANITIZED" ]; then echo "[INFO] REDCap version ${REDCAP_VERSION} files are already present in ${REDCAP_INSTALL_PATH}. Skipping installation process." if [ -f "${APP_INSTALL_PATH}/database.php" ]; then - echo "database.php founded" + echo "[INFO] database.php founded" else update_database_config fi diff --git a/charts/redcap/values.schema.json b/charts/redcap/values.schema.json index 503e206..d164a6b 100644 --- a/charts/redcap/values.schema.json +++ b/charts/redcap/values.schema.json @@ -1021,7 +1021,7 @@ "enabled": { "type": "boolean" }, - "file": { + "files": { "type": "object", "properties": { "image": { diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index 4fe1909..94cbcb3 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -263,21 +263,19 @@ redcap: # REDCap MariaDB Database settings # @default -- Settings for a standalone MariaDB deployment compatible with REDCap. -# See original documentation @ https://github.com/bitnami/charts/tree/main/bitnami/MariaDB +# See original documentation @ https://github.com/CloudPirates-io/helm-charts/tree/main/charts/mariadb # @section -- REDCap MariaDB Database settings mariadb: image: - # # -- Image repository for MariaDB image. - # # @section -- REDCap MariaDB Database settings - # repository: bitnamilegacy/MariaDB - # # -- Image tag for MariaDB image. - # # @section -- REDCap MariaDB Database settings - # tag: 9.4.0-debian-12-r1 - ## @param image.registry MariaDB image registry + # -- Image repository for MariaDB image. + # @section -- REDCap MariaDB Database settings + ## @param image.registry MariaDB image registry registry: docker.io ## @param image.repository MariaDB image repository repository: mariadb + # -- Image tag for MariaDB image. + # @section -- REDCap MariaDB Database settings ## @param image.tag MariaDB image tag (immutable tags are recommended) tag: "12.1.2@sha256:e1bcd6f85781f4a875abefb11c4166c1d79e4237c23de597bf0df81fec225b40" ## @param image.pullPolicy MariaDB image pull policy @@ -371,19 +369,14 @@ backupJob: database: image: - # # -- Image repository for the REDCap database backup container. - # # @section -- REDCap Backup Job's settings - # repository: "bitnamilegacy/MariaDB" - # # -- Image tag for the REDCap database backup container. - # # @section -- REDCap Backup Job's settings - # tag: "9.3.0-debian-12-r1" - # # -- Image pullPolicy for the REDCap database backup container. - # # @section -- REDCap Backup Job's settings - # pullPolicy: "Always" - ## @param image.registry MariaDB image registry + # -- Image repository for MariaDB image. + # @section -- REDCap MariaDB Database settings + ## @param image.registry MariaDB image registry registry: docker.io ## @param image.repository MariaDB image repository repository: mariadb + # -- Image tag for MariaDB image. + # @section -- REDCap MariaDB Database settings ## @param image.tag MariaDB image tag (immutable tags are recommended) tag: "12.1.2@sha256:e1bcd6f85781f4a875abefb11c4166c1d79e4237c23de597bf0df81fec225b40" ## @param image.pullPolicy MariaDB image pull policy @@ -502,19 +495,14 @@ restoreJob: database: image: - # # -- Image repository for the REDCap database restore container. - # # @section -- REDCap Restore Job's settings - # repository: "bitnamilegacy/MariaDB" - # # -- Image yag for the REDCap application restore container. - # # @section -- REDCap Restore Job's settings - # tag: "9.3.0-debian-12-r1" - # # -- Image pullPolicy for the REDCap application restore container. - # # @section -- REDCap Restore Job's settings - # pullPolicy: "Always" + # -- Image repository for MariaDB image. + # @section -- REDCap MariaDB Database settings ## @param image.registry MariaDB image registry registry: docker.io ## @param image.repository MariaDB image repository repository: mariadb + # -- Image tag for MariaDB image. + # @section -- REDCap MariaDB Database settings ## @param image.tag MariaDB image tag (immutable tags are recommended) tag: "12.1.2@sha256:e1bcd6f85781f4a875abefb11c4166c1d79e4237c23de597bf0df81fec225b40" ## @param image.pullPolicy MariaDB image pull policy From a54bea781ba0f0a767de70d73970905bcd041a9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Thu, 22 Jan 2026 16:55:59 +0100 Subject: [PATCH 47/49] Rename MySQL to MariaDB in doc --- README.md | 4 ++-- charts/redcap/configuration/redcap/backup/backup-upload.sh | 2 +- .../redcap/database-conf/creds/credentials.php | 6 +++--- .../redcap/templates/secrets/mysql/database-password.yaml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index cce08ae..ab86edc 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The architecture of the REDCap stack deployed by this Chart is as follows : A minimal setup of this stack includes : - The HTTPd component - The PHP FPM Server hosting the REDCap Application -- The MySQL Database used by REDCap +- The MariaDB Database used by REDCap On top of that, you can also choose to deploy : - A Backup Cronjob, that can generate an archive containing a database dump, a dump of the `edocs` folder, and a dump of the folder containing the REDCap Application. @@ -45,7 +45,7 @@ Here are a few important notions to keep in mind to efficiently manage a REDCap If you choose to automatically install REDCap using your community credentials with this chart, an Kubernetes Job called `init-job` will be automatically fired during the chart's installation process: - The `StartupPrope` will call the `install.php` or `upgrade.php` script (depending if you're installing REDCap from scratch or upgrading from an existing installation) with the query parameter `auto=1` -- The `ReadinessProbe` will call a MySql script allowing to configure REDCap with the following parameter, extracted from the Chart values : +- The `ReadinessProbe` will call a MariaDB script allowing to configure REDCap with the following parameter, extracted from the Chart values : - REDCap Base URL - Institution Name - Organization Name diff --git a/charts/redcap/configuration/redcap/backup/backup-upload.sh b/charts/redcap/configuration/redcap/backup/backup-upload.sh index bd14f6b..190deb3 100644 --- a/charts/redcap/configuration/redcap/backup/backup-upload.sh +++ b/charts/redcap/configuration/redcap/backup/backup-upload.sh @@ -3,7 +3,7 @@ # Name: backup-upload.sh # Version: 1.0 # Author: Kévin ZGRZENDEK for APHP EDS -# Description : Compresses and uploads REDCap backup dir (containing the redcap app dir, the edocs dir & MySQL db dump) +# Description : Compresses and uploads REDCap backup dir (containing the redcap app dir, the edocs dir & MariaDB dump) echo "[INFO] Starting REDCap backup script v1.0" diff --git a/charts/redcap/configuration/redcap/database-conf/creds/credentials.php b/charts/redcap/configuration/redcap/database-conf/creds/credentials.php index 7ad670f..42b3a3d 100644 --- a/charts/redcap/configuration/redcap/database-conf/creds/credentials.php +++ b/charts/redcap/configuration/redcap/database-conf/creds/credentials.php @@ -1,8 +1,8 @@ Date: Mon, 23 Feb 2026 17:24:13 +0100 Subject: [PATCH 48/49] Update REDCap's image tag --- charts/redcap/README.md | 4 ++-- charts/redcap/values.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/redcap/README.md b/charts/redcap/README.md index 92883f5..b7821b4 100644 --- a/charts/redcap/README.md +++ b/charts/redcap/README.md @@ -49,7 +49,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml |-----|------|---------|-------------| | httpd.enabled | bool | `true` | If `true`, activates the deployment of the Apache HTTPd proxy. | | httpd.image.repository | string | `"ghcr.io/aphp/redcap-httpd-shibd"` | Image repository for Apache HTTPd. | -| httpd.image.tag | string | `"1.2.0"` | Image tag for Apache HTTPd. | +| httpd.image.tag | string | `"1.2.1"` | Image tag for Apache HTTPd. | | httpd.image.pullPolicy | string | `"Always"` | PullPolicy for Apache HTTPd's image. | | httpd.tls.enabled | bool | `false` | If `true` activates TLS termination on the Apache HTTPd proxy. | | httpd.tls.certificate.existingSecret | string | `""` | Name of the existing Secret holding the certificate for the TLS termination. The secret must be of type `tls`. | @@ -82,7 +82,7 @@ helm install redcap aphp-redcap/redcap -f ./examples/basic-install.yaml | redcap.install.overrideInstallContainer | list | `[]` | Overrides the initContainers that downloads the REDCap application package. | | redcap.image.repository | string | `"ghcr.io/aphp/redcap-php-fpm"` | Image repository for REDCap PHP-FPM Image. | | redcap.image.pullPolicy | string | `"Always"` | PullPolicy for REDCap PHP-FPM Image. | -| redcap.image.tag | string | `"1.2.0"` | Tag for REDCap PHP-FPM Image. | +| redcap.image.tag | string | `"1.2.1"` | Tag for REDCap PHP-FPM Image. | | redcap.extraInitContainers | list | `[]` | Add additional init containers to the PHP-FPM container hosting the REDCap application. | | redcap.extraContainers | list | `[]` | Add additional containers to the PHP-FPM container hosting the REDCap application. | | redcap.extraVolumes | list | `[]` | Add additional volumes to the PHP-FPM container hosting the REDCap application. | diff --git a/charts/redcap/values.yaml b/charts/redcap/values.yaml index 94cbcb3..e64b855 100644 --- a/charts/redcap/values.yaml +++ b/charts/redcap/values.yaml @@ -11,7 +11,7 @@ httpd: repository: "ghcr.io/aphp/redcap-httpd-shibd" # -- Image tag for Apache HTTPd. # @section -- HTTPd module settings - tag: "1.2.0" + tag: "1.2.1" # -- PullPolicy for Apache HTTPd's image. # @section -- HTTPd module settings pullPolicy: "Always" @@ -122,7 +122,7 @@ redcap: pullPolicy: "Always" # -- Tag for REDCap PHP-FPM Image. # @section -- REDCap settings - tag: "1.2.0" + tag: "1.2.1" # -- Add additional init containers to the PHP-FPM container hosting the REDCap application. # @section -- REDCap settings From fb5cd1609e852ce231d9514342fc3eb8c1015e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Lajus?= Date: Tue, 24 Feb 2026 10:00:20 +0100 Subject: [PATCH 49/49] Update REDCap version in docs --- charts/redcap/Chart.yaml | 4 ++-- charts/redcap/README.md | 2 +- charts/redcap/templates/NOTES.txt | 9 +++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/charts/redcap/Chart.yaml b/charts/redcap/Chart.yaml index 2f59ae3..45b77d5 100644 --- a/charts/redcap/Chart.yaml +++ b/charts/redcap/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: redcap -version: 1.4.6 -appVersion: 14.5.25 +version: 1.5.0 +appVersion: 15.0.27 kubeVersion: '>= 1.24.0-0' description: A Helm chart to deploy REDCap on a Kubernetes cluster. type: application diff --git a/charts/redcap/README.md b/charts/redcap/README.md index b7821b4..c09ba90 100644 --- a/charts/redcap/README.md +++ b/charts/redcap/README.md @@ -1,6 +1,6 @@ # redcap -![Version: 1.4.6](https://img.shields.io/badge/Version-1.4.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 14.5.25](https://img.shields.io/badge/AppVersion-14.5.25-informational?style=flat-square) +![Version: 1.5.0](https://img.shields.io/badge/Version-1.5.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 15.0.27](https://img.shields.io/badge/AppVersion-15.0.27-informational?style=flat-square) A Helm chart to deploy REDCap on a Kubernetes cluster. diff --git a/charts/redcap/templates/NOTES.txt b/charts/redcap/templates/NOTES.txt index a646fb3..0fc8dc6 100644 --- a/charts/redcap/templates/NOTES.txt +++ b/charts/redcap/templates/NOTES.txt @@ -1,4 +1,13 @@ You can access REDCap homepage URL by running these commands: + +{{- if .Values.mariadb.enabled }} +# MariaDB is enabled +The chart has been deployed with MariaDB. Please ensure that any configurations specific to MySQL are updated for MariaDB. +{{- else }} +# MySQL is enabled +The chart is using MySQL as the database. If you wish to migrate to MariaDB, please disable MySQL and enable MariaDB in your `values.yaml` file. +{{- end }} + {{- if .Values.ingress.enabled }} {{- range $host := .Values.ingress.hosts }} {{- range .paths }}