Skip to content

Commit 232e567

Browse files
committed
feat: add renku-ci-cleanup chart
1 parent ef11dba commit 232e567

File tree

12 files changed

+824
-0
lines changed

12 files changed

+824
-0
lines changed

.github/workflows/docker-build.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Build and Push CI Deployment Cleanup Docker Image
2+
3+
on:
4+
push:
5+
tags: [ 'ci-deployment-cleanup-v*' ]
6+
workflow_dispatch:
7+
8+
env:
9+
REGISTRY: ghcr.io
10+
IMAGE_NAME: swissdatasciencecenter/renku-ci-cleanup
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
packages: write
18+
id-token: write
19+
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
23+
24+
- name: Log in to Container Registry
25+
uses: docker/login-action@v3
26+
with:
27+
registry: ${{ env.REGISTRY }}
28+
username: ${{ github.actor }}
29+
password: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- name: Extract version from tag
32+
id: version
33+
run: |
34+
VERSION=$(echo "${{ github.ref_name }}" | sed 's/ci-deployment-cleanup-v//')
35+
echo "version=$VERSION" >> $GITHUB_OUTPUT
36+
37+
- name: Extract metadata (tags, labels) for Docker
38+
id: meta
39+
uses: docker/metadata-action@v5
40+
with:
41+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
42+
tags: |
43+
type=raw,value=${{ steps.version.outputs.version }}
44+
type=raw,value=latest
45+
46+
- name: Set up Docker Buildx
47+
uses: docker/setup-buildx-action@v3
48+
49+
- name: Build and push Docker image
50+
uses: docker/build-push-action@v5
51+
with:
52+
context: .
53+
file: ci-deployment-cleanup/Dockerfile
54+
platforms: linux/amd64,linux/arm64
55+
push: true
56+
tags: ${{ steps.meta.outputs.tags }}
57+
labels: ${{ steps.meta.outputs.labels }}
58+
cache-from: type=gha
59+
cache-to: type=gha,mode=max

.github/workflows/helm-chart.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Package and Push Helm Chart
2+
3+
on:
4+
push:
5+
tags: [ 'ci-deployment-cleanup-v*' ]
6+
workflow_dispatch:
7+
8+
env:
9+
REGISTRY: ghcr.io
10+
11+
jobs:
12+
helm-chart:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
packages: write
17+
id-token: write
18+
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v4
22+
23+
- name: Install Helm
24+
uses: azure/setup-helm@v4
25+
with:
26+
version: '3.14.0'
27+
28+
- name: Log in to Container Registry
29+
if: github.event_name != 'pull_request'
30+
uses: docker/login-action@v3
31+
with:
32+
registry: ${{ env.REGISTRY }}
33+
username: ${{ github.actor }}
34+
password: ${{ secrets.GITHUB_TOKEN }}
35+
36+
- name: Determine app version
37+
id: version
38+
run: |
39+
VERSION=$(echo "${{ github.ref_name }}" | sed 's/ci-deployment-cleanup-v//')
40+
echo "appVersion=$VERSION" >> $GITHUB_OUTPUT
41+
42+
- name: Update Chart.yaml with app version
43+
run: |
44+
cd ci-deployment-cleanup/helm-chart
45+
sed -i "s/appVersion: .*/appVersion: \"${{ steps.version.outputs.appVersion }}\"/" Chart.yaml
46+
47+
- name: Lint Helm chart
48+
run: |
49+
cd ci-deployment-cleanup
50+
helm lint helm-chart/
51+
52+
- name: Package and push Helm chart
53+
run: |
54+
cd ci-deployment-cleanup
55+
helm package helm-chart/
56+
helm push *.tgz oci://${{ env.REGISTRY }}/swissdatasciencecenter/helm-charts

ci-deployment-cleanup/Dockerfile

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
FROM golang:1.24-alpine AS builder
2+
3+
RUN apk add --no-cache make bash
4+
5+
WORKDIR /app
6+
7+
# Copy renku-dev-utils files
8+
COPY . .
9+
10+
# Build the rdu binary
11+
RUN make rdu
12+
13+
FROM alpine:3.18
14+
15+
RUN apk add --no-cache \
16+
bash \
17+
curl \
18+
ca-certificates \
19+
jq \
20+
openssl \
21+
&& ARCH=$(case $(uname -m) in x86_64) echo amd64;; aarch64) echo arm64;; *) echo amd64;; esac) \
22+
&& curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/${ARCH}/kubectl" \
23+
&& chmod +x kubectl \
24+
&& mv kubectl /usr/local/bin/
25+
26+
RUN curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 \
27+
&& chmod 700 get_helm.sh \
28+
&& ./get_helm.sh \
29+
&& rm get_helm.sh
30+
31+
# Copy the rdu binary from builder stage
32+
COPY --from=builder /app/build/renku-dev-utils /usr/local/bin/rdu
33+
34+
# Make rdu executable
35+
RUN chmod +x /usr/local/bin/rdu
36+
37+
# Create a non-root user
38+
RUN addgroup -g 1000 appuser && \
39+
adduser -u 1000 -G appuser -s /bin/bash -D appuser
40+
41+
# Switch to non-root user
42+
USER appuser
43+
44+
# Set working directory
45+
WORKDIR /home/appuser
46+
47+
# Verify installations
48+
RUN rdu version || echo "rdu installed" && \
49+
kubectl version --client && \
50+
helm version
51+
52+
CMD ["/bin/bash"]

