#!/bin/bash
# Shellscript zum Datensicherung auf Root-Servern.
# Version 1.1
# (C) 2010 Stefan Schaefer -- invis-server.org
# (C) 2011 Udo Puetz -- muon IT Dienstleistungen
# Author: Stefan Schaefer / stefan@invis-server.org
# Questions: http://forum.invis-server.org
# License: GPLv3

# Debug-Anschalten wenn Aufruf z.B. so erfolgt
# DEBUG=1 bash allbackup
[ $DEBUG ] && set -x

# Konfigurationsdaten
version="1.1"
conffile="/etc/rootpack/rootpack.cfg"
passfile="/etc/rootpack/rp-pws.cfg"
logfile="/var/log/allbackup.log"

#TODO: Logrotate des logfile

# Funktionen
# Werte aus Konfigurationsdatendatei extrahieren
# $1 = Konfigurationsdatei, $2 = Parameter, $3 Wert (Feld)
getconfdata() {
    [ -e $1 ] || { echo "Achtung, Konfig-Datei $1 fehlt! Breche ab!"; exit 2; }
    grep -i "$2" $1 | cut -d ":" -f $3
}

# Konfigurationsparameter tauschen
changevalues() {
    # Arg1 = Pfad, Arg2 = Datei, Arg3 = sed String
    [ -e $1/$2.new ] && { echo "Datei $1/$2.new existiert schon, breche ab!"; exit 1; }
    cat $1/$2 | sed "s%$3%g" > $1/$2.new
    mv $1/$2.new $1/$2
}

# Ueberpruefe, ob auch wirklich das Tool auf dem System vorhanden ist
# $1 = Toolname (sshfs z.B.)
check_tool_present() {
    if which $1 &> /dev/null ; then
        return 0;
    else
        echo "Das Programm $1 ist nicht installiert, bitte installieren" | tee -a $logfile
        return 1;
    fi
}


usage() {
    echo -e "Rufen Sie allbackup mit einer der folgenden Optionen auf:\n"
    echo -e "\t-h zeigt diese Hilfe."
    echo -e "\t-d Sichert alle Datenbanken."
    echo -e "\t-m Sichert alle Email-Verzeichnisse."
    echo -e "\t-f Sichert alle Dateien der Kundenverzeichnisse."
    echo -e "\t-r Restore Modus - Hängt lediglich das Sicherungsverzeichnis ein."
    echo -e "\t-v Gibt die Version von allbackup aus."
}

