# Workspace and PipelineRun Cleanup for Bakery-IA CI/CD # This CronJob cleans up old PipelineRuns and PVCs to prevent storage exhaustion --- # ServiceAccount for cleanup job apiVersion: v1 kind: ServiceAccount metadata: name: tekton-cleanup-sa namespace: tekton-pipelines labels: app.kubernetes.io/name: bakery-ia-cicd app.kubernetes.io/component: cleanup --- # ClusterRole for cleanup operations apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: tekton-cleanup-role labels: app.kubernetes.io/name: bakery-ia-cicd app.kubernetes.io/component: cleanup rules: - apiGroups: ["tekton.dev"] resources: ["pipelineruns", "taskruns"] verbs: ["get", "list", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "delete"] - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "delete"] --- # ClusterRoleBinding for cleanup apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tekton-cleanup-binding labels: app.kubernetes.io/name: bakery-ia-cicd app.kubernetes.io/component: cleanup subjects: - kind: ServiceAccount name: tekton-cleanup-sa namespace: tekton-pipelines roleRef: kind: ClusterRole name: tekton-cleanup-role apiGroup: rbac.authorization.k8s.io --- # CronJob to clean up old PipelineRuns apiVersion: batch/v1 kind: CronJob metadata: name: tekton-pipelinerun-cleanup namespace: tekton-pipelines labels: app.kubernetes.io/name: bakery-ia-cicd app.kubernetes.io/component: cleanup spec: # Run every 6 hours schedule: "0 */6 * * *" concurrencyPolicy: Forbid successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 3 jobTemplate: spec: ttlSecondsAfterFinished: 3600 template: metadata: labels: app.kubernetes.io/name: bakery-ia-cicd app.kubernetes.io/component: cleanup spec: serviceAccountName: tekton-cleanup-sa restartPolicy: OnFailure containers: - name: cleanup image: bitnami/kubectl:latest command: - /bin/sh - -c - | #!/bin/sh set -e echo "============================================" echo "Tekton Cleanup Job" echo "Timestamp: $(date -u +"%Y-%m-%dT%H:%M:%SZ")" echo "============================================" # Configuration NAMESPACE="tekton-pipelines" MAX_AGE_HOURS=24 KEEP_RECENT=10 echo "" echo "Configuration:" echo " Namespace: $NAMESPACE" echo " Max Age: ${MAX_AGE_HOURS} hours" echo " Keep Recent: $KEEP_RECENT" echo "" # Get current timestamp CURRENT_TIME=$(date +%s) # Clean up completed PipelineRuns older than MAX_AGE_HOURS echo "Cleaning up old PipelineRuns..." # Get all completed PipelineRuns COMPLETED_RUNS=$(kubectl get pipelineruns -n "$NAMESPACE" \ --no-headers \ -o custom-columns=NAME:.metadata.name,STATUS:.status.conditions[0].reason,AGE:.metadata.creationTimestamp \ 2>/dev/null | grep -E "Succeeded|Failed" || true) DELETED_COUNT=0 echo "$COMPLETED_RUNS" | while read -r line; do if [ -z "$line" ]; then continue fi RUN_NAME=$(echo "$line" | awk '{print $1}') RUN_TIME=$(echo "$line" | awk '{print $3}') if [ -z "$RUN_NAME" ] || [ -z "$RUN_TIME" ]; then continue fi # Convert timestamp to seconds RUN_TIMESTAMP=$(date -d "$RUN_TIME" +%s 2>/dev/null || echo "0") if [ "$RUN_TIMESTAMP" = "0" ]; then continue fi # Calculate age in hours AGE_SECONDS=$((CURRENT_TIME - RUN_TIMESTAMP)) AGE_HOURS=$((AGE_SECONDS / 3600)) if [ "$AGE_HOURS" -gt "$MAX_AGE_HOURS" ]; then echo "Deleting PipelineRun: $RUN_NAME (age: ${AGE_HOURS}h)" kubectl delete pipelinerun "$RUN_NAME" -n "$NAMESPACE" --ignore-not-found=true DELETED_COUNT=$((DELETED_COUNT + 1)) fi done echo "Deleted $DELETED_COUNT old PipelineRuns" # Clean up orphaned PVCs (PVCs without associated PipelineRuns) echo "" echo "Cleaning up orphaned PVCs..." ORPHANED_PVCS=$(kubectl get pvc -n "$NAMESPACE" \ -l tekton.dev/pipelineRun \ --no-headers \ -o custom-columns=NAME:.metadata.name,PIPELINERUN:.metadata.labels.tekton\\.dev/pipelineRun \ 2>/dev/null || true) echo "$ORPHANED_PVCS" | while read -r line; do if [ -z "$line" ]; then continue fi PVC_NAME=$(echo "$line" | awk '{print $1}') PR_NAME=$(echo "$line" | awk '{print $2}') if [ -z "$PVC_NAME" ]; then continue fi # Check if associated PipelineRun exists if ! kubectl get pipelinerun "$PR_NAME" -n "$NAMESPACE" > /dev/null 2>&1; then echo "Deleting orphaned PVC: $PVC_NAME (PipelineRun $PR_NAME not found)" kubectl delete pvc "$PVC_NAME" -n "$NAMESPACE" --ignore-not-found=true fi done # Clean up completed/failed pods older than 1 hour echo "" echo "Cleaning up old completed pods..." kubectl delete pods -n "$NAMESPACE" \ --field-selector=status.phase=Succeeded \ --ignore-not-found=true 2>/dev/null || true kubectl delete pods -n "$NAMESPACE" \ --field-selector=status.phase=Failed \ --ignore-not-found=true 2>/dev/null || true echo "" echo "============================================" echo "Cleanup complete" echo "============================================" resources: limits: cpu: 200m memory: 256Mi requests: cpu: 100m memory: 128Mi --- # ConfigMap for cleanup configuration apiVersion: v1 kind: ConfigMap metadata: name: cleanup-config namespace: tekton-pipelines labels: app.kubernetes.io/name: bakery-ia-cicd app.kubernetes.io/component: cleanup data: # Maximum age of completed PipelineRuns to keep (in hours) MAX_AGE_HOURS: "24" # Number of recent PipelineRuns to keep regardless of age KEEP_RECENT: "10" # Cleanup schedule (cron format) CLEANUP_SCHEDULE: "0 */6 * * *"