(Answer) (Category) Products of Aardvarks With Chisels : (Category) Linux : (Category) Aardback :
Download
There's no download yet - I'll package this up someday, but for now, you just get the whole darned shell script and perl script. Paste each into an individual file, chmod +x, edit as needed, and stick backup.sh in /etc/cron.daily/. :)
#!/bin/bash
#
# backup.sh - Danny Sauer, 3/2003
# this needs run as root in order to preserve permissions and make device nodes
# also, each host needs root's private key in its .ssh/authorized_hosts
#
                                                                                
# space-separated list of hosts to be backed up
HOSTS="dialin www router dev web2"
                                                                                
# programs with full paths
RSYNC="/usr/bin/rsync"
ARCHIVE_PL="/Users/dsauer/perl/archive.pl"
DATE="/bin/date"
                                                                                
# variables
TODAY=`$DATE +'%Y.%m.%d'`;
BACKUPDIR="/Volumes/servers"
ARCHIVEDIR="$BACKUPDIR/archive"
                                                                                
# verify that our output directories exist before using them
if [ ! -d $ARCHIVEDIR ]; then
        mkdir -p $ARCHIVEDIR
fi
if [ ! -d $BACKUPDIR ]; then
        mkdir -p $BACKUPDIR
fi
                                                                                
# backup each host
for HOST in $HOSTS; do
        echo "backing up $HOST:"
        OUT="$ARCHIVEDIR/$TODAY/$HOST"
                                                                                
        # archive.pl wants the top output dir to exist and be empty
        if [ -d $OUT ]; then
                if rmdir $OUT && mkdir -p $OUT; then
                        echo -e "\twarn: recreated $OUT"
                else
                        echo -e "\t$OUT exists already and is not empty - there will be problems"
                        echo -e "\ttry 'rm -r $OUT' and run again"
                        #rm -r $OUT
                fi
        else
                mkdir -p $OUT
        fi
                                                                               
        # make snapshot directory
        echo -e "\tarchiving\t("`$DATE +'%T'`")"
        $ARCHIVE_PL $BACKUPDIR/$HOST $OUT
                                                                                
        # synchronize backup directory with server
        echo -e "\tsyncing\t("`$DATE +'%T'`")"
        $RSYNC -z -qa -e ssh --delete --exclude '/proc/*' root@$HOST:/ $BACKUPDIR/$HOST
                                                                                
        # print time of completion
        echo -e "\tdone\t("`$DATE +'%T'`")"
done
#!/usr/bin/perl -w
#
# archive.pl - Danny Sauer, 4/2003
# given a source and destination directory, makes a hardlinked copy of
#  the sorce in the destination, recreating symlinks, nodes, and dirs
#
 
use strict;
 
my $cp_command = '/sw/bin/cp';
 
sub archive($$);
sub cp($$);
 
my $source = shift or die "usage: $0 source_dir destination_dir";
my $dest = shift or die "usage: $0 source_dir destination_dir";
unless( -d $source ){
   die "source must be a directory";
}
 
mkdir($dest);
archive($source, $dest);
1;
 
# copy one file
# note - symlinks have no permissions, hardlinks have the same permissions
#        as the source file, and "cp -a" preserves permissions.  Don't use
#        "cp -p", though - must use at least "cp -pR" to copy device nodes
sub cp($$){
    my $s = shift;
    my $d = shift;
    if( -l $s ){
        # recreate symlink
        symlink(readlink($s), $d);
    }elsif( -p _ || -S _ || -b _ || -c _ ){
        # use system copy call (rewrite this in perl someday)
        system("$cp_command -a $s $d");
    }else{
        # create hardlink
        link($s, $d);
    }
}
 
#walk directory tree
# this just wouldn't work with a while(readdir()), so now readdir into @fs
sub archive($$){
    my $s = shift;
    my $d = shift;
                                                                                
    opendir(S, $s) or die "can't opendir '$s': $!";
        my @fs = readdir S;
        closedir S;
                                                                                
    foreach my $f (@fs){
                next if($f eq '.' || $f eq '..');
        if(-d "$s/$f"){
                        mkdir("$d/$f");
                        my $mode = (stat("$s/$f"))[2] & 07777;
                        my $user = (stat(_))[4];
                        my $group = (stat(_))[5];
                        chmod($mode, "$d/$f");
                        chown($user, $group, "$d/$f");
                        archive("$s/$f", "$d/$f");
        }else{
            cp("$s/$f", "$d/$f");
        }
    }
}
[Append to This Answer]
2003-May-20 10:08am
This document is: http://www.cloudmaster.com/~sauer/projects/index.cgi?file=120
[Search] [Appearance]
This is a Faq-O-Matic 2.719.
This FAQ administered by sauer@cloudmaster.com