Skip to content
Draft
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
25 changes: 16 additions & 9 deletions .github/workflows/lint-test-high-availability.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Lint and Test Charts High Availability
on:
pull_request:
paths:
- 'charts/memgraph-high-availability/**'
- "charts/memgraph-high-availability/**"

jobs:
lint-test:
Expand All @@ -21,7 +21,7 @@ jobs:

- uses: actions/setup-python@v4
with:
python-version: '3.12'
python-version: "3.12"
check-latest: true

- name: Download dependencies
Expand All @@ -46,7 +46,7 @@ jobs:

- name: Run chart-testing (lint)
if: steps.list-changed.outputs.changed == 'true'
run: ct lint --target-branch ${{ github.event.repository.default_branch }} --check-version-increment false --charts charts/memgraph-high-availability
run: ct lint --target-branch ${{ github.event.repository.default_branch }} --check-version-increment false --lint-conf lintconf.yaml --charts charts/memgraph-high-availability

# 🔹 Minikube instead of kind
- name: Set up Minikube
Expand Down Expand Up @@ -90,12 +90,13 @@ jobs:
if: steps.list-changed.outputs.changed == 'true'
run: |
echo "Waiting for all pods in the namespace to be Ready..."
for i in {1..60}; do
all_ready=false
for _ in {1..60}; do
echo "--- Pod status at $(date) ---"
kubectl get pods -o wide
kubectl get pods -o wide | grep -E '(NAME|memgraph-coordinator|memgraph-data)'

# If any pods are Pending, describe them
pending=$(kubectl get pods --no-headers | awk '$3=="Pending"{print $1}')
pending=$(kubectl get pods --no-headers | grep -E 'memgraph-(coordinator|data)' | awk '$3=="Pending"{print $1}')
if [ -n "$pending" ]; then
echo "⚠️ Some pods are Pending, describing..."
for pod in $pending; do
Expand All @@ -104,16 +105,22 @@ jobs:
done
fi

# Check if all pods are ready
not_ready=$(kubectl get pods --no-headers | awk '{print $2}' | grep -vE '^([0-9]+)/\1$' || true)
# Check if all pods are Ready
not_ready=$(kubectl get pods --no-headers | grep -E 'memgraph-(coordinator|data)' | awk '{print $2}' | grep -vE '^([0-9]+)/\1$' || true)
if [ -z "$not_ready" ]; then
echo "✅ All pods are Ready"
all_ready=true
break
fi

sleep 10
done

if [ "$all_ready" = false ]; then
echo "❌ ERROR: Timeout waiting for pods to become ready after 10 minutes"
kubectl get pods | grep -E '(NAME|memgraph-coordinator|memgraph-data)'
exit 1
fi

- name: Run Helm tests (create test Jobs)
if: steps.list-changed.outputs.changed == 'true'
run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ docker/
.DS_Store
Thumbs.db
charts/memgraph-high-availability/charts/
.vscode/
72 changes: 72 additions & 0 deletions charts/memgraph-high-availability/templates/cluster-setup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
apiVersion: batch/v1
kind: Job
metadata:
name: cluster-setup
annotations:
"helm.sh/hook": post-install
spec:
template:
spec:
restartPolicy: Never
containers:
- name: cluster-setup
image: "{{ $.Values.image.repository }}:{{ $.Values.image.tag }}"
command: ["/bin/bash", "-c"]
args:
- |
set -e # Exit on error

echo "Waiting for Memgraph coordinators to be ready..."

# Function to wait for a service to be ready
wait_for_service() {
local host=$1
local port=$2
local max_attempts=60
local attempt=0

while [ $attempt -lt $max_attempts ]; do
echo "Checking $host:$port (attempt $((attempt+1))/$max_attempts)"

if timeout 5 bash -c "cat < /dev/null > /dev/tcp/$host/$port" 2>/dev/null; then
echo "✅ $host:$port is ready"
return 0
fi

attempt=$((attempt+1))
sleep 5
done

echo "❌ Timeout waiting for $host:$port"
return 1
}

# Wait for all coordinators
{{- range .Values.coordinators }}
wait_for_service "memgraph-coordinator-{{ .id }}.{{ $.Release.Namespace }}.svc.cluster.local" {{ $.Values.ports.boltPort }}
{{- end }}

# Wait for all data instances
{{- range .Values.data }}
wait_for_service "memgraph-data-{{ .id }}.{{ $.Release.Namespace }}.svc.cluster.local" {{ $.Values.ports.boltPort }}
{{- end }}

