Skip to content
This repository has been archived by the owner on May 5, 2024. It is now read-only.

Commit

Permalink
feat: add bjw-s volsync stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
truxnell committed Jul 24, 2023
1 parent 234a47c commit dfb149c
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 47 deletions.
11 changes: 4 additions & 7 deletions .taskfiles/VolSync/ListJob.tmpl.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
---


# yaml-language-server: $schema=https://kubernetes-schemas.trux.dev/batch/job_v1.json
apiVersion: batch/v1
kind: Job
metadata:
name: 'list-${ts}'
namespace: '${namespace}'
name: "list-${rsrc}-${ts}"
namespace: "${namespace}"
spec:
ttlSecondsAfterFinished: 3600
template:
Expand All @@ -16,7 +13,7 @@ spec:
containers:
- name: list
image: docker.io/restic/restic:0.14.0
args: ['snapshots']
args: ["snapshots"]
envFrom:
- secretRef:
name: '${rsrc}-restic'
name: "${rsrc}-restic-secret"
18 changes: 9 additions & 9 deletions .taskfiles/VolSync/ReplicationDestination.tmpl.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
---


# yaml-language-server: $schema=https://kubernetes-schemas.trux.dev/volsync.backube/replicationdestination_v1alpha1.json
apiVersion: volsync.backube/v1alpha1
kind: ReplicationDestination
metadata:
name: '${claim}-${ts}'
namespace: '${namespace}'
name: "${rsrc}-${claim}-${ts}"
namespace: "${namespace}"
spec:
trigger:
manual: restore-once
restic:
repository: '${rsrc}-restic'
destinationPVC: '${claim}'
repository: "${rsrc}-restic-secret"
destinationPVC: "${claim}"
copyMethod: Direct
storageClassName: ceph-block
cacheCapacity: 5Gi
# IMPORTANT NOTE:
# Set to the last X number of snapshots to restore from
# previous: 2
Expand All @@ -26,4 +22,8 @@ spec:
# from a application that started with default data in the PVC.
# Do not restore snapshots made after the following RFC3339 Timestamp.
# date --rfc-3339=seconds (--utc)
restoreAsOf: "2023-03-07T01:00:00+11:00"
restoreAsOf: "2023-04-21T08:00:00-00:00"
moverSecurityContext:
runAsUser: 568
runAsGroup: 568
fsGroup: 568
69 changes: 45 additions & 24 deletions .taskfiles/VolSync/Tasks.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
---
version: '3'
version: "3"

x-task-vars: &task-vars
rsrc: '{{.rsrc}}'
controller: '{{.controller}}'
namespace: '{{.namespace}}'
claim: '{{.claim}}'
ts: '{{.ts}}'
kustomization: '{{.kustomization}}'
rsrc: "{{.rsrc}}"
controller: "{{.controller}}"
namespace: "{{.namespace}}"
claim: "{{.claim}}"
ts: "{{.ts}}"
kustomization: "{{.kustomization}}"
previous: "{{.previous}}"

vars:
destinationTemplate: '{{.ROOT_DIR}}/.taskfiles/VolSync/ReplicationDestination.tmpl.yaml'
wipeJobTemplate: '{{.ROOT_DIR}}/.taskfiles/VolSync/WipeJob.tmpl.yaml'
waitForJobScript: '{{.ROOT_DIR}}/.taskfiles/VolSync/wait-for-job.sh'
listJobTemplate: '{{.ROOT_DIR}}/.taskfiles/VolSync/ListJob.tmpl.yaml'
destinationTemplate: "{{.ROOT_DIR}}/.taskfiles/VolSync/ReplicationDestination.tmpl.yaml"
wipeJobTemplate: "{{.ROOT_DIR}}/.taskfiles/VolSync/WipeJob.tmpl.yaml"
waitForJobScript: "{{.ROOT_DIR}}/.taskfiles/VolSync/wait-for-job.sh"
listJobTemplate: "{{.ROOT_DIR}}/.taskfiles/VolSync/ListJob.tmpl.yaml"
unlockJobTemplate: "{{.ROOT_DIR}}/.taskfiles/VolSync/UnlockJob.tmpl.yaml"
ts: '{{now | date "150405"}}'

