diff --git a/build-job-cleanup.yaml b/build-job-cleanup.yaml new file mode 100644 index 0000000..3c62e58 --- /dev/null +++ b/build-job-cleanup.yaml @@ -0,0 +1,119 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: job-cleanup-sa + namespace: flux-builds +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: job-cleanup-role + namespace: flux-builds +rules: +- apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["list", "delete", "deletecollection"] +- apiGroups: [""] + resources: ["pods"] + verbs: ["list", "delete"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: job-cleanup-binding + namespace: flux-builds +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: job-cleanup-role +subjects: +- kind: ServiceAccount + name: job-cleanup-sa + namespace: flux-builds +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: cleanup-old-build-jobs + namespace: flux-builds +spec: + schedule: "*/30 * * * *" # Run every 30 minutes + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 1 + failedJobsHistoryLimit: 1 + jobTemplate: + spec: + template: + spec: + serviceAccountName: job-cleanup-sa + restartPolicy: Never + containers: + - name: cleanup + image: bitnami/kubectl:latest + command: + - /bin/bash + - -c + - | + set -e + echo "===== Cleaning up old build jobs =====" + date + + # Keep only the last 10 successful jobs + echo "Finding old successful jobs..." + SUCCESSFUL_JOBS=$(kubectl get jobs -n flux-builds \ + -l app=neonvortex \ + --sort-by=.metadata.creationTimestamp \ + --field-selector status.successful=1 \ + -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | head -n -10) + + if [ -n "$SUCCESSFUL_JOBS" ]; then + echo "Deleting old successful jobs:" + echo "$SUCCESSFUL_JOBS" + echo "$SUCCESSFUL_JOBS" | xargs -r kubectl delete job -n flux-builds + else + echo "No old successful jobs to delete" + fi + + # Delete failed jobs older than 1 hour + echo "" + echo "Finding old failed jobs..." + CUTOFF_TIME=$(date -u -d '1 hour ago' '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null || date -u -v-1H '+%Y-%m-%dT%H:%M:%SZ') + + FAILED_JOBS=$(kubectl get jobs -n flux-builds \ + -l app=neonvortex \ + --field-selector status.successful=0 \ + -o json | \ + jq -r --arg cutoff "$CUTOFF_TIME" \ + '.items[] | select(.status.completionTime < $cutoff or .status.startTime < $cutoff) | .metadata.name') + + if [ -n "$FAILED_JOBS" ]; then + echo "Deleting old failed jobs:" + echo "$FAILED_JOBS" + echo "$FAILED_JOBS" | xargs -r kubectl delete job -n flux-builds + else + echo "No old failed jobs to delete" + fi + + # Delete jobs older than 24 hours regardless of status + echo "" + echo "Finding jobs older than 24 hours..." + CUTOFF_24H=$(date -u -d '24 hours ago' '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null || date -u -v-24H '+%Y-%m-%dT%H:%M:%SZ') + + OLD_JOBS=$(kubectl get jobs -n flux-builds \ + -l app=neonvortex \ + -o json | \ + jq -r --arg cutoff "$CUTOFF_24H" \ + '.items[] | select(.metadata.creationTimestamp < $cutoff) | .metadata.name') + + if [ -n "$OLD_JOBS" ]; then + echo "Deleting jobs older than 24 hours:" + echo "$OLD_JOBS" + echo "$OLD_JOBS" | xargs -r kubectl delete job -n flux-builds + else + echo "No jobs older than 24 hours" + fi + + echo "" + echo "===== Cleanup complete =====" + kubectl get jobs -n flux-builds -l app=neonvortex diff --git a/build-trigger-cronjob-neonvortex.yaml b/build-trigger-cronjob-neonvortex.yaml new file mode 100644 index 0000000..7eb810f --- /dev/null +++ b/build-trigger-cronjob-neonvortex.yaml @@ -0,0 +1,192 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: build-trigger-script + namespace: neonvortex +data: + trigger-build.sh: | + #!/bin/bash + set -e + + # Configuration + GIT_URL="http://192.168.1.49:13001/admin/neon-vortex.git" + REPO_DIR="/tmp/repo" + LAST_COMMIT_FILE="/data/last_commit" + + echo "Checking for new commits..." + + # Clone or update repository + if [ ! -d "$REPO_DIR" ]; then + git clone "$GIT_URL" "$REPO_DIR" + else + cd "$REPO_DIR" + git fetch origin main + git reset --hard origin/main + fi + + cd "$REPO_DIR" + CURRENT_COMMIT=$(git rev-parse HEAD) + SHORT_COMMIT=$(git rev-parse --short HEAD) + + echo "Current commit: $CURRENT_COMMIT" + + # Read last processed commit + LAST_COMMIT="" + if [ -f "$LAST_COMMIT_FILE" ]; then + LAST_COMMIT=$(cat "$LAST_COMMIT_FILE") + echo "Last processed commit: $LAST_COMMIT" + fi + + # Check if there are new commits + if [ "$CURRENT_COMMIT" != "$LAST_COMMIT" ]; then + echo "New commit detected! Triggering build..." + + # Create a new build job with unique name + TIMESTAMP=$(date +%s) + JOB_NAME="build-cron-$SHORT_COMMIT-$TIMESTAMP" + + # Generate build job YAML + cat < "$LAST_COMMIT_FILE" + echo "Updated last commit reference" + else + echo "No new commits. Skipping build." + fi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: build-trigger-data + namespace: neonvortex +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 100Mi +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: build-trigger-cron-sa + namespace: neonvortex +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: build-trigger-cron-role + namespace: flux-builds +rules: +- apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["create", "get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: build-trigger-cron-binding + namespace: flux-builds +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: build-trigger-cron-role +subjects: +- kind: ServiceAccount + name: build-trigger-cron-sa + namespace: neonvortex +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: neon-vortex-build-trigger + namespace: neonvortex +spec: + schedule: "*/5 * * * *" # Check every 5 minutes (backup to webhooks) + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 1 + failedJobsHistoryLimit: 1 + jobTemplate: + spec: + template: + spec: + serviceAccountName: build-trigger-cron-sa + restartPolicy: Never + containers: + - name: trigger + image: alpine/k8s:1.28.13 + command: ["/bin/bash"] + args: + - -c + - | + apk add --no-cache git bash curl + /scripts/trigger-build.sh + volumeMounts: + - name: script + mountPath: /scripts + - name: data + mountPath: /data + volumes: + - name: script + configMap: + name: build-trigger-script + defaultMode: 0755 + - name: data + persistentVolumeClaim: + claimName: build-trigger-data diff --git a/flux-alerts-neonvortex.yaml b/flux-alerts-neonvortex.yaml new file mode 100644 index 0000000..a502f0e --- /dev/null +++ b/flux-alerts-neonvortex.yaml @@ -0,0 +1,35 @@ +--- +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Alert +metadata: + name: neon-vortex-git + namespace: flux-system +spec: + summary: "Neon Vortex Git Updates" + providerRef: + name: neon-vortex-notify + eventSeverity: info + eventSources: + - kind: GitRepository + name: neon-vortex + namespace: flux-system + exclusionList: + - ".*health check.*" +--- +apiVersion: notification.toolkit.fluxcd.io/v1beta3 +kind: Alert +metadata: + name: neon-vortex-deploy + namespace: flux-system +spec: + summary: "Neon Vortex Deployment Status" + providerRef: + name: neon-vortex-notify + eventSeverity: info + eventSources: + - kind: HelmRelease + name: neon-vortex + namespace: neonvortex + exclusionList: + - ".*health check.*" + - ".*reconciliation in progress.*" diff --git a/flux-helmrelease-neonvortex.yaml b/flux-helmrelease-neonvortex.yaml new file mode 100644 index 0000000..c59fb4b --- /dev/null +++ b/flux-helmrelease-neonvortex.yaml @@ -0,0 +1,21 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: neon-vortex + namespace: neonvortex +spec: + interval: 5m + chart: + spec: + chart: ./neon-vortex-chart + sourceRef: + kind: GitRepository + name: neon-vortex + namespace: flux-system + interval: 1m + values: + image: + registry: images.caffeinetux.com + repository: apps/neon-vortex + tag: latest + pullPolicy: Always diff --git a/namespaces.yaml b/namespaces.yaml new file mode 100644 index 0000000..287396b --- /dev/null +++ b/namespaces.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: neonvortex + labels: + app: neonvortex + toolkit.fluxcd.io/tenant: neonvortex +--- +apiVersion: v1 +kind: Namespace +metadata: + name: flux-builds + labels: + app: flux-builds + toolkit.fluxcd.io/tenant: neonvortex diff --git a/webhook-build-trigger-neonvortex.yaml b/webhook-build-trigger-neonvortex.yaml new file mode 100644 index 0000000..382a8e5 --- /dev/null +++ b/webhook-build-trigger-neonvortex.yaml @@ -0,0 +1,244 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: webhook-build-script + namespace: neonvortex +data: + trigger-build.sh: | + #!/bin/bash + set -e + + echo "===== Git Push Detected - Triggering Build =====" + date + + # Clone the repository + echo "Cloning repository..." + git clone http://192.168.1.49:13001/admin/neon-vortex.git /tmp/repo + cd /tmp/repo + + # Get commit info + GIT_COMMIT=$(git rev-parse HEAD) + GIT_SHORT=$(git rev-parse --short HEAD) + GIT_MSG=$(git log -1 --pretty=%B | head -1) + GIT_AUTHOR=$(git log -1 --pretty=%an) + + echo "Commit: $GIT_SHORT ($GIT_COMMIT)" + echo "Author: $GIT_AUTHOR" + echo "Message: $GIT_MSG" + + # Generate unique job name + TIMESTAMP=$(date +%s) + JOB_NAME="build-${GIT_SHORT}-${TIMESTAMP}" + + echo "Creating build job: $JOB_NAME" + + # Send start notification + curl -s -X POST "https://notify.caffeinetux.com/message?token=APMvTuncQJmm6vd" \ + -F "title=🔨 Neon Vortex Build Started" \ + -F "message=Commit: ${GIT_SHORT} by ${GIT_AUTHOR} - ${GIT_MSG}" \ + -F "priority=5" || echo "Notification failed" + + # Create the build job in flux-builds namespace + kubectl apply -f - <