Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions charts/mcp-stack/templates/NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,14 @@ export GW_TOKEN=$(curl -s -u '{{ .Values.mcpContextForge.secret.BASIC_AUTH_USER
-X POST http://localhost:4444/auth/login | jq -r '.access_token')
{{- else }}
export GW_PASS=$(kubectl -n {{ $ns }} get secret {{ $gwSecret }} -o jsonpath="{.data.BASIC_AUTH_PASSWORD}" | base64 -d)
export GW_TOKEN=$(curl -s -u '{{ .Values.mcpContextForge.secret.BASIC_AUTH_USER }}:$GW_PASS' \
-X POST http://localhost:4444/auth/login | jq -r '.access_token')
export GW_TOKEN=$(curl --request POST \
--url http://localhost:4444/auth/login \
--header 'Content-Type: application/json' \
--data "{
\"email\": \"admin@example.com\",
\"password\": \"$GW_PASS\"
}" | jq -r '.access_token'
)
{{- end }}

# 4) Test the gateway health
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if .Values.postgres.upgrade.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "mcp-stack.fullname" . }}-postgres-upgrade-status
labels:
{{- include "mcp-stack.labels" . | nindent 4 }}
app.kubernetes.io/component: postgres-upgrade-status
data:
backupCompleted: {{ .Values.postgres.upgrade.backupCompleted | quote }}
targetVersion: {{ .Values.postgres.upgrade.targetVersion | quote }}
lastUpdated: {{ now | quote }}
{{- end }}
126 changes: 125 additions & 1 deletion charts/mcp-stack/templates/deployment-postgres.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
- Adds resource requests / limits pulled from values.yaml.
------------------------------------------------------------------- */}}

{{- $targetVersion := .Values.postgres.upgrade.targetVersion | toString -}}
{{- $postgresImage := "" -}}
{{- if and .Values.postgres.upgrade.enabled (eq $targetVersion "18") -}}
{{- $postgresImage = printf "%s:18" .Values.postgres.image.repository -}}
{{- else -}}
{{- $postgresImage = printf "%s:%s" .Values.postgres.image.repository .Values.postgres.image.tag -}}
{{- end -}}

{{- if .Values.postgres.enabled }}
apiVersion: apps/v1
kind: Deployment
Expand All @@ -21,6 +29,11 @@ spec:
selector:
matchLabels:
app: {{ include "mcp-stack.fullname" . }}-postgres
{{- if and .Values.postgres.upgrade.enabled (eq $targetVersion "18") }}
# For PostgreSQL 18 upgrade, we need to perform a rolling update
strategy:
type: Recreate # Recreate strategy to ensure clean transition during upgrade
{{- end }}
template:
metadata:
labels:
Expand All @@ -33,9 +46,116 @@ spec:
- name: {{ . }}
{{- end }}
{{- end }}
initContainers:
{{- if and .Values.postgres.upgrade.enabled (eq $targetVersion "18") .Values.postgres.upgrade.backupCompleted }}
# Init container to upgrade PostgreSQL data from version 17 to 18
- name: postgres-restore
image: "{{ .Values.postgres.image.repository }}:17" # Use PostgreSQL 17 image to access the old data
command:
- /bin/bash
- -c
- |
#!/bin/bash
set -e

PGDATA="/var/lib/postgresql/data/pgdata"
INITDB_DONE_FILE="$PGDATA/.initdb_done"

echo "Checking PostgreSQL data directory..."
if [ -d "$PGDATA" ]; then
ls -la "$PGDATA" | head -20
else
echo "Data directory does not exist yet"
exit 0
fi

# Check if this is a data upgrade scenario (PG_VERSION file exists with version 17)
if [ -f "$PGDATA/PG_VERSION" ]; then
CURRENT_VERSION=$(cat "$PGDATA/PG_VERSION" 2>/dev/null || echo "")
echo "Found PG_VERSION file with version: $CURRENT_VERSION"

if [ "$CURRENT_VERSION" = "17" ]; then
echo "PostgreSQL 17 data detected - this should be removed to allow PostgreSQL 18 to initialize fresh and reload from dump"

# Install MinIO client and jq
apt-get update && apt-get install -y wget jq
wget https://dl.min.io/client/mc/release/linux-amd64/mc -O /tmp/mc
chmod +x /tmp/mc

# Configure MinIO client
/tmp/mc alias set minio http://{{ include "mcp-stack.fullname" . }}-minio:{{ .Values.minio.service.apiPort }} $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD

