mirror of https://github.com/digint/btrbk
btrbk: add {snapshot,target}_preserve shortcut
parent
b90cc132c1
commit
9eb38ac9d0
60
btrbk
60
btrbk
|
@ -83,10 +83,12 @@ my %config_options = (
|
||||||
snapshot_preserve_weekly => { default => 0, accept => [ "all" ], accept_numeric => 1 },
|
snapshot_preserve_weekly => { default => 0, accept => [ "all" ], accept_numeric => 1 },
|
||||||
snapshot_preserve_monthly => { default => "all", accept => [ "all" ], accept_numeric => 1 },
|
snapshot_preserve_monthly => { default => "all", accept => [ "all" ], accept_numeric => 1 },
|
||||||
snapshot_preserve_yearly => { default => "0", accept => [ "all" ], accept_numeric => 1 },
|
snapshot_preserve_yearly => { default => "0", accept => [ "all" ], accept_numeric => 1 },
|
||||||
|
snapshot_preserve => { shortcut => 1, accept_preserve_matrix => 1, },
|
||||||
target_preserve_daily => { default => "all", accept => [ "all" ], accept_numeric => 1 },
|
target_preserve_daily => { default => "all", accept => [ "all" ], accept_numeric => 1 },
|
||||||
target_preserve_weekly => { default => 0, accept => [ "all" ], accept_numeric => 1 },
|
target_preserve_weekly => { default => 0, accept => [ "all" ], accept_numeric => 1 },
|
||||||
target_preserve_monthly => { default => "all", accept => [ "all" ], accept_numeric => 1 },
|
target_preserve_monthly => { default => "all", accept => [ "all" ], accept_numeric => 1 },
|
||||||
target_preserve_yearly => { default => "0", accept => [ "all" ], accept_numeric => 1 },
|
target_preserve_yearly => { default => "0", accept => [ "all" ], accept_numeric => 1 },
|
||||||
|
target_preserve => { shortcut => 1, accept_preserve_matrix => 1, },
|
||||||
btrfs_commit_delete => { default => undef, accept => [ "after", "each", "no" ] },
|
btrfs_commit_delete => { default => undef, accept => [ "after", "each", "no" ] },
|
||||||
ssh_identity => { default => undef, accept_file => { absolute => 1 } },
|
ssh_identity => { default => undef, accept_file => { absolute => 1 } },
|
||||||
ssh_user => { default => "root", accept_regexp => qr/^[a-z_][a-z0-9_-]*$/ },
|
ssh_user => { default => "root", accept_regexp => qr/^[a-z_][a-z0-9_-]*$/ },
|
||||||
|
@ -594,6 +596,8 @@ sub config_dump_keys($;@)
|
||||||
foreach my $key (sort keys %config_options)
|
foreach my $key (sort keys %config_options)
|
||||||
{
|
{
|
||||||
my $val;
|
my $val;
|
||||||
|
next if($config_options{$key}->{deprecated});
|
||||||
|
next if($config_options{$key}->{shortcut});
|
||||||
if($opts{resolve}) {
|
if($opts{resolve}) {
|
||||||
$val = config_key($config, $key);
|
$val = config_key($config, $key);
|
||||||
} else {
|
} else {
|
||||||
|
@ -671,8 +675,9 @@ sub check_file($$;$$)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub check_config_option($$$;$)
|
sub append_config_option($$$$;$)
|
||||||
{
|
{
|
||||||
|
my $config = shift;
|
||||||
my $key = shift;
|
my $key = shift;
|
||||||
my $value = shift;
|
my $value = shift;
|
||||||
my $context = shift;
|
my $context = shift;
|
||||||
|
@ -687,7 +692,28 @@ sub check_config_option($$$;$)
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(grep(/^$value$/, @{$opt->{accept}})) {
|
if($opt->{context} && !grep(/^$context$/, @{$opt->{context}})) {
|
||||||
|
ERROR "Option \"$key\" is only allowed in " . join(" or ", map("\"$_\"", @{$opt->{context}})) . " context" . $config_file_statement;
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($opt->{accept_preserve_matrix}) {
|
||||||
|
# special case: preserve matrix of form: "[NNd] [NNw] [NNm] [NNy]"
|
||||||
|
my $s = $value;
|
||||||
|
TRACE "option \"$key=$value\" is preserve matrix, parsing...";
|
||||||
|
if($s =~ s/([0-9*][0-9]*)\s*d\s*,?\s*//) { my $v = ($1 eq '*' ? 'all' : $1); $config->{$key . "_daily"} = $v; TRACE "adding option \"${key}_daily=$v\" to $context context"; }
|
||||||
|
if($s =~ s/([0-9*][0-9]*)\s*w\s*,?\s*//) { my $v = ($1 eq '*' ? 'all' : $1); $config->{$key . "_weekly"} = $v; TRACE "adding option \"${key}_weekly=$v\" to $context context"; }
|
||||||
|
if($s =~ s/([0-9*][0-9]*)\s*m\s*,?\s*//) { my $v = ($1 eq '*' ? 'all' : $1); $config->{$key . "_monthly"} = $v; TRACE "adding option \"${key}_monthly=$v\" to $context context"; }
|
||||||
|
if($s =~ s/([0-9*][0-9]*)\s*y\s*,?\s*//) { my $v = ($1 eq '*' ? 'all' : $1); $config->{$key . "_yearly"} = $v; TRACE "adding option \"${key}_yearly=$v\" to $context context"; }
|
||||||
|
unless($s eq "") {
|
||||||
|
ERROR "Value \"$value\" failed input validation for option \"$key\"" . $config_file_statement;
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
TRACE "successfully parsed preserve matrix";
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(grep(/^\Q$value\E$/, @{$opt->{accept}})) {
|
||||||
TRACE "option \"$key=$value\" found in accept list";
|
TRACE "option \"$key=$value\" found in accept list";
|
||||||
}
|
}
|
||||||
elsif($opt->{accept_numeric} && ($value =~ /^[0-9]+$/)) {
|
elsif($opt->{accept_numeric} && ($value =~ /^[0-9]+$/)) {
|
||||||
|
@ -724,11 +750,6 @@ sub check_config_option($$$;$)
|
||||||
TRACE "splitted option \"$key\": " . join(',', @$value);
|
TRACE "splitted option \"$key\": " . join(',', @$value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($opt->{context} && !grep(/^$context$/, @{$opt->{context}})) {
|
|
||||||
ERROR "Option \"$key\" is only allowed in " . join(" or ", map("\"$_\"", @{$opt->{context}})) . " context" . $config_file_statement;
|
|
||||||
return undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
if($opt->{deprecated}) {
|
if($opt->{deprecated}) {
|
||||||
WARN "Found deprecated option \"$key $value\"" . $config_file_statement . ": " .
|
WARN "Found deprecated option \"$key $value\"" . $config_file_statement . ": " .
|
||||||
($opt->{deprecated}->{$value}->{warn} // $opt->{deprecated}->{DEFAULT}->{warn});
|
($opt->{deprecated}->{$value}->{warn} // $opt->{deprecated}->{DEFAULT}->{warn});
|
||||||
|
@ -741,7 +762,10 @@ sub check_config_option($$$;$)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
TRACE "adding option \"$key=$value\" to $context context";
|
||||||
|
$value = undef if($value eq "no"); # we don't want to check for "no" all the time
|
||||||
|
$config->{$key} = $value;
|
||||||
|
return $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -808,7 +832,7 @@ sub parse_config_line($$$$$)
|
||||||
if($value =~ /^(\S+)\s+(\S+)$/)
|
if($value =~ /^(\S+)\s+(\S+)$/)
|
||||||
{
|
{
|
||||||
my ($target_type, $droot) = ($1, $2);
|
my ($target_type, $droot) = ($1, $2);
|
||||||
unless(grep(/^$target_type$/, @config_target_types)) {
|
unless(grep(/^\Q$target_type\E$/, @config_target_types)) {
|
||||||
ERROR "Unknown target type \"$target_type\" in \"$file\" line $.";
|
ERROR "Unknown target type \"$target_type\" in \"$file\" line $.";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
@ -835,12 +859,7 @@ sub parse_config_line($$$$$)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$value = check_config_option($key, $value, $cur->{CONTEXT}, $file);
|
return append_config_option($cur, $key, $value, $cur->{CONTEXT}, $file);
|
||||||
return undef unless(defined($value));
|
|
||||||
|
|
||||||
TRACE "config: adding option \"$key=$value\" to $cur->{CONTEXT} context";
|
|
||||||
$value = undef if($value eq "no"); # we don't want to check for "no" all the time
|
|
||||||
$cur->{$key} = $value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cur;
|
return $cur;
|
||||||
|
@ -868,6 +887,7 @@ sub parse_config(@)
|
||||||
# set defaults
|
# set defaults
|
||||||
foreach (keys %config_options) {
|
foreach (keys %config_options) {
|
||||||
next if $config_options{$_}->{deprecated}; # don't pollute hash with deprecated options
|
next if $config_options{$_}->{deprecated}; # don't pollute hash with deprecated options
|
||||||
|
next if $config_options{$_}->{shortcut}; # don't pollute hash with shortcuts
|
||||||
$root->{$_} = $config_options{$_}->{default};
|
$root->{$_} = $config_options{$_}->{default};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2234,6 +2254,7 @@ MAIN:
|
||||||
my $start_time = time;
|
my $start_time = time;
|
||||||
my @today_and_now = Today_and_Now();
|
my @today_and_now = Today_and_Now();
|
||||||
my @today = @today_and_now[0..2];
|
my @today = @today_and_now[0..2];
|
||||||
|
my %config_override_opts;
|
||||||
|
|
||||||
|
|
||||||
my ($config_cmdline, $quiet, $verbose, $preserve_backups, $resume_only);
|
my ($config_cmdline, $quiet, $verbose, $preserve_backups, $resume_only);
|
||||||
|
@ -2250,7 +2271,7 @@ MAIN:
|
||||||
'progress' => \$show_progress,
|
'progress' => \$show_progress,
|
||||||
'table|t' => sub { $output_format = "table" },
|
'table|t' => sub { $output_format = "table" },
|
||||||
'format=s' => \$output_format,
|
'format=s' => \$output_format,
|
||||||
# 'override=s' => \%config_override, # e.g. --override=incremental=no
|
# 'override=s' => \%config_override_opts, # e.g. --override=incremental=no
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
VERSION_MESSAGE();
|
VERSION_MESSAGE();
|
||||||
|
@ -2378,13 +2399,12 @@ MAIN:
|
||||||
exit 2;
|
exit 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach my $key (keys %config_override) {
|
foreach my $key (keys %config_override_opts) {
|
||||||
my $value = check_config_option($key, $config_override{$key}, "root");
|
DEBUG "config_override: \"$key=$config_override_opts{$key}\"";
|
||||||
unless(defined($value)) {
|
unless(append_config_option(\%config_override, $key, $config_override_opts{$key}, "root")) {
|
||||||
HELP_MESSAGE(0);
|
HELP_MESSAGE(0);
|
||||||
exit 2;
|
exit 2;
|
||||||
}
|
}
|
||||||
$config_override{$key} = $value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,15 @@ snapshots, and missing backups are created if needed (complying to the
|
||||||
target preserve matrix). Defaults to \[lq]yes\[rq].
|
target preserve matrix). Defaults to \[lq]yes\[rq].
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
|
\fBtarget_preserve\fR [<daily>d] [<weekly>w] [<monthly>m] [<yearly>y]
|
||||||
|
.RS 4
|
||||||
|
Shortcut to set \fItarget_preserve_daily\fR,
|
||||||
|
\fItarget_preserve_weekly\fR, \fItarget_preserve_monthly\fR and
|
||||||
|
\fItarget_preserve_yearly\fR options (see below) on a single line. Use
|
||||||
|
an asterisk for \[lq]all\[rq] (e.g. "target_preserve 60d *m" expands
|
||||||
|
to "target_preserve_daily 60" and "target_preserve_monthly all").
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
\fBtarget_preserve_daily\fR all|<number>
|
\fBtarget_preserve_daily\fR all|<number>
|
||||||
.RS 4
|
.RS 4
|
||||||
How many days of backups should be preserved. Defaults to \[lq]all\[rq].
|
How many days of backups should be preserved. Defaults to \[lq]all\[rq].
|
||||||
|
@ -152,9 +161,11 @@ preserved. Every last monthly backup in a year is considered a yearly
|
||||||
backup. Defaults to \[lq]0\[rq].
|
backup. Defaults to \[lq]0\[rq].
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\fBsnapshot_preserve_daily\fR
|
\fBsnapshot_preserve\fR
|
||||||
.PD 0
|
.PD 0
|
||||||
.PP
|
.PP
|
||||||
|
\fBsnapshot_preserve_daily\fR
|
||||||
|
.PP
|
||||||
\fBsnapshot_preserve_weekly\fR
|
\fBsnapshot_preserve_weekly\fR
|
||||||
.PP
|
.PP
|
||||||
\fBsnapshot_preserve_monthly\fR
|
\fBsnapshot_preserve_monthly\fR
|
||||||
|
|
Loading…
Reference in New Issue