Make runner smoke CI self contained
All checks were successful
trash-ci / smoke (push) Successful in 0s
All checks were successful
trash-ci / smoke (push) Successful in 0s
This commit is contained in:
commit
72580b1a67
17
.gitea/workflows/trash-ci.yaml
Normal file
17
.gitea/workflows/trash-ci.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
name: trash-ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
smoke:
|
||||
runs-on: linux-shell
|
||||
steps:
|
||||
- name: Smoke
|
||||
run: |
|
||||
echo "runner-ok"
|
||||
pwd
|
||||
date
|
||||
23
.helm/.helmignore
Executable file
23
.helm/.helmignore
Executable file
@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
9
.helm/Chart.lock
Normal file
9
.helm/Chart.lock
Normal file
@ -0,0 +1,9 @@
|
||||
dependencies:
|
||||
- name: universal-chart
|
||||
repository: oci://cr.yandex/crp3ccidau046kdj8g9q/charts
|
||||
version: 0.1.9
|
||||
- name: postgresql-preprod
|
||||
repository: oci://cr.yandex/crp3ccidau046kdj8g9q/charts
|
||||
version: 16.4.8
|
||||
digest: sha256:2fff848510e52c012ae7d941e38fbed2a017c94011e4b3dbca294e672f45a686
|
||||
generated: "2026-05-06T12:00:56.461784+03:00"
|
||||
14
.helm/Chart.yaml
Normal file
14
.helm/Chart.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
apiVersion: v2
|
||||
name: gitea
|
||||
description: Gitea with act_runner, PostgreSQL, S3 backups, and restore jobs.
|
||||
type: application
|
||||
version: 1.0.0
|
||||
appVersion: "1.22.6"
|
||||
dependencies:
|
||||
- name: universal-chart
|
||||
repository: oci://cr.yandex/crp3ccidau046kdj8g9q/charts
|
||||
version: 0.1.9
|
||||
- name: postgresql-preprod
|
||||
alias: postgresql
|
||||
repository: oci://cr.yandex/crp3ccidau046kdj8g9q/charts
|
||||
version: 16.4.8
|
||||
BIN
.helm/charts/postgresql-preprod-16.4.8.tgz
Normal file
BIN
.helm/charts/postgresql-preprod-16.4.8.tgz
Normal file
Binary file not shown.
BIN
.helm/charts/universal-chart-0.1.9.tgz
Normal file
BIN
.helm/charts/universal-chart-0.1.9.tgz
Normal file
Binary file not shown.
42
.helm/restore-values.example.yaml
Normal file
42
.helm/restore-values.example.yaml
Normal file
@ -0,0 +1,42 @@
|
||||
restore:
|
||||
enabled: true
|
||||
name: gitea-restore
|
||||
files:
|
||||
enabled: true
|
||||
postgresql:
|
||||
enabled: true
|
||||
host: postgresql
|
||||
s3:
|
||||
bucket: gitops-gitea
|
||||
endpointUrl: https://storage.yandexcloud.net
|
||||
region: ru-central1
|
||||
giteaFilesKey: gitops-backups/gitea-files/gitea-files-2026-05-06-141255.tar.gz
|
||||
postgresqlDumpKey: gitops-backups/postgresql/gitea-postgresql-2026-05-06-111204.sql.gz
|
||||
scaleGitea:
|
||||
enabled: true
|
||||
serviceAccountName: gitea-restore
|
||||
deploymentName: gitea
|
||||
waitTimeoutSeconds: 300
|
||||
scaleUp:
|
||||
enabled: true
|
||||
replicas: 1
|
||||
waitForRestoreTimeoutSeconds: 1800
|
||||
images:
|
||||
kubectl:
|
||||
repository: bitnamilegacy/kubectl
|
||||
tag: "1.30.6"
|
||||
pullPolicy: IfNotPresent
|
||||
awsCli:
|
||||
repository: amazon/aws-cli
|
||||
tag: "2.15.57"
|
||||
pullPolicy: IfNotPresent
|
||||
postgres:
|
||||
repository: postgres
|
||||
tag: "17"
|
||||
pullPolicy: IfNotPresent
|
||||
busybox:
|
||||
repository: busybox
|
||||
tag: "1.36"
|
||||
pullPolicy: IfNotPresent
|
||||
verify:
|
||||
enabled: true
|
||||
45
.helm/templates/_helpers.tpl
Normal file
45
.helm/templates/_helpers.tpl
Normal file
@ -0,0 +1,45 @@
|
||||
{{- define "gitea.name" -}}
|
||||
{{- default .Chart.Name .Values.global.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "gitea.fullname" -}}
|
||||
{{- if .Values.global.fullnameOverride -}}
|
||||
{{- .Values.global.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- include "gitea.name" . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "gitea.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "gitea.labels" -}}
|
||||
helm.sh/chart: {{ include "gitea.chart" . }}
|
||||
app.kubernetes.io/name: {{ include "gitea.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- with .Values.global.labels }}
|
||||
{{ toYaml . }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "gitea.secretName" -}}
|
||||
{{- default "gitea-secret" .Values.giteaSecret.name -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "gitea.giteaPvcName" -}}
|
||||
{{- if .Values.persistence.gitea.existingClaim -}}
|
||||
{{- .Values.persistence.gitea.existingClaim -}}
|
||||
{{- else -}}
|
||||
{{- default "gitea-data" .Values.persistence.gitea.name -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "gitea.runnerPvcName" -}}
|
||||
{{- if .Values.persistence.runner.existingClaim -}}
|
||||
{{- .Values.persistence.runner.existingClaim -}}
|
||||
{{- else -}}
|
||||
{{- default "gitea-runner-data" .Values.persistence.runner.name -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
170
.helm/templates/backup-cronjobs.yaml
Normal file
170
.helm/templates/backup-cronjobs.yaml
Normal file
@ -0,0 +1,170 @@
|
||||
{{- if and .Values.backup.enabled .Values.backup.giteaFiles.enabled (eq (default "sidecar" .Values.backup.giteaFiles.mode) "cronjob") }}
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: gitea-files-backup
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
spec:
|
||||
schedule: {{ .Values.backup.giteaFiles.schedule | quote }}
|
||||
{{- with .Values.backup.timeZone }}
|
||||
timeZone: {{ . | quote }}
|
||||
{{- end }}
|
||||
concurrencyPolicy: Forbid
|
||||
successfulJobsHistoryLimit: {{ .Values.backup.giteaFiles.successfulJobsHistoryLimit }}
|
||||
failedJobsHistoryLimit: {{ .Values.backup.giteaFiles.failedJobsHistoryLimit }}
|
||||
jobTemplate:
|
||||
spec:
|
||||
{{- with .Values.backup.giteaFiles.ttlSecondsAfterFinished }}
|
||||
ttlSecondsAfterFinished: {{ . }}
|
||||
{{- end }}
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: backup
|
||||
image: "{{ .Values.backup.giteaFiles.image.repository }}:{{ .Values.backup.giteaFiles.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.backup.giteaFiles.image.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
case "${AWS_ACCESS_KEY_ID:-}" in ""|GENERATED_*) echo "AWS_ACCESS_KEY_ID is not configured" >&2; exit 1;; esac
|
||||
case "${AWS_SECRET_ACCESS_KEY:-}" in ""|GENERATED_*) echo "AWS_SECRET_ACCESS_KEY is not configured" >&2; exit 1;; esac
|
||||
test -n "${S3_BUCKET:-}" || { echo "S3_BUCKET is not configured" >&2; exit 1; }
|
||||
|
||||
timestamp="$(date +%F-%H%M%S)"
|
||||
archive_name="gitea-files-${timestamp}.tar.gz"
|
||||
tar -C /data -czf "/tmp/${archive_name}" .
|
||||
aws --endpoint-url "${AWS_ENDPOINT_URL}" \
|
||||
s3 cp "/tmp/${archive_name}" "s3://${S3_BUCKET}/${S3_PREFIX}/gitea-files/${archive_name}"
|
||||
env:
|
||||
- name: S3_BUCKET
|
||||
value: {{ .Values.backup.s3.bucket | quote }}
|
||||
- name: S3_PREFIX
|
||||
value: {{ .Values.backup.s3.prefix | quote }}
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value: {{ .Values.backup.s3.region | quote }}
|
||||
- name: AWS_ENDPOINT_URL
|
||||
value: {{ .Values.backup.s3.endpointUrl | quote }}
|
||||
- name: AWS_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gitea.secretName" . | quote }}
|
||||
key: aws-access-key-id
|
||||
- name: AWS_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gitea.secretName" . | quote }}
|
||||
key: aws-secret-access-key
|
||||
volumeMounts:
|
||||
- name: gitea-data
|
||||
mountPath: /data
|
||||
readOnly: true
|
||||
resources:
|
||||
{{- toYaml .Values.backup.giteaFiles.resources | nindent 16 }}
|
||||
volumes:
|
||||
- name: gitea-data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "gitea.giteaPvcName" . | quote }}
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- if and .Values.backup.enabled .Values.backup.postgresql.enabled }}
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: gitea-postgresql-backup
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
spec:
|
||||
schedule: {{ .Values.backup.postgresql.schedule | quote }}
|
||||
{{- with .Values.backup.timeZone }}
|
||||
timeZone: {{ . | quote }}
|
||||
{{- end }}
|
||||
concurrencyPolicy: Forbid
|
||||
successfulJobsHistoryLimit: {{ .Values.backup.postgresql.successfulJobsHistoryLimit }}
|
||||
failedJobsHistoryLimit: {{ .Values.backup.postgresql.failedJobsHistoryLimit }}
|
||||
jobTemplate:
|
||||
spec:
|
||||
{{- with .Values.backup.postgresql.ttlSecondsAfterFinished }}
|
||||
ttlSecondsAfterFinished: {{ . }}
|
||||
{{- end }}
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
initContainers:
|
||||
- name: dump
|
||||
image: "{{ .Values.backup.postgresql.dumpImage.repository }}:{{ .Values.backup.postgresql.dumpImage.tag }}"
|
||||
imagePullPolicy: {{ .Values.backup.postgresql.dumpImage.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
timestamp="$(date +%F-%H%M%S)"
|
||||
dump_name="gitea-postgresql-${timestamp}.sql.gz"
|
||||
until pg_isready -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -d "${POSTGRES_DB}"; do
|
||||
sleep 5
|
||||
done
|
||||
pg_dump -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" "${POSTGRES_DB}" | gzip -9 > "/backup/${dump_name}"
|
||||
printf "%s" "${dump_name}" > /backup/dump-name
|
||||
env:
|
||||
- name: POSTGRES_HOST
|
||||
value: {{ .Values.backup.postgresql.host | quote }}
|
||||
- name: POSTGRES_DB
|
||||
value: {{ .Values.postgresql.auth.database | quote }}
|
||||
- name: POSTGRES_USER
|
||||
value: {{ .Values.postgresql.auth.username | quote }}
|
||||
- name: PGPASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.databaseSecret.name | quote }}
|
||||
key: {{ .Values.databaseSecret.passwordKey | quote }}
|
||||
volumeMounts:
|
||||
- name: backup
|
||||
mountPath: /backup
|
||||
containers:
|
||||
- name: upload
|
||||
image: "{{ .Values.backup.postgresql.uploadImage.repository }}:{{ .Values.backup.postgresql.uploadImage.tag }}"
|
||||
imagePullPolicy: {{ .Values.backup.postgresql.uploadImage.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
case "${AWS_ACCESS_KEY_ID:-}" in ""|GENERATED_*) echo "AWS_ACCESS_KEY_ID is not configured" >&2; exit 1;; esac
|
||||
case "${AWS_SECRET_ACCESS_KEY:-}" in ""|GENERATED_*) echo "AWS_SECRET_ACCESS_KEY is not configured" >&2; exit 1;; esac
|
||||
test -n "${S3_BUCKET:-}" || { echo "S3_BUCKET is not configured" >&2; exit 1; }
|
||||
|
||||
dump_name="$(cat /backup/dump-name)"
|
||||
aws --endpoint-url "${AWS_ENDPOINT_URL}" \
|
||||
s3 cp "/backup/${dump_name}" "s3://${S3_BUCKET}/${S3_PREFIX}/postgresql/${dump_name}"
|
||||
env:
|
||||
- name: S3_BUCKET
|
||||
value: {{ .Values.backup.s3.bucket | quote }}
|
||||
- name: S3_PREFIX
|
||||
value: {{ .Values.backup.s3.prefix | quote }}
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value: {{ .Values.backup.s3.region | quote }}
|
||||
- name: AWS_ENDPOINT_URL
|
||||
value: {{ .Values.backup.s3.endpointUrl | quote }}
|
||||
- name: AWS_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gitea.secretName" . | quote }}
|
||||
key: aws-access-key-id
|
||||
- name: AWS_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gitea.secretName" . | quote }}
|
||||
key: aws-secret-access-key
|
||||
volumeMounts:
|
||||
- name: backup
|
||||
mountPath: /backup
|
||||
resources:
|
||||
{{- toYaml .Values.backup.postgresql.resources | nindent 16 }}
|
||||
volumes:
|
||||
- name: backup
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
211
.helm/templates/gitea-deployment.yaml
Normal file
211
.helm/templates/gitea-deployment.yaml
Normal file
@ -0,0 +1,211 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: gitea
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
app: gitea
|
||||
service: gitea
|
||||
annotations:
|
||||
owner: "platform"
|
||||
spec:
|
||||
replicas: {{ .Values.gitea.replicaCount }}
|
||||
revisionHistoryLimit: 10
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: gitea
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 8 }}
|
||||
app: gitea
|
||||
service: gitea
|
||||
annotations:
|
||||
traffic.sidecar.istio.io/excludeOutboundPorts: "4317,4318,9411"
|
||||
spec:
|
||||
containers:
|
||||
- name: gitea
|
||||
image: "{{ .Values.gitea.image.repository }}:{{ .Values.gitea.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.gitea.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.gitea.service.targetPort }}
|
||||
protocol: TCP
|
||||
- name: ssh
|
||||
containerPort: 22
|
||||
protocol: TCP
|
||||
env:
|
||||
- name: USER_UID
|
||||
value: {{ .Values.gitea.uid | quote }}
|
||||
- name: USER_GID
|
||||
value: {{ .Values.gitea.gid | quote }}
|
||||
- name: GITEA__database__DB_TYPE
|
||||
value: postgres
|
||||
- name: GITEA__database__HOST
|
||||
value: postgresql:5432
|
||||
- name: GITEA__database__NAME
|
||||
value: {{ .Values.postgresql.auth.database | quote }}
|
||||
- name: GITEA__database__USER
|
||||
value: {{ .Values.postgresql.auth.username | quote }}
|
||||
- name: GITEA__database__PASSWD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.databaseSecret.name | quote }}
|
||||
key: {{ .Values.databaseSecret.passwordKey | quote }}
|
||||
- name: GITEA__server__DOMAIN
|
||||
value: {{ .Values.gitea.domain | quote }}
|
||||
- name: GITEA__server__SSH_DOMAIN
|
||||
value: {{ .Values.gitea.sshDomain | quote }}
|
||||
- name: GITEA__server__ROOT_URL
|
||||
value: {{ .Values.gitea.rootUrl | quote }}
|
||||
- name: GITEA__server__HTTP_PORT
|
||||
value: {{ .Values.gitea.httpPort | quote }}
|
||||
- name: GITEA__server__SSH_PORT
|
||||
value: {{ .Values.gitea.sshPort | quote }}
|
||||
- name: GITEA__server__SSH_LISTEN_PORT
|
||||
value: {{ .Values.gitea.sshListenPort | quote }}
|
||||
- name: GITEA__security__INSTALL_LOCK
|
||||
value: "true"
|
||||
- name: GITEA__actions__ENABLED
|
||||
value: "true"
|
||||
- name: TZ
|
||||
value: {{ .Values.gitea.timezone | quote }}
|
||||
startupProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.gitea.probes.startup.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.gitea.probes.startup.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.gitea.probes.startup.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.gitea.probes.startup.failureThreshold }}
|
||||
readinessProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.gitea.probes.readiness.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.gitea.probes.readiness.periodSeconds }}
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.gitea.probes.liveness.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.gitea.probes.liveness.periodSeconds }}
|
||||
volumeMounts:
|
||||
- name: gitea-data
|
||||
mountPath: /data
|
||||
resources:
|
||||
{{- toYaml .Values.gitea.resources | nindent 12 }}
|
||||
{{- if and .Values.backup.enabled .Values.backup.giteaFiles.enabled (eq (default "sidecar" .Values.backup.giteaFiles.mode) "sidecar") }}
|
||||
- name: gitea-files-archive
|
||||
image: "{{ .Values.backup.giteaFiles.archiveImage.repository }}:{{ .Values.backup.giteaFiles.archiveImage.tag }}"
|
||||
imagePullPolicy: {{ .Values.backup.giteaFiles.archiveImage.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
run_archive() {
|
||||
timestamp="$(date +%F-%H%M%S)"
|
||||
archive_name="gitea-files-${timestamp}.tar.gz"
|
||||
tmp_path="/backup/${archive_name}.tmp"
|
||||
archive_path="/backup/${archive_name}"
|
||||
marker_path="/backup/${archive_name}.ready"
|
||||
tar -C /data -czf "${tmp_path}" .
|
||||
mv "${tmp_path}" "${archive_path}"
|
||||
printf "%s" "${archive_name}" > "${marker_path}"
|
||||
}
|
||||
|
||||
last_run_file="/backup/.gitea-files-backup-last-run"
|
||||
if [ "${RUN_ON_START}" = "true" ]; then
|
||||
run_archive || true
|
||||
date +%F > "${last_run_file}"
|
||||
fi
|
||||
|
||||
while true; do
|
||||
current_time="$(date +%H:%M)"
|
||||
current_day="$(date +%F)"
|
||||
last_run="$(cat "${last_run_file}" 2>/dev/null || true)"
|
||||
if [ "${current_time}" = "${BACKUP_TIME}" ] && [ "${last_run}" != "${current_day}" ]; then
|
||||
if run_archive; then
|
||||
echo "${current_day}" > "${last_run_file}"
|
||||
fi
|
||||
fi
|
||||
sleep 60
|
||||
done
|
||||
env:
|
||||
- name: BACKUP_TIME
|
||||
value: {{ .Values.backup.giteaFiles.time | quote }}
|
||||
- name: RUN_ON_START
|
||||
value: {{ ternary "true" "false" .Values.backup.giteaFiles.runOnStart | quote }}
|
||||
- name: TZ
|
||||
value: {{ .Values.backup.timeZone | quote }}
|
||||
volumeMounts:
|
||||
- name: gitea-data
|
||||
mountPath: /data
|
||||
readOnly: true
|
||||
- name: gitea-files-backup
|
||||
mountPath: /backup
|
||||
resources:
|
||||
{{- toYaml .Values.backup.giteaFiles.resources | nindent 12 }}
|
||||
- name: gitea-files-upload
|
||||
image: "{{ .Values.backup.giteaFiles.uploadImage.repository }}:{{ .Values.backup.giteaFiles.uploadImage.tag }}"
|
||||
imagePullPolicy: {{ .Values.backup.giteaFiles.uploadImage.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
credentials_ready() {
|
||||
case "${AWS_ACCESS_KEY_ID:-}" in ""|GENERATED_*) echo "AWS_ACCESS_KEY_ID is not configured" >&2; return 1;; esac
|
||||
case "${AWS_SECRET_ACCESS_KEY:-}" in ""|GENERATED_*) echo "AWS_SECRET_ACCESS_KEY is not configured" >&2; return 1;; esac
|
||||
test -n "${S3_BUCKET:-}" || { echo "S3_BUCKET is not configured" >&2; return 1; }
|
||||
}
|
||||
|
||||
while true; do
|
||||
for marker_path in /backup/*.ready; do
|
||||
[ -e "${marker_path}" ] || continue
|
||||
archive_name="$(cat "${marker_path}")"
|
||||
archive_path="/backup/${archive_name}"
|
||||
[ -f "${archive_path}" ] || continue
|
||||
|
||||
if credentials_ready; then
|
||||
aws --endpoint-url "${AWS_ENDPOINT_URL}" \
|
||||
s3 cp "${archive_path}" "s3://${S3_BUCKET}/${S3_PREFIX}/gitea-files/${archive_name}"
|
||||
rm -f "${archive_path}" "${marker_path}"
|
||||
else
|
||||
sleep 300
|
||||
fi
|
||||
done
|
||||
sleep 60
|
||||
done
|
||||
env:
|
||||
- name: S3_BUCKET
|
||||
value: {{ .Values.backup.s3.bucket | quote }}
|
||||
- name: S3_PREFIX
|
||||
value: {{ .Values.backup.s3.prefix | quote }}
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value: {{ .Values.backup.s3.region | quote }}
|
||||
- name: AWS_ENDPOINT_URL
|
||||
value: {{ .Values.backup.s3.endpointUrl | quote }}
|
||||
- name: AWS_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gitea.secretName" . | quote }}
|
||||
key: aws-access-key-id
|
||||
- name: AWS_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gitea.secretName" . | quote }}
|
||||
key: aws-secret-access-key
|
||||
volumeMounts:
|
||||
- name: gitea-files-backup
|
||||
mountPath: /backup
|
||||
resources:
|
||||
{{- toYaml .Values.backup.giteaFiles.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: gitea-data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "gitea.giteaPvcName" . | quote }}
|
||||
{{- if and .Values.backup.enabled .Values.backup.giteaFiles.enabled (eq (default "sidecar" .Values.backup.giteaFiles.mode) "sidecar") }}
|
||||
- name: gitea-files-backup
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
18
.helm/templates/gitea-service.yaml
Normal file
18
.helm/templates/gitea-service.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: gitea
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
app: gitea
|
||||
service: gitea
|
||||
spec:
|
||||
type: {{ .Values.gitea.service.type }}
|
||||
selector:
|
||||
app: gitea
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.gitea.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
45
.helm/templates/pvc.yaml
Normal file
45
.helm/templates/pvc.yaml
Normal file
@ -0,0 +1,45 @@
|
||||
{{- if and .Values.persistence.gitea.create (not .Values.persistence.gitea.existingClaim) }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "gitea.giteaPvcName" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
{{- with .Values.persistence.gitea.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- toYaml .Values.persistence.gitea.accessModes | nindent 4 }}
|
||||
{{- with .Values.persistence.gitea.storageClass }}
|
||||
storageClassName: {{ . | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.gitea.size }}
|
||||
{{- end }}
|
||||
{{- if and .Values.persistence.runner.create (not .Values.persistence.runner.existingClaim) }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "gitea.runnerPvcName" . }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
{{- with .Values.persistence.runner.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- toYaml .Values.persistence.runner.accessModes | nindent 4 }}
|
||||
{{- with .Values.persistence.runner.storageClass }}
|
||||
storageClassName: {{ . | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.runner.size }}
|
||||
{{- end }}
|
||||
182
.helm/templates/restore-job.yaml
Normal file
182
.helm/templates/restore-job.yaml
Normal file
@ -0,0 +1,182 @@
|
||||
{{- if and .Values.restore .Values.restore.enabled }}
|
||||
{{- $restoreFiles := default false .Values.restore.files.enabled }}
|
||||
{{- $restorePostgresql := default false .Values.restore.postgresql.enabled }}
|
||||
{{- if not (or $restoreFiles $restorePostgresql) }}
|
||||
{{- fail "restore.enabled=true requires restore.files.enabled=true or restore.postgresql.enabled=true" }}
|
||||
{{- end }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ .Values.restore.name | quote }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-weight: "0"
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
spec:
|
||||
backoffLimit: 1
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
initContainers:
|
||||
- name: download
|
||||
image: "{{ .Values.restore.images.awsCli.repository }}:{{ .Values.restore.images.awsCli.tag }}"
|
||||
imagePullPolicy: {{ .Values.restore.images.awsCli.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
case "${AWS_ACCESS_KEY_ID:-}" in ""|GENERATED_*) echo "AWS_ACCESS_KEY_ID is not configured" >&2; exit 1;; esac
|
||||
case "${AWS_SECRET_ACCESS_KEY:-}" in ""|GENERATED_*) echo "AWS_SECRET_ACCESS_KEY is not configured" >&2; exit 1;; esac
|
||||
test -n "${S3_BUCKET:-}" || { echo "S3_BUCKET is not configured" >&2; exit 1; }
|
||||
{{- if $restoreFiles }}
|
||||
test -n "${GITEA_FILES_KEY}"
|
||||
aws --endpoint-url "${AWS_ENDPOINT_URL}" s3 cp "s3://${S3_BUCKET}/${GITEA_FILES_KEY}" /restore/gitea-files.tar.gz
|
||||
{{- end }}
|
||||
{{- if $restorePostgresql }}
|
||||
test -n "${POSTGRESQL_DUMP_KEY}"
|
||||
aws --endpoint-url "${AWS_ENDPOINT_URL}" s3 cp "s3://${S3_BUCKET}/${POSTGRESQL_DUMP_KEY}" /restore/postgresql.sql.gz
|
||||
{{- end }}
|
||||
env:
|
||||
- name: S3_BUCKET
|
||||
value: {{ .Values.restore.s3.bucket | quote }}
|
||||
- name: GITEA_FILES_KEY
|
||||
value: {{ default "" .Values.restore.s3.giteaFilesKey | quote }}
|
||||
- name: POSTGRESQL_DUMP_KEY
|
||||
value: {{ default "" .Values.restore.s3.postgresqlDumpKey | quote }}
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value: {{ .Values.restore.s3.region | quote }}
|
||||
- name: AWS_ENDPOINT_URL
|
||||
value: {{ .Values.restore.s3.endpointUrl | quote }}
|
||||
- name: AWS_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gitea.secretName" . | quote }}
|
||||
key: aws-access-key-id
|
||||
- name: AWS_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "gitea.secretName" . | quote }}
|
||||
key: aws-secret-access-key
|
||||
volumeMounts:
|
||||
- name: restore
|
||||
mountPath: /restore
|
||||
{{- if $restoreFiles }}
|
||||
- name: restore-files
|
||||
image: "{{ .Values.restore.images.busybox.repository }}:{{ .Values.restore.images.busybox.tag }}"
|
||||
imagePullPolicy: {{ .Values.restore.images.busybox.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
rm -rf /data/* /data/.[!.]* /data/..?*
|
||||
tar -C /data -xzf /restore/gitea-files.tar.gz
|
||||
volumeMounts:
|
||||
- name: restore
|
||||
mountPath: /restore
|
||||
- name: gitea-data
|
||||
mountPath: /data
|
||||
{{- end }}
|
||||
{{- if $restorePostgresql }}
|
||||
- name: restore-postgresql
|
||||
image: "{{ .Values.restore.images.postgres.repository }}:{{ .Values.restore.images.postgres.tag }}"
|
||||
imagePullPolicy: {{ .Values.restore.images.postgres.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
export PGPASSWORD="${POSTGRES_PASSWORD}"
|
||||
until pg_isready -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -d postgres; do
|
||||
sleep 5
|
||||
done
|
||||
|
||||
escaped_user="$(printf "%s" "${POSTGRES_USER}" | sed 's/"/""/g')"
|
||||
escaped_db="$(printf "%s" "${POSTGRES_DB}" | sed 's/"/""/g')"
|
||||
|
||||
if ! psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -d postgres -tAc "select 1 from pg_database where datname = '${POSTGRES_DB}'" | grep -q 1; then
|
||||
createdb -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -O "${POSTGRES_USER}" "${POSTGRES_DB}"
|
||||
fi
|
||||
|
||||
psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -d postgres -v ON_ERROR_STOP=1 \
|
||||
-c "ALTER DATABASE \"${escaped_db}\" OWNER TO \"${escaped_user}\";"
|
||||
|
||||
psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" -v ON_ERROR_STOP=1 \
|
||||
-c "DROP SCHEMA IF EXISTS public CASCADE; CREATE SCHEMA public AUTHORIZATION \"${POSTGRES_USER}\"; GRANT ALL ON SCHEMA public TO \"${POSTGRES_USER}\";"
|
||||
|
||||
gunzip -c /restore/postgresql.sql.gz | psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" -v ON_ERROR_STOP=1
|
||||
env:
|
||||
- name: POSTGRES_HOST
|
||||
value: {{ .Values.restore.postgresql.host | quote }}
|
||||
- name: POSTGRES_DB
|
||||
value: {{ .Values.postgresql.auth.database | quote }}
|
||||
- name: POSTGRES_USER
|
||||
value: {{ .Values.postgresql.auth.username | quote }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.databaseSecret.name | quote }}
|
||||
key: {{ .Values.databaseSecret.passwordKey | quote }}
|
||||
volumeMounts:
|
||||
- name: restore
|
||||
mountPath: /restore
|
||||
{{- end }}
|
||||
containers:
|
||||
{{- if .Values.restore.verify.enabled }}
|
||||
- name: verify
|
||||
image: "{{ .Values.restore.images.postgres.repository }}:{{ .Values.restore.images.postgres.tag }}"
|
||||
imagePullPolicy: {{ .Values.restore.images.postgres.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
{{- if $restoreFiles }}
|
||||
test -d /data
|
||||
objects="$(find /data -mindepth 1 -maxdepth 2 | head -n 1)"
|
||||
test -n "${objects}"
|
||||
{{- end }}
|
||||
{{- if $restorePostgresql }}
|
||||
tables="$(psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" -tAc "select count(*) from information_schema.tables where table_schema = 'public'")"
|
||||
test "${tables}" -gt 0
|
||||
core_tables="$(psql -h "${POSTGRES_HOST}" -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" -tAc "select count(*) from information_schema.tables where table_schema = 'public' and table_name in ('user', 'repository', 'version')")"
|
||||
test "${core_tables}" -gt 0
|
||||
echo "Gitea database restore verification passed: ${tables} public tables, ${core_tables} core tables"
|
||||
{{- end }}
|
||||
echo "Gitea restore verification passed"
|
||||
env:
|
||||
- name: POSTGRES_HOST
|
||||
value: {{ .Values.restore.postgresql.host | quote }}
|
||||
- name: POSTGRES_DB
|
||||
value: {{ .Values.postgresql.auth.database | quote }}
|
||||
- name: POSTGRES_USER
|
||||
value: {{ .Values.postgresql.auth.username | quote }}
|
||||
- name: PGPASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.databaseSecret.name | quote }}
|
||||
key: {{ .Values.databaseSecret.passwordKey | quote }}
|
||||
{{- if $restoreFiles }}
|
||||
volumeMounts:
|
||||
- name: gitea-data
|
||||
mountPath: /data
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- name: done
|
||||
image: "{{ .Values.restore.images.busybox.repository }}:{{ .Values.restore.images.busybox.tag }}"
|
||||
imagePullPolicy: {{ .Values.restore.images.busybox.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- echo "Gitea restore completed"
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: restore
|
||||
emptyDir: {}
|
||||
{{- if $restoreFiles }}
|
||||
- name: gitea-data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "gitea.giteaPvcName" . | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
73
.helm/templates/restore-rbac.yaml
Normal file
73
.helm/templates/restore-rbac.yaml
Normal file
@ -0,0 +1,73 @@
|
||||
{{- if and .Values.restore .Values.restore.enabled .Values.restore.scaleGitea.enabled }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ default .Values.restore.name .Values.restore.scaleGitea.serviceAccountName | quote }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-weight: "-30"
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ default .Values.restore.name .Values.restore.scaleGitea.serviceAccountName | quote }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-weight: "-30"
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
rules:
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- deployments
|
||||
- deployments/scale
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- batch
|
||||
resources:
|
||||
- jobs
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ default .Values.restore.name .Values.restore.scaleGitea.serviceAccountName | quote }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-weight: "-30"
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ default .Values.restore.name .Values.restore.scaleGitea.serviceAccountName | quote }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ default .Values.restore.name .Values.restore.scaleGitea.serviceAccountName | quote }}
|
||||
{{- end }}
|
||||
38
.helm/templates/restore-scale-down-job.yaml
Normal file
38
.helm/templates/restore-scale-down-job.yaml
Normal file
@ -0,0 +1,38 @@
|
||||
{{- if and .Values.restore .Values.restore.enabled .Values.restore.scaleGitea.enabled }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ printf "%s-scale-down" .Values.restore.name | quote }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-weight: "-10"
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
spec:
|
||||
backoffLimit: 1
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
serviceAccountName: {{ default .Values.restore.name .Values.restore.scaleGitea.serviceAccountName | quote }}
|
||||
containers:
|
||||
- name: scale-down-gitea
|
||||
image: "{{ .Values.restore.images.kubectl.repository }}:{{ .Values.restore.images.kubectl.tag }}"
|
||||
imagePullPolicy: {{ .Values.restore.images.kubectl.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
kubectl -n "${K8S_NAMESPACE}" scale deployment "${GITEA_DEPLOYMENT_NAME}" --replicas=0
|
||||
kubectl -n "${K8S_NAMESPACE}" wait --for=delete pod -l app=gitea --timeout="${WAIT_TIMEOUT_SECONDS}s" || true
|
||||
env:
|
||||
- name: K8S_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: GITEA_DEPLOYMENT_NAME
|
||||
value: {{ .Values.restore.scaleGitea.deploymentName | quote }}
|
||||
- name: WAIT_TIMEOUT_SECONDS
|
||||
value: {{ .Values.restore.scaleGitea.waitTimeoutSeconds | quote }}
|
||||
{{- end }}
|
||||
42
.helm/templates/restore-scale-up-job.yaml
Normal file
42
.helm/templates/restore-scale-up-job.yaml
Normal file
@ -0,0 +1,42 @@
|
||||
{{- if and .Values.restore .Values.restore.enabled .Values.restore.scaleGitea.enabled .Values.restore.scaleGitea.scaleUp.enabled }}
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ printf "%s-scale-up" .Values.restore.name | quote }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-weight: "10"
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
spec:
|
||||
backoffLimit: 1
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
serviceAccountName: {{ default .Values.restore.name .Values.restore.scaleGitea.serviceAccountName | quote }}
|
||||
containers:
|
||||
- name: scale-up-gitea
|
||||
image: "{{ .Values.restore.images.kubectl.repository }}:{{ .Values.restore.images.kubectl.tag }}"
|
||||
imagePullPolicy: {{ .Values.restore.images.kubectl.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- |
|
||||
kubectl -n "${K8S_NAMESPACE}" wait --for=condition=complete "job/${RESTORE_JOB_NAME}" --timeout="${RESTORE_WAIT_TIMEOUT_SECONDS}s"
|
||||
kubectl -n "${K8S_NAMESPACE}" scale deployment "${GITEA_DEPLOYMENT_NAME}" --replicas="${REPLICAS_AFTER_RESTORE}"
|
||||
env:
|
||||
- name: K8S_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: RESTORE_JOB_NAME
|
||||
value: {{ .Values.restore.name | quote }}
|
||||
- name: GITEA_DEPLOYMENT_NAME
|
||||
value: {{ .Values.restore.scaleGitea.deploymentName | quote }}
|
||||
- name: REPLICAS_AFTER_RESTORE
|
||||
value: {{ .Values.restore.scaleGitea.scaleUp.replicas | quote }}
|
||||
- name: RESTORE_WAIT_TIMEOUT_SECONDS
|
||||
value: {{ .Values.restore.scaleGitea.scaleUp.waitForRestoreTimeoutSeconds | quote }}
|
||||
{{- end }}
|
||||
43
.helm/templates/runner-configmap.yaml
Normal file
43
.helm/templates/runner-configmap.yaml
Normal file
@ -0,0 +1,43 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: gitea-runner-config
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |-
|
||||
{{ toYaml .Values.runner.config | nindent 4 }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: gitea-runner-entrypoint
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
data:
|
||||
runner-entrypoint.sh: |-
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
case "${GITEA_RUNNER_REGISTRATION_TOKEN:-}" in
|
||||
""|GENERATED_*)
|
||||
echo "GITEA_RUNNER_REGISTRATION_TOKEN is not configured in Kubernetes secret"
|
||||
echo "Patch secret gitea-secret key runner-registration-token and restart this pod"
|
||||
exec tail -f /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ ! -f /data/.runner ]; then
|
||||
echo "Registering Gitea runner ${GITEA_RUNNER_NAME} ..."
|
||||
act_runner register --no-interactive \
|
||||
--instance "${GITEA_INSTANCE_URL}" \
|
||||
--token "${GITEA_RUNNER_REGISTRATION_TOKEN}" \
|
||||
--name "${GITEA_RUNNER_NAME}" \
|
||||
--labels "${GITEA_RUNNER_LABELS}" \
|
||||
--config /config.yaml
|
||||
fi
|
||||
|
||||
echo "Starting Gitea runner daemon"
|
||||
exec act_runner daemon --config /config.yaml
|
||||
31
.helm/templates/secret.yaml
Normal file
31
.helm/templates/secret.yaml
Normal file
@ -0,0 +1,31 @@
|
||||
{{- if .Values.giteaSecret.create }}
|
||||
{{- $secretName := include "gitea.secretName" . }}
|
||||
{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace $secretName }}
|
||||
{{- if not $existingSecret }}
|
||||
{{- $runnerToken := printf "GENERATED_%s" (randAlphaNum 48) }}
|
||||
{{- $awsAccessKeyId := printf "GENERATED_%s" (randAlphaNum 32) }}
|
||||
{{- $awsSecretAccessKey := printf "GENERATED_%s" (randAlphaNum 64) }}
|
||||
{{- $kubeconfig := "apiVersion: v1\nclusters: []\ncontexts: []\ncurrent-context: \"\"\nkind: Config\npreferences: {}\nusers: []" }}
|
||||
{{- $dockerConfigJson := "{\"auths\":{}}" }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ $secretName }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
{{- if .Values.giteaSecret.keep }}
|
||||
annotations:
|
||||
helm.sh/resource-policy: keep
|
||||
{{- end }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
runner-registration-token: {{ $runnerToken | quote }}
|
||||
aws-access-key-id: {{ $awsAccessKeyId | quote }}
|
||||
aws-secret-access-key: {{ $awsSecretAccessKey | quote }}
|
||||
kubeconfig: |-
|
||||
{{ $kubeconfig | nindent 4 }}
|
||||
docker-config.json: |-
|
||||
{{ $dockerConfigJson | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
24
.helm/templates/ssh-service.yaml
Normal file
24
.helm/templates/ssh-service.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
{{- if .Values.sshService.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Values.sshService.name | quote }}
|
||||
namespace: {{ .Release.Namespace | quote }}
|
||||
labels:
|
||||
{{- include "gitea.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.sshService.type }}
|
||||
{{- if and .Values.sshService.externalTrafficPolicy (or (eq .Values.sshService.type "NodePort") (eq .Values.sshService.type "LoadBalancer")) }}
|
||||
externalTrafficPolicy: {{ .Values.sshService.externalTrafficPolicy }}
|
||||
{{- end }}
|
||||
selector:
|
||||
app: gitea
|
||||
ports:
|
||||
- name: ssh
|
||||
port: {{ .Values.sshService.port }}
|
||||
targetPort: {{ .Values.sshService.targetPort }}
|
||||
protocol: TCP
|
||||
{{- if and (eq .Values.sshService.type "NodePort") .Values.sshService.nodePort }}
|
||||
nodePort: {{ .Values.sshService.nodePort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
527
.helm/values.yaml
Normal file
527
.helm/values.yaml
Normal file
@ -0,0 +1,527 @@
|
||||
global:
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
imagePullSecrets: []
|
||||
labels: {}
|
||||
|
||||
giteaSecret:
|
||||
create: true
|
||||
name: gitea-secret
|
||||
keep: true
|
||||
|
||||
databaseSecret:
|
||||
name: postgresql-secret
|
||||
adminPasswordKey: admin-password
|
||||
passwordKey: user-password
|
||||
|
||||
persistence:
|
||||
gitea:
|
||||
create: true
|
||||
name: gitea-data
|
||||
existingClaim: ""
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClass: ""
|
||||
size: 50Gi
|
||||
annotations: {}
|
||||
runner:
|
||||
create: true
|
||||
name: gitea-runner-data
|
||||
existingClaim: ""
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
storageClass: ""
|
||||
size: 10Gi
|
||||
annotations: {}
|
||||
|
||||
postgresql:
|
||||
enabled: true
|
||||
fullnameOverride: postgresql
|
||||
global:
|
||||
imagePullSecrets: []
|
||||
security:
|
||||
allowInsecureImages: true
|
||||
postgresql:
|
||||
auth:
|
||||
username: gitea
|
||||
database: gitea
|
||||
existingSecret: postgresql-secret
|
||||
secretKeys:
|
||||
adminPasswordKey: admin-password
|
||||
userPasswordKey: user-password
|
||||
replicationPasswordKey: replication-password
|
||||
auth:
|
||||
username: gitea
|
||||
database: gitea
|
||||
existingSecret: postgresql-secret
|
||||
secretKeys:
|
||||
adminPasswordKey: admin-password
|
||||
userPasswordKey: user-password
|
||||
replicationPasswordKey: replication-password
|
||||
image:
|
||||
repository: contour/postgresql
|
||||
pullSecrets: []
|
||||
primary:
|
||||
podAntiAffinityPreset: ""
|
||||
networkPolicy:
|
||||
enabled: false
|
||||
podSecurityContext:
|
||||
enabled: false
|
||||
containerSecurityContext:
|
||||
enabled: false
|
||||
persistence:
|
||||
storageClass: ""
|
||||
size: 20Gi
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
metrics:
|
||||
enabled: false
|
||||
image:
|
||||
pullSecrets: []
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
prometheusRule:
|
||||
enabled: false
|
||||
volumePermissions:
|
||||
image:
|
||||
pullSecrets: []
|
||||
|
||||
sshService:
|
||||
enabled: true
|
||||
name: gitea-ssh
|
||||
type: NodePort
|
||||
port: 22
|
||||
targetPort: 22
|
||||
nodePort: 30222
|
||||
externalTrafficPolicy: Cluster
|
||||
|
||||
runner:
|
||||
config:
|
||||
log:
|
||||
level: info
|
||||
runner:
|
||||
file: /data/.runner
|
||||
capacity: 2
|
||||
insecure: false
|
||||
timeout: 3h
|
||||
cache:
|
||||
enabled: true
|
||||
dir: /data/cache
|
||||
container:
|
||||
network: ""
|
||||
privileged: false
|
||||
|
||||
gitea:
|
||||
replicaCount: 1
|
||||
image:
|
||||
repository: gitea/gitea
|
||||
tag: "1.22.6"
|
||||
pullPolicy: IfNotPresent
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
targetPort: 3000
|
||||
uid: "1000"
|
||||
gid: "1000"
|
||||
domain: 158-160-253-227.nip.io
|
||||
sshDomain: 158-160-253-227.nip.io
|
||||
rootUrl: https://158-160-253-227.nip.io/
|
||||
httpPort: "3000"
|
||||
sshPort: "30222"
|
||||
sshListenPort: "22"
|
||||
timezone: Europe/Moscow
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2Gi
|
||||
probes:
|
||||
startup:
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 2
|
||||
failureThreshold: 60
|
||||
readiness:
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
liveness:
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
|
||||
backup:
|
||||
enabled: true
|
||||
timeZone: Europe/Moscow
|
||||
s3:
|
||||
bucket: gitops-gitea
|
||||
region: ru-central1
|
||||
endpointUrl: https://storage.yandexcloud.net
|
||||
prefix: gitops-backups
|
||||
giteaFiles:
|
||||
enabled: true
|
||||
mode: sidecar
|
||||
schedule: "30 2 * * *"
|
||||
time: "02:30"
|
||||
runOnStart: false
|
||||
archiveImage:
|
||||
repository: busybox
|
||||
tag: "1.36"
|
||||
pullPolicy: IfNotPresent
|
||||
uploadImage:
|
||||
repository: amazon/aws-cli
|
||||
tag: "2.15.57"
|
||||
pullPolicy: IfNotPresent
|
||||
successfulJobsHistoryLimit: 3
|
||||
failedJobsHistoryLimit: 3
|
||||
ttlSecondsAfterFinished: 86400
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
postgresql:
|
||||
enabled: true
|
||||
schedule: "45 2 * * *"
|
||||
host: postgresql
|
||||
dumpImage:
|
||||
repository: postgres
|
||||
tag: "17"
|
||||
pullPolicy: IfNotPresent
|
||||
uploadImage:
|
||||
repository: amazon/aws-cli
|
||||
tag: "2.15.57"
|
||||
pullPolicy: IfNotPresent
|
||||
successfulJobsHistoryLimit: 3
|
||||
failedJobsHistoryLimit: 3
|
||||
ttlSecondsAfterFinished: 86400
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
|
||||
universal-chart:
|
||||
global:
|
||||
env: _default
|
||||
|
||||
services:
|
||||
gitea:
|
||||
enabled: false
|
||||
deployment:
|
||||
enabled: true
|
||||
name:
|
||||
_default: gitea
|
||||
replicaCount:
|
||||
_default: 1
|
||||
port:
|
||||
_default: 3000
|
||||
revisionHistoryLimit:
|
||||
_default: 10
|
||||
strategy:
|
||||
_default:
|
||||
type: Recreate
|
||||
resources:
|
||||
requests:
|
||||
cpu:
|
||||
_default: 200m
|
||||
memory:
|
||||
_default: 512Mi
|
||||
limits:
|
||||
cpu:
|
||||
_default: 2000m
|
||||
memory:
|
||||
_default: 2Gi
|
||||
probes:
|
||||
startup:
|
||||
enabled:
|
||||
_default: true
|
||||
type:
|
||||
_default: tcpSocket
|
||||
tcpSocket:
|
||||
port:
|
||||
_default: 3000
|
||||
initialDelaySeconds:
|
||||
_default: 10
|
||||
periodSeconds:
|
||||
_default: 10
|
||||
timeoutSeconds:
|
||||
_default: 2
|
||||
failureThreshold:
|
||||
_default: 60
|
||||
liveness:
|
||||
enabled:
|
||||
_default: true
|
||||
type:
|
||||
_default: tcpSocket
|
||||
tcpSocket:
|
||||
port:
|
||||
_default: 3000
|
||||
initialDelaySeconds:
|
||||
_default: 30
|
||||
periodSeconds:
|
||||
_default: 30
|
||||
readiness:
|
||||
enabled:
|
||||
_default: true
|
||||
type:
|
||||
_default: tcpSocket
|
||||
tcpSocket:
|
||||
port:
|
||||
_default: 3000
|
||||
initialDelaySeconds:
|
||||
_default: 10
|
||||
periodSeconds:
|
||||
_default: 10
|
||||
image:
|
||||
name:
|
||||
_default: gitea/gitea:1.22.6
|
||||
pullPolicy:
|
||||
_default: IfNotPresent
|
||||
imagePullSecrets:
|
||||
enabled:
|
||||
_default: false
|
||||
name:
|
||||
_default: dockerhub
|
||||
service:
|
||||
enabled: true
|
||||
name:
|
||||
_default: gitea
|
||||
type:
|
||||
_default: ClusterIP
|
||||
portName:
|
||||
_default: http
|
||||
port:
|
||||
_default: 3000
|
||||
targetPort:
|
||||
_default: http
|
||||
envs:
|
||||
- name: USER_UID
|
||||
value:
|
||||
_default: "1000"
|
||||
- name: USER_GID
|
||||
value:
|
||||
_default: "1000"
|
||||
- name: GITEA__database__DB_TYPE
|
||||
value:
|
||||
_default: postgres
|
||||
- name: GITEA__database__HOST
|
||||
value:
|
||||
_default: postgresql:5432
|
||||
- name: GITEA__database__NAME
|
||||
value:
|
||||
_default: gitea
|
||||
- name: GITEA__database__USER
|
||||
value:
|
||||
_default: gitea
|
||||
- name: GITEA__server__DOMAIN
|
||||
value:
|
||||
_default: 158-160-253-227.nip.io
|
||||
- name: GITEA__server__SSH_DOMAIN
|
||||
value:
|
||||
_default: 158-160-253-227.nip.io
|
||||
- name: GITEA__server__ROOT_URL
|
||||
value:
|
||||
_default: https://158-160-253-227.nip.io/
|
||||
- name: GITEA__server__HTTP_PORT
|
||||
value:
|
||||
_default: "3000"
|
||||
- name: GITEA__server__SSH_PORT
|
||||
value:
|
||||
_default: "30222"
|
||||
- name: GITEA__server__SSH_LISTEN_PORT
|
||||
value:
|
||||
_default: "22"
|
||||
- name: GITEA__security__INSTALL_LOCK
|
||||
value:
|
||||
_default: "true"
|
||||
- name: GITEA__actions__ENABLED
|
||||
value:
|
||||
_default: "true"
|
||||
- name: TZ
|
||||
value:
|
||||
_default: Europe/Moscow
|
||||
secretEnvs:
|
||||
- name: GITEA__database__PASSWD
|
||||
secretName:
|
||||
_default: postgresql-secret
|
||||
secretKey:
|
||||
_default: user-password
|
||||
volumes:
|
||||
_default:
|
||||
- name: gitea-data
|
||||
mountPath: /data
|
||||
persistentVolumeClaim:
|
||||
claimName:
|
||||
_default: gitea-data
|
||||
commitSha: ""
|
||||
gitlabUri: ""
|
||||
gitlabJobUrl: ""
|
||||
owner: platform
|
||||
|
||||
gitea-ci-worker:
|
||||
enabled: true
|
||||
deployment:
|
||||
enabled: true
|
||||
name:
|
||||
_default: gitea-ci-worker
|
||||
replicaCount:
|
||||
_default: 1
|
||||
port:
|
||||
_default: 8088
|
||||
command:
|
||||
_default:
|
||||
- /bin/sh
|
||||
- /runner-entrypoint.sh
|
||||
revisionHistoryLimit:
|
||||
_default: 10
|
||||
strategy:
|
||||
_default:
|
||||
type: Recreate
|
||||
resources:
|
||||
requests:
|
||||
cpu:
|
||||
_default: 200m
|
||||
memory:
|
||||
_default: 256Mi
|
||||
limits:
|
||||
cpu:
|
||||
_default: 2000m
|
||||
memory:
|
||||
_default: 2Gi
|
||||
probes:
|
||||
liveness:
|
||||
enabled: false
|
||||
readiness:
|
||||
enabled: false
|
||||
image:
|
||||
name:
|
||||
_default: gitea/act_runner:0.2.11
|
||||
pullPolicy:
|
||||
_default: IfNotPresent
|
||||
imagePullSecrets:
|
||||
enabled:
|
||||
_default: false
|
||||
name:
|
||||
_default: dockerhub
|
||||
service:
|
||||
enabled: false
|
||||
name:
|
||||
_default: gitea-ci-worker
|
||||
type:
|
||||
_default: ClusterIP
|
||||
portName:
|
||||
_default: http
|
||||
port:
|
||||
_default: 8088
|
||||
targetPort:
|
||||
_default: http
|
||||
envs:
|
||||
- name: GITEA_INSTANCE_URL
|
||||
value:
|
||||
_default: http://gitea:3000/
|
||||
- name: GITEA_RUNNER_NAME
|
||||
value:
|
||||
_default: registry01-runner
|
||||
- name: GITEA_RUNNER_LABELS
|
||||
value:
|
||||
_default: linux-amd64:docker://node:20-bookworm,linux-shell:host
|
||||
- name: DOCKER_HOST
|
||||
value:
|
||||
_default: unix:///var/run/docker.sock
|
||||
- name: KUBECONFIG
|
||||
value:
|
||||
_default: /data/.kube/config
|
||||
- name: KUBE_CONTEXT
|
||||
value:
|
||||
_default: yc-k8s-test
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value:
|
||||
_default: ru-central1
|
||||
- name: AWS_ENDPOINT_URL
|
||||
value:
|
||||
_default: https://storage.yandexcloud.net
|
||||
- name: S3_BUCKET
|
||||
value:
|
||||
_default: gitops-gitea
|
||||
- name: S3_PREFIX
|
||||
value:
|
||||
_default: gitops-backups
|
||||
secretEnvs:
|
||||
- name: GITEA_RUNNER_REGISTRATION_TOKEN
|
||||
secretName:
|
||||
_default: gitea-secret
|
||||
secretKey:
|
||||
_default: runner-registration-token
|
||||
- name: AWS_ACCESS_KEY_ID
|
||||
secretName:
|
||||
_default: gitea-secret
|
||||
secretKey:
|
||||
_default: aws-access-key-id
|
||||
- name: AWS_SECRET_ACCESS_KEY
|
||||
secretName:
|
||||
_default: gitea-secret
|
||||
secretKey:
|
||||
_default: aws-secret-access-key
|
||||
volumes:
|
||||
_default:
|
||||
- name: runner-data
|
||||
mountPath: /data
|
||||
persistentVolumeClaim:
|
||||
claimName:
|
||||
_default: gitea-runner-data
|
||||
- name: runner-config
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
readOnly: true
|
||||
configMap:
|
||||
name: gitea-runner-config
|
||||
items:
|
||||
- key: config.yaml
|
||||
path: config.yaml
|
||||
- name: runner-entrypoint
|
||||
mountPath: /runner-entrypoint.sh
|
||||
subPath: runner-entrypoint.sh
|
||||
readOnly: true
|
||||
configMap:
|
||||
name: gitea-runner-entrypoint
|
||||
defaultMode: 493
|
||||
items:
|
||||
- key: runner-entrypoint.sh
|
||||
path: runner-entrypoint.sh
|
||||
- name: docker-config
|
||||
mountPath: /root/.docker/config.json
|
||||
subPath: config.json
|
||||
readOnly: true
|
||||
secret:
|
||||
secretName: gitea-secret
|
||||
items:
|
||||
- key: docker-config.json
|
||||
path: config.json
|
||||
- name: kubeconfig
|
||||
mountPath: /data/.kube/config
|
||||
subPath: config
|
||||
readOnly: true
|
||||
secret:
|
||||
secretName: gitea-secret
|
||||
items:
|
||||
- key: kubeconfig
|
||||
path: config
|
||||
- name: docker-sock
|
||||
mountPath: /var/run/docker.sock
|
||||
hostPath:
|
||||
path: /var/run/docker.sock
|
||||
type: Socket
|
||||
commitSha: ""
|
||||
gitlabUri: ""
|
||||
gitlabJobUrl: ""
|
||||
owner: platform
|
||||
80
README.md
Normal file
80
README.md
Normal file
@ -0,0 +1,80 @@
|
||||
# Gitea Helm chart
|
||||
|
||||
Чарт лежит в `.helm`.
|
||||
|
||||
Зависимости:
|
||||
|
||||
- `universal-chart` `0.1.9` для `gitea-ci-worker`
|
||||
- статический `Deployment` для `gitea`, потому что файловый backup должен жить sidecar-ом в том же pod-е, где смонтирован RWO PVC
|
||||
- `postgresql-preprod` `16.4.8` из `oci://cr.yandex/crp3ccidau046kdj8g9q/charts`
|
||||
|
||||
HTTP-маршрутизации здесь нет: ни `Ingress`, ни `VirtualService`. VS управляется отдельным чартом.
|
||||
|
||||
## Секреты
|
||||
|
||||
В `values.yaml` нет чувствительных значений. Чарт создает `gitea-secret` через `lookup`: если Secret уже существует, значения сохраняются; если нет, создаются сгенерированные заглушки. С заглушками runner и S3 backup не заработают, пока Secret не будет заполнен реальными данными.
|
||||
|
||||
Перед установкой можно создать Secret отдельно:
|
||||
|
||||
```bash
|
||||
kubectl create namespace gitea --dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
kubectl -n gitea create secret generic gitea-secret \
|
||||
--from-literal=runner-registration-token="$GITEA_RUNNER_REGISTRATION_TOKEN" \
|
||||
--from-literal=aws-access-key-id="$AWS_ACCESS_KEY_ID" \
|
||||
--from-literal=aws-secret-access-key="$AWS_SECRET_ACCESS_KEY" \
|
||||
--from-file=kubeconfig=./runner/kubeconfig/config \
|
||||
--from-file=docker-config.json=./runner/docker-config/config.json \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
```
|
||||
|
||||
PostgreSQL пароль живет в `postgresql-secret`, который создает PostgreSQL chart и сохраняет через `helm.sh/resource-policy: keep`. Gitea читает ключ `user-password`.
|
||||
|
||||
## Установка
|
||||
|
||||
```bash
|
||||
helm dependency update .helm
|
||||
helm upgrade --install gitea .helm -n gitea --create-namespace
|
||||
```
|
||||
|
||||
Если Secret создан уже после установки, перезапустить runner:
|
||||
|
||||
```bash
|
||||
kubectl -n gitea rollout restart deploy/gitea-ci-worker
|
||||
```
|
||||
|
||||
## Backup
|
||||
|
||||
Backup включен по умолчанию:
|
||||
|
||||
- `gitea-files-backup`: sidecar внутри pod `gitea`, каждый день в `02:30` архивирует `/data` и кладет в `s3://gitops-gitea/gitops-backups/gitea-files/`. Отдельного pod-а с mount PVC нет, поэтому не возникает second attach/Multi-Attach для `gitea-data`.
|
||||
- `gitea-postgresql-backup`: каждый день в `02:45`, делает `pg_dump | gzip` и кладет в `s3://gitops-gitea/gitops-backups/postgresql/`
|
||||
|
||||
Оба backup-процесса используют S3-ключи из `gitea-secret`. Если там сгенерированные заглушки, backup завершится с понятной ошибкой и ничего не загрузит.
|
||||
|
||||
## Restore
|
||||
|
||||
Restore не включен в обычную установку. Это разовый Job, который включается отдельным values-файлом.
|
||||
|
||||
1. Взять имена объектов из S3:
|
||||
|
||||
```bash
|
||||
aws --endpoint-url "$AWS_ENDPOINT_URL" s3 ls s3://gitops-gitea/gitops-backups/gitea-files/
|
||||
aws --endpoint-url "$AWS_ENDPOINT_URL" s3 ls s3://gitops-gitea/gitops-backups/postgresql/
|
||||
```
|
||||
|
||||
2. Скопировать `.helm/restore-values.example.yaml`, указать реальные `giteaFilesKey` и/или `postgresqlDumpKey`.
|
||||
|
||||
3. Запустить restore:
|
||||
|
||||
```bash
|
||||
helm upgrade --install gitea .helm -n gitea -f restore-values.yaml
|
||||
```
|
||||
|
||||
Режимы restore:
|
||||
|
||||
- полный restore: `restore.files.enabled=true` и `restore.postgresql.enabled=true`
|
||||
- только файлы: `restore.files.enabled=true`, `restore.postgresql.enabled=false`
|
||||
- только база: `restore.files.enabled=false`, `restore.postgresql.enabled=true`
|
||||
|
||||
Restore Job при `restore.scaleGitea.enabled=true` сначала масштабирует deployment `gitea` в `0` и ждёт удаления pod-а. Это нужно, чтобы restore файлов не монтировал RWO PVC одновременно с Gitea. После успешного completion отдельный `gitea-restore-scale-up` Job возвращает replicas обратно.
|
||||
Loading…
Reference in New Issue
Block a user