auto select log level
authorHeiko Schlittermann <hs@schlittermann.de>
Wed, 28 Oct 2009 23:00:02 +0100
changeset 9 ab747c27a38b
parent 8 dfda1573e706
child 10 e2e657251d08
child 14 d67df540f68c
auto select log level
ftbackup
--- a/ftbackup	Tue Oct 27 22:32:42 2009 +0100
+++ b/ftbackup	Wed Oct 28 23:00:02 2009 +0100
@@ -8,6 +8,7 @@
 use Perl6::Slurp;
 use Getopt::Long;
 use Sys::Hostname;
+use Time::Local;
 use Pod::Usage;
 use POSIX qw(strftime);;
 use English qw(-no_match_vars);
@@ -23,7 +24,7 @@
 my $NODE = hostname;
 my $NOW = time();
 
-my $opt_level = 0;
+my $opt_level = undef;
 my $opt_today = strftime("%F", localtime $NOW);
 my @opt_debug = ();
 my $opt_verbose = 0;
@@ -34,6 +35,7 @@
 sub get_configs(@);
 sub get_candidates();
 sub verbose(@);
+sub iso2epoch($);
 
 our @AT_EXIT;
 END { $_->() foreach @AT_EXIT };
@@ -90,10 +92,25 @@
 
 	verbose "Now in @{[$ftp->pwd]}.\n";
 
+	# examine the situation and decide about the level
+	# FIXME: currently we simply run a full dump every FULL_CYCLE
+	# days, the intermediate dumps are level 1
+	my @last;
+	foreach (reverse sort $ftp->ls) {
+	    /^(?<date>.*)\.(?<level>\d+)$/;
+	    $last[$+{level}] = $+{date};
+	    last if $+{level} == 0;
+	}
+
+	if (not defined $opt_level) {
+	    $opt_level = 
+		($NOW - iso2epoch $last[0])/86400 > $cf{FULL_CYCLE} ?  0 : 1;
+	}
+
 	my $file = strftime("%F_%R", localtime $NOW)
 	    . ".$opt_level";
 	my $label = "$NODE:" . basename($dev->{rdev});
-	verbose "Working on $dev->{dev} as $dev->{rdev} on $dev->{mountpoint}, stored as $file\n";
+	verbose "\tdumping $dev->{dev} as $dev->{rdev} on $dev->{mountpoint} to $file\n";
 	next if $opt_dry;
 
 	## complain if there is already a full backup in this
@@ -187,6 +204,8 @@
 	# $dev does not have to contain the real device
 	my $rdev = $dev;
 	if ($dev ~~ /^(LABEL|UUID)=/) {
+	    # NOTE: dump is able to handle LABEL=... too, but I think
+	    # it's more easy for recovery to know the real device
 	    chomp($rdev = `blkid -c /dev/null -o device -t '$dev'`);
 	}
 	$rdev = readlink $rdev while -l $rdev;
@@ -277,6 +296,15 @@
   sub get_home { return $data{ref shift}{home} };
 }
 
+sub iso2epoch($) {
+    $_[0] =~ /(?<year>\d+)\D(?<mon>\d+)\D(?<mday>\d+)
+	      (?:\D(?<hour>\d\d)\D(?<min>\d\d)(?:\D(?<sec>\d\d))?)?/x;
+    my %iso = ((sec => 0, min => 0, hour => 0), %+);
+    $iso{mon}--;
+    $iso{year} += 1900 if $iso{year} < 100;
+    return timelocal(@iso{qw/sec min hour mday mon year/});
+}
+
 __END__
 
 =head1 NAME
@@ -308,7 +336,8 @@
 =item B<-l>|B<--level> I<level>
 
 The backup level. Level other than "0" needs a previous
-level 0 (full) backup. (default: 0)
+level 0 (full) backup. If not specified, it is choosen automagically.
+(default: undef)
 
 =item B<-L>|B<--label> I<label>
 
@@ -322,6 +351,8 @@
 
 =head1 FILES
 
+=head2 Configuration
+
 The config files are searched in the following places:
 
     /etc/ftbackup
@@ -333,6 +364,21 @@
 be a config file. The config files have to be mode 0600 and they have to be 
 owned by the EUID running the process.
 
+The config file may contain the following items (listed with their built in defaults)
+
+    KEY		= <no default>
+    FTP_HOST	= <no default>
+    FTP_DIR	= "backup/<LABEL>/<NODE>"
+    FTP_PASSIVE = 1
+    FULL_CYCLE	= 7
+
+=head2 F<.netrc>
+
+You may miss the login information for the FTP server. Currently we rely on a valid
+F<~/.netrc> entry. An example line of the F<~/.netrc>:
+
+    machine ... login ... password ...
+
 =cut
 
 # vim:sts=4 sw=4 aw ai sm: