diff --git a/tarback.sh b/tarback.sh index 8501c5e..6166130 100755 --- a/tarback.sh +++ b/tarback.sh @@ -7,6 +7,7 @@ XDG_DATA_DIRS="${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" TARBACK_REMOTE_DEFAULT= TARBACK_TRANSFORM_REMOTE_COMMAND_DEFAULT= +TARBACK_TRANSFORM_REMOTE_ARGUMENT_COMMAND_DEFAULT= # shellcheck disable=SC2016 # disable variable not expanding hint TARBACK_TAR_CREATE_COMMAND_DEFAULT='tar c -C "$1" .' # shellcheck disable=SC2016 # disable variable not expanding hint @@ -26,6 +27,7 @@ TARBACK_REMOTE="${TARBACK_REMOTE:-$TARBACK_REMOTE_DEFAULT}" # maybe the command needs to be transformed before being passed to the # remote command, see _transform_ssh_command for an example TARBACK_TRANSFORM_REMOTE_COMMAND="${TARBACK_TRANSFORM_REMOTE_COMMAND:-$TARBACK_TRANSFORM_REMOTE_COMMAND_DEFAULT}" +TARBACK_TRANSFORM_REMOTE_ARGUMENT_COMMAND="${TARBACK_TRANSFORM_REMOTE_ARGUMENT_COMMAND:-$TARBACK_TRANSFORM_REMOTE_ARGUMENT_COMMAND_DEFAULT}" TARBACK_TAR_CREATE_COMMAND="${TARBACK_TAR_CREATE_COMMAND:-$TARBACK_TAR_CREATE_COMMAND_DEFAULT}" TARBACK_TAR_CREATE_COMMAND_FILE="${TARBACK_TAR_CREATE_COMMAND_FILE:-$TARBACK_TAR_CREATE_COMMAND_FILE_DEFAULT}" TARBACK_TAR_EXTRACT_COMMAND="${TARBACK_TAR_EXTRACT_COMMAND:-$TARBACK_TAR_EXTRACT_COMMAND_DEFAULT}" @@ -45,40 +47,19 @@ _transform_split_name() { fi } -_transform_ssh_command() { - command_name="$(echo "$TARBACK_REMOTE" | awk '{print $1}')" - if echo "$command_name" | grep -q 'ssh'; then - echo "'$1'" - else - echo "$1" - fi -} - _transform_remote() { r="$1" - # TODO add more transformers - for t in _transform_ssh_command "$TARBACK_TRANSFORM_REMOTE_COMMAND"; do - [ -z "$t" ] && continue # skip empty transformers - r="$("$t" "$r")" - done - echo "$r" -} - -_transform_argument_ssh() { - command_name="$(echo "$TARBACK_REMOTE" | awk '{print $1}')" - if echo "$command_name" | grep -q 'ssh'; then - echo "'$(printf '%s' "$1" | sed "s/'/'\\\\''/g")'" - else - echo "$1" + if [ -n "$TARBACK_TRANSFORM_REMOTE_COMMAND" ]; then + r="$("$TARBACK_TRANSFORM_REMOTE_COMMAND" "$r")" fi + echo "$r" } _transform_argument() { a="$1" - for t in _transform_argument_ssh; do - [ -z "$t" ] && continue # skip empty transformers - a="$("$t" "$a")" - done + if [ -n "$TARBACK_TRANSFORM_REMOTE_ARGUMENT_COMMAND" ]; then + a="$("$TARBACK_TRANSFORM_REMOTE_ARGUMENT_COMMAND" "$a")" + fi echo "$a" } @@ -93,7 +74,7 @@ _create() { tarback_tar_create_command="$TARBACK_TAR_CREATE_COMMAND_FILE" fi tarback_tar_create_command="$(_transform_remote "$tarback_tar_create_command")" - $TARBACK_REMOTE sh -c "$tarback_tar_create_command" - "$(_transform_argument_ssh "$src")" \ + $TARBACK_REMOTE sh -c "$tarback_tar_create_command" - "$(_transform_argument "$src")" \ | $TARBACK_COMPRESSION \ | $TARBACK_SPLIT "$dst" } @@ -113,7 +94,7 @@ _restore() { tarback_tar_extract_command="$(_transform_remote "$tarback_tar_extract_command")" $TARBACK_MERGE "$src"* \ | $TARBACK_COMPRESSION --decompress --stdout \ - | $TARBACK_REMOTE sh -c "$tarback_tar_extract_command" - "$(_transform_argument_ssh "$dst")" + | $TARBACK_REMOTE sh -c "$tarback_tar_extract_command" - "$(_transform_argument "$dst")" } restore() { @@ -124,25 +105,27 @@ short_options='p:' while getopts "$short_options" arg; do case "$arg" in p) - # source plugin file - sourced=false - for loc in $TARBACK_PLUGIN_SEARCH_PATH; do - if [ -e "$loc/tarback/$OPTARG.sh" ]; then - # shellcheck disable=SC1090 # disable cannot follow source - . "$loc/tarback/$OPTARG.sh" - sourced=true - break + for p in $(echo "$OPTARG" | tr ',' ' '); do + # source plugin file(s) + sourced=false + for loc in $TARBACK_PLUGIN_SEARCH_PATH; do + if [ -e "$loc/tarback/$p.sh" ]; then + # shellcheck disable=SC1090 # disable cannot follow source + . "$loc/tarback/$p.sh" + sourced=true + break + fi + done + if ! "$sourced"; then + echo "couldn't find plugin $p" >&2 + exit 1 fi done - if ! "$sourced"; then - echo "couldn't find plugin $OPTARG" >&2 - exit 1 - fi shift 2 ;; *) echo "unknown option $1" >&2 - exit 1 + #exit 1 ;; esac done diff --git a/tarback/ssh.sh b/tarback/ssh.sh new file mode 100644 index 0000000..3326ee1 --- /dev/null +++ b/tarback/ssh.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +_tarback_plugin_ssh_transform_ssh_command() { + command_name="$(echo "$TARBACK_REMOTE" | awk '{print $1}')" + if echo "$command_name" | grep -q 'ssh'; then + echo "'$1'" + else + echo "$1" + fi +} + +_tarback_plugin_ssh_transform_ssh_argument() { + command_name="$(echo "$TARBACK_REMOTE" | awk '{print $1}')" + if echo "$command_name" | grep -q 'ssh'; then + echo "'$(printf '%s' "$1" | sed "s/'/'\\\\''/g")'" + else + echo "$1" + fi +} + +short_options='p:s:' +while getopts "$short_options" arg; do + case "$arg" in + s) + TARBACK_REMOTE="$OPTARG" + shift 2 + ;; + *) + echo "unknown option $1" >&2 + #exit 1 + ;; + esac +done + +TARBACK_TRANSFORM_REMOTE_COMMAND=_tarback_plugin_ssh_transform_ssh_command +TARBACK_TRANSFORM_REMOTE_ARGUMENT_COMMAND=_tarback_plugin_ssh_transform_ssh_argument + diff --git a/tests/test-001-ssh.sh b/tests/test-001-ssh.sh index 4bc13cf..bece3b5 100755 --- a/tests/test-001-ssh.sh +++ b/tests/test-001-ssh.sh @@ -8,24 +8,24 @@ export TARBACK_REMOTE='ssh localhost' # archive whole directory workdir="$(create_directories)" -./tarback.sh create "$workdir/source" "$workdir/dest/source.tar.xz" -./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore" +./tarback.sh -p ssh create "$workdir/source" "$workdir/dest/source.tar.xz" +./tarback.sh -p ssh restore "$workdir/dest/source.tar.xz" "$workdir/restore" diff "$workdir/source" "$workdir/restore" rm -rf "$workdir" # archive single file workdir="$(create_directories)" filename="$(basename "$(find "$workdir/source" -type f)")" -./tarback.sh create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" -./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" +./tarback.sh -p ssh create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +./tarback.sh -p ssh restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" diff "$workdir/source" "$workdir/restore" rm -rf "$workdir" # split archive workdir="$(create_directories)" filename="$(basename "$(find "$workdir/source" -type f)")" -TARBACK_SPLIT="split -b 10 -" ./tarback.sh create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" -TARBACK_SPLIT="split -b 10 -" ./tarback.sh restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p ssh create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p ssh restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" diff "$workdir/source" "$workdir/restore" [ "$(ls -1 "$workdir/dest/"*.part* | wc -l)" -gt 1 ] rm -rf "$workdir" diff --git a/tests/test-003-ssh-docker.sh b/tests/test-003-ssh-docker.sh index 2746f82..aae6ba4 100755 --- a/tests/test-003-ssh-docker.sh +++ b/tests/test-003-ssh-docker.sh @@ -8,24 +8,24 @@ export TARBACK_REMOTE='ssh localhost' # archive whole directory workdir="$(create_directories)" -./tarback.sh -p docker create "$workdir/source" "$workdir/dest/source.tar.xz" -./tarback.sh -p docker restore "$workdir/dest/source.tar.xz" "$workdir/restore" +./tarback.sh -p ssh,docker create "$workdir/source" "$workdir/dest/source.tar.xz" +./tarback.sh -p ssh,docker restore "$workdir/dest/source.tar.xz" "$workdir/restore" diff "$workdir/source" "$workdir/restore" rm -rf "$workdir" # archive single file workdir="$(create_directories)" filename="$(basename "$(find "$workdir/source" -type f)")" -./tarback.sh -p docker create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" -./tarback.sh -p docker restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" +./tarback.sh -p ssh,docker create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +./tarback.sh -p ssh,docker restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" diff "$workdir/source" "$workdir/restore" rm -rf "$workdir" # split archive workdir="$(create_directories)" filename="$(basename "$(find "$workdir/source" -type f)")" -TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p docker create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" -TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p docker restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p ssh,docker create "$workdir/source/$filename" "$workdir/dest/source.tar.xz" +TARBACK_SPLIT="split -b 10 -" ./tarback.sh -p ssh,docker restore "$workdir/dest/source.tar.xz" "$workdir/restore/$filename" diff "$workdir/source" "$workdir/restore" [ "$(ls -1 "$workdir/dest/"*.part* | wc -l)" -gt 1 ] rm -rf "$workdir"