Refactor borg to be backup and restore script.

This commit is contained in:
Lars Hahn 2024-07-24 20:39:13 +02:00
parent 2e113e7219
commit 8d57815b79
6 changed files with 157 additions and 117 deletions

View File

@ -17,6 +17,12 @@ backup_run_folder: "{{ cloud_storage }}"
backup_storage_key: "MyStorageKey" backup_storage_key: "MyStorageKey"
backup_client: true backup_client: true
backup_host: "example" backup_app: app
backup_cron_specialtime: "daily" backup_cron_specialtime: "daily"
backup_cron_owner: "{{ backup_owner }}" backup_cron_owner: "{{ backup_owner }}"
backup_script:
prework_backup: |
echo "This is executed before borg backup. Please collect data for backup in path: {{ backup_storage }}"
postwork_restore: |
echo "This is executed after borg restore. Please collect data during restore from path: {{ backup_storage }}"

View File

@ -32,15 +32,15 @@
- name: setup backup script - name: setup backup script
template: template:
src: "./usr/local/bin/{{ backup_host }}-backup.sh.j2" src: "./usr/local/bin/cloud_backup.j2"
dest: "/usr/local/bin/backup.sh" dest: "/usr/local/bin/cloud_backup"
owner: "{{ backup_owner }}" owner: "{{ backup_owner }}"
group: "{{ backup_group }}" group: "{{ backup_group }}"
mode: "0750" mode: "0750"
- name: setup cron backup job - name: setup cron backup job
cron: cron:
name: "{{ backup_host }} backup" name: "cloud backup"
user: "{{ backup_cron_owner }}" user: "{{ backup_cron_owner }}"
job: "/usr/local/bin/backup.sh" job: "/usr/local/bin/cloud_backup backup"
special_time: "{{ backup_cron_specialtime }}" special_time: "{{ backup_cron_specialtime }}"

View File

@ -1,65 +0,0 @@
#!/bin/bash
BORGUSER="{{ backup_owner }}";
RUNFOLDER="{{ backup_run_folder }}";
TARGETFOLDER="{{ backup_storage }}";
REPOLOCATION="{{ backup_location }}";
ARCHIVENAME="authentik-$(date '+%s')";
cd $RUNFOLDER;
POSTGRES_DOCKER_ID=$(docker ps --format '{{.ID}} {{.Names}}' | grep postgres | cut -f 1 -d ' ');
mkdir $TARGETFOLDER/$ARCHIVENAME;
docker exec -i $POSTGRES_DOCKER_ID /usr/local/bin/pg_dump --username {{ authentik_db.user }} {{ authentik_db.name }} > $TARGETFOLDER/authentik-postgres-backup.sql
sudo -H -u $BORGUSER bash -c '
TARGETFOLDER='$TARGETFOLDER';
REPOLOCATION='$REPOLOCATION';
ARCHIVENAME='$ARCHIVENAME';
export BORG_PASSPHRASE=$(cat {{ backup_home }}/.borg.key);
borg create -C lzma $REPOLOCATION::$ARCHIVENAME $TARGETFOLDER/$ARCHIVENAME';
rm -rf $TARGETFOLDER/$ARCHIVENAME;
### RESTORE!!! ###
SHUTDOWN_CONTAINER_IDS=$(docker ps --format '{{.ID}} {{.Names}}' | cut -f 1 -d ' ' | grep -v $POSTGRES_DOCKER_ID | tr '\n' ' ');
docker stop $SHUTDOWN_CONTAINER_IDS
docker exec -i $POSTGRES_DOCKER_ID /usr/local/bin/dropdb --username {{ authentik_db.user }} '{{ authentik_db.name }}'
docker exec -i $POSTGRES_DOCKER_ID /usr/local/bin/createdb --username {{ authentik_db.user }} '{{ authentik_db.name }}'
docker exec -i $POSTGRES_DOCKER_ID /usr/local/bin/psql --username {{ authentik_db.user }} -d {{ authentik_db.name }} < $TARGETFOLDER/authentik-postgres-backup.sql
docker-compose down
docker-compose up -d
help (){
echo "Here Help";
}
(
flock -n 9 || {
echo "PERFORMANCE TEST ABORTED! ALREADY RUNNING!";
exit 1;
}
if [[ $(id -u) != 0 ]]; then
echo "Performance test aborted; please become root in order to run a performance test.";
exit 1;
fi
if [ $# = 0 ]; then
help
exit 0;
fi
case $tooling in
"atlassian")
echo "blah";
;;
*)
# I know this looks stupid, only one case, but in future we want to use TaaS/TReX aswell...
# So let's make it future safe!
echo -e "Invalid tooling '$tooling'.Please check help for correct list."
exit 1
;;
esac
echo ""
) 9>/var/run/lock/devstack-loadtest.lock;

