btrbk: show scheduling summary if -v is set on run/dryrun

pull/57/head
Axel Burri 2015-10-12 20:46:05 +02:00
parent 01b7ab0ebf
commit 93249d1154
2 changed files with 88 additions and 29 deletions

View File

@ -4,9 +4,10 @@ btrbk-current
* Allow filtering subcommands by group as well as targets. * Allow filtering subcommands by group as well as targets.
* Added "config print" command. * Added "config print" command.
* Added "list" command (experimental). * Added "list" command (experimental).
* Added "--format=table|long|raw" and "-t, --table" command line * Added "--format=table|long|raw" and "-t,--table" command line
options, producing tabular and raw (machine-readable) output for options, producing tabular and raw (machine-readable) output for
"(dry)run", "tree" and "list" commands. "(dry)run", "tree" and "list" commands.
* Print scheduler details if -v option is set on action run/dryrun.
* Added configuration option "ssh_cipher_spec" (close: #47). * Added configuration option "ssh_cipher_spec" (close: #47).
* Added "target raw", with GnuPG and compression support * Added "target raw", with GnuPG and compression support
(experimental). (experimental).

112
btrbk
View File

@ -1542,13 +1542,12 @@ sub schedule(@)
my $preserve_weekly = $args{preserve_weekly} // die; my $preserve_weekly = $args{preserve_weekly} // die;
my $preserve_monthly = $args{preserve_monthly} // die; my $preserve_monthly = $args{preserve_monthly} // die;
my $preserve_latest = $args{preserve_latest} || 0; my $preserve_latest = $args{preserve_latest} || 0;
my $log_verbose = $args{log_verbose}; my $results_list = $args{results};
my $result_hints = $args{result_hints} // {};
if($log_verbose) { DEBUG "Filter scheme: preserving all within $preserve_daily days";
INFO "Filter scheme: preserving all within $preserve_daily days"; DEBUG "Filter scheme: preserving first in week (starting on $preserve_day_of_week), for $preserve_weekly weeks";
INFO "Filter scheme: preserving first in week (starting on $preserve_day_of_week), for $preserve_weekly weeks"; DEBUG "Filter scheme: preserving last weekly of month, for $preserve_monthly months";
INFO "Filter scheme: preserving last weekly of month, for $preserve_monthly months";
}
# sort the schedule, ascending by date # sort the schedule, ascending by date
my @sorted_schedule = sort { ($a->{btrbk_date}->[0] <=> $b->{btrbk_date}->[0]) || my @sorted_schedule = sort { ($a->{btrbk_date}->[0] <=> $b->{btrbk_date}->[0]) ||
@ -1610,32 +1609,49 @@ sub schedule(@)
# assemble results # assemble results
my @delete; my @delete;
my @preserve; my @preserve;
my %preserve_matrix = ( d => $preserve_daily,
w => $preserve_weekly,
m => $preserve_monthly,
dow => $preserve_day_of_week,
);
my %result_base = ( %preserve_matrix,
scheme => format_preserve_matrix(%preserve_matrix, format => "short"),
%$result_hints,
);
foreach my $href (@sorted_schedule) foreach my $href (@sorted_schedule)
{ {
if($href->{preserve}) { if($href->{preserve}) {
INFO "=== $href->{name}: $href->{preserve}" if($href->{name});
push(@preserve, $href->{value}); push(@preserve, $href->{value});
DEBUG "=== $href->{name}: $href->{preserve}" if($href->{name});
push @$results_list, { %result_base,
# action => "preserve",
reason => $href->{preserve},
value => $href->{value},
} if($results_list);
} }
else { else {
INFO "<<< $href->{name}" if($href->{name});
push(@delete, $href->{value}); push(@delete, $href->{value});
DEBUG "<<< $href->{name}" if($href->{name});
push @$results_list, { %result_base,
action => "delete",
value => $href->{value},
} if($results_list);;
} }
} }
DEBUG "Preserving " . @preserve . "/" . @$schedule . " items" unless($log_verbose); DEBUG "Preserving " . @preserve . "/" . @$schedule . " items";
return (\@preserve, \@delete); return (\@preserve, \@delete);
} }
sub format_preserve_matrix($$;$) sub format_preserve_matrix(@)
{ {
my $config = shift || die; my %args = @_;
my $prefix = shift || die; my $dow = $args{dow} // config_key($args{config}, "preserve_day_of_week");
my $format = shift || "long"; my $d = $args{d} // config_key($args{config}, "$args{prefix}_preserve_daily");
my @out = ""; my $w = $args{w} // config_key($args{config}, "$args{prefix}_preserve_weekly");
my $dow = config_key($config, "preserve_day_of_week"); my $m = $args{m} // config_key($args{config}, "$args{prefix}_preserve_monthly");
my $d = config_key($config, "${prefix}_preserve_daily"); my $format = $args{format} // "long";
my $w = config_key($config, "${prefix}_preserve_weekly");
my $m = config_key($config, "${prefix}_preserve_monthly");
$d =~ s/^all$/-1/; $d =~ s/^all$/-1/;
$w =~ s/^all$/-1/; $w =~ s/^all$/-1/;
$m =~ s/^all$/-1/; $m =~ s/^all$/-1/;
@ -1690,7 +1706,8 @@ sub print_header(@)
sub print_formatted(@) sub print_formatted(@)
{ {
my %args = @_; my %args = @_;
my $format = $args{output_format} || die; my $title = $args{title};
my $format = $args{output_format} || "table";
my $default = $args{default_format} || die; my $default = $args{default_format} || die;
my $data = $args{data} || die; my $data = $args{data} || die;
my $keys = $args{formats}->{$format}; my $keys = $args{formats}->{$format};
@ -1701,6 +1718,7 @@ sub print_formatted(@)
$format = $default; $format = $default;
} }
print "$title\n" if($title);
if($format eq "raw") if($format eq "raw")
{ {
# output: key0="value0" key1="value1" ... # output: key0="value0" key1="value1" ...
@ -2220,7 +2238,7 @@ MAIN:
source_rsh => ($svol->{RSH} ? join(" ", @{$svol->{RSH}}) : undef), source_rsh => ($svol->{RSH} ? join(" ", @{$svol->{RSH}}) : undef),
snapshot_path => $sroot->{PATH} . (config_key($config_subvol, "snapshot_dir", prefix => '/') // ""), snapshot_path => $sroot->{PATH} . (config_key($config_subvol, "snapshot_dir", prefix => '/') // ""),
snapshot_name => config_key($config_subvol, "snapshot_name"), snapshot_name => config_key($config_subvol, "snapshot_name"),
snapshot_preserve => format_preserve_matrix($config_subvol, "snapshot"), snapshot_preserve => format_preserve_matrix(config => $config_subvol, prefix => "snapshot"),
}; };
push @subvol_data, $subvolh; push @subvol_data, $subvolh;
@ -2234,7 +2252,7 @@ MAIN:
target_path => $droot->{PATH}, target_path => $droot->{PATH},
target_host => $droot->{HOST}, target_host => $droot->{HOST},
target_rsh => ($droot->{RSH} ? join(" ", @{$droot->{RSH}}) : undef), target_rsh => ($droot->{RSH} ? join(" ", @{$droot->{RSH}}) : undef),
target_preserve => format_preserve_matrix($config_target, "target"), target_preserve => format_preserve_matrix(config => $config_target, prefix => "target"),
}; };
if($action_list eq "target_uniq") { if($action_list eq "target_uniq") {
next if($target_uniq{$droot->{URL}}); next if($target_uniq{$droot->{URL}});
@ -2832,6 +2850,7 @@ MAIN:
# #
# remove backups following a preserve daily/weekly/monthly scheme # remove backups following a preserve daily/weekly/monthly scheme
# #
my $schedule_results = [];
if($preserve_backups || $resume_only) { if($preserve_backups || $resume_only) {
INFO "Preserving all backups (option \"-p\" or \"-r\" present)"; INFO "Preserving all backups (option \"-p\" or \"-r\" present)";
} }
@ -2890,7 +2909,7 @@ MAIN:
# next; # next;
# } # }
push(@schedule, { value => $vol, push(@schedule, { value => $vol,
name => $vol->{PRINT}, name => $vol->{PRINT}, # only for logging
btrbk_date => $filename_info->{btrbk_date}, btrbk_date => $filename_info->{btrbk_date},
preserve => $vol->{FORCE_PRESERVE} preserve => $vol->{FORCE_PRESERVE}
}); });
@ -2903,7 +2922,8 @@ MAIN:
preserve_weekly => config_key($config_target, "target_preserve_weekly"), preserve_weekly => config_key($config_target, "target_preserve_weekly"),
preserve_monthly => config_key($config_target, "target_preserve_monthly"), preserve_monthly => config_key($config_target, "target_preserve_monthly"),
preserve_latest => $preserve_latest_backup, preserve_latest => $preserve_latest_backup,
log_verbose => 1, results => $schedule_results,
result_hints => { topic => "backup", root_path => $droot->{PATH} },
); );
my $ret = btrfs_subvolume_delete($delete, commit => config_key($config_target, "btrfs_commit_delete")); my $ret = btrfs_subvolume_delete($delete, commit => config_key($config_target, "btrfs_commit_delete"));
if(defined($ret)) { if(defined($ret)) {
@ -2933,7 +2953,7 @@ MAIN:
my $filename_info = parse_filename($vol->{SUBVOL_PATH}, $snapdir . $snapshot_basename); my $filename_info = parse_filename($vol->{SUBVOL_PATH}, $snapdir . $snapshot_basename);
next unless($filename_info); # ignore non-btrbk files next unless($filename_info); # ignore non-btrbk files
push(@schedule, { value => $vol, push(@schedule, { value => $vol,
name => $vol->{PRINT}, name => $vol->{PRINT}, # only for logging
btrbk_date => $filename_info->{btrbk_date} btrbk_date => $filename_info->{btrbk_date}
}); });
} }
@ -2945,7 +2965,8 @@ MAIN:
preserve_weekly => config_key($config_subvol, "snapshot_preserve_weekly"), preserve_weekly => config_key($config_subvol, "snapshot_preserve_weekly"),
preserve_monthly => config_key($config_subvol, "snapshot_preserve_monthly"), preserve_monthly => config_key($config_subvol, "snapshot_preserve_monthly"),
preserve_latest => $preserve_latest_snapshot, preserve_latest => $preserve_latest_snapshot,
log_verbose => 1, results => $schedule_results,
result_hints => { topic => "snapshot", root_path => $sroot->{PATH} },
); );
my $ret = btrfs_subvolume_delete($delete, commit => config_key($config_subvol, "btrfs_commit_delete")); my $ret = btrfs_subvolume_delete($delete, commit => config_key($config_subvol, "btrfs_commit_delete"));
if(defined($ret)) { if(defined($ret)) {
@ -2962,11 +2983,47 @@ MAIN:
my $time_elapsed = time - $start_time; my $time_elapsed = time - $start_time;
INFO "Completed within: ${time_elapsed}s (" . localtime(time) . ")"; INFO "Completed within: ${time_elapsed}s (" . localtime(time) . ")";
unless($quiet)
{
#
# print scheduling results
#
if($loglevel >= 2) {
my @data = map { $_->{url} = $_->{value}->{URL};
$_->{host} = $_->{value}->{HOST};
$_->{path} = $_->{value}->{PATH};
$_->{name} = $_->{value}->{SUBVOL_PATH};
$_->{target} = $_->{value}->{PRINT};
$_;
} @$schedule_results;
my @data_backup = map { $_->{topic} eq "backup" ? $_ : () } @data;
my @data_snapshot = map { $_->{topic} eq "snapshot" ? $_ : () } @data;
my %format_args = (
output_format => $output_format,
default_format => "table",
formats => { raw => [ qw( topic action url host path dow d m w) ],
table => [ qw( action target scheme reason ) ],
long => [ qw( action host root_path name scheme reason ) ],
},
);
print_formatted( title => "SNAPSHOT SCHEDULE",
data => \@data_snapshot,
%format_args,
);
print "\n";
print_formatted( title => "BACKUP SCHEDULE",
data => \@data_backup,
%format_args,
);
print "\n";
}
# #
# print summary # print summary
# #
unless($quiet)
{
my @unrecoverable; my @unrecoverable;
my @out; my @out;
my @raw_data; my @raw_data;
@ -3115,6 +3172,7 @@ MAIN:
else else
{ {
print_formatted( print_formatted(
title => "SUMMARY",
output_format => $output_format, output_format => $output_format,
default_format => "table", default_format => "table",
data => [ sort { $a->{SORT} <=> $b->{SORT} } @raw_data ], data => [ sort { $a->{SORT} <=> $b->{SORT} } @raw_data ],