theshire/.taskfiles/volsync/Taskfile.yaml

137 lines
6.1 KiB
YAML
Raw Normal View History

2024-07-08 10:53:12 -05:00
---
# yaml-language-server: $schema=https://taskfile.dev/schema.json
version: '3'
2024-07-08 10:53:12 -05:00
# This taskfile is used to manage certain VolSync tasks for a given application, limitations are described below.
# 1. Fluxtomization, HelmRelease, PVC, ReplicationSource all have the same name (e.g. plex)
# 2. ReplicationSource and ReplicationDestination are a Restic repository
# 3. Applications are deployed as either a Kubernetes Deployment or StatefulSet
# 4. Each application only has one PVC that is being replicated
vars:
VOLSYNC_RESOURCES_DIR: '{{.ROOT_DIR}}/.taskfiles/volsync/resources'
2024-07-08 10:53:12 -05:00
tasks:
2024-07-08 10:53:12 -05:00
state-*:
desc: Suspend or Resume Volsync
summary: |-
CLUSTER: Cluster to run command against (default: main)
STATE: resume or suspend (required)
2024-07-08 10:53:12 -05:00
cmds:
# - until kubectl wait jobs --all --all-namespaces --for=condition=complete --timeout=5m &>/dev/null; do sleep 5; done
- flux {{.STATE}} kustomization volsync
- flux --namespace {{.NS}} {{.STATE}} helmrelease volsync
- kubectl --namespace {{.NS}} scale deployment --all --replicas {{if eq .STATE "suspend"}}0{{else}}1{{end}}
2024-07-08 10:53:12 -05:00
vars:
NS: '{{.NS | default "volsync-system"}}'
STATE: '{{index .MATCH 0}}'
2024-07-08 10:53:12 -05:00
requires:
vars: [CLUSTER]
2024-07-08 10:53:12 -05:00
unlock:
desc: Unlock all Restic repositories
summary: |-
CLUSTER: Cluster to run command against (default: main)
cmd: >
kubectl get replicationsources --all-namespaces --no-headers -A | awk '{print $1, $2}'
| xargs --max-procs=2 -l bash -c 'kubectl --namespace "$0" patch --field-manager=flux-client-side-apply replicationsources "$1" --type merge --patch "{\"spec\":{\"restic\":{\"unlock\":\"{{now | unixEpoch}}\"}}}"'
2024-07-08 10:53:12 -05:00
requires:
vars: [CLUSTER]
2024-07-08 10:53:12 -05:00
# To run backup jobs in parallel for all replicationsources:
# - kubectl get replicationsources --all-namespaces --no-headers | awk '{print $2, $1}' | xargs --max-procs=4 -l bash -c 'task volsync:snapshot APP=$0 NS=$1'
2024-07-08 10:53:12 -05:00
snapshot:
desc: Snapshot an application
summary: |-
CLUSTER: Cluster to run command against (default: main)
NS: Namespace the application is in (default: default)
APP: Application to snapshot (required)
2024-07-08 10:53:12 -05:00
cmds:
- kubectl --namespace {{.NS}} patch replicationsources {{.APP}} --type merge -p '{"spec":{"trigger":{"manual":"{{now | unixEpoch}}"}}}'
- until kubectl --namespace {{.NS}} get job/{{.JOB}} &>/dev/null; do sleep 5; done
- kubectl --namespace {{.NS}} wait job/{{.JOB}} --for=condition=complete --timeout=120m
2024-07-08 10:53:12 -05:00
vars:
NS: '{{.NS | default "default"}}'
JOB: volsync-src-{{.APP}}
requires:
vars: [CLUSTER, APP]
2024-07-08 10:53:12 -05:00
preconditions:
- kubectl --namespace {{.NS}} get replicationsources {{.APP}}
2024-07-08 10:53:12 -05:00
# To run restore jobs in parallel for all replicationdestinations:
# - kubectl get replicationsources --all-namespaces --no-headers | awk '{print $2, $1}' | xargs --max-procs=4 -l bash -c 'task volsync:restore APP=$0 NS=$1'
2024-07-08 10:53:12 -05:00
restore:
desc: Restore an application
summary: |-
CLUSTER: Cluster to run command against (default: main)
NS: Namespace the application is in (default: default)
APP: Application to restore (required)
PREVIOUS: Previous number of snapshots to restore (default: 2)
2024-07-08 10:53:12 -05:00
cmds:
- task: .suspend
- task: .restore
- task: .resume
2024-07-08 10:53:12 -05:00
requires:
vars: [CLUSTER, APP]
2024-07-08 10:53:12 -05:00
.suspend:
internal: true
cmds:
- flux --namespace flux-system suspend kustomization {{.APP}}
- flux --namespace {{.NS}} suspend helmrelease {{.APP}}
- kubectl --namespace {{.NS}} scale {{.CONTROLLER}}/{{.APP}} --replicas 0
- kubectl --namespace {{.NS}} wait pod --for=delete --selector="app.kubernetes.io/name={{.APP}}" --timeout=5m
2024-07-08 10:53:12 -05:00
vars:
NS: '{{.NS | default "default"}}'
APP: '{{.APP}}'
CONTROLLER:
sh: kubectl --namespace {{.NS}} get deployment {{.APP}} &>/dev/null && echo deployment || echo statefulset
2024-07-08 10:53:12 -05:00
.restore:
internal: true
cmds:
- minijinja-cli --env --trim-blocks --lstrip-blocks --autoescape=none {{.VOLSYNC_RESOURCES_DIR}}/replicationdestination.yaml.j2 | kubectl apply --server-side --filename -
- until kubectl --namespace {{.NS}} get job/{{.JOB}} &>/dev/null; do sleep 5; done
- kubectl --namespace {{.NS}} wait job/{{.JOB}} --for=condition=complete --timeout=120m
- kubectl --namespace {{.NS}} delete replicationdestination {{.JOB}}
2024-07-08 10:53:12 -05:00
vars:
NS: '{{.NS | default "default"}}'
JOB: volsync-dst-{{.APP}}
PREVIOUS: '{{.PREVIOUS | default 2}}'
CLAIM:
sh: kubectl --namespace {{.NS}} get replicationsources/{{.APP}} --output=jsonpath="{.spec.sourcePVC}"
ACCESS_MODES:
sh: kubectl --namespace {{.NS}} get replicationsources/{{.APP}} --output=jsonpath="{.spec.restic.accessModes}"
STORAGE_CLASS_NAME:
sh: kubectl --namespace {{.NS}} get replicationsources/{{.APP}} --output=jsonpath="{.spec.restic.storageClassName}"
PUID:
sh: kubectl --namespace {{.NS}} get replicationsources/{{.APP}} --output=jsonpath="{.spec.restic.moverSecurityContext.runAsUser}"
PGID:
sh: kubectl --namespace {{.NS}} get replicationsources/{{.APP}} --output=jsonpath="{.spec.restic.moverSecurityContext.runAsGroup}"
env:
NS: '{{.NS}}'
JOB: '{{.JOB}}'
APP: '{{.APP}}'
PREVIOUS: '{{.PREVIOUS}}'
CLAIM: '{{.CLAIM}}'
ACCESS_MODES: '{{.ACCESS_MODES}}'
STORAGE_CLASS_NAME: '{{.STORAGE_CLASS_NAME}}'
PUID: '{{.PUID}}'
PGID: '{{.PGID}}'
2024-07-08 10:53:12 -05:00
preconditions:
- test -f {{.VOLSYNC_RESOURCES_DIR}}/replicationdestination.yaml.j2
2024-07-08 10:53:12 -05:00
.resume:
internal: true
cmds:
- flux --namespace {{.NS}} resume helmrelease {{.APP}}
- flux --namespace flux-system resume kustomization {{.APP}}
- kubectl --namespace {{.NS}} scale {{.CONTROLLER}}/{{.APP}} --replicas 1
- kubectl --namespace {{.NS}} wait pod --for=condition=ready --selector="app.kubernetes.io/name={{.APP}}" --timeout=5m
vars:
NS: '{{.NS | default "default"}}'
APP: '{{.APP}}'
CONTROLLER:
sh: kubectl --namespace {{.NS}} get deployment {{.APP}} &>/dev/null && echo deployment || echo statefulset