Commit 42767794 authored by Nigel Kukard's avatar Nigel Kukard
Browse files

Added --exclude-* options and configuration file

parent 53530dab
......@@ -19,12 +19,12 @@
# TODO:
# - Exclude system subdirs of a dir /dev
# - USE incremental backups!!!! fucking awesome
use strict;
use Compress::Zlib;
use Config::IniFiles;
use Cwd;
use Fcntl qw (:mode);
use File::Find;
......@@ -37,11 +37,14 @@ use MIME::Base64;
my $VERSION = "0.0.3";
my $VERSION = "0.0.4";
# System dirs we don't care about
my @defaultSystemExcl = ("/dev","/run","/proc","/sys","/tmp","/var/tmp");
# These should be backed up separately
my @defaultDataExcl = ("/var/lib/mysql","/var/lib/pgsql");
# Main config
my %config;
# Backup constants
......@@ -64,6 +67,8 @@ my %optctl = ();
GetOptions(\%optctl,
"help",
"config=s",
"backup",
"compress:s",
"exclude-system",
......@@ -72,6 +77,8 @@ GetOptions(\%optctl,
"exclude-data",
"exclude-data-dir=s@",
"exclude-files=s@",
"restore",
"tar-keep-newer",
......@@ -108,6 +115,72 @@ if (! -d $ARGV[1]) {
exit 1;
}
# Check config file exists
if (defined($optctl{'config'})) {
if (! -f $optctl{'config'}) {
print(STDERR "ERROR: Configuration file '".$optctl{'config'}."' NOT found!\n");
exit 1;
}
# Use config file, ignore case
tie my %inifile, 'Config::IniFiles', (
-file => $optctl{'config'},
-nocase => 1
) or die "Failed to open config file '".$optctl{'config'}."': ".join("\n",@Config::IniFiles::errors);
# Check if we actually have something...
if (defined($inifile{'backup'})) {
# Loop with config items
foreach my $item (keys %{$inifile{'backup'}}) {
$config{$item} = $inifile{'backup'}{$item};
}
}
}
# Setup config defaults...
if (!defined($config{'compress'})) {
# Choose default compression method
if (-x "/bin/xz" || -x "/usr/bin/xz") {
$config{'compress'} = "xz";
} else {
$config{'compress'} = "bzip2";
}
}
if (!defined($config{'exclude-system'})) {
$config{'exclude-system'} = 0;
}
if (!defined($config{'exclude-system-path'})) {
# Quick hack to see if we have a cmdline option
if (!defined($optctl{'exclude-system-path'})) {
$config{'exclude-system-path'} = ["/"];
} else {
$config{'exclude-system-path'} = [];
}
} else {
$config{'exclude-system-path'} = toArray($config{'exclude-system-path'});
}
if (!defined($config{'exclude-system-dir'})) {
$config{'exclude-system-dir'} = [];
} else {
$config{'exclude-system-dir'} = toArray($config{'exclude-system-dir'});
}
if (!defined($config{'exclude-data-dir'})) {
$config{'exclude-data-dir'} = [];
} else {
$config{'exclude-data-dir'} = toArray($config{'exclude-data-dir'});
}
if (!defined($config{'exclude-files'})) {
$config{'exclude-files'} = [];
} else {
$config{'exclude-files'} = toArray($config{'exclude-data'});
}
# Check compression
if (defined($optctl{'compress'})) {
# Why use --compress with --restore?
......@@ -126,25 +199,27 @@ if (defined($optctl{'compress'})) {
displayHelp();
exit 1;
}
} else {
# Choose default compression method
if (-x "/bin/xz" || -x "/usr/bin/xz") {
$optctl{'compress'} = "xz";
} else {
$optctl{'compress'} = "bzip2";
}
$config{'compress'} = $optctl{'compress'};
}
# Loop with system exclude dirs to add to our list
if (!defined($optctl{'exclude-system-path'})) {
@{$optctl{'exclude-system-path'}} = ("/");
# Process our exclusion lists...
if (defined($optctl{'exclude-system'})) {
$config{'exclude-system'} = 1;
}
if (defined($optctl{'exclude-system-path'})) {
push(@{$config{'exclude-system-path'}},@{$optctl{'exclude-system-path'}});
}
if (!defined($optctl{'exclude-system-dir'})) {
@{$optctl{'exclude-system-dir'}} = ();
if (defined($optctl{'exclude-system-dir'})) {
push(@{$config{'exclude-system-dir'}},@{$optctl{'exclude-system-dir'}});
}
# Do similar for data dirs
if (!defined($optctl{'exclude-data-dir'})) {
@{$optctl{'exclude-data-dir'}} = ();
if (defined($optctl{'exclude-data-dir'})) {
push(@{$config{'exclude-data-dir'}},@{$optctl{'exclude-data-dir'}});
}
# And file filter
if (defined($optctl{'exclude-files'})) {
push(@{$config{'exclude-files'}},@{$optctl{'exclude-files'}});
}
# Sanitize the source and dest
......@@ -195,28 +270,28 @@ sub backup
}
# Exclude system directories
if (defined($optctl{'exclude-system'})) {
if ($config{'exclude-system'}) {
# Loop through system dirs
foreach my $sysdir (@{$optctl{'exclude-system-path'}}) {
foreach my $sysdir (@{$config{'exclude-system-path'}}) {
# Loop with system paths
foreach my $excl (@defaultSystemExcl,@{$optctl{'exclude-system-dir'}}) {
foreach my $excl (@defaultSystemExcl,@{$config{'exclude-system-dir'}}) {
# Sanitize path
my $testPath = File::Spec->rel2abs("$sysdir/$path");
my $testPath = File::Spec->rel2abs("$sysdir/$excl");
# Check...
if ($excl eq $testPath) {
if ("/$path" eq $testPath) {
printLog("S: Path '[$source]/($path)' is a system directory, ignoring files\n");
$doBackup{$path} |= ST_DIR_SYS;
return ();
}
}
# Check if we excluding data dirs
if (defined($optctl{'exclude-data'})) {
if (defined($config{'exclude-data'})) {
# Loop with data dirs
foreach my $excl (@defaultDataExcl,@{$optctl{'exclude-data-dir'}}) {
foreach my $excl (@defaultDataExcl,@{$config{'exclude-data-dir'}}) {
# Sanitize path
my $testPath = File::Spec->rel2abs("$sysdir/$path");
my $testPath = File::Spec->rel2abs("$sysdir/$excl");
# Check...
if ($excl eq $testPath) {
if ("/$path" eq $testPath) {
printLog("S: Path '[$source]/($path)' is a data directory, ignoring files\n");
$doBackup{$path} |= ST_DIR_SYS;
return ();
......@@ -250,7 +325,31 @@ sub backup
print(STDERR "ERROR: No dbackup version information found in '$source/$path/.dbackup-state', IGNORING\n");
delete($origDirList{$path});
delete($origFileList{$path});
return @list;
}
}
# Apply filter...
if ((@{$config{'exclude-files'}}) > 0) {
my @newList;
foreach my $item (@list) {
my $match = 0;
# Apply only to files
if ( -f "$source/$path/$item") {
# Loop with exclude filters
foreach my $filter (@{$config{'exclude-files'}}) {
# Check for match
if ($item =~ $filter) {
# printLog("S: Path '[$source]/($path)/$item' matches file exclude filter, ignoring\n");
# XXX: NK - If this ws backed up before and now not, dir has changed?
$match = 1;
last;
}
}
}
# If not matched, add to new list
if (!$match) {
push(@newList,$item);
}
}
}
......@@ -502,22 +601,22 @@ sub backup
# Setup tar args
my @tarArgs = ();
my $tarExt;
if ($optctl{'compress'} eq "xz") {
if ($config{'compress'} eq "xz") {
push(@tarArgs,"--xz");
$tarExt = ".xz";
} elsif ($optctl{'compress'} eq "bzip2") {
} elsif ($config{'compress'} eq "bzip2") {
push(@tarArgs,"--bzip2");
$tarExt = ".bz2";
} elsif ($optctl{'compress'} eq "gzip") {
} elsif ($config{'compress'} eq "gzip") {
push(@tarArgs,"--gzip");
$tarExt = ".gz";
} elsif ($optctl{'compress'} eq "none") {
} elsif ($config{'compress'} eq "none") {
$tarExt = "";
}
# Save format and compression
$newPathAttribs{$path}->{'format'} = "tar";
$newPathAttribs{$path}->{'compression'} = $optctl{'compress'};
$newPathAttribs{$path}->{'compression'} = $config{'compress'};
# Change dir and start backup
system(
......@@ -646,16 +745,18 @@ sub backup
}
printLog("BACKUP START: $source => $dest\n");
printLog("Compression : ".$optctl{'compress'}."\n");
printLog("Compression: ".$config{'compress'}."\n");
# Check if we excluding system files
if ($optctl{'exclude-system'}) {
printLog("Exclude System Paths: ".join(", ",@{$optctl{'exclude-system-path'}})."\n");
printLog("Exclude System Dirs : ".join(", ",@defaultSystemExcl,@{$optctl{'exclude-system-dir'}})."\n");
if ($config{'exclude-system'}) {
printLog("Exclude System Paths: ".join(", ",@{$config{'exclude-system-path'}})."\n");
printLog("Exclude System Dirs: ".join(", ",@defaultSystemExcl,@{$config{'exclude-system-dir'}})."\n");
# If we excluding data too...
if ($optctl{'exclude-data'}) {
printLog("Exclude Data Dirs : ".join(", ",@defaultDataExcl,@{$optctl{'exclude-data-dir'}})."\n");
if ($config{'exclude-data'}) {
printLog("Exclude Data Dirs: ".join(", ",@defaultDataExcl,@{$config{'exclude-data-dir'}})."\n");
}
}
printLog("Exclude Files: ".join(", ",@{$config{'exclude-files'}})."\n");
# We need an entry for our main dir before we start
$doBackup{""} = 0;
......@@ -970,6 +1071,8 @@ Usage: $0 [args] <src> <dst>
listed below.
--exclude-data-dir=dir Exclude an additional directory.
--exclude-files=pcre PCRE to exclude files from backup.
Restore Options:
--restore|-r Restore src to dst.
--tar-keep-newer Do not overwrite newer files.
......@@ -1090,5 +1193,15 @@ sub removeBackups
}
}
sub toArray
{
my $param = shift;
if (ref $param eq "ARRAY") {
return $param;
} else {
return [$param];
}
}
# vim: ts=4
# The parameters in this file correspond to the commandline arguments
# that can be given for the --backup option
[backup]
exclude-system=1
exclude-system-dir=/sys2
exclude-system-path=/vservers/myvserver1
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment