summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2016-04-01 09:40:29 +0200
committerErich Eckner <git@eckner.net>2016-04-01 09:40:29 +0200
commit61998f2eaabadd4fa531d97e9a42373ff9bc6fbc (patch)
tree9e7afcb83f4cc30b3aae146a3b7de02415916183
downloadhardlinkedBackups-61998f2eaabadd4fa531d97e9a42373ff9bc6fbc.tar.xz
Initial Commit
-rwxr-xr-xbackup115
-rw-r--r--backup.conf24
-rwxr-xr-xlastBackups67
3 files changed, 206 insertions, 0 deletions
diff --git a/backup b/backup
new file mode 100755
index 0000000..f6501dc
--- /dev/null
+++ b/backup
@@ -0,0 +1,115 @@
+#!/bin/bash
+
+. /etc/backup.conf
+
+usage()
+{
+ echo 'usage:'
+ echo ' backup /tmp/pidFile /path/to/destination/ user@source:path'
+ echo ' backup /tmp/pidFile /path/to/destination/ user@source:path proxy_user@ssh_host'
+ echo 'or as a symlink (e.g. in /etc/cron/daily) named after a key of $backups in /etc/backup.conf without arguments'
+ exit 1
+}
+
+if [ $# -eq 0 ]
+then
+ backupID="$(basename $0)"
+ [ -z "${backups[${backupID}]}" ] && usage
+ set /tmp/${backupID}.pid ${backups[${backupID}]}
+fi
+
+Basis="$2"
+pidFile="$1"
+QuellIP=$(echo "$3" | sed "s|^[a-zA-Z]*://||; s|^[a-zA-Z]*@||; s|:\?/.*$||")
+
+if [ "$#" -eq 3 ]
+then
+ Quelle="$3"
+elif [ "$#" -eq 4 ]
+then
+ sshHopp="$4"
+ lokPort=$[$RANDOM/2+8000]
+ rsyncShell="-e ssh -p${lokPort} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
+ tunnelBefehl="ssh -t -t -L${lokPort}:${QuellIP}:22 ${sshHopp}"
+ HoppIP="${sshHopp#*@}"
+ Quelle="$(echo "$3" | sed "s|${QuellIP}|127.0.0.1|")"
+else
+ usage
+fi
+
+ping -c1 ${QuellIP} > /dev/null || exit 11
+if [ -n "${HoppIP}" ]
+then
+ ping -c1 ${HoppIP} > /dev/null || exit 11
+fi
+
+if [ ! -d ${Basis} ]
+then
+ [ $(mount | grep -c "\S\+\s\+\S\+\s\+/var/ftp\s") -eq 0 ] && exit 11
+ exit 2
+fi
+
+neues_Datum=${Basis}/$(date "+%Y_%m_%d")
+neues=${Basis}/aktuell
+linkdests=""
+for s in $(ls -1tr ${Basis} | grep -v aktuell | tail -n20 )
+do
+ linkdests="${linkdests} --link-dest ${Basis}/${s}"
+done
+
+if [ ! "$(whoami)" == "root" ]
+then
+ echo "I need to be root."
+ exit 3
+fi
+
+[ -w ${Basis} ] || exit 11
+[ -e ${neues_Datum} ] && exit 4
+[ -e ${pidFile} ] && exit 5
+
+echo $$ > ${pidFile}
+
+if [ -n "${tunnelBefehl}" ]
+then
+ ${tunnelBefehl} &
+ backgroundPid=$!
+ sleep 4
+fi
+
+for toExclude in ${excludes}
+do
+ excludeArgs="${excludeArgs} --exclude ${toExclude}"
+done
+
+if [ ! -e ${neues} ]
+then
+ mkdir ${neues}
+fi
+chmod 750 ${neues}
+chown erich:root ${neues}
+if [ -z "${rsyncShell}" ]
+then
+ rsync -av -x --no-p --no-o --no-g ${linkdests} \
+ ${excludeArgs} \
+ ${Quelle} ${neues}/
+ sleep 1
+ rsync ${Quelle}
+else
+ rsync "${rsyncShell}" -av -x --no-p --no-o --no-g ${linkdests} \
+ ${excludeArgs} \
+ ${Quelle} ${neues}/
+ sleep 1
+ rsync "${rsyncShell}" ${Quelle}
+fi
+erg=$?
+
+[ -n "${backgroundPid}" ] && kill ${backgroundPid}
+
+if [ ${erg} -eq 0 ] || [ ${erg} -eq 24 ]
+then
+ mv ${neues} ${neues_Datum}
+ rm ${pidFile}
+else
+ rm ${pidFile}
+ exit 11
+fi
diff --git a/backup.conf b/backup.conf
new file mode 100644
index 0000000..0b65488
--- /dev/null
+++ b/backup.conf
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# config file for hardlinkedBackups
+
+# files/paths to exclude from backup (via --exclude)
+excludes=(
+ "path/to/exclude/from/backup"
+ "yet/another/one"
+)
+
+# definition of backups to do
+declare -A backups
+
+backups["directBackup"]="/path/to/destination/ user@source:path"
+backups["proxiedBackup"]="/path/to/destination/ user@source:path proxy_user@ssh_host"
+
+# how long to wait for destination directories to appear in lastBackups [seconds]
+maxWait=100
+
+# how old may backups be before we warn about outdated ones [seconds]
+outdatedLimit=$[2*24*60*60]
+
+# subdirectories which should be appended to the parent directory in the report
+recognSubdirRegex="home\|boot\|root\|erich"
diff --git a/lastBackups b/lastBackups
new file mode 100755
index 0000000..7a03c11
--- /dev/null
+++ b/lastBackups
@@ -0,0 +1,67 @@
+#!/bin/bash
+
+. /etc/backup.conf
+
+unset namen
+unset veraltet
+unset daten
+
+for backupID in ${!backups[@]}
+do
+ dest="${backups["${backupID}"]%% *}"
+ dest="${dest%/}"
+ while [ ! -d "${dest}" ] && [ ${maxWait} -gt 0 ]
+ do
+ sleep 1
+ maxWait=$[${maxWait}-1]
+ done
+
+ lbu=$(
+ ls -1 ${dest} | \
+ grep -v "^aktuell$" | \
+ sed "s/^duplicity-\(inc\|full\)\.\(.*\.\)\?\([0-9]\{4\}\)\([0-9]\{2\}\)\([0-9]\{2\}\)T[0-9]\{6\}Z\..*$/\3_\4_\5/" | \
+ sort -n | \
+ uniq | \
+ grep "^[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}$" | \
+ tail -n1
+ )
+ [ "${lbu}" == "" ] && lbu="2000_01_01"
+ delta=$[$(date +%s) - $(date -d $(echo ${lbu} | sed "s/_//g") +%s)]
+ namen[${#namen[@]}]="$(basename $(echo ${dest} | sed "s#/\(${recognSubdirRegex}\)\$#_\1#" | sed "s#/rsync\$##; s#/duplicity\$##"))"
+ [ ${delta} -gt ${outdatedLimit} ] && veraltet[${#veraltet[@]}]="VERALTET!" || veraltet[${#veraltet[@]}]=""
+ daten[${#daten[@]}]="${lbu}"
+done
+
+nl=0
+vl=0
+dl=0
+
+for ((i=0; i<${#namen[@]}; i++))
+{
+ [ ${#namen[${i}]} -gt ${nl} ] && nl=${#namen[${i}]}
+ [ ${#veraltet[${i}]} -gt ${vl} ] && vl=${#veraltet[${i}]}
+ [ ${#daten[${i}]} -gt ${dl} ] && dl=${#daten[${i}]}
+}
+
+for ((i=0; i<${#namen[@]}; i++))
+{
+ while [ ${#namen[${i}]} -lt ${nl} ]
+ do
+ namen[${i}]="${namen[${i}]} "
+ done
+ while [ ${#veraltet[${i}]} -lt ${vl} ]
+ do
+ veraltet[${i}]="${veraltet[${i}]} "
+ done
+ while [ ${#daten[${i}]} -lt ${dl} ]
+ do
+ daten[${i}]="${daten[${i}]} "
+ done
+}
+
+for ((i=0; i<${#namen[@]}; i++))
+{
+ echo "${daten[${i}]} ${veraltet[${i}]} ${namen[${i}]} ${daten[${i}]}"
+} | \
+ sort | \
+ sed "s/^\S\+\s//"