Add Gitea Actions act runner (#666)

Co-authored-by: dementhorr <dementhorr@proton.me>
Co-authored-by: Vince Montalbano <vince.montalbano@gmail.com>

Reviewed-on: https://gitea.com/gitea/helm-chart/pulls/666
Reviewed-by: justusbunsi <justusbunsi@noreply.gitea.com>
Co-authored-by: vjm <vjm@noreply.gitea.com>
Co-committed-by: vjm <vjm@noreply.gitea.com>
This commit is contained in:
vjm
2024-11-10 13:35:56 +00:00
committed by justusbunsi
parent 5c7e78b467
commit f7c66c0336
24 changed files with 1142 additions and 0 deletions

View File

@ -25,6 +25,13 @@ If release name contains chart name it will be used as a full name.
{{- end -}}
{{- end -}}
{{/*
Create a default worker name.
*/}}
{{- define "gitea.workername" -}}
{{- printf "%s-%s" .global.Release.Name .worker | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
@ -92,6 +99,15 @@ version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{- define "gitea.labels.actRunner" -}}
helm.sh/chart: {{ include "gitea.chart" . }}
app: {{ include "gitea.name" . }}-act-runner
{{ include "gitea.selectorLabels.actRunner" . }}
app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
version: {{ .Values.image.tag | default .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
@ -100,6 +116,11 @@ app.kubernetes.io/name: {{ include "gitea.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{- define "gitea.selectorLabels.actRunner" -}}
app.kubernetes.io/name: {{ include "gitea.name" . }}-act-runner
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{- define "postgresql-ha.dns" -}}
{{- if (index .Values "postgresql-ha").enabled -}}
{{- printf "%s-postgresql-ha-pgpool.%s.svc.%s:%g" .Release.Name .Release.Namespace .Values.clusterDomain (index .Values "postgresql-ha" "service" "ports" "postgresql") -}}
@ -199,6 +220,15 @@ https
{{- end -}}
{{- end -}}
{{- define "gitea.act_runner.local_root_url" -}}
{{- if not .Values.gitea.config.server.LOCAL_ROOT_URL -}}
{{- printf "http://%s-http:%.0f" (include "gitea.fullname" .) .Values.service.http.port -}}
{{- else -}}
{{/* fallback for allowing to overwrite this value via inline config */}}
{{- .Values.gitea.config.server.LOCAL_ROOT_URL -}}
{{- end -}}
{{- end -}}
{{- define "gitea.inline_configuration" -}}
{{- include "gitea.inline_configuration.init" . -}}
{{- include "gitea.inline_configuration.defaults" . -}}
@ -263,6 +293,9 @@ https
{{- if not (hasKey .Values.gitea.config "indexer") -}}
{{- $_ := set .Values.gitea.config "indexer" dict -}}
{{- end -}}
{{- if not (hasKey .Values.gitea.config "actions") -}}
{{- $_ := set .Values.gitea.config "actions" dict -}}
{{- end -}}
{{- end -}}
{{- define "gitea.inline_configuration.defaults" -}}
@ -309,6 +342,9 @@ https
{{- if not .Values.gitea.config.indexer.ISSUE_INDEXER_TYPE -}}
{{- $_ := set .Values.gitea.config.indexer "ISSUE_INDEXER_TYPE" "db" -}}
{{- end -}}
{{- if not .Values.gitea.config.actions.ENABLED -}}
{{- $_ := set .Values.gitea.config.actions "ENABLED" (ternary "true" "false" .Values.actions.enabled) -}}
{{- end -}}
{{- end -}}
{{- define "gitea.inline_configuration.defaults.server" -}}
@ -328,6 +364,9 @@ https
{{- if not .Values.gitea.config.server.ROOT_URL -}}
{{- $_ := set .Values.gitea.config.server "ROOT_URL" (printf "%s://%s" (include "gitea.public_protocol" .) .Values.gitea.config.server.DOMAIN) -}}
{{- end -}}
{{- if .Values.actions.enabled -}}
{{- $_ := set .Values.gitea.config.server "LOCAL_ROOT_URL" (include "gitea.act_runner.local_root_url" .) -}}
{{- end -}}
{{- if not .Values.gitea.config.server.SSH_DOMAIN -}}
{{- $_ := set .Values.gitea.config.server "SSH_DOMAIN" .Values.gitea.config.server.DOMAIN -}}
{{- end -}}

View File

@ -0,0 +1,15 @@
{{- if .Values.actions.enabled -}}
{{- if .Values.actions.provisioning.enabled -}}
{{- if not (and .Values.persistence.enabled .Values.persistence.mount) -}}
{{- fail "persistence.enabled and persistence.mount are required when provisioning is enabled" -}}
{{- end -}}
{{- if and .Values.persistence.enabled .Values.persistence.mount -}}
{{- if .Values.actions.existingSecret -}}
{{- fail "Can't specify both actions.provisioning.enabled and actions.existingSecret" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if and (not .Values.actions.provisioning.enabled) (or (empty .Values.actions.existingSecret) (empty .Values.actions.existingSecretKey)) -}}
{{- fail "actions.existingSecret and actions.existingSecretKey are required when provisioning is disabled" -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,14 @@
{{- if .Values.actions.enabled }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "gitea.fullname" . }}-act-runner-config
labels:
{{- include "gitea.labels" . | nindent 4 }}
data:
config.yaml: |
{{- with .Values.actions.statefulset.actRunner.config -}}
{{ . | nindent 4}}
{{- end -}}
{{- end }}

View File

@ -0,0 +1,13 @@
{{- if .Values.actions.enabled }}
{{- if and (and .Values.actions.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "gitea.fullname" . }}-scripts
labels:
{{- include "gitea.labels" . | nindent 4 }}
data:
{{ (.Files.Glob "scripts/*.sh").AsConfig | indent 2 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,114 @@
{{- if .Values.actions.enabled }}
{{- if and (and .Values.actions.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- $name := include "gitea.workername" (dict "global" . "worker" "actions-token-job") }}
{{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
---
apiVersion: batch/v1
kind: Job
metadata:
name: {{ $name }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
{{- with .Values.actions.provisioning.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
app.kubernetes.io/component: token-job
annotations:
{{- with .Values.actions.provisioning.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ttlSecondsAfterFinished: {{ .Values.actions.provisioning.ttlSecondsAfterFinished }}
template:
metadata:
labels:
{{- include "gitea.labels" . | nindent 8 }}
{{- with .Values.actions.provisioning.labels }}
{{- toYaml . | nindent 8 }}
{{- end }}
app.kubernetes.io/component: token-job
spec:
initContainers:
- name: init-gitea
image: "{{ .Values.actions.init.image.repository }}:{{ .Values.actions.init.image.tag }}"
command:
- sh
- -c
- |
while ! nc -z {{ include "gitea.fullname" . }}-http {{ .Values.service.http.port }}; do
sleep 5
done
containers:
- name: actions-token-create
image: "{{ include "gitea.image" . }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: GITEA_APP_INI
value: /data/gitea/conf/app.ini
command:
- sh
- -c
- |
echo "Generating act_runner token via 'gitea actions generate-runner-token'..."
mkdir -p /data/actions/
gitea actions generate-runner-token | grep -E '^.{40}$' | tr -d '\n' > /data/actions/token
resources:
{{- toYaml .Values.actions.provisioning.resources | nindent 12 }}
volumeMounts:
- name: data
mountPath: /data
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
- name: actions-token-upload
image: "{{ .Values.actions.provisioning.publish.repository }}:{{ .Values.actions.provisioning.publish.tag }}"
imagePullPolicy: {{ .Values.actions.provisioning.publish.pullPolicy }}
env:
- name: SECRET_NAME
value: {{ $secretName }}
command:
- sh
- -c
- |
printf "Checking rights to update kubernetes act_runner secret..."
kubectl auth can-i update secret/${SECRET_NAME}
/scripts/token.sh
resources:
{{- toYaml .Values.actions.provisioning.resources | nindent 12 }}
volumeMounts:
- mountPath: /scripts
name: scripts
readOnly: true
- mountPath: /data
name: data
readOnly: true
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
{{- with .Values.actions.provisioning.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.actions.provisioning.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.actions.provisioning.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
restartPolicy: Never
serviceAccount: {{ $name }}
volumes:
- name: scripts
configMap:
name: {{ include "gitea.fullname" . }}-scripts
defaultMode: 0755
- name: data
persistentVolumeClaim:
claimName: {{ .Values.persistence.claimName }}
parallelism: 1
completions: 1
backoffLimit: 1
{{- end }}
{{- end }}

View File

@ -0,0 +1,25 @@
{{- if .Values.actions.enabled }}
{{- if and (and .Values.actions.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- $name := include "gitea.workername" (dict "global" . "worker" "actions-token-job") }}
{{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ $name }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
app.kubernetes.io/component: token-job
rules:
- apiGroups:
- ""
resources:
- secrets
resourceNames:
- {{ $secretName }}
verbs:
- get
- update
- patch
{{- end }}
{{- end }}

View File

@ -0,0 +1,22 @@
{{- if .Values.actions.enabled }}
{{- if and (and .Values.actions.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- $name := include "gitea.workername" (dict "global" . "worker" "actions-token-job") }}
{{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ $name }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
app.kubernetes.io/component: token-job
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ $name }}
subjects:
- kind: ServiceAccount
name: {{ $name }}
namespace: {{ .Release.Namespace }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,19 @@
{{- if .Values.actions.enabled }}
{{- if and (and .Values.actions.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- $name := include "gitea.workername" (dict "global" . "worker" "actions-token-job") }}
{{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ $secretName }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
app.kubernetes.io/component: token-job
{{ $secret := (lookup "v1" "Secret" .Release.Namespace $secretName) -}}
{{ if $secret -}}
data:
token: {{ (b64dec (index $secret.data "token")) | b64enc }}
{{ end -}}
{{- end }}
{{- end }}

View File

@ -0,0 +1,13 @@
{{- if .Values.actions.enabled }}
{{- if and (and .Values.actions.provisioning.enabled .Values.persistence.enabled) .Values.persistence.mount }}
{{- $name := include "gitea.workername" (dict "global" . "worker" "actions-token-job") }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ $name }}
labels:
{{- include "gitea.labels" . | nindent 4 }}
app.kubernetes.io/component: token-job
{{- end }}
{{- end }}

View File

@ -0,0 +1,114 @@
{{- if .Values.actions.enabled }}
{{- $secretName := include "gitea.workername" (dict "global" . "worker" "actions-token") }}
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
{{- include "gitea.labels.actRunner" . | nindent 4 }}
{{- with .Values.actions.statefulset.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
annotations:
{{- with .Values.actions.statefulset.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
name: {{ include "gitea.fullname" . }}-act-runner
spec:
selector:
matchLabels:
{{- include "gitea.selectorLabels.actRunner" . | nindent 6 }}
template:
metadata:
labels:
{{- include "gitea.labels.actRunner" . | nindent 8 }}
{{- with .Values.actions.statefulset.labels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
initContainers:
- name: init-gitea
image: "{{ .Values.actions.init.image.repository }}:{{ .Values.actions.init.image.tag }}"
command:
- sh
- -c
- |
while ! nc -z {{ include "gitea.fullname" . }}-http {{ .Values.service.http.port }}; do
sleep 5
done
containers:
- name: act-runner
image: "{{ .Values.actions.statefulset.actRunner.repository }}:{{ .Values.actions.statefulset.actRunner.tag }}"
imagePullPolicy: {{ .Values.actions.statefulset.actRunner.pullPolicy }}
workingDir: /data
env:
- name: DOCKER_HOST
value: tcp://127.0.0.1:2376
- name: DOCKER_TLS_VERIFY
value: "1"
- name: DOCKER_CERT_PATH
value: /certs/server
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
name: "{{ .Values.actions.existingSecret | default $secretName }}"
key: "{{ .Values.actions.existingSecretKey | default "token" }}"
- name: GITEA_INSTANCE_URL
value: {{ include "gitea.act_runner.local_root_url" . }}
- name: CONFIG_FILE
value: /actrunner/config.yaml
resources:
{{- toYaml .Values.actions.statefulset.resources | nindent 12 }}
volumeMounts:
- mountPath: /actrunner/config.yaml
name: act-runner-config
subPath: config.yaml
- mountPath: /certs/server
name: docker-certs
- mountPath: /data
name: data-act-runner
- name: dind
image: "{{ .Values.actions.statefulset.dind.repository }}:{{ .Values.actions.statefulset.dind.tag }}"
imagePullPolicy: {{ .Values.actions.statefulset.dind.pullPolicy }}
env:
- name: DOCKER_HOST
value: tcp://127.0.0.1:2376
- name: DOCKER_TLS_VERIFY
value: "1"
- name: DOCKER_CERT_PATH
value: /certs/server
securityContext:
privileged: true
resources:
{{- toYaml .Values.actions.statefulset.resources | nindent 12 }}
volumeMounts:
- mountPath: /certs/server
name: docker-certs
{{- with .Values.actions.statefulset.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.actions.statefulset.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.actions.statefulset.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: act-runner-config
configMap:
name: {{ include "gitea.fullname" . }}-act-runner-config
- name: docker-certs
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: data-act-runner
spec:
accessModes: [ "ReadWriteOnce" ]
{{- include "gitea.persistence.storageClass" . | nindent 8 }}
resources:
requests:
storage: 1Mi
{{- end }}