ci-deployment-cleanup/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Renku CI Deployment Cleanup
2+
3+
A Kubernetes-based CI deployment cleanup system that uses a Helm chart to deploy automated cleanup of old Renku CI deployments. This system runs as a CronJob that leverages the `rdu` tool for comprehensive cleanup.
4+
5+
## Installation
6+
7+
Install the Helm chart:
8+
```bash
9+
helm install renku-ci-cleanup ./helm-chart
10+
```
11+
12+
## Exemption
13+
14+
Namespaces can be exempted from cleanup by adding the label `renku.io/cleanup-exempt: "true"` to the namespace.
15+
16+
## How It Works
17+
18+
1. The CronJob runs on the specified schedule (default: every 6 hours)
19+
2. It queries Kubernetes for ALL namespaces in the cluster
20+
3. For each namespace found:
21+
- Checks if the namespace has the exemption label (if so, skips it)
22+
- Checks if the namespace name matches any of the configured patterns (if enforcement is enabled)
23+
- Calculates the age based on the namespace creation timestamp
24+
- Checks GitHub PR status for PR-based cleanup (if enabled)
25+
- If the namespace is older than the configured threshold AND matches the naming patterns AND is not exempt, it uses `rdu cleanup-deployment` to:
26+
- Delete all sessions
27+
- Uninstall all Helm releases
28+
- Delete all jobs and PVCs
29+
- Delete the entire namespace
30+
4. Logging shows what actions were taken, including exemption and pattern matching results
31+
32+
## Key Configuration
33+
34+
The main configuration options in `values.yaml`:
35+
36+
- `cleanup.maxAge`: Maximum age in hours before cleanup (default: 720 hours / 30 days)
37+
- `cleanup.dryRun`: Enable dry-run mode (default: false)
38+
- `cleanup.namespacePatterns`: List of regex patterns for namespace names
39+
- `cleanup.enforceNamePatterns`: Enable strict pattern matching (default: true)
40+
- `cleanup.prCleanup.enabled`: Enable GitHub PR-based cleanup (default: false)
41+
- `cronJob.schedule`: Cron schedule (default: "0 */6 * * *" - every 6 hours)
42+
43+
## PR-Based Cleanup
44+
45+
The system supports GitHub PR-based cleanup that can automatically clean up namespaces when their associated pull requests are closed or merged. This feature requires:
46+
47+
- `cleanup.prCleanup.enabled: true`
48+
- GitHub API token configured
49+
- Repository mappings in `cleanup.prCleanup.repositories`
50+
51+
Example configuration maps namespace patterns to GitHub repositories and PR numbers.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: v2
2+
name: renku-ci-cleanup
3+
description: A Helm chart for cleaning up old Renku CI deployments
4+
type: application
5+
version: 1.0.0
6+
appVersion: "1.0.0"
7+
keywords:
8+
- renku
9+
- ci
10+
- cleanup
11+
- deployment
12+
home: https://github.com/SwissDataScienceCenter/renku-dev-utils
13+
sources:
14+
- https://github.com/SwissDataScienceCenter/renku-dev-utils
15+
maintainers:
16+
- name: Renku Team
17+
18+
url: https://renkulab.io
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "renku-ci-cleanup.name" -}}
5+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
8+
{{/*
9+
Create a default fully qualified app name.
10+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
11+
If release name contains chart name it will be used as a full name.
12+
*/}}
13+
{{- define "renku-ci-cleanup.fullname" -}}
14+
{{- if .Values.fullnameOverride }}
15+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
16+
{{- else }}
17+
{{- $name := default .Chart.Name .Values.nameOverride }}
18+
{{- if contains $name .Release.Name }}
19+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
20+
{{- else }}
21+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
22+
{{- end }}
23+
{{- end }}
24+
{{- end }}
25+
26+
{{/*
27+
Create chart name and version as used by the chart label.
28+
*/}}
29+
{{- define "renku-ci-cleanup.chart" -}}
30+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
31+
{{- end }}
32+
33+
{{/*
34+
Common labels
35+
*/}}
36+
{{- define "renku-ci-cleanup.labels" -}}
37+
helm.sh/chart: {{ include "renku-ci-cleanup.chart" . }}
38+
{{ include "renku-ci-cleanup.selectorLabels" . }}
39+
{{- if .Chart.AppVersion }}
40+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
41+
{{- end }}
42+
app.kubernetes.io/managed-by: {{ .Release.Service }}
43+
{{- end }}
44+
45+
{{/*
46+
Selector labels
47+
*/}}
48+
{{- define "renku-ci-cleanup.selectorLabels" -}}
49+
app.kubernetes.io/name: {{ include "renku-ci-cleanup.name" . }}
50+
app.kubernetes.io/instance: {{ .Release.Name }}
51+
{{- end }}
52+
53+
{{/*
54+
Create the name of the service account to use
55+
*/}}
56+
{{- define "renku-ci-cleanup.serviceAccountName" -}}
57+
{{- if .Values.serviceAccount.create }}
58+
{{- default (include "renku-ci-cleanup.fullname" .) .Values.serviceAccount.name }}
59+
{{- else }}
60+
{{- default "default" .Values.serviceAccount.name }}
61+
{{- end }}
62+
{{- end }}

0 commit comments

Comments
 (0)