# List and find the latest backup file
LATEST_BACKUP=$(/tmp/mc ls --json minio/postgres-backups/ | jq -r '"\(.time) \(.key)"' | sort -r | head -n1 | cut -d' ' -f2-)

if [ -z "$LATEST_BACKUP" ]; then
echo "No backup file found in MinIO - cannot perform upgrade"
exit 0 # Allow to continue but no dump will be loaded
fi

echo "Found backup file: $LATEST_BACKUP"

# Download the backup file to the initdb directory
/tmp/mc cp minio/postgres-backups/$LATEST_BACKUP /docker-entrypoint-initdb.d/

# Remove the old data directory to allow PostgreSQL 18 to initialize fresh
echo "Removing old PostgreSQL 17 data to allow fresh initialization with PG18..."
# Move current data to backup directory first
mv "$PGDATA" "/tmp/postgres-data-old"

# Create new data directory
mkdir -p "$PGDATA"

# Set proper ownership
chown -R postgres:postgres /var/lib/postgresql/data
chown -R postgres:postgres /docker-entrypoint-initdb.d

echo "Old data backed up and directory prepared for PostgreSQL 18 initialization"
else
echo "Data version ($CURRENT_VERSION) is not 17, skipping removal"
# Still touch the initdb_done file to indicate this is not a fresh install
touch "$PGDATA/.initdb_done"
fi
else
echo "No PG_VERSION file found - this is likely a fresh install"
# Create the directory if doesn't exist
mkdir -p "$PGDATA"
touch "$PGDATA/.initdb_done"
fi

echo "Init container completed successfully"
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: {{ if .Values.minio.existingSecret }}{{ .Values.minio.existingSecret }}{{ else }}{{ include "mcp-stack.fullname" . }}-minio{{ end }}
key: MINIO_ROOT_USER
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: {{ if .Values.minio.existingSecret }}{{ .Values.minio.existingSecret }}{{ else }}{{ include "mcp-stack.fullname" . }}-minio{{ end }}
key: MINIO_ROOT_PASSWORD
- name: PGUSER
valueFrom:
secretKeyRef:
name: {{ include "mcp-stack.postgresSecretName" . | trim }}
key: POSTGRES_USER
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: {{ include "mcp-stack.postgresSecretName" . | trim }}
key: POSTGRES_PASSWORD
volumeMounts:
- name: postgredb
mountPath: /var/lib/postgresql/data
- name: postgres-initdb
mountPath: /docker-entrypoint-initdb.d
securityContext:
runAsUser: 0 # Run as root to have permission to move files
{{- end }}
containers:
- name: postgres
image: "{{ .Values.postgres.image.repository }}:{{ .Values.postgres.image.tag }}"
image: "{{ $postgresImage }}"
imagePullPolicy: "{{ .Values.postgres.image.pullPolicy }}"

# Expose Postgres TCP port inside the pod
Expand Down Expand Up @@ -71,6 +191,8 @@ spec:
volumeMounts:
- name: postgredb
mountPath: /var/lib/postgresql/data
- name: postgres-initdb
mountPath: /docker-entrypoint-initdb.d

# ─── Resource limits & requests ───
resources:
Expand All @@ -84,4 +206,6 @@ spec:
{{- else }}
emptyDir: {}
{{- end }}
- name: postgres-initdb
emptyDir: {}
{{- end }}
86 changes: 86 additions & 0 deletions charts/mcp-stack/templates/job-postgres-backup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{{- $targetVersion := .Values.postgres.upgrade.targetVersion | toString -}}
{{- if and .Values.postgres.upgrade.enabled (eq $targetVersion "18") (not .Values.postgres.upgrade.backupCompleted) }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "mcp-stack.fullname" . }}-postgres-backup
labels:
{{- include "mcp-stack.labels" . | nindent 4 }}
app.kubernetes.io/component: postgres-backup
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded"
spec:
template:
spec:
restartPolicy: Never
containers:
- name: postgres-backup
image: "{{ .Values.postgres.image.repository }}:{{ .Values.postgres.image.tag }}"
command:
- /bin/bash
- -c
- |
#!/bin/bash
set -e

echo "Starting PostgreSQL backup..."

# Wait for PostgreSQL to be ready
echo "Waiting for PostgreSQL to be ready..."
until pg_isready -h {{ include "mcp-stack.fullname" . }}-postgres -U {{ .Values.postgres.credentials.user }}; do
sleep 2
done

