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

23Mar/104

How to backup from a Western Digital Sharespace to another Sharespace via rsync and FreeBSD

This script simply syncs from a WD ShareSpace drive to another WD ShareSpace drive. It gets started from a other server which is in my case FreeBSD.

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

Create the following files on FreeBSD:

/backup/sharespace/ssh-wrapper

#!/bin/sh
sh /backup/run &

/backup/sharespace/run

#!/bin/sh
# WD ShareSpace sync script v1.1
# By Marius van Witzenburg <info@kitara.nl>
# http://kitara.nl
#
# Works with busybox 1.1.1 and newer versions.
#
 
# Settings
source="192.168.8.4"
target="192.168.8.9"
mailto="info@kitara.nl"
mailfrom="noreply@kitara.nl"
daemon="yes"
force="no"
waittime=5
maxlogs=48
beforetime=6
aftertime=20
 
#
# DO NOT CHANGE BELOW!
#
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin
PID=$$
rarg="-aWvz"
 
curdir=`pwd`
cd /backup/
 
echo ${PID} > /backup/run.pid
cleanup() {
    rm /backup/key
    cd ${curdir}
    ssh -ax root@${target} "test -f /backup/rsyncd.pid && kill `cat /backup/rsyncd.pid`"
    return $?
}
s_hup() {
    logger -s -p daemon.notice -t 'backup' "*** SIGHUP! Ignoring... ***"
    #exit $?
}
s_int() {
    logger -s -p daemon.notice -t 'backup' "*** SIGINT! Exiting... ***"
    cleanup 
    echo -e "From: ${mailfrom}nTo: ${mailto}nSubject: ShareSpace backup.nnSIGINT! Exiting..." | /usr/sbin/msmtp ${mailto}
    rm /backup/run.pid
    kill ${JOB}
    exit $? 
}
s_term() {
    logger -s -p daemon.notice -t 'backup' "*** SIGTERM! Exiting... ***"
    cleanup
    echo -e "From: ${mailfrom}nTo: ${mailto}nSubject: ShareSpace backup.nnSIGTERM! Exiting..." | /usr/sbin/msmtp ${mailto}
    rm /backup/run.pid
    kill ${JOB}
    exit $?
}
 
trap s_hup SIGHUP
trap s_int SIGINT
trap s_term SIGTERM
 
if [ "${daemon}" = "yes" ]
then
    logger -s -p daemon.notice -t 'backup' "Having a rest for the first run..."
    sleep 30 &
    JOB=$!
    wait ${JOB}
fi
 
while [ "true" ]
do
    # Time to backup?
    hour=`date "+%H"`
    if [ "${hour}" -lt "${beforetime}" ] || [ "$hour" -gt "${aftertime}" ]
    then
        # Change the 1 to 1-3 depending on which load you want
        loadavg=`uptime | sed 's/.*average: ([0-9]).*/1/g'`
        if [ "${loadavg}" -eq 0 ] || [ "${force}" = "yes" ]
        then
            alive=`ssh -ax -q -q -o "BatchMode=yes" -o "ConnectTimeout 5" root@${target} "echo 2>&1" && return 0 || echo 1`
            if [ "${alive}" -eq 0 ]
            then
                user=`echo $(head /dev/urandom)$(date +%Y%m%d%H%M%S%N) | md5sum | uuencode -m -| sed -n 2p | cut -c3-43 | cut -c1-${1:-16}`
                sleep 1
                pass=`echo $(head /dev/urandom)$(date +%Y%m%d%H%M%S%N) | md5sum | uuencode -m -| sed -n 2p | cut -c3-43 | cut -c1-${1:-16}`
                echo ${pass} > /backup/key
 
                test -d /backup/log || mkdir /backup/log
                test -d /backup/server || mkdir /backup/server
 
                test -f /backup/log/run.${maxlogs} && rm -f /backup/log/run.${maxlogs}
                lcur=${maxlogs}
                while [ ${lcur} -gt 1 ]
                do
                    lpre=${lcur}
                    lcur=`expr ${lcur} - 1`
                    test -f /backup/log/run.${lcur}.gz && mv /backup/log/run.${lcur}.gz /backup/log/run.${lpre}.gz
                done
                test -f /backup/log/run && mv /backup/log/run /backup/log/run.1
                test -f /backup/log/run.1 && gzip /backup/log/run.1
 
                touch /backup/log/run
 
                logger -s -p daemon.notice -t 'backup' "Creating rsync server configuration"
 
                cat > /backup/server/rsyncd.conf < <EOF
pid file = /backup/rsyncd.pid
 
[shares]
path = /shares/
comment = Rsync Server
uid = root
gid = jewab
use chroot = no
read only = no
list = no
auth users = ${user}
secrets file = /backup/rsync.users
EOF
 
                cat > /backup/server/rsync.users < <EOF
${user}:${pass}
EOF
 
                cat > /backup/server/start < <EOF
