Marius van Witzenburg We fight for our survival, we fight!

30jun/110

How to backup to a Western Digital ShareSpace drive via SSH-only rsync from FreeBSD

Posted by mariusvw

This manual helps you to backup directories from your server to a Western Digital ShareSpace.

You might need this: How to enable SSH on a Western Digital ShareSpace

Create directories and generate a key for the target

mkdir /usr/data/backup
mkdir /usr/data/backup/keys
ssh-keygen -t rsa -f /usr/data/backup/keys/sharespace
find /usr/data/backup -type f -exec chmod 600 "{}" \; 
find /usr/data/backup -type d -exec chmod 700 "{}" \;

Add public key to the ShareSpace root account

ssh root@<SharespaceIP>
 
cd /root
mkdir .ssh
chmod 700 .ssh
 
# Add key to this file.
vi ssh/authorized_keys
 
chmod 700 .ssh/authorized_keys

Add scripts to server

Place backup.sh in /usr/backup/ and functions.sh in /usr/backup/includes/. Then simply edit to your needs and run with ./backup.sh or from Cron.

backup.sh

#!/bin/bash
# Backup system
# by Marius van Witzenburg <marius@kitara.nl>
# http://kitara.nl
 
mailto="marius@kitara.nl"
mailfrom="noreply@kitara.nl"
 
root="/usr/data/backup"
 
###
# Do not edit below!
###
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin
pid=$$
 
source $root/include/functions.sh
 
# Create needed directories
test -d $root/files || mkdir $root/files
test -d $root/include || mkdir $root/include
test -d $root/keys || mkdir $root/keys
test -d $root/log || mkdir $root/log
test -d $root/tmp || mkdir $root/tmp
test -d $root/tmp/server || mkdir $root/tmp/server
 
echo $pid > $root/tmp/backup.pid
 
# Sync Public
sync_public "192.168.1.50" "neo" "/usr/data/storage/public" 22
sync_public "192.168.2.50" "trinity" "/usr/data/storage/public" 12345
 
# Sync files to ShareSpace drives
sync_sharespace "192.168.1.50" "neo" "/usr/data/files" "files" 22
sync_sharespace "192.168.1.50" "neo" "/usr/data/music" "music" 22
sync_sharespace "192.168.1.50" "neo" "/usr/data/storage" "storage" 22
sync_sharespace "192.168.2.50" "trinity" "/usr/data/files" "files" 12345
sync_sharespace "192.168.2.50" "trinity" "/usr/data/music" "music" 12345
sync_sharespace "192.168.2.50" "trinity" "/usr/data/storage" "storage" 12345
 
# EOF

includes/functions.sh

#!/bin/bash
 
if [ -z "$root" ]
then
    echo "DO NOT CALL THIS FILE DIRECTLY!"
fi
 
date=`date "+%d-%m-%Y"`
date_reverse=`date "+%Y-%m-%d"`
hostname=`hostname -s`
hostletters=`hostname | sed -E 's/([A-Za-z0-9])[^.]*\.?/\1/g'`
sshport=22
 
# Usage: email "subject" "message"
email() {
    all=$@  
    subject=$1
    message=$2
    echo -e "From: $mailfrom\nTo: $mailto\nSubject: $subject\n\n$message" | /usr/sbin/sendmail -t $mailto 
}
 
# Cleanup loggin and temp directories
cleanup() {
    rm -r $root/log/
    rm -r $root/tmp/
}
 
stop_public() {
    all=$@  
    signal=$1
    name=$2 
    ip=$3   
 
    if [ "$signal" != "finish" ]
    then    
        if [ "$signal" == 'int' ] || [ "$signal" == 'term' ]
        then    
            cleanup 
        fi      
 
        logger -s -p daemon.notice -t 'backup' "stop_public(): Public Sync shutdown!. Target: $name ($ip), Signal: $signal"
        kill $JOB
 
        if [ "$signal" == 'int' ] || [ "$signal" == 'term' ]
        then    
            exit $? 
        else    
            return $?
        fi      
    fi
}
 
# Syntax: sync_public "srv_ip" "srv_name" "source"
sync_public() {
    all=$@  
    srv_ip=$1
    srv_name=$2
    src=$3  
    sshport=$4
 
    # Give it a rest so we don't flood the sshd!
    sleep 3 
 
    key="$root/keys/$srv_name"
 
    #trap "stop_public hub $srv_name $srv_ip" SIGHUP
    trap "stop_public int $srv_name $srv_ip" SIGINT
    trap "stop_public term $srv_name $srv_ip" SIGTERM 
 
    alive=`ssh -ax -q -q -o "BatchMode=yes" -o "ConnectTimeout 15" -i $key -p $sshport root@$srv_ip "echo 0 2>&1" && return 0 || echo 1`
    if [ $alive -eq 0 ] 
    then    
        rsync -e "ssh -ax -i $key -p $sshport" -aWvz --timeout=300 --delete-during $src/ root@$srv_ip:/shares/Public/ >> $root/log/run 2>&1 &
        JOB=$!  
        wait $JOB
 
        tail -2 $root/log/run | logger -p daemon.info -t 'backup'
 
        stop_public finish $srv_name $srv_ip
    else
        logger -s -p daemon.notice -t 'backup' "sync_public(): Connection to $srv_name ($srv_ip) failed..."
    fi
}  
 
