Commit ce5308a0 authored by Simone Piccardi's avatar Simone Piccardi
Browse files

First draft of the new backup script.

parent b9c622ec
#!/bin/sh
#!/bin/bash
#
# fuss-backup -- A script to dump server databases and other info and
# backup data files with borg.
#
# Look for LDAP/MySQL/Postgres installazion and it they are present dumps:
#
# * a .ldif backup for a slapd database
# * a .sql.gz dump for a MySQL database
# * a .sql dump for users/grants on a MySQL database
# * a .sql.gz dump for all Postgres database by pg_dumpall
#
# automatically select gzip or pigz for compression, optional
# encryption and remote saving via scp
#
# Copyright (C) 2009-2016 Truelite Srl by Simone Piccardi
# Copyright (C) 2017 Simone Piccardi <piccardi@truelite.it>,
# Elena Grandi <elena@truelite.it>,
# Progetto Fuss <info@fuss.bz.it>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
# initialize locales and umask
LC_ALL=C
umask 077
# define exit function (sending email)
mail_exit () {
if [ $1 != 0 ]; then
MAILSUBJ="Backup fail on $(hostname) for $(date +%x)"
else
MAILSUBJ="Backup ok on $(hostname) for $(date +%x)"
fi
if [ "$MAILTO" ]; then
DESTINARI="$MAILTO"
else
DESTINARI=root
fi
for i in $DESTINARI; do
grep -v "Hexadecimal number" $TMPLOG | mailx -s "$MAILSUBJ" $i
done
exit $1
}
# local data variables (for dump retention)
MAXDAYS=7
MINCOPIES=6
BACKDIR=/var/backups
# temporary log files
DAY=$(date +%a)
TMPLOG=/tmp/dumpdata-$DAY.log
ERRLOG=/tmp/dumpdata-err.log
# clear logs
MESS="Data dump on $(hostname) for $(date +%x)"
exec > $TMPLOG 2>&1
echo "$MESS started, at $(date +%R)"
echo
# get configuration
if [ -f /etc/fuss-backup/fuss-backup.conf ]; then
. /etc/fuss-backup/fuss-backup.conf
. /etc/fuss-backup/fuss-backup.conf
else
echo "Errore: file di configurazione non presente"
exit 1
echo "Errore: file di configurazione non presente"
mail_exit 1
fi
#
# check if the backup is enabled
if [ $START != "yes" ]; then
echo "ERRORE: e' necessario configurare l'applicazione fuss-backup"
echo "per avviarne l'esecuzione!"
echo "Modificare il file /etc/fuss-backup/fuss-backup.conf"
exit 2
fi
# data e ora correnti
DATE=`date "+%Y%m%d-%H%M"`
# creo, se non esiste, la directory principale di backup
if [ ! -d $BACKUP_DIR ]; then
mkdir $BACKUP_DIR
echo "ERRORE: è necessario configurare l'applicazione fuss-backup"
echo "per avviarne l'esecuzione!"
echo "Modificare il file /etc/fuss-backup/fuss-backup.conf"
mail_exit 2
fi
# creo
# creo una directory ad hoc per contenere tutti i backup
BD=$BACKUP_DIR/fuss-backup-$DATE
mkdir $BD
# definizione dei programmi da utilizzare nello script
# se esiste il file di esclusione, utilizzarlo
if [ -f /etc/fuss-backup/fuss-backup.exclude ]; then
echo "E' attivo un file di esclusione"
TAR="/bin/tar --exclude-from=/etc/fuss-backup/fuss-backup.exclude"
# select compression
if which pigz > /dev/null; then
GZ=pigz
else
echo "Non e' stato utilizzato il file di esclusione"
TAR=/bin/tar
fi
GZ=gzip
fi
##
## Some checks
##
# function to check for almost full disks
check_disk_full () {
for i in $(df -h | egrep '([8-9][0-9]|100)\%' | awk '{print $6}'); do
echo Warning: $i at $(df -h | grep $i | awk '{print $5}');
done
}
# function to check full disks
panic_disk_full () {
FULL=$(df -h | egrep '100\%' | awk '{print $6}')
if [ -n "$FULL" ]; then
echo "$FULL is full, backup will be inconplete"
echo "please remove unused files, make fewer copies"
echo "or buy a bigger disk"
fi
}
# common init functions
function init_dump () {
bak=$BACKDIR/$1
[ -d $bak ] || mkdir -m 750 -p $bak
NAME=$1
cd $bak
}
# do a package list backup anyway
dpkg --get-selections > $BACKDIR/package-list.txt
### LDAP ###
# controlla se e' installato LDAP, se si fai il backup
if [ -f /etc/init.d/slapd ]; then
# leggo dati da ldap, interrompendo il servizio Q.B.
/etc/init.d/slapd stop
slapcat | gzip > $BD/backup-ldap-$DATE.ldif.gz
/etc/init.d/slapd start
fi
### LISTA SOFTWARE INSTALLATO ###
# leggo la lista del software installato SUL SERVER e la salvo
dpkg --get-selections | gzip > $BD/lista-sw-$HOSTNAME-$HOSTNAME-$DATE.txt.gz
### BACKUP DI HOME ###
# fare backup di /home se non siamo su di un
# client NFS
if touch /home/.test-fuss-backup ; then
HOMES="/home $HOME"
else
HOMES="$HOME"
#
# LDAP Section
#
if which slapd > /dev/null; then
echo "LDAP dump started at $(date +%R)"
init_dump slapd
FILEBACK=$NAME-`date +%F`.ldif.gz
# do the backup if the daemon is running
if [ -f /var/run/slapd/slapd.pid ]; then
# dump data with slapcat
slapcat | $GZ > $FILEBACK
echo "* slapcat dump in $FILEBACK"
tranfencrypt $FILEBACK
# clean old (more than MAXDAYS) copies, leaving at least MINCOPIES
if [ $(ls $NAME* | wc -l) -gt $MINCOPIES ]; then
find . -name "${NAME}*" -mtime $MAXDAYS -exec rm -f \{\} \;
fi
else
cat <<-EOF
slapd not running, nothing done
EOF
exit 1
fi
echo "LDAP dump completed at $(date +%R)"
fi
$TAR -zcf $BD/backup-home-$DATE.tar.gz $HOMES
### BACKUP DEL DATABASE DI OCTOFUSS, SE PRESENTE
if [ -d /var/lib/octofuss/ ]; then
$TAR -zcf $BD/backup-octofuss-$DATE.tar.gz /var/lib/octofuss/
#
# MySQL Section
#
if which mysqld_safe > /dev/null; then
echo "MySQL dump started at $(date +%R)"
init_dump mysql
# Define DB to not be dumped in the form ...|db1|db2|...
NODUMPDB="information_schema|performance_schema"
# Backup MySQL databases, each one to a separate file.
if [ -z "$NODUMPDB" ]; then
REGEX="Database"
else
REGEX="(Database|$NODUMPDB)"
fi
if ! dblist=$(mysql --batch -e "show databases" | egrep -v "$REGEX"); then
cat <<-EOF
Cannot access database list with command mysql, check MySQL installation
and configuration; remind also to put the password for the root MySQL
user in the .my.cnf file
EOF
fi
for i in $dblist; do
FILEBACK=${i}-`date +%F`.sql.gz
> $ERRLOG
mysqldump ${i} --events --user=$DBUSER | $GZ > $FILEBACK 2>> $ERRLOG
grep -v information_schema $ERRLOG >>$TMPLOG
echo "* database ${i} dumped in $FILEBACK"
tranfencrypt $FILEBACK
if [ $(ls ${i}-*.sql.gz|wc -l) -gt $MINCOPIES ]; then
find . -name "${i}-*.sql.gz" -mtime +$MAXDAYS -exec rm -f \{\} \;
fi
done
DUMPFILE=mysql_user_grants-$DAY.sql
mysql -B -N $@ -e "SELECT DISTINCT CONCAT(
'SHOW GRANTS FOR \'', user, '\'@\'', host, '\';'
) AS query FROM mysql.user WHERE user
NOT IN ('root','phpmyadmin','debian-sys-maint')" | \
mysql $@ | \
sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}' \
> $DUMPFILE
echo "* dumped MySQL grants in $DUMPFILE"
tranfencrypt $DUMPFILE
echo "MySQL dump completed at $(date +%R)"
fi
### BACKUP DI ETC ###
$TAR -zcf $BD/backup-etc-$DATE.tar.gz /etc
### BACKUP DI /VAR/LOG ###
$TAR -zcf $BD/backup-var-log-$DATE.tar.gz /var/log/
### BACKUP DI ALTRE CARTELLE AGGIUNTIVE ###
# eseguo il backup della cartelle aggiuntive
# solo se specificate nel file di configurazione
if [ "$ALTRE_DIR" ]; then
$TAR -zcf $BD/backup-altro-$DATE.tar.gz $ALTRE_DIR
#
# PostgreSQL section
#
if which pg_dumpall > /dev/null; then
echo "PostgreSQL dump started at $(date +%R)"
init_dump pgsql
FILEBACK=dumpall-`date +%F`.sql.gz
su postgres -c "pg_dumpall" | $GZ > $FILEBACK
echo "* pg_dumpall dump in $FILEBACK"
tranfencrypt $FILEBACK
if [ $(ls dumpall-*.sql.gz|wc -l) -gt $MINCOPIES ]; then
find . -name "dumpall-*.sql.gz" -mtime +$MAXDAYS -exec rm -f \{\} \;
fi
echo "PostgreSQL dump completed at $(date +%R)"
fi
### IL BACKUP VIENE SPEZZATO SE RICHIESTO ###
## da spezzare anche gli altri oltre a home!!! ###
if [ "$SPLIT" ]; then
cd $BD
split -d -b $SPLIT backup-home-$DATE.tar.gz backup-home-$DATE.tar.gz.
rm backup-home-$DATE.tar.gz
#
# Borg backup section
#
if [ ! $DISK ]; then
echo "Deve essere definito il disco/NAS di destinazione"
mail_exit 3
fi
## STORICO ##
# manteniamo $STORICO backup vecchi
if [ $STORICO -ge 0 ]; then
STORICO=`expr $STORICO + 1`
cd $BACKUP_DIR
TOTALE=`ls -d fuss-backup-* | wc -l`
DAELIMINARE=`expr $TOTALE - $STORICO`
if [ $DAELIMINARE -gt 0 ]; then
for i in `ls -d fuss-backup-* | head -$DAELIMINARE`; do
echo "Elimino il backup $i"
rm -rf $i
done
fi
if mount $DISK $BASEDIR >> $TMPLOG 2>&1; then
DESTINATION=$BASEDIR/$BACKUP_DIR
# init backup repository if no exists
if [ ! -d $DESTINATION ]; then
borg init --encryption=none $DESTINATION
fi
if [ -f /etc/fuss-backup/fuss-backup.exclude ]; then
echo "E' attivo un file di esclusione"
borg create --exclude-from=/etc/fuss-backup/fuss-backup.exclude \
$DESTINATION::{hostname}-{now:%Y-%m-%dT%H:%M:%S} $PATHS
else
echo "Non e' stato utilizzato il file di esclusione"
borg create \
$DESTINATION::{hostname}-{now:%Y-%m-%dT%H:%M:%S} $PATHS
fi
# enforce data retention
borg prune --keep-daily $STORICO
else
echo "Failed to mount backup disk"
mail_exit 4
fi
# sending completion emails
mail_exit 0
......@@ -5,15 +5,21 @@
# utilizzare START=yes per avviare la procedura di backup
START=no
# dove salvare i dati di backup
BACKUP_DIR=/var/backups
# quanti giorni dei backup vecchi vengono mantenuti, passato
# all'opzione -d di borg (costituisce anche il numero minimo di backup
# che restano in archivio (default 7, il programma deduplica)
STORICO=7
# le altre directory di cui fare backup
ALTRE_DIR="/var/www"
# disco del backup (montato prima di eseguire borg), nel caso di NFS
# va specificato nella forma IP:directory
DISK=""
# se spezzare il backup alla dimensione richiesta
SPLIT=
# Backup directory (sul disco montato)
BACKUP_DIR=borgdata
# List of directory put in the backup
PATHS="/etc /home /var/backups /var/lib /var/log /var/mail /var/local"
# A chi inviare le mail (lista separata da spazi)
MAILTO="root"
# quanti dei backup vecchi manteniamo nella directory
# dei backup?
STORICO=1
\ No newline at end of file
#!/bin/sh
#
#
#
if [ -f /etc/fuss-backup/fuss-backup.conf ]; then
. /etc/fuss-backup/fuss-backup.conf
else
echo "Errore: file di configurazione non presente"
exit 1
fi
#
if [ $START != "yes" ]; then
echo "ERRORE: e' necessario configurare l'applicazione fuss-backup"
echo "per avviarne l'esecuzione!"
echo "Modificare il file /etc/fuss-backup/fuss-backup.conf"
exit 2
fi
# data e ora correnti
DATE=`date "+%Y%m%d-%H%M"`
# creo, se non esiste, la directory principale di backup
if [ ! -d $BACKUP_DIR ]; then
mkdir $BACKUP_DIR
fi
# creo
# creo una directory ad hoc per contenere tutti i backup
BD=$BACKUP_DIR/fuss-backup-$DATE
mkdir $BD
# definizione dei programmi da utilizzare nello script
# se esiste il file di esclusione, utilizzarlo
if [ -f /etc/fuss-backup/fuss-backup.exclude ]; then
echo "E' attivo un file di esclusione"
TAR="/bin/tar --exclude-from=/etc/fuss-backup/fuss-backup.exclude"
else
echo "Non e' stato utilizzato il file di esclusione"
TAR=/bin/tar
fi
### LDAP ###
# controlla se e' installato LDAP, se si fai il backup
if [ -f /etc/init.d/slapd ]; then
# leggo dati da ldap, interrompendo il servizio Q.B.
/etc/init.d/slapd stop
slapcat | gzip > $BD/backup-ldap-$DATE.ldif.gz
/etc/init.d/slapd start
fi
### LISTA SOFTWARE INSTALLATO ###
# leggo la lista del software installato SUL SERVER e la salvo
dpkg --get-selections | gzip > $BD/lista-sw-$HOSTNAME-$HOSTNAME-$DATE.txt.gz
### BACKUP DI HOME ###
# fare backup di /home se non siamo su di un
# client NFS
if touch /home/.test-fuss-backup ; then
HOMES="/home $HOME"
else
HOMES="$HOME"
fi
$TAR -zcf $BD/backup-home-$DATE.tar.gz $HOMES
### BACKUP DEL DATABASE DI OCTOFUSS, SE PRESENTE
if [ -d /var/lib/octofuss/ ]; then
$TAR -zcf $BD/backup-octofuss-$DATE.tar.gz /var/lib/octofuss/
fi
### BACKUP DI ETC ###
$TAR -zcf $BD/backup-etc-$DATE.tar.gz /etc
### BACKUP DI /VAR/LOG ###
$TAR -zcf $BD/backup-var-log-$DATE.tar.gz /var/log/
### BACKUP DI ALTRE CARTELLE AGGIUNTIVE ###
# eseguo il backup della cartelle aggiuntive
# solo se specificate nel file di configurazione
if [ "$ALTRE_DIR" ]; then
$TAR -zcf $BD/backup-altro-$DATE.tar.gz $ALTRE_DIR
fi
### IL BACKUP VIENE SPEZZATO SE RICHIESTO ###
## da spezzare anche gli altri oltre a home!!! ###
if [ "$SPLIT" ]; then
cd $BD
split -d -b $SPLIT backup-home-$DATE.tar.gz backup-home-$DATE.tar.gz.
rm backup-home-$DATE.tar.gz
fi
## STORICO ##
# manteniamo $STORICO backup vecchi
if [ $STORICO -ge 0 ]; then
STORICO=`expr $STORICO + 1`
cd $BACKUP_DIR
TOTALE=`ls -d fuss-backup-* | wc -l`
DAELIMINARE=`expr $TOTALE - $STORICO`
if [ $DAELIMINARE -gt 0 ]; then
for i in `ls -d fuss-backup-* | head -$DAELIMINARE`; do
echo "Elimino il backup $i"
rm -rf $i
done
fi
fi
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment