mirror of https://github.com/digint/btrbk
btrbk: show scheduling summary if -v is set on run/dryrun
parent
01b7ab0ebf
commit
93249d1154
|
@ -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).
|
||||||
|
|
114
btrbk
114
btrbk
|
@ -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) . ")";
|
||||||
|
|
||||||
#
|
|
||||||
# print summary
|
|
||||||
#
|
|
||||||
unless($quiet)
|
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
|
||||||
|
#
|
||||||
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 ],
|
||||||
|
|
Loading…
Reference in New Issue