tasks:
list:
desc: List all snapshots taken by restic for a given ReplicationSource (ex. task vs:list rsrc=plex [namespace=default])
desc: List all snapshots taken by restic for a given ReplicationSource (ex. task volsync:list rsrc=plex [namespace=default])
silent: true
cmds:
- envsubst < <(cat {{.listJobTemplate}}) | kubectl apply -f -
Expand All @@ -34,16 +36,34 @@ tasks:
- sh: test -f {{.waitForJobScript}}
- sh: test -f {{.listJobTemplate}}

unlock:
desc: Unlocks restic repository for a given ReplicationSource (ex. task volsync:unlock rsrc=plex [namespace=default])
silent: true
cmds:
- envsubst < <(cat {{.unlockJobTemplate}}) | kubectl apply -f -
- bash {{.waitForJobScript}} unlock-{{.rsrc}}-{{.ts}} {{.namespace}}
- kubectl -n {{.namespace}} wait job/unlock-{{.rsrc}}-{{.ts}} --for condition=complete --timeout=1m
- kubectl -n {{.namespace}} logs job/unlock-{{.rsrc}}-{{.ts}} --container unlock
- kubectl -n {{.namespace}} delete job unlock-{{.rsrc}}-{{.ts}}
vars:
rsrc: '{{ or .rsrc (fail "ReplicationSource `rsrc` is required") }}'
namespace: '{{.namespace | default "default"}}'
env: *task-vars
preconditions:
- sh: test -f {{.waitForJobScript}}
- sh: test -f {{.unlockJobTemplate}}

# 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 vs:snapshot rsrc=$0 namespace=$1'
# - kubectl get replicationsources --all-namespaces --no-headers | awk '{print $2, $1}' | xargs --max-procs=4 -l bash -c 'task volsync:snapshot rsrc=$0 namespace=$1'
#
snapshot:
desc: Trigger a Restic ReplicationSource snapshot (ex. task vs:snapshot rsrc=plex [namespace=default])
desc: Trigger a Restic ReplicationSource snapshot (ex. task volsync:snapshot rsrc=plex [namespace=default])
cmds:
- kubectl -n {{.namespace}} patch replicationsources {{.rsrc}} --type merge -p '{"spec":{"trigger":{"manual":"{{.ts}}"}}}'
- bash {{.waitForJobScript}} volsync-src-{{.rsrc}} {{.namespace}}
- kubectl -n {{.namespace}} wait job/volsync-src-{{.rsrc}} --for condition=complete --timeout=120m
# TODO: Error from server (NotFound): jobs.batch "volsync-src-zzztest" not found
# TODO: Find a way to output logs
# Error from server (NotFound): jobs.batch "volsync-src-zzztest" not found
# - kubectl -n {{.namespace}} logs job/volsync-src-{{.rsrc}}
vars:
rsrc: '{{ or .rsrc (fail "ReplicationSource `rsrc` is required") }}'
Expand All @@ -55,10 +75,10 @@ tasks:
msg: "ReplicationSource '{{.rsrc}}' not found in namespace '{{.namespace}}'"

# To run restore jobs in parallel for all replicationdestinations:
# - kubectl get replicationsources --all-namespaces --no-headers | awk '{print $2, $1}' | xargs --max-procs=2 -l bash -c 'task vs:restore rsrc=$0 namespace=$1'
# - kubectl get replicationsources --all-namespaces --no-headers | awk '{print $2, $1}' | xargs --max-procs=2 -l bash -c 'task volsync:restore rsrc=$0 namespace=$1'
#
restore:
desc: Trigger a Restic ReplicationSource restore (ex. task vs:restore rsrc=plex [namespace=default])
desc: Trigger a Restic ReplicationSource restore (ex. task volsync:restore rsrc=plex [namespace=default])
cmds:
- task: restore-suspend-app
vars: *task-vars
Expand Down Expand Up @@ -90,6 +110,7 @@ tasks:
else
echo "statefulset.apps/$app"
fi
previous: "{{.previous | default 2}}"
env: *task-vars
preconditions:
- sh: test -f {{.wipeJobTemplate}}
Expand All @@ -111,20 +132,20 @@ tasks:
internal: true
cmds:
- envsubst < <(cat {{.wipeJobTemplate}}) | kubectl apply -f -
- bash {{.waitForJobScript}} wipe-{{.claim}}-{{.ts}} {{.namespace}}
- kubectl -n {{.namespace}} wait job/wipe-{{.claim}}-{{.ts}} --for condition=complete --timeout=120m
- kubectl -n {{.namespace}} logs job/wipe-{{.claim}}-{{.ts}} --container wipe
- kubectl -n {{.namespace}} delete job wipe-{{.claim}}-{{.ts}}
- bash {{.waitForJobScript}} wipe-{{.rsrc}}-{{.claim}}-{{.ts}} {{.namespace}}
- kubectl -n {{.namespace}} wait job/wipe-{{.rsrc}}-{{.claim}}-{{.ts}} --for condition=complete --timeout=120m
- kubectl -n {{.namespace}} logs job/wipe-{{.rsrc}}-{{.claim}}-{{.ts}} --container wipe
- kubectl -n {{.namespace}} delete job wipe-{{.rsrc}}-{{.claim}}-{{.ts}}
env: *task-vars