stop_sharespace() {
    all=$@
    signal=$1
    name=$2
    ip=$3
    key=$4
 
    if [ "$signal" != "finish" ]
    then
        if [ "$signal" == 'int' ] || [ "$signal" == 'term' ]
        then
            cleanup
        fi
 
        logger -s -p daemon.notice -t 'backup' "stop_sharespace(): ShareSpace backup shutdown!. Target: $name ($ip), Signal: $signal"
        kill $JOB
 
        if [ "$signal" == 'int' ] || [ "$signal" == 'term' ]
        then
            exit $?
        else
            return $?
        fi
    fi
}  
 
sync_sharespace() {
    all=$@
    srv_ip=$1
    srv_name=$2
    src=$3
    target=$4
    sshport=$5
 
    # Give it a rest so we don't flood the sshd!
    sleep 3
 
    key="$root/keys/$srv_name"
 
    #trap "stop_sharespace hub $srv_name $srv_ip $key" SIGHUP
    trap "stop_sharespace int $srv_name $srv_ip $key" SIGINT
    trap "stop_sharespace term $srv_name $srv_ip $key" SIGTERM
 
    alive=`ssh -ax -q -q -o "BatchMode=yes" -o "ConnectTimeout 15" -i $key -p $sshport root@$srv_ip "echo 0 2>&1" && return 0 || echo 1`
    if [ $alive -eq 0 ]
    then
        # Create required directory for server name
        ssh -ax -i $key -p $sshport root@$srv_ip "test -d /shares/backup/$hostname || mkdir /shares/backup/$hostname"
        JOB=$!
        wait $JOB
 
        # Sync data
        logger -p daemon.notice -t 'backup' "sync_sharespace(): Syncing '$src'..."
        rsync -e "ssh -ax -i $key -p $sshport" -rtlDWvp --timeout=300 --chmod=Dug=rwX,Fug=rwX,Do=rX,Fo=r --delete-during $src/ root@$srv_ip:/shares/backup/$hostname/$target/ >> $root/log/run 2>&1 &
        JOB=$!
        wait $JOB
 
        tail -2 $root/log/run | logger -p daemon.info -t 'backup'
 
        stop_sharespace finish $srv_name $srv_ip $key
    else
        logger -s -p daemon.notice -t 'backup' "sync_sharespace(): Connection to $srv_name ($srv_ip) failed..."
    fi
}
 
# EOF
Geëtiketeerd als: , , , , , Geen reacties
11mrt/108

How to backup from a Western Digital Sharespace to another Sharespace

Posted by mariusvw

There is a newer version of this script available here.

You might need this: How to enable SSH on a Western Digital ShareSpace

For a script running from a FreeBSD server check this script.
~~~
Lately I've been busy with making a backup script to automate the backup of a WD Sharespace drive.

This script has been made to backup between two Sharespace drives.

The script works quite simple. In a endless loop it keeps on running when you start it to the background with: ./backup.sh &

It scans for the shares on your master drive and it will Rsync it to your slave drive on the share backup.

Put this script on your slave drive in /root/backup.sh

If you decide to modify this script please leave my name in the script.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/bin/sh
time=5
src_ip="192.168.3.3"
log="/root/backup.log"
 
# Written by Marius van Witzenburg
# http://kitara.nl
 
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin
PID=$$
cleanup() {
    rm -f ${log}
    return $?
}
s_hup() {
    echo -e "n*** SIGHUP! Ignoring ***n"
    cleanup
    #exit $?
}
s_int() {
    echo -en "n*** SIGINT! Exiting ***n"
    kill ${JOB}
    exit $?
}
s_term() {
    echo -en "n*** SIGTERM! Exiting ***n"
    kill ${JOB}
    exit $?
}
 
trap s_hup SIGHUP
trap s_int SIGINT
trap s_term SIGTERM
 
echo "Having a rest for the first run..." > ${log}
sleep 30 &
JOB=$!
wait ${JOB}
 
echo "Running backup..." >> ${log}
while [ "true" ]
do
    for x in `ssh ${src_ip} ls -l /shares/| grep "^d" | awk '{ print $9 }'`
    do
        if [ ! -z ${x} ]
        then
            output=''
            if [ ! -z "`expr ${x} : '(usb[0-9]-[0-9]share[0-9])'`" ]
            then
                if [ -d "/shares/${x}" ]
                then
                    echo -e "USB Syncing '/shares/${x}' to '/shares/${x}'n" >> $log
                    rsync -qau --no-t --checksum --delete ${src_ip}:/shares/${x}/ /shares/${x}/ & 2>> ${log} 1> /dev/null
                    JOB=$!
                    wait ${JOB}
                    echo -e "n${JOB} -- finished.nn" >> ${log}
                else
                    echo -e "Skipping USB for '/shares/${x}'n" >> ${log}
                fi
            else
                echo -e "Syncing '/shares/${x}' to '/shares/backup/${x}'n" >> $log
                rsync -qau --no-t --checksum --delete ${src_ip}:/shares/${x}/ /shares/backup/${x}/ & 2>> ${log} 1> /dev/null
                JOB=$!
                wait ${JOB}
                echo -e "n${JOB} -- finished.nn" >> ${log}
            fi
        fi
    done
    message=`cat ${log}`
    echo -e "From: noreply@kitara.nlnTo: info@kitara.nlnSubject: ShareSpace backup output.nn${message}" | /usr/sbin/msmtp info@kitara.nl
    echo -e "Waiting for cycle (${time} minutes)...n" >> ${log}
    sleep `expr ${time} * 60` &
    JOB=$!
    wait ${JOB}
    echo "Running cycle..." > ${log}
done
# EOF

Comments and donations are more than welcome :-)