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/

Reply via email to