# Create VolSync replicationdestination CR to restore data
restore-volsync-job:
internal: true
cmds:
- envsubst < <(cat {{.destinationTemplate}}) | kubectl apply -f -
- bash {{.waitForJobScript}} volsync-dst-{{.claim}}-{{.ts}} {{.namespace}}
- kubectl -n {{.namespace}} wait job/volsync-dst-{{.claim}}-{{.ts}} --for condition=complete --timeout=120m
- kubectl -n {{.namespace}} delete replicationdestination {{.claim}}-{{.ts}}
- bash {{.waitForJobScript}} volsync-dst-{{.rsrc}}-{{.claim}}-{{.ts}} {{.namespace}}
- kubectl -n {{.namespace}} wait job/volsync-dst-{{.rsrc}}-{{.claim}}-{{.ts}} --for condition=complete --timeout=120m
- kubectl -n {{.namespace}} delete replicationdestination {{.rsrc}}-{{.claim}}-{{.ts}}
env: *task-vars

# Resume Flux ks and hr
Expand Down
19 changes: 19 additions & 0 deletions .taskfiles/VolSync/UnlockJob.tmpl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
apiVersion: batch/v1
kind: Job
metadata:
name: "unlock-${rsrc}-${ts}"
namespace: "${namespace}"
spec:
ttlSecondsAfterFinished: 3600
template:
spec:
automountServiceAccountToken: false
restartPolicy: OnFailure
containers:
- name: unlock
image: docker.io/restic/restic:0.14.0
args: ["unlock", "--remove-all"]
envFrom:
- secretRef:
name: "${rsrc}-restic"
11 changes: 4 additions & 7 deletions .taskfiles/VolSync/WipeJob.tmpl.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
---


# yaml-language-server: $schema=https://kubernetes-schemas.trux.dev/batch/job_v1.json
apiVersion: batch/v1
kind: Job
metadata:
name: 'wipe-${claim}-${ts}'
namespace: '${namespace}'
name: "wipe-${rsrc}-${claim}-${ts}"
namespace: "${namespace}"
spec:
ttlSecondsAfterFinished: 3600
template:
Expand All @@ -16,7 +13,7 @@ spec:
containers:
- name: wipe
image: ghcr.io/onedr0p/alpine:3.17.0@sha256:8e1eb13c3ca5c038f3bf22a5fe9e354867f97f98a78027c44b7c76fce81fa61d
command: ['/bin/bash', '-c', 'cd /config; find . -delete']
command: ["/bin/bash", "-c", "cd /config; find . -delete"]
volumeMounts:
- name: config
mountPath: /config
Expand All @@ -25,4 +22,4 @@ spec:
volumes:
- name: config
persistentVolumeClaim:
claimName: '${claim}'
claimName: "${claim}"
Empty file modified .taskfiles/VolSync/wait-for-job.sh
100755 → 100644
Empty file.
14 changes: 14 additions & 0 deletions .taskfiles/_scripts/wait-for-k8s-job.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

JOB_NAME=$1
NAMESPACE="${2:-default}"

[[ -z "${JOB_NAME}" ]] && echo "Job name not specified" && exit 1

while true; do
STATUS="$(kubectl -n "${NAMESPACE}" get pod -l job-name="${JOB_NAME}" -o jsonpath='{.items[*].status.phase}')"
if [ "${STATUS}" == "Pending" ]; then
break
fi
sleep 1
done

0 comments on commit dfb149c

Please sign in to comment.