diff --git a/.gitignore b/.gitignore index 268bba3..da1175e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -charts/*.tgz \ No newline at end of file +charts/*.tgz +publish.md diff --git a/Chart.yaml b/Chart.yaml index 6c61f4d..fae2db7 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.1-alpha +version: 0.2.0-alpha # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "0.6.1" +appVersion: "0.7.0" diff --git a/Dockerfile b/Dockerfile index 8cc9067..7612789 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM alpine AS builder -ARG RUSTIC_VERSION=0.6.1 +ARG RUSTIC_VERSION=0.7.0 RUN wget https://github.com/rustic-rs/rustic/releases/download/v${RUSTIC_VERSION}/rustic-v${RUSTIC_VERSION}-x86_64-unknown-linux-musl.tar.gz && \ tar -xzf rustic-v${RUSTIC_VERSION}-x86_64-unknown-linux-musl.tar.gz && \ mkdir /etc_files && \ diff --git a/README.md b/README.md index a2946e0..21c9cc3 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ the [FAQ](https://rustic.cli.rs/docs/FAQ.html). ### Prerequisites -* Kubernetes >=1.29 or 1.28 (with featureGate `SidecarContainers` enabled) +* Kubernetes >=1.24 * Helm v3 (Tested with v3.11.2) * Rustic's chart repository: `helm repo add rustic https://rustic-rs.github.io/rustic-helm/charts` * A valid `values.yml` file, the following example represents the bare minimum: @@ -55,13 +55,13 @@ This will trigger a daily backup of the nodes to the giv ### Deploying rustic ``` -helm install rustic rustic/rustic --set rustic.init=true -f values.yml +helm install rustic rustic/rustic --version 0.2.0-alpha --set rustic.init=true -f values.yml ``` If there is already an initialized restic repository in the Bucket omit `--set rustic.init=true`: ``` -helm install rustic rustic/rustic -f values.yml +helm install rustic rustic/rustic --version 0.2.0-alpha -f values.yml ``` ### Examples diff --git a/charts/index.yaml b/charts/index.yaml index 8945e0e..5c0c49c 100644 --- a/charts/index.yaml +++ b/charts/index.yaml @@ -1,6 +1,16 @@ apiVersion: v1 entries: rustic: + - apiVersion: v2 + appVersion: 0.7.0 + created: "2024-02-18T10:55:53.386175116+01:00" + description: fast, encrypted and deduplicated backups + digest: 2bc1f8ffb051210a595a7cd8097d35f77e378a3d5b4d82eafc7fbc9cc883f11f + name: rustic + type: application + urls: + - https://github.com/rustic-rs/rustic-helm/releases/download/0.2.0-alpha/rustic-0.2.0-alpha.tgz + version: 0.2.0-alpha - apiVersion: v2 appVersion: 0.6.1 created: "2024-01-12T18:11:53.714144944+01:00" @@ -21,4 +31,4 @@ entries: urls: - https://github.com/rustic-rs/rustic-helm/releases/download/0.1.0-alpha/rustic-0.1.0-alpha.tgz version: 0.1.0-alpha -generated: "2024-01-12T18:11:53.712973339+01:00" +generated: "2024-02-18T10:55:53.383180364+01:00" diff --git a/templates/cronjob.yaml b/templates/cronjob.yaml index 7331458..09f54cd 100644 --- a/templates/cronjob.yaml +++ b/templates/cronjob.yaml @@ -18,88 +18,19 @@ spec: automountServiceAccountToken: false hostname: {{ .Values.hostname }} restartPolicy: {{ .Values.cronjob.restartPolicy }} - initContainers: - - name: rclone - image: "{{ .Values.rclone.image.repository }}:{{ .Values.rclone.image.tag }}" - imagePullPolicy: {{ .Values.rclone.image.pullPolicy }} - restartPolicy: Always - args: - - serve - - restic - - -v - - --addr - - :8080 - - repo:{{ .Values.s3.repo.bucket }} - volumeMounts: - - mountPath: /config/rclone - name: rclone-config - startupProbe: - httpGet: - path: / - port: 8080 - httpHeaders: - - name: Accept - value: application/vnd.x.restic.rest.v2 - failureThreshold: 30 - periodSeconds: 1 - resources: - {{- toYaml .Values.rclone.resources | nindent 16 }} - securityContext: - {{- toYaml .Values.rclone.securityContext | nindent 16 }} - {{- if .Values.s3.repo_hot }} - - name: rclone-hot - image: "{{ .Values.rclone.image.repository }}:{{ .Values.rclone.image.tag }}" - imagePullPolicy: {{ .Values.rclone.image.pullPolicy }} - restartPolicy: Always - args: - - serve - - restic - - -v - - --addr - - :8081 - - repo-hot:{{ .Values.s3.repo_hot.bucket }} - volumeMounts: - - mountPath: /config/rclone - name: rclone-hot-config - startupProbe: - httpGet: - path: / - port: 8081 - httpHeaders: - - name: Accept - value: application/vnd.x.restic.rest.v2 - failureThreshold: 30 - periodSeconds: 1 - resources: - {{- toYaml .Values.rclone.resources | nindent 16 }} - securityContext: - {{- toYaml .Values.rclone.securityContext | nindent 16 }} - {{- end }} containers: - name: {{ .Chart.Name }} image: "{{ .Values.rustic.image.repository }}:{{ .Values.rustic.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.rustic.image.pullPolicy }} args: - backup - - --password-file - - "/etc/rustic/.rustic" - - --repository - - rest:http://localhost:8080/ - {{- if .Values.s3.repo_hot }} - - --repo-hot - - rest:http://localhost:8081/ - {{- end }} - {{- if .Values.persistence }} - - --cache-dir - - /cache - {{- end }} - "/backup" volumeMounts: - mountPath: /backup name: backup-folder readOnly: true - mountPath: /etc/rustic - name: rustic-encryption-secret + name: config {{- if .Values.persistence }} - name: cache mountPath: /cache @@ -111,21 +42,13 @@ spec: volumes: - name: backup-folder {{- toYaml .Values.rustic.backup_volume | nindent 14 }} - - name: rustic-encryption-secret - secret: - secretName: {{ include "rustic.fullname" . }}-encryption-secret {{- with .Values.persistence }} - name: cache {{- toYaml . | nindent 14 }} {{- end }} - - name: rclone-config - secret: - secretName: {{ include "rustic.fullname" . }}-rclone - {{- if .Values.s3.repo_hot }} - - name: rclone-hot-config + - name: config secret: - secretName: {{ include "rustic.fullname" . }}-rclone-hot - {{- end }} + secretName: {{ include "rustic.fullname" . }}-config {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 12 }} diff --git a/templates/job.yaml b/templates/job.yaml index 1cf7cf7..4976d63 100644 --- a/templates/job.yaml +++ b/templates/job.yaml @@ -14,88 +14,23 @@ spec: spec: automountServiceAccountToken: false restartPolicy: OnFailure - initContainers: - - name: rclone - image: "{{ .Values.rclone.image.repository }}:{{ .Values.rclone.image.tag }}" - imagePullPolicy: {{ .Values.rclone.image.pullPolicy }} - restartPolicy: Always - args: - - serve - - restic - - -v - - --addr - - :8080 - - repo:{{ .Values.s3.repo.bucket }} - volumeMounts: - - mountPath: /config/rclone - name: rclone-config - startupProbe: - tcpSocket: - port: 8080 - failureThreshold: 30 - periodSeconds: 1 - resources: - {{- toYaml .Values.rclone.resources | nindent 16 }} - securityContext: - {{- toYaml .Values.rclone.securityContext | nindent 16 }} - {{- if .Values.s3.repo_hot }} - - name: rclone-hot - image: "{{ .Values.rclone.image.repository }}:{{ .Values.rclone.image.tag }}" - imagePullPolicy: {{ .Values.rclone.image.pullPolicy }} - restartPolicy: Always - args: - - serve - - restic - - -v - - --addr - - :8081 - - repo-hot:{{ .Values.s3.repo_hot.bucket }} - volumeMounts: - - mountPath: /config/rclone - name: rclone-hot-config - startupProbe: - tcpSocket: - port: 8081 - failureThreshold: 30 - periodSeconds: 1 - resources: - {{- toYaml .Values.rclone.resources | nindent 16 }} - securityContext: - {{- toYaml .Values.rclone.securityContext | nindent 16 }} - {{- end }} containers: - name: {{ .Chart.Name }} image: "{{ .Values.rustic.image.repository }}:{{ .Values.rustic.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.rustic.image.pullPolicy }} args: - init - - --password-file - - "/etc/rustic/.rustic" - - --repository - - rest:http://localhost:8080/ - {{- if .Values.s3.repo_hot }} - - --repo-hot - - rest:http://localhost:8081/ - {{- end }} volumeMounts: - mountPath: /etc/rustic - name: rustic-encryption-secret + name: config resources: {{- toYaml .Values.rustic.resources | nindent 16 }} securityContext: {{- toYaml .Values.rustic.securityContext | nindent 16 }} volumes: - - name: rustic-encryption-secret - secret: - secretName: {{ include "rustic.fullname" . }}-encryption-secret - - name: rclone-config - secret: - secretName: {{ include "rustic.fullname" . }}-rclone - {{- if .Values.s3.repo_hot }} - - name: rclone-hot-config + - name: config secret: - secretName: {{ include "rustic.fullname" . }}-rclone-hot - {{- end }} + secretName: {{ include "rustic.fullname" . }}-config {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 12 }} diff --git a/templates/secret.yaml b/templates/secret.yaml index ef17184..44ddb0b 100644 --- a/templates/secret.yaml +++ b/templates/secret.yaml @@ -1,52 +1,38 @@ apiVersion: v1 kind: Secret metadata: - name: {{ include "rustic.fullname" . }}-encryption-secret + name: {{ include "rustic.fullname" . }}-config type: Opaque stringData: - .rustic: "{{ .Values.rustic.encryption_secret }}" - ---- -apiVersion: v1 -kind: Secret -metadata: - name: {{ include "rustic.fullname" . }}-rclone -type: Opaque -stringData: - rclone.conf: | - [repo] - type = s3 - provider = {{ .Values.s3.repo.provider }} - env_auth = false - endpoint = {{ .Values.s3.repo.endpoint }} - access_key_id = {{ .Values.s3.repo.access_key_id }} - secret_access_key = {{ .Values.s3.repo.secret_access_key }} - region = {{ .Values.s3.repo.region }} - location_constraint = - acl = private - server_side_encryption = - storage_class = {{ .Values.s3.repo.storage_class }} + rustic.toml: | + [repository] + repository = "opendal:s3" +{{- if .Values.s3.repo_hot }} + repo-hot = "opendal:s3" +{{- end }} + password = "{{ .Values.rustic.encryption_secret }}" +{{- if .Values.persistence }} + cache-dir = "/cache" +{{- end }} {{- if .Values.s3.repo_hot }} ---- -apiVersion: v1 -kind: Secret -metadata: - name: {{ include "rustic.fullname" . }}-rclone-hot -type: Opaque -stringData: - rclone.conf: | - [repo-hot] - type = s3 - provider = {{ .Values.s3.repo_hot.provider }} - env_auth = false - endpoint = {{ .Values.s3.repo_hot.endpoint }} - access_key_id = {{ .Values.s3.repo_hot.access_key_id }} - secret_access_key = {{ .Values.s3.repo_hot.secret_access_key }} - region = {{ .Values.s3.repo_hot.region }} - location_constraint = - acl = private - server_side_encryption = - storage_class = {{ .Values.s3.repo_hot.storage_class }} + [repository.options-cold] +{{- else}} + [repository.options] +{{- end }} + endpoint = "https://{{ .Values.s3.repo.endpoint }}" + bucket = "{{ .Values.s3.repo.bucket }}" + region = "{{ .Values.s3.repo.region }}" + access_key_id = "{{ .Values.s3.repo.access_key_id }}" + secret_access_key = "{{ .Values.s3.repo.secret_access_key }}" + default_storage_class = "{{ .Values.s3.repo.storage_class }}" -{{- end }} \ No newline at end of file +{{- if .Values.s3.repo_hot }} + [repository.options-hot] + endpoint = "https://{{ .Values.s3.repo_hot.endpoint }}" + bucket = "{{ .Values.s3.repo_hot.bucket }}" + region = "{{ .Values.s3.repo_hot.region }}" + access_key_id = "{{ .Values.s3.repo_hot.access_key_id }}" + secret_access_key = "{{ .Values.s3.repo_hot.secret_access_key }}" + default_storage_class = "{{ .Values.s3.repo_hot.storage_class }}" +{{- end }} diff --git a/values.yaml b/values.yaml index 3026c8b..79bc78c 100644 --- a/values.yaml +++ b/values.yaml @@ -11,20 +11,6 @@ cronjob: nameOverride: "" fullnameOverride: "" -rclone: - image: - repository: rclone/rclone - pullPolicy: IfNotPresent - tag: 1.65.0 - resources: {} - securityContext: - runAsUser: 1009 - runAsGroup: 1009 - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - rustic: image: repository: ghcr.io/mueckinger/rustic