Backup system
Imported both the server- and client-side backup scripts.
This commit is contained in:
commit
d9f75447a6
24 changed files with 1043 additions and 0 deletions
backup/server/share
44
backup/server/share/fetch-local
Normal file
44
backup/server/share/fetch-local
Normal file
|
@ -0,0 +1,44 @@
|
|||
#!/bin/bash
|
||||
|
||||
function FETCH
|
||||
{
|
||||
local fetchroot="/"
|
||||
|
||||
if [ "x$BASE" != "x" ]; then
|
||||
fetchroot="$fetchroot/$BASE"
|
||||
fi
|
||||
|
||||
if [ "x$ROOT" != "x" ]; then
|
||||
fetchroot="$fetchroot/$ROOT"
|
||||
fi
|
||||
|
||||
fetchroot="`echo "$fetchroot" | sed -e 's/\/\+/\//g'`"
|
||||
if ! [ -d "$fetchroot" ]; then
|
||||
echo -e "\t\t\tCONFIGURATION ERROR: missing root directory '$fetchroot'" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo -e "\t\t\tRoot directory:\t$fetchroot" >&2
|
||||
|
||||
local tarerrors="`mktemp`"
|
||||
chmod 600 "$tarerrors"
|
||||
|
||||
local command='tar --numeric-owner --one-file-system --ignore-failed-read --warning=none -c'
|
||||
local index=
|
||||
for index in $( seq 0 $(( ${#backup_exclude[@]} - 1 )) ); do
|
||||
command="$command"' "--exclude='"`echo "./${backup_exclude[$index]}" | sed -e 's/\/\+/\//g' -e 's/\/$//'`"'"'
|
||||
done
|
||||
command="$command"' ".'"$backup_directory"'"'
|
||||
|
||||
cd "$fetchroot"
|
||||
eval $command 2>"$tarerrors"
|
||||
if ! [ -z "`cat $tarerrors`" ]; then
|
||||
echo -e "\t\t\tFETCH ERROR: something went wrong while creating the archive:" >&2
|
||||
echo -e "-----------------------------------------------------" >&2
|
||||
cat "$tarerrors" >&2
|
||||
echo -e "-----------------------------------------------------" >&2
|
||||
rm -f "$tarerrors"
|
||||
return 1
|
||||
fi
|
||||
rm -f "$tarerrors"
|
||||
return 0
|
||||
}
|
55
backup/server/share/fetch-ssh
Normal file
55
backup/server/share/fetch-ssh
Normal file
|
@ -0,0 +1,55 @@
|
|||
#!/bin/bash
|
||||
|
||||
function FETCH
|
||||
{
|
||||
if [ -z "$SSH_KEY" ]; then
|
||||
echo -e "\t\t\tCONFIGURATION ERROR: no SSH key" >&2
|
||||
exit 1
|
||||
elif [ -z "$SSH_HOST" ]; then
|
||||
echo -e "\t\t\tCONFIGURATION ERROR: no destination SSH host" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local command="ssh -T"
|
||||
|
||||
if [ "x$SSH_USER" != "x" ]; then
|
||||
command="$command -l $SSH_USER"
|
||||
fi
|
||||
|
||||
if [ "x$SSH_PORT" != "x" ]; then
|
||||
command="$command -p $SSH_PORT"
|
||||
fi
|
||||
|
||||
command="$command -i $SSH_KEY $SSH_HOST echo"
|
||||
|
||||
local errorfile="`mktemp`"
|
||||
chmod 600 "$errorfile"
|
||||
|
||||
{
|
||||
echo "$backup_directory"
|
||||
local index=
|
||||
for index in $( seq 0 $(( ${#backup_exclude[@]} - 1 )) ); do
|
||||
echo "${backup_exclude[$index]}"
|
||||
done
|
||||
} | eval $command 2>"$errorfile"
|
||||
|
||||
local nerrfile=`mktemp`
|
||||
echo 0 > $nerrfile
|
||||
cat $errorfile | while read line; do
|
||||
if [[ "$line" =~ ^\.\.\.SRC\.\.\..*$ ]]; then
|
||||
local text="`echo "$line" | sed -e 's/^.........//'`"
|
||||
if [[ "$text" =~ ERROR ]]; then
|
||||
echo 1 > $nerrfile;
|
||||
fi
|
||||
printf "\t\t\t%s\n" "$text" >&2
|
||||
else
|
||||
echo -e "\t\t\tCONNECTION ERROR: SSH or the remote script caused errors:" >&2
|
||||
printf "\t\t\t\t%s\n" "$line" >&2
|
||||
echo 1 > $nerrfile
|
||||
fi
|
||||
done
|
||||
local rv="`cat $nerrfile`"
|
||||
rm -f "$nerrfile" "$errorfile"
|
||||
return $rv
|
||||
}
|
||||
|
179
backup/server/share/postprocess
Executable file
179
backup/server/share/postprocess
Executable file
|
@ -0,0 +1,179 @@
|
|||
#!/bin/bash
|
||||
|
||||
#
|
||||
# An example post-processing script
|
||||
#
|
||||
# This script runs in parallel to the main backup script (once the actual
|
||||
# data fetching is completed, the main script will wait for the post-processing
|
||||
# script to complete).
|
||||
#
|
||||
# It uses openssl to encrypt backup archives, then sends them to a remote FTP
|
||||
# server using kermit; backups of type "full" (i.e. root filesystems) will not
|
||||
# be processed.
|
||||
#
|
||||
|
||||
[ -z "$1" ] && exit 1
|
||||
echo $$ >"$1/pid"
|
||||
|
||||
source /etc/backup.conf
|
||||
source "${BACKUP_CONFS}/post/ftp-access.conf"
|
||||
|
||||
if ! [ -f "${BACKUP_CONFS}/post/crypto.key" ]; then
|
||||
echo "ERROR: no cryptographic key"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
function crypt
|
||||
{
|
||||
openssl enc -kfile "${BACKUP_CONFS}/post/crypto.key" -aes-256-cbc -e
|
||||
}
|
||||
|
||||
|
||||
function makeFTPScript
|
||||
{
|
||||
local script=`mktemp`
|
||||
chmod 600 $script
|
||||
{
|
||||
echo "set ftp passive-mode off"
|
||||
echo "ftp open $ftp_host /user:$ftp_user /password:$ftp_pass"
|
||||
echo "if fail exit 1 Connection failed"
|
||||
echo 'if not \v(ftp_loggedin) exit 1 Login failed'
|
||||
for cmd in "$@"; do
|
||||
if [[ "$cmd" =~ ^lcd\ ]]; then
|
||||
echo "$cmd"
|
||||
else
|
||||
echo "ftp $cmd"
|
||||
echo "if fail exit 1 ftp $cmd: \\v(ftp_message)"
|
||||
fi
|
||||
done
|
||||
echo "ftp bye"
|
||||
echo "exit 0"
|
||||
} > $script
|
||||
echo $script
|
||||
}
|
||||
|
||||
|
||||
function executeKermitScript
|
||||
{
|
||||
local script="$1"
|
||||
local dest="$2"
|
||||
|
||||
wermit + < $script > $dest 2>/dev/null
|
||||
local result=$?
|
||||
rm -f "$script"
|
||||
return $result
|
||||
}
|
||||
|
||||
|
||||
function fileExists
|
||||
{
|
||||
local file="$1"
|
||||
local script=`makeFTPScript "check $file"`
|
||||
local output=`mktemp`
|
||||
if ! executeKermitScript "$script" $output; then
|
||||
if grep -q '^ftp check ' $output; then
|
||||
echo "no"
|
||||
else
|
||||
echo "error"
|
||||
fi
|
||||
else
|
||||
echo "yes"
|
||||
fi
|
||||
rm -f "$output"
|
||||
}
|
||||
|
||||
|
||||
function rotateRemoteFilesFor
|
||||
{
|
||||
local host="$1"
|
||||
local btype="$2"
|
||||
|
||||
local commands=()
|
||||
local fnum=
|
||||
for fnum in $( seq $ftp_rotate -1 1 ); do
|
||||
local fname="/encrypted-${host}-${btype}-$fnum.tar.gz"
|
||||
local fe=`fileExists "$fname"`
|
||||
if [ "x$fe" = "xerror" ]; then
|
||||
echo "FTP check error for $fname"
|
||||
exit 1;
|
||||
elif [ "x$fe" = "xyes" ]; then
|
||||
local ncommand=
|
||||
if [ $fnum -eq $ftp_rotate ]; then
|
||||
ncommand="delete $fname"
|
||||
else
|
||||
ncommand="rename $fname /encrypted-${host}-${btype}-$(( $fnum + 1 )).tar.gz"
|
||||
fi
|
||||
commands=( "${commands[@]}" "$ncommand" )
|
||||
fi
|
||||
done
|
||||
[ ${#commands[@]} -eq 0 ] && return 0
|
||||
|
||||
local temp=`mktemp`
|
||||
executeKermitScript `makeFTPScript "${commands[@]}"` "$temp"
|
||||
local rv=$?
|
||||
rm -f "$temp"
|
||||
return $rv
|
||||
}
|
||||
|
||||
|
||||
function putRemoteFileFor
|
||||
{
|
||||
local host="$1"
|
||||
local btype="$2"
|
||||
local tempdir="$3"
|
||||
|
||||
if ! rotateRemoteFilesFor "$host" "$btype"; then
|
||||
return 1;
|
||||
fi
|
||||
|
||||
local temp=`mktemp`
|
||||
executeKermitScript `makeFTPScript "lcd $tempdir" "put encrypted-${host}-${btype}-1.tar.gz"` $temp
|
||||
local rv=$?
|
||||
rm -f "$temp"
|
||||
|
||||
return $rv
|
||||
}
|
||||
|
||||
|
||||
|
||||
function handleFile
|
||||
{
|
||||
local host="$1"
|
||||
local btype="$2"
|
||||
|
||||
if [ "x$btype" = "xfull" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "\tCopying data for $host / $btype to FTP server" >&2
|
||||
|
||||
local tempdir="`mktemp -d`"
|
||||
local src="${BACKUP_TARGET}/${host}/${btype}-1.tar.gz"
|
||||
local dest="$tempdir/encrypted-${host}-${btype}-1.tar.gz"
|
||||
cat "$src" | crypt > $dest
|
||||
|
||||
putRemoteFileFor $host $btype $tempdir
|
||||
|
||||
rm -rf "$tempdir"
|
||||
}
|
||||
|
||||
|
||||
function initPost
|
||||
{
|
||||
echo "======================================================"
|
||||
echo "POST-PROCESSING BACKUPS"
|
||||
echo
|
||||
}
|
||||
|
||||
function finishPost
|
||||
{
|
||||
echo
|
||||
}
|
||||
|
||||
|
||||
initPost
|
||||
while read host btype; do
|
||||
handleFile $host $btype 2>&1
|
||||
done
|
||||
finishPost
|
Loading…
Add table
Add a link
Reference in a new issue