## Script beenden, wenn keine Option übergeben wurden
if (( $# < 1 )); then
    usage
    exit 1
fi

while getopts ":hdmfrv" option ; do

    ## Sicherungsverzeichnisse
    dasidir=$(getconfdata $conffile "DasiDir" "2")
    dumpdir=$(getconfdata $conffile "DumpDir" "2")

    # Erstellen, wenn nicht vorhanden
    if [[ ! -d $dumpdir ]]; then
	mkdir -p $dumpdir
	chmod 0777 $dumpdir
    fi

    if [[ ! -d $dasidir ]]; then
	mkdir -p $dasidir
    fi

    datum=`date +%Y%m%d`
    logfiledatum=`date +%d.%B.%Y`
    echo "Sicherung vom $logfiledatum" >> $logfile
    
    ## Zielverzeichnis vom Backupserver mounten
    # Protokoll der Datensicherungsfreigabe abfragen
    targetsystem=$(getconfdata $conffile "DasiProto" "2")
    targeturl=$(getconfdata $conffile "BackupServerUrl" "2")
    targetdir=$(getconfdata $conffile "BackupServerDir" "2")
    buuser=$(getconfdata $passfile "BuUser" "2")
    bupass=$(getconfdata $passfile "BuPass" "2")

    # Mountstatus ermitteln
    mount | grep -q "$dasidir"
    mountok=${0}
    # checken ob schon etwas auf dem $dasidir eingebunden ist
    if [[ $mountok == true ]]; then
        targetsystem="schon eingebunden"
    fi
    
    # Backup-Freigabe einhaengen
    if [[ $targetsystem == "cifs" ]]; then
	# Samba-Freigabe einhaengen (benoetigt cifs-mount)
	mount -t cifs -o user=$buuser,pass=$bupass //$targeturl/$targetdir $dasidir | tee -a $logfile
    fi

    if [[ $targetsystem == "nfs" ]]; then
	# NFS-Freigabe einhaengen
	mount -t nfs $targeturl/$targetdir $dasidir | tee -a $logfile
    fi

    if [[ $targetsystem == "ftp" ]]; then
	# FTP-Freigabe einhaengen (benoetigt curlftpfs)
	[ check_tool_present curlftpfs ] && curlftpfs -o use_ino $buuser:$bupass@$targeturl/$targetdir $dasidir | tee -a $logfile
    fi

    if [[ $targetsystem == "sftp" ]]; then
	# SFTP-Freigabe einhaengen
	# Funktioniert nur, wenn SSH-Authorisation via Schluessel moeglich ist.
	[ check_tool_present sshfs ] && sshfs $buuser@$targeturl:/$targetdir $dasidir | tee -a $logfile
	# Folgende Zeile ist eher unnoetig, da nicht davon auszugehen ist, dass auf 
	# einen Backupserver der SSH-Port geaendert wurde.
	#sshfs -p $sshport $buuser@$targeturl:/$targetdir $dasidir
    fi
    
    if [[ $targetsystem == "local" ]]; then
	echo -e "Daten werden nur lokal gesichert. Dies kann nicht als vollwertige Datensicherung angesehen werden,\nda im Falle eines Festplattendefekts auch die Datensicherung verloren gehen kann." | tee -a $logfile
    fi

    # Mountstatus ermitteln
    mount | grep -q "$dasidir"
    mountok=${0}
    # checken ob das Einbinden auf $dasidir funktioniert hat
    if [[ $mountok == false ]]; then
        echo "Einbinden des Datensicherungsverzeichnisses $dasidir hat nicht funktioniert, breche ab!" | tee -a $logfile
        exit 2
    fi
    
    # Datensicherung
    case $option in 
    h)
	usage
	umount $dasidir
	exit 0
	;;
    d)
	## Datenbanken sichern
	echo "Datenbanken werden gesichert." >> $logfile
	# Quelldatenbanksysteme abfragen
	dbsystems=$(getconfdata $conffile "DbSys" "2")

	for dbs in $dbsystems; do
	    echo $dbs
    
	    case $dbs in
            ldap)
            	## Sichern eines LDAP-Verzeichnisses 
		slapcat > $dumpdir/ldap-sicherung.ldif | tee -a $logfile
                ;;
    	    mysql)
		## MySQL
		# root PW einlesen
		mysqlrootpw=$(getconfdata $passfile "MySQLRootPW" "2")
		loginstring="-u root --password=$mysqlrootpw"

		# Alle Datenbanken ermitteln und sichern
		alldbs=($(mysqlshow  $loginstring |tr -s " "| cut -d " " -f2| grep -v "+"|grep -v "Databases"))
		for db in ${alldbs[*]}; do
		#if [[ $db != "Databases" ]]; then
		    mysqldump $loginstring --single-transaction --add-drop-table $db > $dumpdir/mysql-$db-sicherung.sql| tee -a $logfile
		#fi
		done
                ;;
            pgsql)
		## PostgreSQL
		# ins Home-Verzeichnis von User postgres wechseln
		cd /var/lib/pgsql
		alldbs=($(sudo -u postgres psql -l|tr -d " "|grep -v "Name"|grep -v "-"|grep -v "Listof"|grep -v "("|cut -d "|" -f1))
    
		for db in ${alldbs[*]}; do
		    sudo -u postgres pg_dump -C -d -b $db > $dumpdir/pgsql-$db-sicherung.sql  | tee -a $logfile
		done
		cd
                ;;
	    esac
	done
	## Datenbanksicherungen archivieren
	if [[ ! -d $dasidir/datenbanken ]]; then
	    mkdir $dasidir/datenbanken
	fi
	find $dumpdir/* | afio -oZ $dasidir/datenbanken/$datum-alle-datenbanken.cpio | tee -a $logfile
        RETVAL=$?
        #echo $RETVAL
	## Dump-Verzeichnis leeren
	if [[ $RETVAL == "0" ]]; then
	    rm -rf $dumpdir/* 
	else
	    echo "Sichern der Datenbankdumps nach $dasidir/datenbanken/$datum-alle-datenbanken.cpio hat nicht funktioniert! Die Quelldateien liegen noch unter $dumpdir. Bitte haendisch beheben."
	    exit 2
	fi
	umount $dasidir
	;;
    m)
	## Sicherung aller Maildirs
	echo "E-Mail-Verzeichnisse werden synchronisiert." >> $logfile
	mailhome=$(getconfdata $conffile "MailHome" "2")
	# Synchronisation mit rsync, im Original gelöschte Dateien werden auch in der Sicherung geloescht
	rsync --bwlimit=500 --temp-dir=/var/tmp/rsync -rq --del $mailhome $dasidir/maildirs | tee -a $logfile
	umount $dasidir
	;;
    f)
	## Datensicherung der vhosts
	echo "Benutzerverzeichnisse werden gesichert." >> $logfile
	# differentielle Sicherung mit monatlicher Vollsicherung
	# Die Sicherung des Vormonats wird jeweils fuer einen Monat aufbewahrt.
	vhostdir=$(getconfdata $conffile "VhostDir" "2")

	vhdasidir="$dasidir/vhosts"

	if [[ ! -d $vhdasidir/active ]]; then
	    mkdir -p $vhdasidir/active
	fi

	if [[ ! -d $vhdasidir/lastmonth ]]; then
	    mkdir -p $vhdasidir/lastmonth
	fi

	fullbackup() {
	    for customdir in $vhostdir; do
		if [[ -d $customdir ]]; then
		    customer=$(basename $customdir)
		    find $customdir/* | afio -oZ $vhdasidir/active/$datum-$customer-full.cpio | tee -a $logfile
		fi
	    done
	}

	diffbackup() {
	    for customdir in $vhostdir; do
		if [[ -d $customdir ]]; then
		customer=$(basename $customdir)
		find $customdir/ -newer $vhdasidir/active/*$customer-full.cpio | afio -oZ $vhdasidir/active/$datum-$customer-diff.cpio | tee -a $logfile
	        fi
	    done
	}

	# Wenn nicht vorhanden, Monatszahl in eine Kontrolldatei schreiben und primaere Vollsicherung anlegen
	if [[ ! -f $vhdasidir/month ]]; then
	    date +%m > $vhdasidir/month
	    fullbackup
	else 
            # Bei Monatswechsel eine neue Vollsicherung anlegen. Vorher letzten Monat sichern
	    if (( $(cat $vhdasidir/month) != $(date +%m) )); then
		rm -rf $vhdasidir/lastmonth/*
		mv $vhdasidir/active/* $vhdasidir/lastmonth/
		fullbackup
	    else
		diffbackup
	    fi
	fi
	umount $dasidir
	;;
    r)
	echo -e "Restore Modus"
	echo -e "Das Sicherungsverzeichnis wurde lediglich eingebunden."
	echo -e "Sie können jetzt manuell Rücksicherungen vornehmen."
	echo -e "Hängen Sie das Verzeichnis nach erfolgter Rücksicherung\nmit \"umount $dasidir\" wieder aus."
	;;
    v)
	echo -e "allbackup $version"
	echo -e "(C) 2010 invis-server.org"
	echo -e "Author: Stefan Schaefer / stefan@invis-server.org"
	echo -e "Questions: http://forum.invis-server.org"
	echo -e "License: GPLv3"
	umount $dasidir
	;;
    ?)
	usage
	umount $dasidir
	exit 1
	;;
    esac
done
