mirror of https://github.com/digint/btrbk
btrbk: allow targets for subvolume/group command-line argument
parent
e7c6e37bd0
commit
d64aea9cc9
87
btrbk
87
btrbk
|
@ -85,7 +85,7 @@ my %config_options = (
|
||||||
ssh_port => { default => "default", accept => [ "default" ], accept_numeric => 1 },
|
ssh_port => { default => "default", accept => [ "default" ], accept_numeric => 1 },
|
||||||
ssh_compression => { default => undef, accept => [ "yes", "no" ] },
|
ssh_compression => { default => undef, accept => [ "yes", "no" ] },
|
||||||
btrfs_progs_compat => { default => undef, accept => [ "yes", "no" ] },
|
btrfs_progs_compat => { default => undef, accept => [ "yes", "no" ] },
|
||||||
group => { default => undef, accept_regexp => qr/^$group_match(\s*,\s*$group_match)*$/, split => qr/\s*,\s*/, context => [ "volume", "subvolume" ] },
|
group => { default => undef, accept_regexp => qr/^$group_match(\s*,\s*$group_match)*$/, split => qr/\s*,\s*/ },
|
||||||
|
|
||||||
# deprecated options
|
# deprecated options
|
||||||
snapshot_create_always => { default => undef, accept => [ "yes", "no" ],
|
snapshot_create_always => { default => undef, accept => [ "yes", "no" ],
|
||||||
|
@ -1424,7 +1424,8 @@ sub schedule(@)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub print_header(@) {
|
sub print_header(@)
|
||||||
|
{
|
||||||
my %args = @_;
|
my %args = @_;
|
||||||
my $config = $args{config};
|
my $config = $args{config};
|
||||||
|
|
||||||
|
@ -1435,9 +1436,17 @@ sub print_header(@) {
|
||||||
}
|
}
|
||||||
if($config) {
|
if($config) {
|
||||||
print " Config: $config->{SRC_FILE}\n";
|
print " Config: $config->{SRC_FILE}\n";
|
||||||
if($config->{CMDLINE_FILTER_LIST}) {
|
|
||||||
|
if($config->{CMDLINE_FILTER_LIST})
|
||||||
|
{
|
||||||
|
my @list = sort @{$config->{CMDLINE_FILTER_LIST}};
|
||||||
|
my @sorted = ( grep(/^group/, @list),
|
||||||
|
grep(/^volume/, @list),
|
||||||
|
grep(/^subvolume/, @list),
|
||||||
|
grep(/^target/, @list) );
|
||||||
|
die unless(scalar(@list) == scalar(@sorted));
|
||||||
print " Filter: ";
|
print " Filter: ";
|
||||||
print join("\n ", map { $_->{PRINT} } @{$config->{CMDLINE_FILTER_LIST}});
|
print join("\n ", @sorted);
|
||||||
print "\n";
|
print "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1694,57 +1703,72 @@ MAIN:
|
||||||
#
|
#
|
||||||
if(($action_run || $action_tree || $action_info) && scalar(@filter_args))
|
if(($action_run || $action_tree || $action_info) && scalar(@filter_args))
|
||||||
{
|
{
|
||||||
my $filter_count = undef;
|
|
||||||
my @filter;
|
|
||||||
my %match;
|
my %match;
|
||||||
foreach my $config_vol (@{$config->{VOLUME}}) {
|
foreach my $config_vol (@{$config->{VOLUME}}) {
|
||||||
my $vol_url = $config_vol->{url} // die;
|
my $vol_url = $config_vol->{url} // die;
|
||||||
my $found = 0;
|
my $found_vol = 0;
|
||||||
foreach my $filter (@filter_args) {
|
foreach my $filter (@filter_args) {
|
||||||
if(($vol_url eq $filter) || (map { ($filter eq $_) || () } @{$config_vol->{group}})) {
|
if(($vol_url eq $filter) || (map { ($filter eq $_) || () } @{$config_vol->{group}})) {
|
||||||
push(@filter, vinfo($vol_url, $config_vol));
|
|
||||||
$match{$filter} = 1;
|
|
||||||
TRACE "filter argument \"$filter\" matches volume: $vol_url\n";
|
TRACE "filter argument \"$filter\" matches volume: $vol_url\n";
|
||||||
$found = 1;
|
$match{$filter} = ($vol_url eq $filter) ? "volume=" . vinfo($vol_url, $config_vol)->{PRINT} : "group=$filter";
|
||||||
|
$found_vol = 1;
|
||||||
# last; # need to cycle through all filter_args for correct %match
|
# last; # need to cycle through all filter_args for correct %match
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next if($found);
|
next if($found_vol);
|
||||||
|
|
||||||
my @filter_subvol;
|
my @filter_subvol;
|
||||||
foreach my $config_subvol (@{$config_vol->{SUBVOLUME}}) {
|
foreach my $config_subvol (@{$config_vol->{SUBVOLUME}}) {
|
||||||
my $subvol_url = $config_subvol->{url} // die;
|
my $subvol_url = $config_subvol->{url} // die;
|
||||||
|
my $found_subvol = 0;
|
||||||
$found = 0;
|
|
||||||
foreach my $filter (@filter_args) {
|
foreach my $filter (@filter_args) {
|
||||||
if(($subvol_url eq $filter) || (map { ($filter eq $_) || () } @{$config_subvol->{group}})) {
|
if(($subvol_url eq $filter) || (map { ($filter eq $_) || () } @{$config_subvol->{group}})) {
|
||||||
push(@filter_subvol, vinfo($subvol_url, $config_subvol));
|
|
||||||
$match{$filter} = 1;
|
|
||||||
TRACE "filter argument \"$filter\" matches subvolume: $subvol_url\n";
|
TRACE "filter argument \"$filter\" matches subvolume: $subvol_url\n";
|
||||||
$found = 1;
|
$match{$filter} = ($subvol_url eq $filter) ? "subvolume=" . vinfo($subvol_url, $config_subvol)->{PRINT} : "group=$filter";
|
||||||
|
$found_subvol = 1;
|
||||||
|
$found_vol = 1;
|
||||||
# last; # need to cycle through all filter_args for correct %match
|
# last; # need to cycle through all filter_args for correct %match
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unless($found) {
|
next if($found_subvol);
|
||||||
DEBUG "No match on subvolume/group command line argument, skipping subvolume: $subvol_url";
|
|
||||||
|
foreach my $config_target (@{$config_subvol->{TARGET}}) {
|
||||||
|
my $target_url = $config_target->{url} // die;
|
||||||
|
my $found_target = 0;
|
||||||
|
foreach my $filter (@filter_args) {
|
||||||
|
if(($target_url eq $filter) || (map { ($filter eq $_) || () } @{$config_target->{group}})) {
|
||||||
|
TRACE "filter argument \"$filter\" matches target: $target_url\n";
|
||||||
|
$match{$filter} = ($target_url eq $filter) ? "target=" . vinfo($target_url, $config_target)->{PRINT} : "group=$filter";
|
||||||
|
$found_target = 1;
|
||||||
|
$found_subvol = 1;
|
||||||
|
$found_vol = 1;
|
||||||
|
# last; # need to cycle through all filter_args for correct %match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unless($found_target) {
|
||||||
|
DEBUG "No match on filter command line argument, skipping target: $target_url";
|
||||||
|
$config_target->{ABORTED} = "USER_SKIP";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unless($found_subvol) {
|
||||||
|
DEBUG "No match on filter command line argument, skipping subvolume: $subvol_url";
|
||||||
$config_subvol->{ABORTED} = "USER_SKIP";
|
$config_subvol->{ABORTED} = "USER_SKIP";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unless(@filter_subvol) {
|
unless($found_vol) {
|
||||||
DEBUG "No match on subvolume/group command line argument, skipping volume: $vol_url";
|
DEBUG "No match on filter command line argument, skipping volume: $vol_url";
|
||||||
$config_vol->{ABORTED} = "USER_SKIP";
|
$config_vol->{ABORTED} = "USER_SKIP";
|
||||||
}
|
}
|
||||||
push(@filter, @filter_subvol);
|
|
||||||
}
|
}
|
||||||
# make sure all args have a match
|
# make sure all args have a match
|
||||||
my @nomatch = map { $match{$_} ? () : $_ } @filter_args;
|
my @nomatch = map { $match{$_} ? () : $_ } @filter_args;
|
||||||
if(@nomatch) {
|
if(@nomatch) {
|
||||||
foreach(@nomatch) {
|
foreach(@nomatch) {
|
||||||
ERROR "Command line argument does not match any volume/subvolume declaration: $_";
|
ERROR "Command line argument does not match any volume, subvolume, target or group declaration: $_";
|
||||||
}
|
}
|
||||||
exit 1;
|
exit 1;
|
||||||
}
|
}
|
||||||
$config->{CMDLINE_FILTER_LIST} = \@filter;
|
$config->{CMDLINE_FILTER_LIST} = [ values %match ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1863,6 +1887,7 @@ MAIN:
|
||||||
|
|
||||||
foreach my $config_target (@{$config_subvol->{TARGET}})
|
foreach my $config_target (@{$config_subvol->{TARGET}})
|
||||||
{
|
{
|
||||||
|
next if($config_target->{ABORTED});
|
||||||
my $droot = vinfo($config_target->{url}, $config_target);
|
my $droot = vinfo($config_target->{url}, $config_target);
|
||||||
unless(vinfo_root($droot)) {
|
unless(vinfo_root($droot)) {
|
||||||
$config_target->{ABORTED} = "Failed to fetch subvolume detail" . ($err ? ": $err" : "");
|
$config_target->{ABORTED} = "Failed to fetch subvolume detail" . ($err ? ": $err" : "");
|
||||||
|
@ -2071,7 +2096,7 @@ MAIN:
|
||||||
my $snapshot_name = $snapshot_basename . '.' . $timestamp . ($postfix_counter ? "_$postfix_counter" : "");
|
my $snapshot_name = $snapshot_basename . '.' . $timestamp . ($postfix_counter ? "_$postfix_counter" : "");
|
||||||
|
|
||||||
if(@unconfirmed_target_name) {
|
if(@unconfirmed_target_name) {
|
||||||
INFO "Failed to check all targets, assuming non-present subvolume \"$snapshot_name\" in: " . join(", ", map { "\"$_->{PRINT}\"" } @unconfirmed_target_name);
|
INFO "Assuming non-present subvolume \"$snapshot_name\" in skipped targets: " . join(", ", map { "\"$_->{PRINT}\"" } @unconfirmed_target_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
# finally create the snapshot
|
# finally create the snapshot
|
||||||
|
@ -2240,7 +2265,11 @@ MAIN:
|
||||||
foreach my $config_target (@{$config_subvol->{TARGET}})
|
foreach my $config_target (@{$config_subvol->{TARGET}})
|
||||||
{
|
{
|
||||||
if($config_target->{ABORTED}) {
|
if($config_target->{ABORTED}) {
|
||||||
$target_aborted = 1;
|
if($config_target->{ABORTED} eq "USER_SKIP") {
|
||||||
|
$target_aborted ||= -1;
|
||||||
|
} else {
|
||||||
|
$target_aborted = 1;
|
||||||
|
}
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
my $droot = $config_target->{droot} || die;
|
my $droot = $config_target->{droot} || die;
|
||||||
|
@ -2278,7 +2307,7 @@ MAIN:
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$config_target->{ABORTED} = "Failed to delete subvolume";
|
$config_target->{ABORTED} = "Failed to delete subvolume";
|
||||||
$target_aborted = 1;
|
$target_aborted = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2286,7 +2315,11 @@ MAIN:
|
||||||
# delete snapshots
|
# delete snapshots
|
||||||
#
|
#
|
||||||
if($target_aborted) {
|
if($target_aborted) {
|
||||||
WARN "Skipping cleanup of snapshots for subvolume \"$svol->{PRINT}\", as at least one target aborted earlier";
|
if($target_aborted == -1) {
|
||||||
|
INFO "Skipping cleanup of snapshots for subvolume \"$svol->{PRINT}\", as at least one target is skipped by command line argument";
|
||||||
|
} else {
|
||||||
|
WARN "Skipping cleanup of snapshots for subvolume \"$svol->{PRINT}\", as at least one target aborted earlier";
|
||||||
|
}
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
INFO "Cleaning snapshots: $sroot->{PRINT}/$snapdir$snapshot_basename.*";
|
INFO "Cleaning snapshots: $sroot->{PRINT}/$snapdir$snapshot_basename.*";
|
||||||
|
|
Loading…
Reference in New Issue