add generic vps-to-local backup script
This commit is contained in:
parent
46a69efb3e
commit
704f7ecb0c
4 changed files with 227 additions and 0 deletions
26
old/copy_forgejo_db_backup.sh
Executable file
26
old/copy_forgejo_db_backup.sh
Executable file
|
@ -0,0 +1,26 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
source /home/thomas/.env
|
||||||
|
|
||||||
|
# Copy backup of Forgejo database on VPS to local device
|
||||||
|
|
||||||
|
LOCAL_MOUNTPOINT="/media/my-passport"
|
||||||
|
RCHAT_NOTIFIER="${HOME}/repos/utilities/rocketchat_notifier.sh"
|
||||||
|
|
||||||
|
mountpoint -q ${LOCAL_MOUNTPOINT}
|
||||||
|
|
||||||
|
if [ $? -eq 1 ]; then
|
||||||
|
$RCHAT_NOTIFIER "backups" "error" \
|
||||||
|
"Could not transfer Forgejo DB backup from VPS. Local backup disk (/media/my-passport) not mounted."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
scp 'thomas@systemsobscure.net:/home/thomas/backups/forgejo/*.sql.gz' "${LOCAL_MOUNTPOINT}/vps_backups/mysql/forgejo/"
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
BACKUP_FILE=$(ls -t "${LOCAL_MOUNTPOINT}/vps_backups/mysql/forgejo" | head -1)
|
||||||
|
$RCHAT_NOTIFIER "backups" "success" "Copied Forgejo DB backup from VPS. File: ${BACKUP_FILE}"
|
||||||
|
else
|
||||||
|
$RCHAT_NOTIFIER "backups" "error" \
|
||||||
|
"Could not transfer Forgejo DB backup from VPS."
|
||||||
|
fi
|
87
old/slack_notifier.sh
Executable file
87
old/slack_notifier.sh
Executable file
|
@ -0,0 +1,87 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Send error and success notifications to Slack channels
|
||||||
|
|
||||||
|
# Env vars:
|
||||||
|
# --- Webhook URLs for given channel, eg $SLACK_WEBHOOK_TEST, $SLACK_WEBHOOK_EOLAS
|
||||||
|
# --- sourced from `.env` file in Zsh path
|
||||||
|
|
||||||
|
# Parameters:
|
||||||
|
# --- $1 = Slack channel,
|
||||||
|
# --- $2 = type 'error' | 'success'
|
||||||
|
# --- $3 = Message
|
||||||
|
# --- $4 = (Opt) Error details
|
||||||
|
# --- $5 = (Opt) Error source
|
||||||
|
|
||||||
|
# Usage:
|
||||||
|
# --- ./slack_notifier.sh test 'SUCCESS: ...'
|
||||||
|
# --- ./slack_notifier.sh test 'ERROR: ... ' 'Error details' 'source'
|
||||||
|
|
||||||
|
declare -A CHANNEL_TO_WEBHOOK
|
||||||
|
CHANNEL_TO_WEBHOOK["test"]=$SLACK_WEBHOOK_TEST
|
||||||
|
CHANNEL_TO_WEBHOOK["backups"]=$SLACK_WEBHOOK_BACKUPS
|
||||||
|
CHANNEL_TO_WEBHOOK["eolas"]=$SLACK_WEBHOOK_EOLAS
|
||||||
|
CHANNEL_TO_WEBHOOK["website"]=$SLACK_WEBHOOK_SYSTEMS_OBSCURE
|
||||||
|
CHANNEL_TO_WEBHOOK["time-tracking"]=$SLACK_WEBHOOK_TIME_TRACKING
|
||||||
|
|
||||||
|
WEBHOOK=${CHANNEL_TO_WEBHOOK[$1]}
|
||||||
|
|
||||||
|
ERROR_BLOCKS=$(
|
||||||
|
jq -n \
|
||||||
|
--arg channel "$1" \
|
||||||
|
--arg message "$3" \
|
||||||
|
--arg details "$4" \
|
||||||
|
--arg source "$5" \
|
||||||
|
'{
|
||||||
|
channel: $channel,
|
||||||
|
blocks: ([
|
||||||
|
{
|
||||||
|
type: "section",
|
||||||
|
text: {
|
||||||
|
type: "plain_text",
|
||||||
|
text: "🔴 \($message)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "section",
|
||||||
|
text: {
|
||||||
|
type: "mrkdwn",
|
||||||
|
text: "```\n\($details)\n```"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "context",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "plain_text",
|
||||||
|
text: $source
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Initialise sound playback
|
||||||
|
|
||||||
|
# mpv --volume=0 --start=0 --length=0.1 "${HOME}/dotfiles/sounds/star-trek-computer-success.mp3" \
|
||||||
|
# >/dev/null 2>&1
|
||||||
|
# sleep 1
|
||||||
|
|
||||||
|
# Process notification
|
||||||
|
if [ "$2" != "error" ]; then
|
||||||
|
curl -X POST \
|
||||||
|
-H 'Content-type: application/json' \
|
||||||
|
--data '{"text":"🟢 '"$3"'"}' \
|
||||||
|
"$WEBHOOK"
|
||||||
|
# mpv --volume=100 "${HOME}/dotfiles/sounds/star-trek-computer-success.mp3" \
|
||||||
|
>/dev/null 2>&1
|
||||||
|
|
||||||
|
else
|
||||||
|
curl -X POST \
|
||||||
|
-H 'Content-type: application/json' \
|
||||||
|
--json "$ERROR_BLOCKS" \
|
||||||
|
"$WEBHOOK"
|
||||||
|
# mpv --volume=100 "${HOME}/dotfiles/sounds/star-trek-computer-error.mp3" \
|
||||||
|
>/dev/null 2>&1
|
||||||
|
fi
|
84
old/storagebox_alpha_backup_old.sh
Executable file
84
old/storagebox_alpha_backup_old.sh
Executable file
|
@ -0,0 +1,84 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Backup Hetzner Storagebox (Alpha) used by VPS for service data.
|
||||||
|
|
||||||
|
NAS_DEVICE_NAME="Hetzner Storagebox (Alpha)"
|
||||||
|
RCHAT_NOTIFIER="${HOME}/repos/utilities/rocketchat_notifier.sh"
|
||||||
|
SOURCE_MOUNTPOINT="/media/hetzner-storagebox-alpha"
|
||||||
|
LOCAL_MOUNTPOINT="/media/my-passport"
|
||||||
|
|
||||||
|
function clean_up() {
|
||||||
|
# Dismount NAS
|
||||||
|
echo "INFO Dismounting ${NAS_DEVICE_NAME}."
|
||||||
|
sudo umount /media/hetzner-storagebox-alpha/
|
||||||
|
|
||||||
|
# Turn on VPN
|
||||||
|
echo "INFO Re-connecting Mullvad VPN."
|
||||||
|
mullvad connect
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
# Turn off VPN
|
||||||
|
echo "INFO Attempting backup of ${NAS_DEVICE_NAME} NAS device."
|
||||||
|
echo "INFO Checking VPN status."
|
||||||
|
|
||||||
|
mullvad status | grep "Disconnected" 2>&1
|
||||||
|
STATUS=$?
|
||||||
|
if [ $STATUS -eq 0 ]; then
|
||||||
|
echo "INFO VPN is not connected. Proceeding."
|
||||||
|
else
|
||||||
|
echo "INFO Mullvad VPN is connected. Disconnecting."
|
||||||
|
mullvad disconnect
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check source disk is mounted
|
||||||
|
if mountpoint -q ${LOCAL_MOUNTPOINT}; then
|
||||||
|
echo "INFO Local disk /media/my-passport mounted. Proceeding."
|
||||||
|
else
|
||||||
|
echo "INFO Local disk not mounted. Mounting /media/my-passport."
|
||||||
|
sudo mount ${LOCAL_MOUNTPOINT}
|
||||||
|
if mountpoint -q ${LOCAL_MOUNTPOINT}; then
|
||||||
|
echo "INFO Mounted /media/my-passport"
|
||||||
|
else
|
||||||
|
$RCHAT_NOTIFIER "backups" "error" \
|
||||||
|
"Could not complete scheduled backup of ${NAS_DEVICE_NAME}. Local backup disk (/media/my-passport) not mounted."
|
||||||
|
clean_up
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Mount NAS locally
|
||||||
|
sudo mount -t cifs -v //u455282.your-storagebox.de/backup /media/hetzner-storagebox-alpha -o \
|
||||||
|
credentials=/etc/hetzner-storagebox-alpha-credentials,uid=1000,gid=1000,file_mode=0775,dir_mode=0775,vers=3.0
|
||||||
|
|
||||||
|
if mountpoint -q ${SOURCE_MOUNTPOINT}; then
|
||||||
|
echo "INFO Mounted ${NAS_DEVICE_NAME} device to /media/hetzner-storagebox-alpha"
|
||||||
|
else
|
||||||
|
$RCHAT_NOTIFIER "backups" "error" \
|
||||||
|
"Could not complete scheduled ${NAS_DEVICE_NAME} backup. Source disk (/media/hetzner-storagebox-alpha) not mounted."
|
||||||
|
clean_up
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create backup (ignoring lock files)
|
||||||
|
|
||||||
|
echo "INFO Beginning backup."
|
||||||
|
|
||||||
|
sudo rsync -avzP --delete --no-perms \
|
||||||
|
--exclude="*.lock" \
|
||||||
|
--exclude="*.bleve/store/root.bolt" \
|
||||||
|
--exclude="mongo/db/mongod.lock" \
|
||||||
|
"$SOURCE_MOUNTPOINT/" "$LOCAL_MOUNTPOINT/vps_backups/hetzner_storagebox_alpha"
|
||||||
|
|
||||||
|
STATUS=$?
|
||||||
|
if [ $STATUS -eq 0 ]; then
|
||||||
|
$RCHAT_NOTIFIER "backups" "success" \
|
||||||
|
"Created backup of ${NAS_DEVICE_NAME}."
|
||||||
|
# 23 = partial backup, 24 = some vanished files, both != major failure
|
||||||
|
elif [ $STATUS -eq 23 ] || [ $STATUS -eq 24 ]; then
|
||||||
|
$RCHAT_NOTIFIER "backups" "success" \
|
||||||
|
"Created backup of ${NAS_DEVICE_NAME}. A few files could not be copied."
|
||||||
|
else
|
||||||
|
$RCHAT_NOTIFIER "backups" "error" \
|
||||||
|
"Failed to create backup of ${NAS_DEVICE_NAME}: problem with rsync (exit code $STATUS)."
|
||||||
|
fi
|
||||||
|
|
||||||
|
clean_up
|
30
vps_backups/copy_vps_backup_to_local.sh
Executable file
30
vps_backups/copy_vps_backup_to_local.sh
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Copy backups of databases on VPS to local machine
|
||||||
|
|
||||||
|
# Parameters
|
||||||
|
# --- $1 = Service name, e.g. "forgejo"
|
||||||
|
# --- $2 = Database location on VPS, e.g. "thomas@systemsobscure.net:/home/thomas/backups/forgejo/*.sql.gz"
|
||||||
|
# --- $3 = Backup location path on VPS, e.g. "/vps_backups/mysql/forgejo/"
|
||||||
|
|
||||||
|
source "$HOME/.env"
|
||||||
|
|
||||||
|
LOCAL_MOUNTPOINT="/media/my-passport"
|
||||||
|
RCHAT_NOTIFIER="${HOME}/repos/utilities/rocketchat_notifier.sh"
|
||||||
|
|
||||||
|
mountpoint -q ${LOCAL_MOUNTPOINT}
|
||||||
|
|
||||||
|
if [ $? -eq 1 ]; then
|
||||||
|
$RCHAT_NOTIFIER "backups" "error" \
|
||||||
|
"Could not transfer $1 DB backup from VPS. Local backup disk (/media/my-passport) not mounted."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
scp "thomas@systemsobscure.net:${2}" "${LOCAL_MOUNTPOINT}/${3}"
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
BACKUP_FILE=$(ls -t "${LOCAL_MOUNTPOINT}/${3}" | head -1)
|
||||||
|
$RCHAT_NOTIFIER "backups" "success" "Copied $1 DB backup from VPS. File: ${BACKUP_FILE}"
|
||||||
|
else
|
||||||
|
$RCHAT_NOTIFIER "backups" "error" \
|
||||||
|
"Could not transfer $1 DB backup from VPS."
|
||||||
|
fi
|
Loading…
Add table
Reference in a new issue