#!/bin/sh
rsync --daemon --config=/backup/rsyncd.conf &
EOF
 
                # Transfer server files
                rsync -e 'ssh -ax' ${rarg} --timeout=30 --delete /backup/server/ ${target}:/backup/ >> /backup/log/run 2>&1 &
                JOB=$!
                wait ${JOB}
 
                # Start rsync server
                ssh -ax root@${target} "sh /backup/start > /dev/null 2>&1; exit"
                JOB=$!
                wait ${JOB}
 
                # Sync internal shares and exclude usb shares
                logger -s -p daemon.notice -t 'backup' "Syncing internal shares..."
                rsync ${rarg} --timeout=60 --password-file=/backup/key --exclude="/usb[1-3]-1share1" --delete /shares/ rsync://${user}@${target}/shares/ >> /backup/log/run 2>&1 &
                JOB=$!
                wait ${JOB}
                tail -2 /backup/log/run | logger -s -p daemon.info -t 'backup'
 
                # Sync usb shares if connected
                for x in `ssh -ax root@${target} ls -l /shares/| grep "^d" | awk '{ print $9 }'`
                do
                    if [ ! -z "`expr ${x} : '(usb[0-9]-[0-9]share[0-9])'`" ]
                    then
                        if [ -d "/shares/${x}/" ]
                            then
                            logger -s -p daemon.notice -t 'backup' "Syncing ${x}..."
                            rsync ${rarg} --timeout=60 --password-file=/backup/key --delete /shares/${x}/ rsync://${user}@${target}/shares/${x}/ >> /backup/log/run 2>&1 &
                            JOB=$!
                            wait ${JOB}
                            tail -2 /backup/log/run | logger -s -p daemon.info -t 'backup'
                        fi
                    fi
                done
 
                sleep 5
 
                echo -e "From: ${mailfrom}nTo: ${mailto}nSubject: ShareSpace backup.nnCycle finished..." | /usr/sbin/msmtp ${mailto}
 
                # Shutdown rsync server
                cleanup
            else
                logger -s -p daemon.notice -t 'backup' "No access to '${target}' - aborting"
            fi
        else
            logger -s -p daemon.notice -t 'backup' "Load average on '${source}' is ${loadavg} - aborting"
        fi
    else
        logger -s -p daemon.notice -t 'backup' "Not the time to make backups - sleeping"
    fi
 
    # Daemonize or stop?
    if [ "${daemon}" != "yes" ]
    then
        logger -s -p daemon.notice -t 'backup' "Backup finished"
        break
    fi
 
    # Cycle
    logger -s -p daemon.notice -t 'backup' "Waiting for cycle (${waittime} minutes)..."
    sleep `expr ${waittime} * 60` &
    JOB=$!
    wait ${JOB}
    logger -s -p daemon.notice -t 'backup' "Running cycle..."
done
 
# EOF

/backup/sync.sh

#!/usr/local/bin/bash
#
# Sync backup system on ShareSpace drive
#
 
ip="192.168.8.4"
 
# Fix permissions
find /backup/sharespace/ -type d -exec chmod 700 '{}' ; 
find /backup/sharespace/ -type f -exec chmod 600 '{}' ; 
 
echo "-- Shutting down current backup"
ssh -ax root@${ip} "test -f /backup/run.pid && kill `cat /backup/run.pid`"
sleep 15
echo "-- Syncing new files"
rsync -e 'ssh -ax' -aWv --timeout=30 --exclude '.svn' --delete --delete-excluded /backup/sharespace/ root@${ip}:/backup/
echo "-- Restarting backup"
ssh -ax root@${ip} "sh /backup/ssh-wrapper > /dev/null 2>&1; exit"
 
# EOF

After creating these files set these permissions and start the script:

chmod 700 /backup/sync.sh
/backup/sync.sh

Keep in mind that you setup SSH-keys before you use these scripts :-)

Have fun!

Posted by mariusvw

Comments (4) Trackbacks (5)
  1. Hi.
    Not sure how you make it work. Tried on my Ubuntu server, created the three files, changed the IP address of the two boxes. When I start sync.sh, I’m asked to enter my SSH password (welc0me) 3 times for the first IP address, then I get something like :

    sent 100 bytes received 26 bytes 22.91 bytes/sec
    total size is 6385 speedup is 50.67

    Nothing in the syslog.
    Any step I forgot ? I used names instead of IPs, but I don’t think it would change anything.

    Thanks !

  2. Hey,

    Nice script! but I have an issue, how did you get SSH to work without passwords on your sharespaces, any other linux system I can get this work work on but I just can’t get my sharespace to work with authorized_keys :(

    Thanks

    Steve

  3. Fixed it, for anyone else interested the issue was to do with permissions on the /root directory so a quick reset of those fixed it

    chmod go-w ~/
    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/authorized_keys


Leave a comment

(required)