View File

@ -0,0 +1,145 @@
#!/bin/bash
BORGUSER="{{ backup_owner }}";
RUNFOLDER="{{ backup_run_folder }}";
TARGETFOLDER="{{ backup_storage }}";
REPOLOCATION="{{ backup_location }}";
ARCHIVENAME="{{ backup_app }}-$(date '+%s')";
help (){
echo "cloud_backup - backup and restore script on cloud with borg target v1.0 by L.Hahn.
Usage: $0 COMMAND [ARCHIVENAME]
COMMAND:
- list List available archives in remote borg repository for your host.
- backup Perform backup of your host and create a new archive in borg repository.
- restore [ARCHIVENAME] Download backup from borg repository to your host and restore files.
May turn off your application if still running.
If no ARCHIVENAME is provided, the latest one based on timestamp is taken.
IF ARCHIVENAME is provided, will try to download it; throws error if not found.
";
}
### INDIVIDUAL TEMPLATE PART ###
prework_backup () {
{{ backup_script.prework_backup | indent( width=4) }}
}
postwork_restore () {
{{ backup_script.postwork_restore | indent( width=4) }}
}
### SHARED TEMPLATE PART ###
get_archives () {
ARCHIVEIDS=$(
sudo -H -u $BORGUSER bash -c '
REPOLOCATION='$REPOLOCATION';
export BORG_PASSPHRASE=$(cat {{ backup_home }}/.borg.key);
borg list $REPOLOCATION' | sort -r);
echo "$ARCHIVEIDS";
}
cloud_backup () {
mkdir -p $TARGETFOLDER/$ARCHIVENAME;
prework_backup;
cd /;
sudo -H -u $BORGUSER bash -c '
TARGETFOLDER='$TARGETFOLDER';
REPOLOCATION='$REPOLOCATION';
ARCHIVENAME='$ARCHIVENAME';
export BORG_PASSPHRASE=$(cat {{ backup_home }}/.borg.key);
borg create -C lzma $REPOLOCATION::$ARCHIVENAME $TARGETFOLDER/$ARCHIVENAME';
rm -rf $TARGETFOLDER/$ARCHIVENAME;
}
cloud_restore () {
ARCHIVENAME=$1;
ARCHIVEIDS=$(get_archives | cut -f 1 -d ' ');
if [[ "${ARCHIVENAME,,}" == "latest" ]];
then
ARCHIVENAME=$(echo "$ARCHIVEIDS" | head -n 1);
else
if [[ "$ARCHIVEIDS" != *$ARCHIVENAME* ]];
then
echo "ERROR! Provided archivename '$ARCHIVENAME' is not part of the available archives! Aborting.";
exit 1;
fi
fi
mkdir -p $TARGETFOLDER/$ARCHIVENAME;
chown -R $BORGUSER: $TARGETFOLDER
cd /;
sudo -H -u $BORGUSER bash -c '
REPOLOCATION='$REPOLOCATION';
ARCHIVENAME='$ARCHIVENAME';
export BORG_PASSPHRASE=$(cat {{ backup_home }}/.borg.key);
borg extract $REPOLOCATION::$ARCHIVENAME --list';
postwork_restore;
rm -rf $TARGETFOLDER/$ARCHIVENAME;
}
cloud_backup_delete () {
ARCHIVENAME=$1;
ARCHIVEIDS=$(get_archives | cut -f 1 -d ' ');
if [[ "$ARCHIVEIDS" != *$ARCHIVENAME* ]];
then
echo "ERROR! Provided archivename '$ARCHIVENAME' is not part of the available archives! Aborting.";
exit 1;
fi
sudo -H -u $BORGUSER bash -c '
REPOLOCATION='$REPOLOCATION';
ARCHIVENAME='$ARCHIVENAME';
export BORG_PASSPHRASE=$(cat {{ backup_home }}/.borg.key);
borg delete $REPOLOCATION::$ARCHIVENAME';
}
has_argument () {
if [[ -z "$1" ]];
then
echo "Missing required paramter!";
fi
}
(
flock -n 9 || {
echo "BACKUP ALREADY RUNNING! ABORTING.";
exit 1;
}
if [ $# = 0 ]; then
help;
exit 0;
fi
action=$1
case $action in
"list")
get_archives;
;;
"backup")
cloud_backup;
;;
"restore")
has_argument $2;
cloud_restore $2;
;;
"delete")
has_argument $2;
cloud_backup_delete $2;
;;
*)
help;
;;
esac
echo ""
) 9>/var/run/lock/cloud-backup.lock;

