btrbk: add archive_exclude configuration option

Support wildcard characters, matches against both "$sroot->{PATH}" and
"$sroot->{PATH}/$snapshot_name".
pull/204/merge
Axel Burri 2018-02-13 21:36:21 +01:00
parent 0ebe2ea2e1
commit 8610e75459
3 changed files with 39 additions and 5 deletions

View File

@ -2,6 +2,7 @@ btrbk-current
* Bugfix: fix parsing of "openssl_iv_size" configuration option. * Bugfix: fix parsing of "openssl_iv_size" configuration option.
* Bugfix: fix filter statement matching for volume=/ (close #209). * Bugfix: fix filter statement matching for volume=/ (close #209).
* Add "archive_exclude" configuration option.
btrbk-0.26.0 btrbk-0.26.0

38
btrbk
View File

@ -128,6 +128,8 @@ my %config_options = (
target_qgroup_destroy => { default => undef, accept => [ "yes", "no" ] }, target_qgroup_destroy => { default => undef, accept => [ "yes", "no" ] },
archive_qgroup_destroy => { default => undef, accept => [ "yes", "no" ], context => [ "root" ] }, archive_qgroup_destroy => { default => undef, accept => [ "yes", "no" ], context => [ "root" ] },
archive_exclude => { default => undef, accept_file => { wildcards => 1 }, allow_multiple => 1, context => [ "root" ] },
# deprecated options # deprecated options
btrfs_progs_compat => { default => undef, accept => [ "yes", "no" ], btrfs_progs_compat => { default => undef, accept => [ "yes", "no" ],
deprecated => { DEFAULT => { ABORT => 1, warn => 'This feature has been dropped in btrbk-v0.23.0. Please update to newest btrfs-progs, AT LEAST >= $BTRFS_PROGS_MIN' } } }, deprecated => { DEFAULT => { ABORT => 1, warn => 'This feature has been dropped in btrbk-v0.23.0. Please update to newest btrfs-progs, AT LEAST >= $BTRFS_PROGS_MIN' } } },
@ -2958,7 +2960,7 @@ sub check_file($$;@)
return undef; return undef;
} }
} }
else { elsif(not $accept->{wildcards}) {
die("accept_type must contain either 'relative' or 'absolute'"); die("accept_type must contain either 'relative' or 'absolute'");
} }
} }
@ -4657,6 +4659,17 @@ MAIN:
} }
} }
# translate archive_exclude globs to regex
my $exclude_list = config_key($config, 'archive_exclude') // [];
my @exclude_match;
foreach my $exclude (@$exclude_list) {
$exclude = '/' . $exclude unless($exclude =~ /^\//); # add leading slash
# support "*some*file*", "*/*"
push(@exclude_match, join('[^\/]*', map(quotemeta($_), split(/\*+/, $exclude, -1))));
TRACE "translated exclude globs \"$exclude\" to regex \"$exclude_match[-1]\"";
}
# create archives
my $schedule_results = []; my $schedule_results = [];
my $aborted; my $aborted;
foreach my $sroot (vinfo_subsection($config, 'archive_source')) { foreach my $sroot (vinfo_subsection($config, 'archive_source')) {
@ -4665,8 +4678,18 @@ MAIN:
ABORTED($sroot, $aborted); ABORTED($sroot, $aborted);
next; next;
} }
my $snapshot_name = config_key($sroot, "snapshot_name") // die;
# skip on archive_exclude
foreach(@exclude_match) {
if(($sroot->{PATH} =~ /$_$/) || ("$sroot->{PATH}/$snapshot_name" =~ /$_$/)) {
INFO "Skip archiving subvolumes (archive_exclude): $sroot->{PRINT}/${snapshot_name}.*";
ABORTED($sroot, "ARCHIVE_EXCLUDE_SKIP");
}
}
next if(ABORTED($sroot));
foreach my $droot (vinfo_subsection($sroot, 'target')) { foreach my $droot (vinfo_subsection($sroot, 'target')) {
my $snapshot_name = config_key($droot, "snapshot_name") // die;
INFO "Archiving subvolumes: $sroot->{PRINT}/${snapshot_name}.*"; INFO "Archiving subvolumes: $sroot->{PRINT}/${snapshot_name}.*";
macro_archive_target($sroot, $droot, $snapshot_name, { results => $schedule_results }); macro_archive_target($sroot, $droot, $snapshot_name, { results => $schedule_results });
if(ABORTED($droot)) { if(ABORTED($droot)) {
@ -4679,7 +4702,7 @@ MAIN:
} }
} }
# delete archives
my $del_schedule_results; my $del_schedule_results;
if($preserve_backups) { if($preserve_backups) {
INFO "Preserving all archives (option \"-p\" or \"-r\" present)"; INFO "Preserving all archives (option \"-p\" or \"-r\" present)";
@ -4688,8 +4711,8 @@ MAIN:
{ {
$del_schedule_results = []; $del_schedule_results = [];
foreach my $sroot (vinfo_subsection($config, 'archive_source')) { foreach my $sroot (vinfo_subsection($config, 'archive_source')) {
my $snapshot_name = config_key($sroot, "snapshot_name") // die;
foreach my $droot (vinfo_subsection($sroot, 'target')) { foreach my $droot (vinfo_subsection($sroot, 'target')) {
my $snapshot_name = config_key($droot, "snapshot_name") // die;
INFO "Cleaning archive: $droot->{PRINT}/${snapshot_name}.*"; INFO "Cleaning archive: $droot->{PRINT}/${snapshot_name}.*";
macro_delete($droot, "", $snapshot_name, $droot, macro_delete($droot, "", $snapshot_name, $droot,
{ preserve => config_preserve_hash($droot, "archive"), { preserve => config_preserve_hash($droot, "archive"),
@ -4754,7 +4777,12 @@ MAIN:
} }
if((ABORTED($droot) && (ABORTED($droot) ne "USER_SKIP")) || if((ABORTED($droot) && (ABORTED($droot) ne "USER_SKIP")) ||
(ABORTED($sroot) && (ABORTED($sroot) ne "USER_SKIP"))) { (ABORTED($sroot) && (ABORTED($sroot) ne "USER_SKIP"))) {
push @subvol_out, "!!! Target \"$droot->{PRINT}\" aborted: " . (ABORTED($droot) || ABORTED($sroot)); if(ABORTED($sroot) && (ABORTED($sroot) eq "ARCHIVE_EXCLUDE_SKIP")) {
push @subvol_out, "<archive_exclude>";
}
else {
push @subvol_out, "!!! Target \"$droot->{PRINT}\" aborted: " . (ABORTED($droot) || ABORTED($sroot));
}
} }
if($droot->{CONFIG}->{UNRECOVERABLE}) { if($droot->{CONFIG}->{UNRECOVERABLE}) {
push(@unrecoverable, $droot->{CONFIG}->{UNRECOVERABLE}); push(@unrecoverable, $droot->{CONFIG}->{UNRECOVERABLE});

View File

@ -191,6 +191,11 @@ Note that using ``long-iso'' has implications on the scheduling, see
Set retention policy for archives ("btrbk archive" command), with Set retention policy for archives ("btrbk archive" command), with
same semantics as 'target_preserve_min'. same semantics as 'target_preserve_min'.
*archive_exclude* <pattern> _*experimental*_::
Exclude subvolumes matching <pattern> from archiving. The pattern
accepts wildcard character "*", and is matched against the end of
the pathname.
=== SSH Options === SSH Options