diff --git a/charts/heureka/docker/maintenance/Dockerfile b/charts/heureka/docker/maintenance/Dockerfile new file mode 100644 index 00000000..dc55377f --- /dev/null +++ b/charts/heureka/docker/maintenance/Dockerfile @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +FROM alpine:3.20 + +# Install mysql-client and bash (for scripts) +RUN apk add --no-cache mysql-client bash + +# Create non-root user +RUN addgroup -g 1000 dbuser && \ + adduser -u 1000 -G dbuser -s /bin/bash -D dbuser + +# Create directory for scripts +WORKDIR /scripts +COPY scripts/* /scripts/ + +# Set permissions +RUN chown -R dbuser:dbuser /scripts && \ + chmod -R 755 /scripts + +# Switch to non-root user +USER dbuser + +# Entry point script +ENTRYPOINT ["/scripts/entrypoint.sh"] diff --git a/charts/heureka/docker/maintenance/docker-compose.yaml b/charts/heureka/docker/maintenance/docker-compose.yaml new file mode 100644 index 00000000..f0577e6c --- /dev/null +++ b/charts/heureka/docker/maintenance/docker-compose.yaml @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +services: + maintenance: + build: . + image: db-maintenance:latest + container_name: heureka_maintenance + environment: + DB_HOST: host.docker.internal + DB_NAME: ${DB_NAME} + DB_USER: ${DB_USER} + DB_PASSWORD: ${DB_PASSWORD} + volumes: + - ./scripts:/scripts diff --git a/charts/heureka/docker/maintenance/scripts/entrypoint.sh b/charts/heureka/docker/maintenance/scripts/entrypoint.sh new file mode 100755 index 00000000..2d97588a --- /dev/null +++ b/charts/heureka/docker/maintenance/scripts/entrypoint.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + +set -e + +# Validate environment variables +if [ -z "$DB_HOST" ] || [ -z "$DB_NAME" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ]; then + echo "Error: Required environment variables are not set" + exit 1 +fi + +# Execute the maintenance script +echo "Starting database maintenance at $(date)" +mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" < /scripts/maintenance.sql + +echo "Database maintenance completed at $(date)" diff --git a/charts/heureka/docker/maintenance/scripts/maintenance.sql b/charts/heureka/docker/maintenance/scripts/maintenance.sql new file mode 100644 index 00000000..3ca0151f --- /dev/null +++ b/charts/heureka/docker/maintenance/scripts/maintenance.sql @@ -0,0 +1,47 @@ +-- SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +-- SPDX-License-Identifier: Apache-2.0 + +-- Maintenance script for database truncation +-- Enable logging +SET @start_time = NOW(); +SELECT CONCAT('Starting maintenance at ', @start_time) AS log_message; + +-- Start transaction +START TRANSACTION; + +-- Disable foreign key checks temporarily +SET FOREIGN_KEY_CHECKS = 0; + +-- Truncate junction join tables first +TRUNCATE TABLE IssueMatchEvidence; +TRUNCATE TABLE ComponentVersionIssue; +TRUNCATE TABLE IssueRepositoryService; +TRUNCATE TABLE IssueMatchChange; +TRUNCATE TABLE SupportGroupService; +TRUNCATE TABLE SupportGroupUser; +TRUNCATE TABLE Owner; + +-- Truncate dependent entity tables +TRUNCATE TABLE IssueMatch; +TRUNCATE TABLE Evidence; +TRUNCATE TABLE ComponentInstance; +-- TRUNCATE TABLE IssueVariant; +TRUNCATE TABLE ComponentVersion; +TRUNCATE TABLE Activity; + +-- Truncate main entity tables +TRUNCATE TABLE Component; +TRUNCATE TABLE Service; +TRUNCATE TABLE SupportGroup; +-- TRUNCATE TABLE Issue; +-- TRUNCATE TABLE IssueRepository; + +-- Re-enable foreign key checks +SET FOREIGN_KEY_CHECKS = 1; + +-- Log completion +SELECT CONCAT('Maintenance completed at ', NOW(), '. Duration: ', + TIMESTAMPDIFF(SECOND, @start_time, NOW()), ' seconds') AS log_message; + +-- Commit transaction +COMMIT; diff --git a/charts/heureka/templates/cronjob.yaml b/charts/heureka/templates/cronjob.yaml new file mode 100644 index 00000000..28c96c35 --- /dev/null +++ b/charts/heureka/templates/cronjob.yaml @@ -0,0 +1,39 @@ +{{- if .Values.dbMaintenance.enabled }} +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ include "heureka.fullname" . }}-db-maintenance + labels: + {{- include "heureka.labels" . | nindent 4 }} + app.kubernetes.io/component: db-maintenance +spec: + schedule: {{ .Values.dbMaintenance.schedule | quote }} + concurrencyPolicy: Forbid + jobTemplate: + spec: + template: + spec: + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + containers: + - name: db-maintenance + image: {{ .Values.dbMaintenance.image.repository }}:{{ .Values.dbMaintenance.image.tag }} + env: + - name: DB_HOST + value: {{ .Values.mariadb.fullnameOverride | default (printf "%s-mariadb" (include "heureka.fullname" .)) }} + - name: DB_NAME + value: {{ .Values.mariadb.auth.database }} + - name: DB_USER + valueFrom: + secretKeyRef: + name: heureka + key: mariadb-username + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: heureka + key: mariadb-password + restartPolicy: OnFailure +{{- end }} diff --git a/charts/heureka/templates/secret.yaml b/charts/heureka/templates/secret.yaml index ea339fab..0f07a5c8 100644 --- a/charts/heureka/templates/secret.yaml +++ b/charts/heureka/templates/secret.yaml @@ -5,6 +5,7 @@ metadata: labels: {{- include "heureka.labels" . | nindent 4 }} data: - environment: {{ .Values.environment | b64enc | quote }} + environment: {{ .Values.environment | b64enc | quote }} + mariadb-username: {{ .Values.mariadb.auth.username | b64enc }} mariadb-password: {{ .Values.mariadb.auth.password | b64enc }} - mariadb-root-password: {{ .Values.mariadb.auth.rootPassword | b64enc }} \ No newline at end of file + mariadb-root-password: {{ .Values.mariadb.auth.rootPassword | b64enc }} diff --git a/charts/heureka/values.yaml b/charts/heureka/values.yaml index f222051a..029d0442 100644 --- a/charts/heureka/values.yaml +++ b/charts/heureka/values.yaml @@ -83,3 +83,16 @@ mariadb: username: my_username rootPassword: my_password password: my_password + +dbMaintenance: + enabled: true + # schedule: "0 0 * * *" + schedule: "*/1 * * * *" # Every minute for testing + image: + # Just for testing purposes + repository: db-maintenance + tag: "latest" + pullPolicy: "never" + scripts: + - name: cleanup + enabled: true