I've made a *bunch* of changes to BackupPC_delete from
http://sourceforge.net/apps/mediawiki/backuppc/index.php?title=How_to_delete_backups
, including integration of the given patch. If someone could post
this version, that would be swell.
I AM NOT THE ORIGINAL AUTHOR. Hopefully the original author doesn't
mind.
Changes:
1. -b mode doesn't delete a full and all dependents; it deletes the
full IFF all dependents are gone. From the comments:
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 is what motivated my modifications: I lost a bunch of data
that way)
2. Now has -n: the dry run flag
-Robin
--
http://singinst.org/ : Our last, best hope for a fantastic future.
Lojban (http://www.lojban.org/): The language in which "this parrot
is dead" is "ti poi spitaki cu morsi", but "this sentence is false"
is "na nei". My personal page: http://www.digitalkingdom.org/rlp/
#! /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
mv $TopDir/pc/$client/backups.new $TopDir/pc/$client/backups
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"
rm -f $TopDir/pc/$client/backups.new > /dev/null 2>&1
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)
echo "num: $BackupNumber"
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
bNumber=$BackupNumber
delete_dir $TopDir/pc/$client/$bNumber
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 [ "$BackupNumber" != "$bNumber" ]
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/