RdiffRebuilder

From RdiffBackupWiki

Jump to: navigation, search

If you feel the need to convert your rdiff-backup repositories to the current version, this script might be a start. It builds in the principle of dumping the old backups and rebuildning them in a new fresh repository.

It can also be downloaded from http://www.andreasolsson.se/perl/

#!/usr/bin/perl

# # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
#  RDIFF-REBUILDER 0.0.1
#
#  This is a script to rebuild old versions of rdiff-backup repositories
#  to the version of the current rdiff-backup client. This is done by 
#  dumping one backup at a time and adding it to the new repositori
#  using the --current-time option.
#
#  While this script actually managed to work on my computer there is a
#  very real possibility that it won't on your computer. Please look at
#  this piece of code as a very rough draft to a proof of concept.
#
#  Author: Andreas Olsson <andreas@arrakis.se>
#
#  syntax: rdiff-rebuilder.pl source-folder destination-folder temp-folder
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # #

use strict;
use warnings;
use POSIX;
use File::Path;

# Set the full path of rdiff-backup
my $rdfbu_bin = "/usr/local/bin/rdiff-backup";

# Here we test the specified folders. They must exist and they must have proper permissions.
die "Usage: $0 source_folder destination_folder temporary_folder.\n" unless($ARGV[2]);

my ($sourcefolder, $destfolder, $tempfolder) = ($ARGV[0], $ARGV[1], $ARGV[2]);

die "Specified source folder ( $sourcefolder ) doesn't seem to be a folder.\n" unless( -d $sourcefolder);
die "Source folder ( $sourcefolder ) must be readable.\n" unless ( -r $sourcefolder );

my $rdfchk = system("rdiff-backup --terminal-verbosity 0 -l $sourcefolder  > /dev/null");
die "Source folder ( $sourcefolder ) doesn't seem to be a rdiff-backup archive.\n" if($rdfchk);

die "Specified destination folder ( $destfolder ) doesn't seem to be a folder.\n" unless( -d $destfolder);
die "Destination folder ( $destfolder ) must be readable.\n" unless ( -r $destfolder );
die "Destination folder ( $destfolder ) must be writable.\n" unless ( -w $destfolder );

die "Specified temporary folder ( $tempfolder ) doesn't seem to be a folder.\n" unless( -d $tempfolder);
die "Temporary folder ( $tempfolder ) must be readable.\n" unless ( -r $tempfolder );
die "Temporary folder ( $tempfolder ) must be writable.\n" unless ( -w $tempfolder );


# Making sure the destination folder and the temporary folder are empty.
# This is done by making sure they only include "." and ".."
opendir DDH, $destfolder;
foreach (readdir DDH){
    die "Your destination folder ( $destfolder ) must be empty.\n" unless (/^\.{1,2}$/);
}
closedir DDH;

opendir TDH, $tempfolder;
foreach (readdir TDH){
    die "Your temporary folder ( $tempfolder ) must be empty.\n" unless (/^\.{1,2}$/);
}
closedir TDH;


my $currenttime;
my %oldincr;

# Parsing of the old repositify to find out what diffrent versions there are.
opendir SDH, $sourcefolder . "/rdiff-backup-data";
foreach (readdir SDH){
    if(/^current_mirror\.(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\+\d{2}:\d{2}\.data$/){
        $currenttime = mktime($6, $5, $4, $3, $2 - 1, $1 - 1900, 0, 0);
    }
    if(/^increments\.(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\+\d{2}:\d{2}\.dir$/){
        my $timestamp = mktime($6, $5, $4, $3, $2 - 1, $1 - 1900, 0, 0);
        $oldincr{$timestamp} = $_;
    }
}

closedir SDH;

# Making sure the backups are rebuilt in the right order.
my @sortedtimes = sort { $oldincr{$a} cmp $oldincr{$b} } keys %oldincr; 


# This is the part where we actually rebuild the repositories.
# The original backup-times are fed into the new backups using --current-time.
foreach my $timestamp (@sortedtimes){
    my $incrfile = $oldincr{$timestamp};
    $incrfile =~ s/:/\\:/g;

    my $fullincr = $sourcefolder . "/rdiff-backup-data/" . $incrfile;
    my $thistemp = $tempfolder . "/" . $timestamp;
   
    mkdir $thistemp;

    system("$rdfbu_bin -v1 $fullincr $thistemp");
    system("$rdfbu_bin -v1 --current-time $timestamp $thistemp $destfolder");
    
    rmtree($thistemp);

}

my $rescenttemp = $tempfolder . "/mostrescent";
mkdir $rescenttemp;

system("$rdfbu_bin -v1 -r now $sourcefolder $rescenttemp");
system("$rdfbu_bin -v1 --current-time $currenttime $rescenttemp $destfolder");

rmtree($rescenttemp);

print "Done!\n";
Personal tools