# Check if instances are already registered
INSTANCE_COUNT=$(echo "SHOW INSTANCES;" | mgconsole --host memgraph-coordinator-{{ (index .Values.coordinators 0).id }}.{{ .Release.Namespace }}.svc.cluster.local --port {{$.Values.ports.boltPort }} --output-format=csv 2>/dev/null | tail -n +2 | wc -l)
if [ "$INSTANCE_COUNT" -gt 1 ]; then
echo "✅ Cluster already configured with $INSTANCE_COUNT instances. Skipping registration."
exit 0
fi

# Add all coordinators
{{- range .Values.coordinators }}
echo 'ADD COORDINATOR {{ .id }} WITH CONFIG {"bolt_server": "memgraph-coordinator-{{ .id }}.{{ $.Release.Namespace }}.svc.cluster.local:{{ $.Values.ports.boltPort }}", "management_server": "memgraph-coordinator-{{ .id }}.{{ $.Release.Namespace }}.svc.cluster.local:{{ $.Values.ports.managementPort }}", "coordinator_server": "memgraph-coordinator-{{ .id }}.{{$.Release.Namespace }}.svc.cluster.local:{{ $.Values.ports.coordinatorPort }}"};' | mgconsole --host memgraph-coordinator-{{ (index $.Values.coordinators 0).id }}.{{ $.Release.Namespace}}.svc.cluster.local --port {{ $.Values.ports.boltPort }}
{{- end }}

# Register all data instances
{{- range $index, $instance := .Values.data }}
echo 'REGISTER INSTANCE instance_{{ add $index 1 }} WITH CONFIG {"bolt_server": "memgraph-data-{{ $instance.id }}.{{ $.Release.Namespace }}.svc.cluster.local:{{$.Values.ports.boltPort }}", "management_server": "memgraph-data-{{ $instance.id }}.{{ $.Release.Namespace }}.svc.cluster.local:{{ $.Values.ports.managementPort }}", "replication_server": "memgraph-data-{{ $instance.id }}.{{ $.Release.Namespace }}.svc.cluster.local:{{ $.Values.ports.replicationPort }}"};' | mgconsole --host memgraph-coordinator-{{ (index $.Values.coordinators 0).id }}.{{ $.Release.Namespace }}.svc.cluster.local --port {{ $.Values.ports.boltPort }}
{{- end }}

# Set first data instance as MAIN
echo 'SET INSTANCE instance_1 TO MAIN;' | mgconsole --host memgraph-coordinator-{{ (index .Values.coordinators 0).id }}.{{ $.Release.Namespace }}.svc.cluster.local --port {{ $.Values.ports.boltPort }}
Original file line number Diff line number Diff line change
Expand Up @@ -19,41 +19,6 @@ spec:
- |
PORT=7687

echo "=== Cluster init via coordinator-1 ==="
cat > /tmp/cluster-setup.cypher <<'EOF'
ADD COORDINATOR 1 WITH CONFIG {
"bolt_server": "memgraph-coordinator-1.default.svc.cluster.local:7687",
"management_server": "memgraph-coordinator-1.default.svc.cluster.local:10000",
"coordinator_server": "memgraph-coordinator-1.default.svc.cluster.local:12000"
};
ADD COORDINATOR 2 WITH CONFIG {
"bolt_server": "memgraph-coordinator-2.default.svc.cluster.local:7687",
"management_server": "memgraph-coordinator-2.default.svc.cluster.local:10000",
"coordinator_server": "memgraph-coordinator-2.default.svc.cluster.local:12000"
};
ADD COORDINATOR 3 WITH CONFIG {
"bolt_server": "memgraph-coordinator-3.default.svc.cluster.local:7687",
"management_server": "memgraph-coordinator-3.default.svc.cluster.local:10000",
"coordinator_server": "memgraph-coordinator-3.default.svc.cluster.local:12000"
};
REGISTER INSTANCE instance_0 WITH CONFIG {
"bolt_server": "memgraph-data-0.default.svc.cluster.local:7687",
"management_server": "memgraph-data-0.default.svc.cluster.local:10000",
"replication_server": "memgraph-data-0.default.svc.cluster.local:20000"
};
REGISTER INSTANCE instance_1 WITH CONFIG {
"bolt_server": "memgraph-data-1.default.svc.cluster.local:7687",
"management_server": "memgraph-data-1.default.svc.cluster.local:10000",
"replication_server": "memgraph-data-1.default.svc.cluster.local:20000"
};
SET INSTANCE instance_0 TO MAIN;
EOF

echo "Applying cluster setup..."
mgconsole \
--host "memgraph-coordinator-1.default.svc.cluster.local" \
--port "$PORT" < /tmp/cluster-setup.cypher

hosts_coordinators="
memgraph-coordinator-1.default.svc.cluster.local
memgraph-coordinator-2.default.svc.cluster.local
Expand Down
Loading