btrbk: add "compat" config option (busybox: add test -d command)

Add compat, compat_local, compat_remote configuration options.

Used for busybox: instead of running `readlink -e` (which is not
available on busybox), run `readlink -f` followed by `test -d`.
lsbtr-related
Axel Burri 2020-05-24 00:13:10 +02:00
parent 52a823bb93
commit ec037952cf
4 changed files with 46 additions and 13 deletions

34
btrbk
View File

@ -132,6 +132,10 @@ my %config_options = (
backend_local => { default => undef, accept => [ "no", "btrfs-progs", "btrfs-progs-btrbk", "btrfs-progs-sudo" ] },
backend_remote => { default => undef, accept => [ "no", "btrfs-progs", "btrfs-progs-btrbk", "btrfs-progs-sudo" ] },
compat => { default => undef, accept => [ "no", "busybox" ] },
compat_local => { default => undef, accept => [ "no", "busybox" ] },
compat_remote => { default => undef, accept => [ "no", "busybox" ] },
snapshot_qgroup_destroy => { default => undef, accept => [ "yes", "no" ], context => [ "global", "volume", "subvolume" ] },
target_qgroup_destroy => { default => undef, accept => [ "yes", "no" ] },
archive_qgroup_destroy => { default => undef, accept => [ "yes", "no" ], context => [ "global" ] },
@ -1883,23 +1887,43 @@ sub system_list_mountinfo($)
}
sub system_testdir($)
{
my $vol = shift // die;
my $path = $vol->{PATH} // die;
my $ret = run_cmd(cmd => vinfo_cmd($vol, "test", '-d', { unsafe => $path } ),
rsh => vinfo_rsh($vol),
non_destructive => 1,
);
return undef unless(defined($ret));
DEBUG "Directory exists: $vol->{PRINT}";
return 1;
}
sub system_realpath($)
{
my $vol = shift // die;
my $path = $vol->{PATH} // die;;
my $ret = run_cmd(cmd => vinfo_cmd($vol, "readlink", '-v', '-e', { unsafe => $path } ),
my $path = $vol->{PATH} // die;
my $compat = (($vol->{HOST} && config_key($vol, "compat_remote")) //
config_key($vol, "compat_local") //
config_key($vol, "compat")) // "" eq "busybox";
my @options = ("-v"); # report error messages
push @options, "-e" unless($compat); # all components must exist (not available in busybox!)
push @options, "-f" if($compat); # all but the last component must exist.
my $ret = run_cmd(cmd => vinfo_cmd($vol, "readlink", @options, { unsafe => $path } ),
rsh => vinfo_rsh($vol),
non_destructive => 1,
);
return undef unless(defined($ret));
unless(scalar(@$ret) && ($ret->[0] =~ /^($file_match)$/)) {
my $realpath = scalar(@$ret) ? (check_file($ret->[0], { absolute => 1 }) // "") : "";
unless($realpath) {
ERROR "Failed to parse output of `realpath` for \"$vol->{PRINT}\": \"$ret->[0]\"";
return undef;
}
my $realpath = $1; # untaint argument
DEBUG "Real path for \"$vol->{PRINT}\" is: $realpath";
return undef if($compat && !system_testdir($vol));
return $realpath;
}

View File

@ -364,6 +364,9 @@ constraints.
*backend* btrfs-progs|btrfs-progs-btrbk|btrfs-progs-sudo::
Backend filesystem utilities to be used for btrfs specific
operations. Defaults to ``btrfs-progs''.
If you want to set this option for local or remote hosts only, you
can set *backend_local* or *backend_remote*
(e.g. "backend_remote btrfs-progs-btrbk").
+
--
btrfs-progs::
@ -381,13 +384,17 @@ btrfs-progs-sudo::
btrfs commands are prefixed with "sudo -n" (e.g. "sudo -n btrfs
subvolume show" instead of "btrfs subvolume show"). Make sure to
have appropriate (root) permissions for the "btrfs" command groups
and the "readlink" command in /etc/sudoers.
as well as the "readlink" and "test" commands in /etc/sudoers.
--
+
For convenience, it is also possible to set *backend_local* or
*backend_remote* options, which will override the backend only for
local or remote sources/targets (e.g. "backend_remote
btrfs-progs-btrbk").
*compat* busybox|no::
If set to ``busybox'', use busybox compatible commands. Defaults
to ``no''.
If you want to set this option for local or remote hosts only, you
can set *compat_local* or *compat_remote*
(e.g. "compat_remote busybox").
=== Btrfs Specific Options

View File

@ -37,6 +37,7 @@ The following commands are always allowed:
- "btrfs subvolume show" (not affected by "--restrict-path")
- "btrfs subvolume list" (not affected by "--restrict-path")
- "readlink"
- "test -d" (only if "compat busybox" configuration option is set)
- "cat /proc/self/mountinfo"
- pipes through "gzip", "pigz", "bzip2", "pbzip2", "xz", "lzop",
"lz4" (stream_compress)

View File

@ -164,9 +164,10 @@ done
# NOTE: subvolume queries are NOT affected by "--restrict-path":
# btrbk also calls show/list on the mount point of the subvolume
allow_exact_cmd "${sudo_prefix}btrfs subvolume (show|list)( ${option_match})* ${file_match}";
allow_cmd "${sudo_prefix}readlink" # used to resolve mountpoints
allow_exact_cmd "cat /proc/self/mountinfo" # used to resolve mountpoints
allow_exact_cmd "cat /proc/self/mounts" # legacy, for btrbk < 0.27.0
allow_cmd "${sudo_prefix}readlink" # resolve symlink
allow_exact_cmd "${sudo_prefix}test -d ${file_match}" # check directory (only for compat=busybox)
allow_exact_cmd "cat /proc/self/mountinfo" # resolve mountpoints
allow_exact_cmd "cat /proc/self/mounts" # legacy, for btrbk < 0.27.0
# remove leading "|" on alternation lists
allow_list=${allow_list#\|}