View File

@ -1,26 +0,0 @@
#!/bin/bash
BORGUSER="{{ backup_owner }}";
RUNFOLDER="{{ backup_run_folder }}";
TARGETFOLDER="{{ backup_storage }}";
REPOLOCATION="{{ backup_location }}";
ARCHIVENAME="mailcow-$(date '+%s')";
cd $RUNFOLDER;
MAILCOW_BACKUP_LOCATION="$TARGETFOLDER/" ./helper-scripts/backup_and_restore.sh backup all;
LATESTBACKUP="$(ls -t $TARGETFOLDER | head -n 1)";
if [[ "$LATESTBACKUP" != *"mailcow"* ]];
then
echo "NOT MAILCOW! ABORT!";
exit 1;
fi
chown -R $BORGUSER: $TARGETFOLDER/$LATESTBACKUP;
sudo -H -u $BORGUSER bash -c '
TARGETFOLDER='$TARGETFOLDER';
REPOLOCATION='$REPOLOCATION';
ARCHIVENAME='$ARCHIVENAME';
export BORG_PASSPHRASE=$(cat {{ backup_home }}/.borg.key);
borg create -C lzma $REPOLOCATION::$ARCHIVENAME $TARGETFOLDER/$LATESTBACKUP';
rm -rf $TARGETFOLDER/$LATESTBACKUP;

View File

@ -1,20 +0,0 @@
#!/bin/bash
BORGUSER="{{ backup_owner }}";
RUNFOLDER="{{ backup_run_folder }}";
TARGETFOLDER="{{ backup_storage }}";
REPOLOCATION="{{ backup_location }}";
ARCHIVENAME="vault-$(date '+%s')";
cd $RUNFOLDER;
cp -r $RUNFOLDER/home $TARGETFOLDER/$ARCHIVENAME;
chown -R $BORGUSER: $TARGETFOLDER/$ARCHIVENAME;
sudo -H -u $BORGUSER bash -c '
TARGETFOLDER='$TARGETFOLDER';
REPOLOCATION='$REPOLOCATION';
ARCHIVENAME='$ARCHIVENAME';
export BORG_PASSPHRASE=$(cat {{ backup_home }}/.borg.key);
borg create -C lzma $REPOLOCATION::$ARCHIVENAME $TARGETFOLDER/$ARCHIVENAME';
rm -rf $TARGETFOLDER/$ARCHIVENAME;