Skip to content

Commit d2d3064

Browse files
authored
feat: gitea backup to object storage (#1723)
1 parent f7f5271 commit d2d3064

File tree

12 files changed

+203
-28
lines changed

12 files changed

+203
-28
lines changed

charts/otomi-db/templates/backup.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ spec:
1111
suspend: {{ .Values.backup.suspend }}
1212
immediate: {{ .Values.backup.immediate }}
1313
target: {{ .Values.backup.target }}
14-
schedule: {{ .Values.backup.schedule }}
14+
schedule: {{ .Values.backup.schedule | quote }}
1515
backupOwnerReference: {{ .Values.backup.backupOwnerReference }}
1616
cluster:
1717
name: {{ .Values.name }}

charts/team-ns/templates/backup/schedule.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ metadata:
99
name: team-{{ $v.teamId }}-backup-{{ .name }}
1010
namespace: velero
1111
spec:
12-
schedule: {{ .schedule }}
12+
schedule: {{ .schedule | quote }}
1313
template:
1414
includedNamespaces:
1515
- team-{{ $v.teamId }}

helmfile.d/snippets/defaults.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,8 @@ environments:
10781078
enabled: false
10791079
keycloak:
10801080
enabled: false
1081+
gitea:
1082+
enabled: false
10811083
cluster:
10821084
provider: linode
10831085
name: apl

tests/fixtures/env/settings.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ obj:
5252
loki: my-clusterid-loki
5353
tempo: my-clusterid-tempo
5454
velero: my-clusterid-velero
55+
gitea: my-clusterid-gitea
5556
type: linode
5657
oidc:
5758
adminGroupID: someAdminGroupID
@@ -85,6 +86,10 @@ platformBackups:
8586
enabled: true
8687
retentionPolicy: 7d
8788
schedule: 0 0 0 * * *
89+
gitea:
90+
enabled: true
91+
retentionPolicy: 7d
92+
schedule: 0 0 0 * * *
8893
smtp:
8994
auth_username: [email protected]
9095

values-schema.yaml

+20
Original file line numberDiff line numberDiff line change
@@ -2987,6 +2987,22 @@ properties:
29872987
description: Linode API Token
29882988
$ref: '#/definitions/wordCharacterPattern'
29892989
x-secret: ''
2990+
gitea:
2991+
type: object
2992+
title: Gitea
2993+
description: Enable application-level backup of Gitea repositories and database
2994+
additionalProperties: false
2995+
properties:
2996+
enabled:
2997+
type: boolean
2998+
default: false
2999+
resources:
3000+
$ref: '#/definitions/resources'
3001+
retentionPolicy:
3002+
$ref: '#/definitions/backupRetentionPolicy'
3003+
schedule:
3004+
$ref: '#/definitions/backupSchedule'
3005+
29903006
obj:
29913007
properties:
29923008
provider:
@@ -3027,6 +3043,10 @@ properties:
30273043
type: string
30283044
$ref: '#/definitions/wordCharacterPattern'
30293045
default: tempo
3046+
gitea:
3047+
type: string
3048+
$ref: '#/definitions/wordCharacterPattern'
3049+
default: gitea
30303050
required:
30313051
- region
30323052
- accessKeyId

values/gitea/gitea-otomi-db.gotmpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ instances: {{ $gdb.replicas }}
1414
{{- if $b.enabled }}
1515
backup:
1616
enabled: {{ $b.enabled }}
17-
schedule: {{ $b.schedule }}
17+
schedule: {{ $b.schedule | quote }}
1818
retentionPolicy: {{ $b.retentionPolicy }}
1919
type: {{ $obj.type }}
2020
{{- if eq $obj.type "minioLocal" }}

values/gitea/gitea-raw.gotmpl

+103
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{{- $v := .Values }}
22
{{- $otomiAdmin := "otomi-admin" }}
33
{{- $obj := $v.obj.provider }}
4+
{{- $giteaBackupConfig := $v.platformBackups.gitea }}
45

56
resources:
67
{{- if $v._derived.untrustedCA }}
@@ -19,6 +20,7 @@ resources:
1920
data:
2021
username: "{{ "gitea" | b64enc }}"
2122
password: "{{ $v.apps.gitea.postgresqlPassword | b64enc }}"
23+
# DB / app backup resources
2224
{{- if eq $obj.type "minioLocal" }}
2325
- apiVersion: v1
2426
kind: Secret
@@ -37,3 +39,104 @@ resources:
3739
S3_STORAGE_ACCOUNT: "{{ $obj.linode.accessKeyId | b64enc }}"
3840
S3_STORAGE_KEY: "{{ $obj.linode.secretAccessKey | b64enc }}"
3941
{{- end }}
42+
# Application backup resources
43+
- apiVersion: v1
44+
kind: PersistentVolumeClaim
45+
metadata:
46+
name: gitea-backup
47+
spec:
48+
accessModes:
49+
- ReadWriteOnce
50+
resources:
51+
requests:
52+
{{- if eq $v.cluster.provider "vultr" }}
53+
storage: 10Gi
54+
{{- else }}
55+
storage: 1Gi
56+
{{- end }}
57+
{{- if $giteaBackupConfig.enabled }}
58+
- apiVersion: v1
59+
kind: ServiceAccount
60+
metadata:
61+
name: gitea-backup
62+
- apiVersion: rbac.authorization.k8s.io/v1
63+
kind: Role
64+
metadata:
65+
name: gitea-backup-operator
66+
rules:
67+
- apiGroups: [""]
68+
resources: ["pods"]
69+
verbs: ["get", "watch", "list"]
70+
- apiGroups: [""]
71+
resources: ["pods/exec"]
72+
verbs: ["create"]
73+
- apiVersion: rbac.authorization.k8s.io/v1
74+
kind: RoleBinding
75+
metadata:
76+
name: gitea-backup
77+
subjects:
78+
- kind: ServiceAccount
79+
name: gitea-backup
80+
roleRef:
81+
kind: Role
82+
name: gitea-backup-operator
83+
apiGroup: rbac.authorization.k8s.io
84+
- apiVersion: batch/v1
85+
kind: CronJob
86+
metadata:
87+
name: gitea-backup-job
88+
spec:
89+
schedule: {{ $giteaBackupConfig.schedule | quote }}
90+
concurrencyPolicy: Forbid
91+
jobTemplate:
92+
spec:
93+
template:
94+
metadata:
95+
annotations:
96+
sidecar.istio.io/inject: "false"
97+
spec:
98+
serviceAccountName: gitea-backup
99+
containers:
100+
- image: bitnami/kubectl:1.30
101+
name: kubectl
102+
command:
103+
- /bin/sh
104+
- -ec
105+
- >-
106+
kubectl exec gitea-0 -- /bin/sh -ec "
107+
if [ ! -f '/backup/.bin/rclone' ]; then
108+
echo 'Installing RClone...' &&
109+
mkdir -p /backup/.bin &&
110+
cd /backup/.bin &&
111+
curl -fsSL -o rclone.zip https://github.com/rclone/rclone/releases/download/v1.68.0/rclone-v1.68.0-linux-amd64.zip &&
112+
echo '2fd93c246c72fa6bb192d33b0447013b31a982f9daaaa1f9c0b85e99f4233ee47c089e8b3f7f994dfe21090dab8e2adaec2e62c68aed0c7dadbac9bcce4e1706 rclone.zip' | sha512sum -c - &&
113+
unzip -oj rclone.zip
114+
fi &&
115+
cd /backup &&
116+
echo 'Creating backup...' &&
117+
gitea dump --type tar.bz2 &&
118+
echo '5d20f5562609695b565d696980bbee91ec0503ed946410eb2e6024a8b6850ebd5b587d5c71488f471012ea39e6bf440d843840165e8ac75cd0ec737defa2a749 .bin/rclone' | sha512sum -c - &&
119+
echo 'Uploading to object storage...' &&
120+
.bin/rclone copy --exclude '\.*/**' /backup gitea:/\$BUCKET_NAME &&
121+
echo 'Removing old backups from object storage...' &&
122+
.bin/rclone sync --min-age $RETENTION_TIME --exclude '\.*/**' /backup gitea:/\$BUCKET_NAME &&
123+
echo 'Cleaning up local backups...' &&
124+
find . -type f -iname '*.tar.bz2' -ctime +1 -delete"
125+
resources:
126+
limits:
127+
cpu: 250m
128+
memory: 256Mi
129+
requests:
130+
cpu: 100m
131+
memory: 128Mi
132+
env:
133+
- name: RETENTION_TIME
134+
value: {{ $giteaBackupConfig.retentionPolicy }}
135+
securityContext:
136+
runAsNonRoot: true
137+
runAsUser: 65535
138+
runAsGroup: 65535
139+
restartPolicy: Never
140+
securityContext:
141+
fsGroup: 65535
142+
{{- end }}

values/gitea/gitea.gotmpl

+53-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
{{- $giteaDomain := printf "gitea.%s" $v.cluster.domainSuffix }}
66
{{- $cm := $v.apps | get "cert-manager" }}
77
{{- $gdb := $v.databases.gitea }}
8+
{{- $obj := $v.obj.provider }}
9+
{{- $giteaBucketName := "" }}
10+
{{- if eq $obj.type "minioLocal" }}
11+
{{- $giteaBucketName = "gitea" }}
12+
{{- else if eq $obj.type "linode" }}
13+
{{- $giteaBucketName = $obj.linode.buckets | get "gitea" nil }}
14+
{{- end }}
815

916
nameOverride: gitea
1017
fullnameOverride: gitea
@@ -115,6 +122,44 @@ gitea:
115122
init:
116123
resources: {{- $g.resources.init | toYaml | nindent 4 }}
117124

125+
statefulset:
126+
env:
127+
- name: RCLONE_CONFIG_GITEA_TYPE
128+
value: s3
129+
{{- if eq $obj.type "minioLocal" }}
130+
- name: RCLONE_CONFIG_GITEA_PROVIDER
131+
value: Minio
132+
- name: RCLONE_CONFIG_GITEA_ENDPOINT
133+
value: http://minio.minio.svc.cluster.local:9000
134+
- name: RCLONE_CONFIG_GITEA_ACCESS_KEY_ID
135+
valueFrom:
136+
secretKeyRef:
137+
name: minio-creds
138+
key: MINIO_ACCESS_KEY
139+
- name: RCLONE_CONFIG_GITEA_SECRET_ACCESS_KEY
140+
valueFrom:
141+
secretKeyRef:
142+
name: minio-creds
143+
key: MINIO_SECRET_KEY
144+
{{- else if eq $obj.type "linode" }}
145+
- name: RCLONE_CONFIG_GITEA_PROVIDER
146+
value: Linode
147+
- name: RCLONE_CONFIG_GITEA_ENDPOINT
148+
value: {{ $obj.linode.region }}.linodeobjects.com
149+
- name: RCLONE_CONFIG_GITEA_ACCESS_KEY_ID
150+
valueFrom:
151+
secretKeyRef:
152+
name: linode-creds
153+
key: S3_STORAGE_ACCOUNT
154+
- name: RCLONE_CONFIG_GITEA_SECRET_ACCESS_KEY
155+
valueFrom:
156+
secretKeyRef:
157+
name: linode-creds
158+
key: S3_STORAGE_KEY
159+
{{- end }}
160+
- name: BUCKET_NAME
161+
value: {{ $giteaBucketName }}
162+
118163
memcached:
119164
# @TODO:
120165
image:
@@ -185,12 +230,19 @@ postgresql:
185230
additionalLabels:
186231
prometheus: system
187232

188-
{{- if $v._derived.untrustedCA }}
189233
extraVolumeMounts:
234+
- name: backup
235+
mountPath: /backup
236+
{{- if $v._derived.untrustedCA }}
190237
- name: custom-ca
191238
mountPath: /etc/ssl/certs/ca-certificates.crt
192239
subPath: ca-certificates.crt
240+
{{- end }}
193241
extraVolumes:
242+
- name: backup
243+
persistentVolumeClaim:
244+
claimName: gitea-backup
245+
{{- if $v._derived.untrustedCA }}
194246
- name: custom-ca
195247
secret:
196248
secretName: custom-ca

values/harbor/harbor-otomi-db.gotmpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ instances: {{ $hdb.replicas }}
1313
{{- if $b.enabled }}
1414
backup:
1515
enabled: {{ $b.enabled }}
16-
schedule: {{ $b.schedule }}
16+
schedule: {{ $b.schedule | quote }}
1717
retentionPolicy: {{ $b.retentionPolicy }}
1818
type: {{ $obj.type }}
1919
{{- if eq $obj.type "minioLocal" }}

values/keycloak/keycloak-otomi-db.gotmpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ instances: {{ $kdb.replicas }}
1414
{{- if $b.enabled }}
1515
backup:
1616
enabled: {{ $b.enabled }}
17-
schedule: {{ $b.schedule }}
17+
schedule: {{ $b.schedule | quote }}
1818
retentionPolicy: {{ $b.retentionPolicy }}
1919
type: {{ $obj.type }}
2020
{{- if eq $obj.type "minioLocal" }}

values/minio/minio.gotmpl

+13-20
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
{{- $k := $v.apps.keycloak }}
44
{{- $minioDomain := printf "minio.%s" $v.cluster.domainSuffix }}
55
{{- $rootCASecretName := "root-ca" }}
6+
{{- $bucketNames := list "cnpg" "gitea" "harbor" "loki" "tempo" "velero" -}}
67

78
mode: standalone
89
auth:
@@ -63,11 +64,9 @@ provisioning:
6364
cpu: 200m
6465
memory: 128Mi
6566
buckets:
66-
- name: velero
67-
- name: loki
68-
- name: harbor
69-
- name: tempo
70-
- name: cnpg
67+
{{- range $bucketNames }}
68+
- name: {{ . }}
69+
{{- end }}
7170
policies:
7271
- name: otomi-apps
7372
statements:
@@ -79,23 +78,19 @@ provisioning:
7978
- s3:GetBucketLocation
8079
- s3:ListBucketMultipartUploads
8180
resources:
82-
- arn:aws:s3:::velero
83-
- arn:aws:s3:::loki
84-
- arn:aws:s3:::harbor
85-
- arn:aws:s3:::tempo
86-
- arn:aws:s3:::cnpg
81+
{{- range $bucketNames }}
82+
- arn:aws:s3:::{{ . }}
83+
{{- end }}
8784
- effect: Allow
8885
principal:
8986
AWS:
9087
- "*"
9188
actions:
9289
- s3:ListBucket
9390
resources:
94-
- arn:aws:s3:::velero
95-
- arn:aws:s3:::loki
96-
- arn:aws:s3:::harbor
97-
- arn:aws:s3:::tempo
98-
- arn:aws:s3:::cnpg
91+
{{- range $bucketNames }}
92+
- arn:aws:s3:::{{ . }}
93+
{{- end }}
9994
condition:
10095
StringEquals:
10196
s3:prefix:
@@ -111,8 +106,6 @@ provisioning:
111106
- s3:DeleteObject
112107
- s3:GetObject
113108
resources:
114-
- arn:aws:s3:::velero/**
115-
- arn:aws:s3:::loki/**
116-
- arn:aws:s3:::harbor/**
117-
- arn:aws:s3:::tempo/**
118-
- arn:aws:s3:::cnpg/**
109+
{{- range $bucketNames }}
110+
- arn:aws:s3:::{{ . }}/**
111+
{{- end }}

versions.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
api: main
2-
console: main
1+
api: APL-121-gitea-app-backup
2+
console: v3.0.0-rc.0
33
tasks: 3.2.0
44
tools: 2.6.0

0 commit comments

Comments
 (0)