Commit e465032e authored by Jerome Charaoui's avatar Jerome Charaoui

Merge branch 'multi-backup'

Conflicts:
	README

See merge request !5
parents fbddc25e 873eb70e
...@@ -8,7 +8,7 @@ backupninja! ...@@ -8,7 +8,7 @@ backupninja!
If you were previously using this module, some pieces have changed, If you were previously using this module, some pieces have changed,
and you need to carefully change your use of them, or you will find and you need to carefully change your use of them, or you will find
your backups could stop working. your backups could stop working or get duplicated.
The backupninja::client class has been renamed to backupninja, and is The backupninja::client class has been renamed to backupninja, and is
now *required* in all node manifests. Make sure the backupninja class now *required* in all node manifests. Make sure the backupninja class
...@@ -24,12 +24,35 @@ $nagios_server. The $manage_nagios parameter also replaces the ...@@ -24,12 +24,35 @@ $nagios_server. The $manage_nagios parameter also replaces the
$use_nagios global. $use_nagios global.
As for handlers, they don't include the backupninja::client anymore and As for handlers, they don't include the backupninja::client anymore and
now read several default values from the backupninja base class. Most now read several default values from the backupninja base class. If you
handler declarations shouldn't need any changes. were using the rdiff-backup handler, read the following section
carefully. Other handlers have not changed in any significant way.
See below for dependencies which have been introduced in this version. Changes to the rdiff-backup handler
-----------------------------------
Dependencies You will need to make sure you change all of your "$directory"
parameters to be "$home" instead, and on your backupserver you will need
to move all of your backups into "$home"/rdiff-backup. Previously, they
were put in "$directory", which doubled as the home for the user that
was created. This caused problems with rdiff-backup because of dot files
and other things which were not part of any rdiff-backup.
The rdiff resource name is now used as the subdirectory where rdiff
backups are sent. This was previously hardcoded to "rdiff-backup", but
in order to support multiple rdiff backups per host, we now use the
resource name. So if you were using the following resource:
backupninja::rdiff { 'main': }
You will want to use the following resource:
backupninja::rdiff { 'rdiff-backup': }
file { '/etc/backup.d/90_main.rdiff': ensure => absent; }
Otherwise your backups may be duplicated!
Getting started
--------------- ---------------
This module requires Puppet versions 2.7 and up. This module requires Puppet versions 2.7 and up.
......
...@@ -34,6 +34,7 @@ my $STATE_WARNING=1; ...@@ -34,6 +34,7 @@ my $STATE_WARNING=1;
my $STATE_CRITICAL=2; my $STATE_CRITICAL=2;
my $STATE_UNKNOWN=3; my $STATE_UNKNOWN=3;
my $STATE_DEPENDENT=4; my $STATE_DEPENDENT=4;
my %ERRORS=(0=>'OK',1=>'WARNING',2=>'CRITICAL',3=>'UNKNOWN',4=>'DEPENDENT');
# gross hack: we look into subdirs to find vservers # gross hack: we look into subdirs to find vservers
my @vserver_dirs = qw{/var/lib/vservers /vservers}; my @vserver_dirs = qw{/var/lib/vservers /vservers};
...@@ -43,18 +44,104 @@ our $opt_c = 48 * 60 * 60; ...@@ -43,18 +44,104 @@ our $opt_c = 48 * 60 * 60;
our $opt_w = 24 * 60 * 60; our $opt_w = 24 * 60 * 60;
our $opt_v = 0; our $opt_v = 0;
our $opt_o; our $opt_o;
our $opt_s;
if (!getopts('d:c:w:vo')) { if (!getopts('d:c:w:s:vo')) {
print <<EOF print <<EOF
Usage: $0 [ -d <backupdir> ] [ -c <threshold> ] [ -w <threshold> ] [ -o ] [ -v ] Usage: $0 [ -d <backupdir> ] [ -c <threshold> ] [ -w <threshold> ] [ -o ] [ -s <host> ] [ -v ]
EOF EOF
; ;
exit(); exit();
} }
sub check_rdiff {
my ($host, $dir, $optv) = @_;
my $flag="$dir/rdiff-backup-data/backup.log";
my $extra_msg = '';
my @vservers;
if (open(FLAG, $flag)) {
while (<FLAG>) {
if (/EndTime ([0-9]*).[0-9]* \((.*)\)/) {
$last_bak = $1;
$extra_msg = ' [backup.log]';
$opt_v && print STDERR "found timestamp $1 ($2) in $flag\n";
}
}
if (!$last_bak) {
print_status($host, $STATE_UNKNOWN, "cannot parse $flag for a valid timestamp");
next;
}
} else {
$opt_v && print STDERR "cannot open $flag\n";
}
close(FLAG);
($state, $delta) = check_age($last_bak);
$dir =~ /([^\/]+)\/?$/;
$service = "backups-$1";
print_status($host, $state, "$delta hours old$extra_msg", $service);
foreach my $vserver_dir (@vserver_dirs) {
$vsdir = "$dir/$vserver_dir";
if (opendir(DIR, $vsdir)) {
@vservers = grep { /^[^\.]/ && -d "$vsdir/$_" } readdir(DIR);
$opt_v && print STDERR "found vservers $vsdir: @vservers\n";
closedir DIR;
} else {
$opt_v && print STDERR "no vserver in $vsdir\n";
}
}
my @dom_sufx = split(/\./, $host);
my $dom_sufx = join('.', @dom_sufx[1,-1]);
foreach my $vserver (@vservers) {
print_status("$vserver.$dom_sufx", $state, "$delta hours old$extra_msg, same as parent: $host");
}
}
sub check_age {
my ($last_bak) = @_;
my $t = time();
my $delta = $t - $last_bak;
if ($delta > $opt_c) {
$state = $STATE_CRITICAL;
} elsif ($delta > $opt_w) {
$state = $STATE_WARNING;
} elsif ($delta >= 0) {
$state = $STATE_OK;
}
$delta = sprintf '%.2f', $delta/3600.0;
return ($state, $delta);
}
sub print_status {
my ($host, $state, $message, $service) = @_;
my $state_msg = $ERRORS{$state};
if (!$service) {
$service = 'backups';
}
$line = "$host\t$service\t$state\t$state_msg $message\n";
if ($opt_s) {
$opt_v && print STDERR "sending results to nagios...\n";
open(NSCA, "|/usr/sbin/send_nsca -H $opt_s") or die("cannot start send_nsca: $!\n");
print NSCA $line;
close(NSCA) or warn("could not close send_nsca pipe correctly: $!\n");
}
if (!$opt_s || $opt_v) {
printf $line;
}
}
sub check_flag {
my ($host, $flag) = @_;
my @stats = stat($flag);
if (not @stats) {
print_status($host, $STATE_UNKNOWN, "cannot stat flag $flag");
}
else {
($state, $delta) = check_age($stats[9]);
print_status($host, $state, "$delta hours old");
}
}
my $backupdir= $opt_d; my $backupdir= $opt_d;
my $crit = $opt_c;
my $warn = $opt_w;
my @hosts; my @hosts;
if (defined($opt_o)) { if (defined($opt_o)) {
...@@ -65,7 +152,7 @@ if (defined($opt_o)) { ...@@ -65,7 +152,7 @@ if (defined($opt_o)) {
} }
chdir($backupdir); chdir($backupdir);
my ($state, $message, @vservers, $host); my ($delta, $state, $host);
foreach $host (@hosts) { foreach $host (@hosts) {
chomp($host); chomp($host);
if ($opt_o) { if ($opt_o) {
...@@ -73,89 +160,35 @@ foreach $host (@hosts) { ...@@ -73,89 +160,35 @@ foreach $host (@hosts) {
} else { } else {
$dir = $host; $dir = $host;
} }
my $flag=""; my $flag;
my $type="unknown";
my $extra_msg="";
@vservers = ();
$state = $STATE_UNKNOWN;
$message = "???";
if (-d $dir) { if (-d $dir) {
# guess the backup type and find a proper stamp file to compare # guess the backup type and find a proper stamp file to compare
# XXX: the backup type should be part of the machine registry @rdiffs = glob("$dir/*/rdiff-backup-data");
my $last_bak; foreach $subdir (@rdiffs) {
if (-d "$dir/rdiff-backup") { $subdir =~ s/rdiff-backup-data$//;
$flag="$dir/rdiff-backup/rdiff-backup-data/backup.log"; $opt_v && print STDERR "inspecting dir $subdir\n";
$type="rdiff"; check_rdiff($host, $subdir, $opt_v);
if (open(FLAG, $flag)) { $flag = 1;
while (<FLAG>) { }
if (/StartTime ([0-9]*).[0-9]* \((.*)\)/) { if (-d "$dir/dump") {
$last_bak = $1;
$extra_msg = ' [backup.log]';
$opt_v && print STDERR "found timestamp $1 ($2) in backup.log\n";
}
}
if (!$last_bak) {
$message = "cannot parse backup.log for a valid timestamp";
next;
}
} else {
$opt_v && print STDERR "cannot open backup.log\n";
}
close(FLAG);
foreach my $vserver_dir (@vserver_dirs) {
$vsdir = "$dir/rdiff-backup$vserver_dir";
if (opendir(DIR, $vsdir)) {
@vservers = grep { /^[^\.]/ && -d "$vsdir/$_" } readdir(DIR);
$opt_v && print STDERR "found vservers $vsdir: @vservers\n";
closedir DIR;
} else {
$opt_v && print STDERR "no vserver in $vsdir\n";
}
}
} elsif (-d "$dir/dump") {
# XXX: this doesn't check backup consistency # XXX: this doesn't check backup consistency
$flag="$dir/dump/" . `ls -tr $dir/dump | tail -1`; $flag="$dir/dump/" . `ls -tr $dir/dump | tail -1`;
chomp($flag); chomp($flag);
$type="dump"; check_flag($host, $flag);
} elsif (-d "$dir/dup") { } elsif (-d "$dir/dup") {
# XXX: this doesn't check backup consistency # XXX: this doesn't check backup consistency
$flag="$dir/dup/" . `ls -tr $dir/dup | tail -1`; $flag="$dir/dup/" . `ls -tr $dir/dup | tail -1`;
chomp($flag); chomp($flag);
$type="dup"; check_flag($host, $flag);
} elsif (-r "$dir/rsync.log") { } elsif (-r "$dir/rsync.log") {
# XXX: this doesn't check backup consistency # XXX: this doesn't check backup consistency
$flag="$dir/rsync.log"; $flag="$dir/rsync.log";
$type="rsync"; check_flag($host, $flag);
} else {
$message = "unknown system";
next;
} }
if (!defined($last_bak)) { if (!$flag) {
my @stats = stat($flag); print_status($host, $STATE_UNKNOWN, 'unknown system');
if (not @stats) {
$message = "cannot stat flag $flag";
next;
}
$last_bak = $stats[9];
} }
my $t = time();
my $delta = $t - $last_bak;
if ($delta > $crit) {
$state = $STATE_CRITICAL;
} elsif ($delta > $warn) {
$state = $STATE_WARNING;
} elsif ($delta >= 0) {
$state = $STATE_OK;
}
$message = "$delta seconds old$extra_msg";
} else { } else {
$message = "no directory"; print_status($host, $STATE_UNKNOWN, 'no directory');
}
} continue {
printf "$host\tbackups\t$state\t$message\n";
my @dom_sufx = split(/\./, $host);
my $dom_sufx = join('.', @dom_sufx[1,-1]);
foreach my $vserver (@vservers) {
printf "$vserver.$dom_sufx\tbackups\t$state\t$message, same as parent: $host\n";
} }
} }
...@@ -32,7 +32,7 @@ define backupninja::rdiff( ...@@ -32,7 +32,7 @@ define backupninja::rdiff(
# install client dependencies # install client dependencies
ensure_resource('package', 'rdiff-backup', {'ensure' => $backupninja::ensure_rdiffbackup_version}) ensure_resource('package', 'rdiff-backup', {'ensure' => $backupninja::ensure_rdiffbackup_version})
$directory = "$home/rdiff-backup/" $directory = "$home/$name/"
case $type { case $type {
'remote': { 'remote': {
......
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