aboutsummaryrefslogtreecommitdiff
path: root/backup.sh
diff options
context:
space:
mode:
authorMitchell Riedstra <mitch@riedstra.dev>2025-12-31 17:39:36 -0500
committerMitchell Riedstra <mitch@riedstra.dev>2025-12-31 17:39:36 -0500
commit99957c2e49121b616c61e483bf6ebc2271789a50 (patch)
tree8ac8d97c400b0df61f4362868e1ae580509c7068 /backup.sh
downloadsvr-backups-master.tar.gz
svr-backups-master.tar.xz
initialHEADmaster
Diffstat (limited to 'backup.sh')
-rwxr-xr-xbackup.sh101
1 files changed, 101 insertions, 0 deletions
diff --git a/backup.sh b/backup.sh
new file mode 100755
index 0000000..5aa1f96
--- /dev/null
+++ b/backup.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+set -e
+svr=""
+ssh_conf="ssh/config"
+ssh_key="ssh/id_ed25519"
+_backup_type="daily"
+_suffix="tar.zst"
+force=false
+
+
+_date_for_type() {
+case "$1" in
+daily) date +%Y-%m-%d ;;
+weekly) date +%Y-%U ;;
+monthly) date +%Y-%m ;;
+*) date +%s ;; # somehow, a bad type so just default to unix timestamp
+esac
+}
+
+__help() {
+cat <<EOF
+$0 -svr <server> [opts]
+
+Create a backup for <server>, defaults to daily. Calls <server>/backup.sh
+on the remote host and saves the stdout. It's up to the server's
+specific backup script to determine the specifics of that format. Tarballs
+are suggested, but snapshots, cpio archives, etc can all be used.
+
+Where [opts] are one of:
+
+-ssh_conf <filename> # For ssh configuration i.e. -F flag on ssh
+-ssh_key <filename> # SSH key to use, passed in as -i to ssh
+-type <daily|monthly|weekly> # Passed to the subscript, and changes output dir
+-suffix <suffix> # Defaults to 'tar.zst', but could be anything, should match
+ # the output of the server's specific backup script
+-force # Normally we bail if a backup exists, this will force overwrite
+
+Normal usage is that weekly and monthly backups are full, and the daily
+backups only include files that were changed in the past 24 hours, usually
+via find command and piping a list of input files to tar.
+
+A separate ./cleanup.sh script can take care of removing the old backups
+on a schedule that you prefer.
+EOF
+exit 2
+}
+
+while [ $# -gt 0 ] ; do case $1 in
+ -svr) svr="$2"; shift ; shift ;;
+ -ssh_conf) ssh_conf="$2"; shift ; shift ;;
+ -ssh_key) ssh_key="$2"; shift ; shift ;;
+ -type) _backup_type="$2"; shift ; shift ;;
+ -suffix) _suffix="$2"; shift ; shift ;;
+ -force) force=true ; shift ;;
+ *) __help ;;
+esac ; done
+
+_err=0
+if [ -z "$svr" ] ; then
+ echo "-svr flag needs to be set"
+ _err=1
+fi
+if [ -z "$ssh_conf" ] ; then
+ echo "-ssh_conf flag needs to be set"
+ _err=1
+fi
+if [ -z "$ssh_key" ] ; then
+ echo "-ssh_key flag needs to be set"
+ _err=1
+fi
+
+if ! [ -x "$svr/backup.sh" ] ; then
+ echo "$svr/backup.sh should exist and be executable!"
+ _err=1
+fi
+
+case "$_backup_type" in
+ daily|weekly|monthly) true ;;
+ *) echo "Bad backup type: '$_backup_type' valid options are daily, weekly, or monthly"; _err=1 ;;
+esac
+
+if [ "$_err" -ne 0 ] ; then
+ exit "$_err"
+fi
+
+ssh -F "$ssh_conf" -i "$ssh_key" "$svr" "mkdir -p /root/.backup"
+ssh -F "$ssh_conf" -i "$ssh_key" "$svr" "cat > /root/.backup/script.sh" < "$svr/backup.sh"
+ssh -F "$ssh_conf" -i "$ssh_key" "$svr" "chmod +x /root/.backup/script.sh"
+
+
+outfile="$svr/$_backup_type/$(_date_for_type "$_backup_type").$_suffix"
+mkdir -p "$(dirname "$outfile")"
+if [ -e "$outfile" ] ; then
+ echo "BACKUP FILE EXISTS ALREADY: $outfile"
+ if $force ; then
+ echo "OVERWRITING"
+ else
+ exit 1
+ fi
+fi
+ssh -F "$ssh_conf" -i "$ssh_key" "$svr" "/root/.backup/script.sh \"$_backup_type\"" | pv > "$outfile"