SSH host keys, split out swarm-cronjob
This commit is contained in:
parent
721c393d2d
commit
a990dc27c7
|
@ -9,8 +9,12 @@ RESTIC_HOST=minio.example.com
|
||||||
|
|
||||||
CRON_SCHEDULE='*/5 * * * *'
|
CRON_SCHEDULE='*/5 * * * *'
|
||||||
|
|
||||||
|
# swarm-cronjob, instead of built-in cron
|
||||||
|
#COMPOSE_FILE="$COMPOSE_FILE:compose.swarm-cronjob.yml"
|
||||||
|
|
||||||
# SSH storage
|
# SSH storage
|
||||||
#SECRET_SSH_KEY_VERSION=v1
|
#SECRET_SSH_KEY_VERSION=v1
|
||||||
|
#SSH_HOST_KEY="hostname ssh-rsa AAAAB3...
|
||||||
#COMPOSE_FILE="$COMPOSE_FILE:compose.ssh.yml"
|
#COMPOSE_FILE="$COMPOSE_FILE:compose.ssh.yml"
|
||||||
|
|
||||||
# S3 storage
|
# S3 storage
|
||||||
|
|
|
@ -19,8 +19,8 @@ A first stab:
|
||||||
- [ ] SSH remote storage
|
- [ ] SSH remote storage
|
||||||
- [ ] Add SSH key handling
|
- [ ] Add SSH key handling
|
||||||
- [ ] SSH host key checking
|
- [ ] SSH host key checking
|
||||||
- [ ] S3 remote storage
|
- [x] S3 remote storage
|
||||||
- [ ] Re-add `crond` support
|
- [x] Re-add `crond` support
|
||||||
|
|
||||||
Future:
|
Future:
|
||||||
- [ ] Continuous linting with shellcheck
|
- [ ] Continuous linting with shellcheck
|
||||||
|
|
87
backup.sh
87
backup.sh
|
@ -16,7 +16,18 @@ restic_extra_options=
|
||||||
|
|
||||||
if [ -n "$ssh_key_file" ] && [ -f "$ssh_key_file" ]; then
|
if [ -n "$ssh_key_file" ] && [ -f "$ssh_key_file" ]; then
|
||||||
restic_repo="sftp:$restic_host:/$server_name"
|
restic_repo="sftp:$restic_host:/$server_name"
|
||||||
restic_extra_options="sftp.command=ssh -i $ssh_key_file $restic_host -s sftp"
|
|
||||||
|
# Only check server against provided SSH_HOST_KEY, if set
|
||||||
|
if [ -n "$SSH_HOST_KEY" ]; then
|
||||||
|
tmpfile=$(mktemp)
|
||||||
|
echo "$SSH_HOST_KEY" >> "$tmpfile"
|
||||||
|
ssh_options="-o 'UserKnownHostsFile $tmpfile'"
|
||||||
|
elif [ "$SSH_HOST_KEY_DISABLE" = "1" ]; then
|
||||||
|
ssh_options="-o 'StrictHostKeyChecking=No'"
|
||||||
|
else
|
||||||
|
echo "Neither SSH_HOST_KEY nor SSH_HOST_KEY_DISABLE set"
|
||||||
|
fi
|
||||||
|
restic_extra_options="sftp.command=ssh $ssh_options -i $ssh_key_file $restic_host -s sftp"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$s3_key_file" ] && [ -f "$s3_key_file" ] && [ -n "$AWS_ACCESS_KEY_ID" ]; then
|
if [ -n "$s3_key_file" ] && [ -f "$s3_key_file" ] && [ -n "$AWS_ACCESS_KEY_ID" ]; then
|
||||||
|
@ -57,45 +68,49 @@ else
|
||||||
mapfile -t services < <(docker service ls --format '{{ .Name }}')
|
mapfile -t services < <(docker service ls --format '{{ .Name }}')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for service in "${services[@]}"; do
|
if [[ \ $*\ != *\ --skip-backup\ * ]]; then
|
||||||
echo "service: $service"
|
for service in "${services[@]}"; do
|
||||||
details=$(docker service inspect "$service" --format "{{ json .Spec.Labels }}")
|
echo "service: $service"
|
||||||
if echo "$details" | jq -r '.["backupbot.backup"]' | grep -q 'true'; then
|
details=$(docker service inspect "$service" --format "{{ json .Spec.Labels }}")
|
||||||
pre=$(echo "$details" | jq -r '.["backupbot.backup.pre-hook"]')
|
if echo "$details" | jq -r '.["backupbot.backup"]' | grep -q 'true'; then
|
||||||
post=$(echo "$details" | jq -r '.["backupbot.backup.post-hook"]')
|
pre=$(echo "$details" | jq -r '.["backupbot.backup.pre-hook"]')
|
||||||
path=$(echo "$details" | jq -r '.["backupbot.backup.path"]')
|
post=$(echo "$details" | jq -r '.["backupbot.backup.post-hook"]')
|
||||||
|
path=$(echo "$details" | jq -r '.["backupbot.backup.path"]')
|
||||||
if [ "$path" = "null" ]; then
|
|
||||||
echo "ERROR: missing 'path' for $service"
|
if [ "$path" = "null" ]; then
|
||||||
continue # or maybe exit?
|
echo "ERROR: missing 'path' for $service"
|
||||||
fi
|
continue # or maybe exit?
|
||||||
|
fi
|
||||||
|
|
||||||
container=$(docker container ls -f "name=$service" --format '{{ .ID }}')
|
container=$(docker container ls -f "name=$service" --format '{{ .ID }}')
|
||||||
|
|
||||||
echo "backing up $service"
|
echo "backing up $service"
|
||||||
test -d "$backup_path/$service" || mkdir "$backup_path/$service"
|
test -d "$backup_path/$service" || mkdir "$backup_path/$service"
|
||||||
|
|
||||||
if [ "$pre" != "null" ]; then
|
if [ "$pre" != "null" ]; then
|
||||||
# run the precommand
|
# run the precommand
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
docker exec "$container" sh -c "$pre"
|
docker exec "$container" sh -c "$pre"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# run the backup
|
# run the backup
|
||||||
docker cp "$container:$path" "$backup_path/$service"
|
docker cp "$container:$path" "$backup_path/$service"
|
||||||
|
|
||||||
if [ "$post" != "null" ]; then
|
if [ "$post" != "null" ]; then
|
||||||
# run the postcommand
|
# run the postcommand
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
docker exec "$container" sh -c "$post"
|
docker exec "$container" sh -c "$post"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# check if restic repo exists, initialise if not
|
||||||
|
if [ -z "$(_restic cat config)" ] 2>/dev/null; then
|
||||||
|
echo "initializing restic repo"
|
||||||
|
_restic init
|
||||||
fi
|
fi
|
||||||
done
|
|
||||||
|
|
||||||
# check if restic repo exists, initialise if not
|
|
||||||
if [ -z "$(_restic cat config)" ] 2>/dev/null; then
|
|
||||||
echo "initializing restic repo"
|
|
||||||
_restic init
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_restic backup --tag coop-cloud "$backup_path"
|
if [[ \ $*\ != *\ --skip-upload\ * ]]; then
|
||||||
|
_restic backup --tag coop-cloud "$backup_path"
|
||||||
|
fi
|
||||||
|
|
|
@ -4,8 +4,11 @@ services:
|
||||||
app:
|
app:
|
||||||
environment:
|
environment:
|
||||||
- SSH_KEY_FILE=/run/secrets/ssh_key
|
- SSH_KEY_FILE=/run/secrets/ssh_key
|
||||||
|
- SSH_HOST_KEY
|
||||||
secrets:
|
secrets:
|
||||||
- ssh_key
|
- source: ssh_key
|
||||||
|
mode: 0400
|
||||||
|
entrypoint: [ "/usr/bin/backup.sh" ]
|
||||||
|
|
||||||
secrets:
|
secrets:
|
||||||
ssh_key:
|
ssh_key:
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
version: "3.8"
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
deploy:
|
||||||
|
mode: replicated
|
||||||
|
replicas: 0
|
||||||
|
labels:
|
||||||
|
- "swarm.cronjob.enable=true"
|
||||||
|
# Note(3wc): every 5m, testing
|
||||||
|
- "swarm.cronjob.schedule=*/5 * * * *"
|
||||||
|
# Note(3wc): blank label to be picked up by `abra recipe sync`
|
||||||
|
restart_policy:
|
||||||
|
condition: none
|
|
@ -16,18 +16,9 @@ services:
|
||||||
- SERVER_NAME
|
- SERVER_NAME
|
||||||
secrets:
|
secrets:
|
||||||
- restic_password
|
- restic_password
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
mode: replicated
|
|
||||||
replicas: 0
|
|
||||||
labels:
|
labels:
|
||||||
- "swarm.cronjob.enable=true"
|
|
||||||
# Note(3wc): every 5m, testing
|
|
||||||
- "swarm.cronjob.schedule=*/5 * * * *"
|
|
||||||
# Note(3wc): blank label to be picked up by `abra recipe sync`
|
|
||||||
- coop-cloud.${STACK_NAME}.app.version=
|
- coop-cloud.${STACK_NAME}.app.version=
|
||||||
restart_policy:
|
|
||||||
condition: none
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
backups:
|
backups:
|
||||||
|
|
Loading…
Reference in New Issue