# Create backup file
BACKUP_FILE="/tmp/postgres-dump-$(date +%Y%m%d-%H%M%S).sql"
pg_dump -h {{ include "mcp-stack.fullname" . }}-postgres \
-U {{ .Values.postgres.credentials.user }} \
-d {{ .Values.postgres.credentials.database }} \
--no-password > $BACKUP_FILE

echo "Database dumped to $BACKUP_FILE"

# Install MinIO client and jq
apt-get update && apt-get install -y wget jq
wget https://dl.min.io/client/mc/release/linux-amd64/mc -O /tmp/mc
chmod +x /tmp/mc

# Configure MinIO client
/tmp/mc alias set minio http://{{ include "mcp-stack.fullname" . }}-minio:{{ .Values.minio.service.apiPort }} $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD

# Create bucket if it doesn't exist
/tmp/mc mb minio/postgres-backups --ignore-existing

# Upload the backup file to MinIO
/tmp/mc cp $BACKUP_FILE minio/postgres-backups/

echo "Backup uploaded to MinIO successfully"

# Clean up local file
rm $BACKUP_FILE

echo "PostgreSQL backup completed and stored in MinIO"
env:
- name: PGUSER
valueFrom:
secretKeyRef:
name: {{ include "mcp-stack.postgresSecretName" . | trim }}
key: POSTGRES_USER
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: {{ include "mcp-stack.postgresSecretName" . | trim }}
key: POSTGRES_PASSWORD
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: {{ if .Values.minio.existingSecret }}{{ .Values.minio.existingSecret }}{{ else }}{{ include "mcp-stack.fullname" . }}-minio{{ end }}
key: MINIO_ROOT_USER
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: {{ if .Values.minio.existingSecret }}{{ .Values.minio.existingSecret }}{{ else }}{{ include "mcp-stack.fullname" . }}-minio{{ end }}
key: MINIO_ROOT_PASSWORD
{{- end }}
64 changes: 64 additions & 0 deletions charts/mcp-stack/templates/job-postgres-migration-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{{- $targetVersion := .Values.postgres.upgrade.targetVersion | toString -}}
{{- if and .Values.postgres.upgrade.enabled (eq $targetVersion "18") }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "mcp-stack.fullname" . }}-postgres-migration-check
labels:
{{- include "mcp-stack.labels" . | nindent 4 }}
app.kubernetes.io/component: postgres-migration-check
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "10"
"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded"
spec:
template:
spec:
restartPolicy: Never
containers:
- name: postgres-migration-check
image: "{{ .Values.postgres.image.repository }}:18"
command:
- /bin/bash
- -c
- |
#!/bin/bash
set -e

echo "Checking PostgreSQL 18 migration status..."

# Wait for PostgreSQL to be ready
echo "Waiting for PostgreSQL 18 to be ready..."
until pg_isready -h {{ include "mcp-stack.fullname" . }}-postgres -U {{ .Values.postgres.credentials.user }}; do
sleep 2
done

# Run a simple query to verify the database is working
RESULT=$(psql -h {{ include "mcp-stack.fullname" . }}-postgres \
-U {{ .Values.postgres.credentials.user }} \
-d {{ .Values.postgres.credentials.database }} \
-t -c "SELECT version();" 2>/dev/null || echo "ERROR")

if [[ $RESULT == *"ERROR"* ]] || [[ -z "$RESULT" ]]; then
echo "❌ Migration check failed - PostgreSQL 18 is not working properly"
exit 1
else
echo "βœ… PostgreSQL 18 is working properly"
echo "PostgreSQL version: $RESULT"

# Update the upgrade status in a ConfigMap or similar
# For now, we'll just log that the migration was successful
echo "Migration to PostgreSQL 18 completed successfully"
fi
env:
- name: PGUSER
valueFrom:
secretKeyRef:
name: {{ include "mcp-stack.postgresSecretName" . | trim }}
key: POSTGRES_USER
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: {{ include "mcp-stack.postgresSecretName" . | trim }}
key: POSTGRES_PASSWORD
{{- end }}
4 changes: 4 additions & 0 deletions charts/mcp-stack/templates/job-postgres-restore.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{{- /* removed: job-postgres-restore is deprecated and intentionally disabled.
Restores are handled by the postgres initContainer during the upgrade flow.
Keeping this template present would be confusing; it is left inert on purpose.
*/ -}}
Loading
Loading