Whoops. More testing, new script. :)
-Robin
#! /bin/bash
#this script contributed by Matthias Meyer
#note that if your $Topdir has been changed, the script will ask you
#the new location.
#
# Significant modifications by Robin Lee Powell, aka
# rlpow...@digitalkingdom.org, all of which are placed into the public domain.
#
usage="\
Usage: $0 -c <client> [-d <backupnumber> -b <before data> [-f] [-n]] | [-l]
Delete specified backups.
Attention!
If a full backup is deleted, all incremental backups
that depends on it will also be deleted.
-c <client> - client machine for which the backup was made
-d <number> - backup number to delete; if this is a full, deletes all
dependent incrementals. Conflicts with -b
-b <date> - delete all backups before this date (YYYY-MM-DD); will
only remove fulls if all dependent incrementals are gone.
Conflicts with -d
-f - run Backuppc_nightly afterwards to clean up the pool
-l - list all backups for <client>
-n | --dry-run - Don't actually do anything, just say what would be done
-h - this help
Example:
list backups of <client>
$0 -c <name of the client which was backed up> -l
remove backup #3 from <client>
$0 -c <name of the client which was backed up> -d 3
remove all backups before 2007-07-02 from <client>
$0 -c <name of the client which was backed up> -b 2007-07-02
"
typeset -i len
while test $# -gt 0; do
case "$1" in
-c | --client )
shift; client=$1; shift;;
-b | --before )
shift; bDate=$1; shift;;
-d | --delete )
shift; bNumber=$1; shift;;
-f | --force )
nightly="true"; shift;;
-n | --dry-run )
dryRun="true"; shift;;
-l | --list )
list="true"; shift;;
* | -h | --help)
echo "$usage"
exit 0
;;
esac
done
if [ -z "$client" ] || [ -z $list ] && [ -z $bNumber ] && [ -z $bDate ]
then
echo "$usage"
exit 0
fi
if [ "$bNumber" -a "$bDate" ]
then
echo "Please use either a specific number or a date, not both."
echo "$usage"
exit 0
fi
if [ -e /engineyard/etc/backuppc/config.pl ]
then
TopDir=`grep $Conf{TopDir} /engineyard/etc/backuppc/config.pl | awk '{print
$3}'`
len=${#TopDir}-3
TopDir=${TopDir:1:len}
else
echo "/engineyard/etc/backuppc/config.pl not found"
exit 1
fi
ls $TopDir/pc > /dev/null 2>&1
while [ $? != 0 ]
do
read -p "examined $TopDir seems wrong. What is TopDir ? " TopDir
ls $TopDir/pc > /dev/null 2>&1
done
ls $TopDir/pc/$client > /dev/null 2>&1
if [ $? != 0 ]
then
echo "$client have no backups"
exit 1
fi
if [ ! -z $list ]
then
while read CLine
do
BackupNumber=`echo $CLine | awk '{print $1}'`
BackupType=`echo $CLine | awk '{print $2}'`
BackupTime=$(date -d @$(echo $CLine | awk '{ print $4 }'))
echo "BackupNumber $BackupNumber - $BackupType-Backup from $BackupTime"
done < $TopDir/pc/$client/backups
exit 0
fi
if [ ! -z $bNumber ] && [ ! -e $TopDir/pc/$client/$bNumber ]
then
echo "Backup Number $bNumber does not exist for client $client"
exit 1
fi
LogDir=`grep $Conf{LogDir} /engineyard/etc/backuppc/config.pl | awk '{print
$3}'`
len=${#LogDir}-3
LogDir=${LogDir:1:len}
rm -f $TopDir/pc/$client/backups.new > /dev/null 2>&1
#**********************************************************
# Two Processes
#
# Deleting a single backup is very different from deleting
# everything before a date.
#
# If the user specifies a backup number, and the backup is a full,
# well, the user said to delete it, so delete it and everything that
# depends on it. This means walking the list forwards deleting
# everything until we get to the next full.
#
# On the other hand, if the user asks to delete everything before a
# particular date, and that date comes just after a full, deleting
# the full and all the incrementals is not the expected behaviour at
# all.
#
# As an example: If the first backup is a full on the 5th, and an
# incremental for every day from then on, and it's the 30th, and the
# user says to delete everything older than the 6th, deleting the
# full *and all the incrementals* up to today (i.e. all the
# backups!!) is probably not what they had in mind.
#
# This means that for -b we walk backwards in time so we know if the
# fulls are still needed.
#
# So the two versions actually walk the backup list in opposite
# directions.
#
# -_-
#
# My (Robin Lee Powell) apologies for the resulting code
# duplication. It's hard to abstract a lot of things in bash.
#
#**********************************************************
delete_dir() {
dir=$1
if [ "$dryRun" ]
then
echo "not actually removing $dir, in dry run mode"
else
echo "remove $dir"
echo "`date +\"%Y-%m-%d %T\"` BackupPC_deleteBackup delete $dir" >>
$LogDir/LOG
rm -fr $dir > /dev/null 2>&1
echo "`date +\"%Y-%m-%d %T\"` BackupPC_deleteBackup $dir deleted" >>
$LogDir/LOG
fi
}
swap_backups_file() {
if [ "$dryRun" ]
then
echo "Not updating the backups list; in dry run mode. Compare
$TopDir/pc/$client/backups.new to $TopDir/pc/$client/backups to see what would
have changed."
else
echo "Updating $TopDir/pc/$client/backups"
cp --backup=t $TopDir/pc/$client/backups $TopDir/pc/$client/backups.old
# Need to un-revers if doing date-based
if [ "$bDate" ]
then
sort -n $TopDir/pc/$client/backups.new > $TopDir/pc/$client/backups
rm $TopDir/pc/$client/backups.new
else
mv $TopDir/pc/$client/backups.new $TopDir/pc/$client/backups
fi
echo "`date +\"%Y-%m-%d %T\"` BackupPC_deleteBackup
$TopDir/pc/$client/backups updated" >> $LogDir/LOG
fi
}
#*************************
# -d / forwards / delete a full and all its friends handling
#*************************
if [ "$bNumber" ]
then
delete2full="false"
while read CLine
do
BackupNumber=`echo $CLine | awk '{print $1}'`
BackupTime=$(echo $CLine | awk '{ print $4 }')
BackupType=`echo $CLine | awk '{print $2}'`
if [ $BackupType == "full" ]
then
delete2full="false"
fi
if [ $BackupNumber == "$bNumber" ] || [ $delete2full == "true" ]
then
if [ $BackupType == "full" ]
then
if [ $delete2full == "false" ]
then
delete2full="true"
else
delete2full="false"
fi
fi
bNumber=$BackupNumber
delete_dir $TopDir/pc/$client/$bNumber
fi
if [ "$BackupNumber" != "$bNumber" ]
then
echo "$CLine" >> $TopDir/pc/$client/backups.new
fi
done < $TopDir/pc/$client/backups
swap_backups_file
fi
#*************************
# -b / backwards / delete a full only if all dependents are gone handling
#*************************
# What we do here is walk the list of backups backwards in time. If we skip
# over an incremental, we mark a flag that says we need the corresponding full.
# When we hit a full, we clear that flag.
if [ "$bDate" ]
then
needFull=""
sort -rn $TopDir/pc/$client/backups | while read CLine
do
BackupNumber=`echo $CLine | awk '{print $1}'`
BackupTime=$(echo $CLine | awk '{ print $4 }')
BackupType=`echo $CLine | awk '{print $2}'`
testTime=$(date -d "$bDate" +%s)
removed=""
if [ "$BackupTime" -lt "$testTime" ]
then
if [ $BackupType == "full" -a "$needFull" ]
then
echo "Not deleting backup number $BackupNumber ; it is a full
and there still exist incrementals that depend on it."
else
removed="true"
delete_dir $TopDir/pc/$client/$BackupNumber
fi
else
if [ $BackupType != "full" ]
then
needFull="true"
fi
fi
# Clear the flag whether the backup was selected or not
if [ $BackupType == "full" ]
then
needFull=""
fi
if [ ! "$removed" ]
then
echo "$CLine" >> $TopDir/pc/$client/backups.new
fi
done
swap_backups_file
fi
#*************************
# Run nightly cleanup, if requested
#*************************
if [ ! -z $nightly ]
then
if [ "$dryRun" ]
then
echo "Not doing a nightly run; in dry run mode."
else
path=${0%/BackupPC*}
su backuppc -c "$path/BackupPC_serverMesg BackupPC_nightly run"
su backuppc -c "$path/BackupPC_serverMesg log I honestly apologize for
the inconvenience"
echo `date "+%Y-%m-%d %T"` BackupPC_deleteBackup BackupPC_nightly
politely scheduled via daemon >> $LogDir/LOG
fi
fi
exit $?
------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2 & L3.
Spend less time writing and rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb
_______________________________________________
BackupPC-users mailing list
BackupPC-users@lists.sourceforge.net
List: https://lists.sourceforge.net/lists/listinfo/backuppc-users
Wiki: http://backuppc.wiki.sourceforge.net
Project: http://backuppc.sourceforge.net/