bitreich-drist

fork of bitreich.org/drist
git clone git://git.pyratebeard.net/bitreich-drist.git
Log | Files | Refs | README | LICENSE

commit 1ddb1582cfb17a5d79fd9725907a1b329dacbd6b
parent c6481050031bc54fa99a6fcfa7d3408850040883
Author: Solene Rapenne <solene@perso.pw>
Date:   Wed, 26 Aug 2020 21:13:06 +0200

Major rework

Files are now copied in a temporary subtree and files must be copied on the
system from the script. This is safer in many ways and result is predictable.

Drop "absent" function
Drop simulate flag

If previous behavior is prefered, you should stay with previous version

Diffstat:
Mdrist | 165+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mdrist.1 | 28+++++++++-------------------
2 files changed, 94 insertions(+), 99 deletions(-)

diff --git a/drist b/drist @@ -1,20 +1,71 @@ #!/bin/sh -SIMULATE=0 SUDO=0 SUDO_BIN=sudo EXEC="" SSHONCE=0 TRUNCATE=0 +TEMPDIR="" usage() { - echo "$0 [-n] [-d] [-s [-e sudo|doas]] server" + echo "$0 [-n] [-d] [-s [-e sudo|doas]] server [...]" exit 0 } +# $1 = directory name +# $2 = remote server +copy_files() { + # -l = keep symlink / -D = special device + if [ -d "${1}" ] + then + LIST=$(mktemp /tmp/drist-rsync.XXXXXXXXXX) + if [ -f "$LIST" ] + then + printf 'Copying files from "%s" to temporary directory %s:\n' "$1" "$3" + find "${1}"/ -type f -or -type l | cut -d '/' -f 2- | tee "${LIST}" | sed 's/^/ \//' + rsync -e "ssh $SSH_PARAMS" -lD --files-from="${LIST}" "${1}/" "${2}":"/${3}" + rm "$LIST" + fi + fi +} + +# $1 = script filename +# $2 = remote server +# $3 = tempdir +remote_script() { + if [ -f "${1}" ] + then + printf 'Executing file "%s":\n' "$1" + ssh $SSH_PARAMS "${2}" "cd ${3} && DRIST=${3}/script && + cat - > \$DRIST && + chmod u+x \$DRIST && + ${EXEC} \$DRIST" < "$1" + fi +} + +# $1 = remote server +create_temp() { + TEMPDIR=$(ssh $SSH_PARAMS "$1" "mktemp -d ~/.drist_files_XXXXXXXXXXXXXXX") + if [ "$TEMPDIR" = "" ]; then + echo "mktemp error, aborting" + fi +} + +# $1 = remote server +# $2 = temporary directory +delete_temp() { + if echo "${2}" | grep drist_files_ >/dev/null ; then + ssh $SSH_PARAMS "$1" "rm -fr ${2}" + else + echo "Problem, TEMPDIR was reset during execution, current value is = $2" + exit 2 + fi +} + + +# RUNTIME BEGINS HERE while getopts pndse: arg; do case ${arg} in - n) SIMULATE=1 ;; d) TRUNCATE=1 ;; s) SUDO=1 ;; e) SUDO_BIN="${OPTARG}" ;; @@ -36,93 +87,47 @@ then SSH_PARAMS=-o"ControlMaster=auto"" "-o"ControlPath=/tmp/drist_ssh_%h_%p_%r.sock"" "-o"ControlPersist=1m" fi -# check if host exists -if [ "$#" -ne 1 ]; then - usage +# start looping over server list +if [ -f "$1" ] +then + SERVER_LIST="$(cat $1 | tr '\n' ' ')" else - HOSTNAME=$(ssh $SSH_PARAMS "$1" "${EXEC} uname -n") + SERVER_LIST="$@" +fi + +if [ "${SERVER_LIST}" = "" ] +then + echo "No server specified" + exit 1 +fi + +for remote_server in ${SERVER_LIST} +do + echo "Running on ${remote_server}" + + # check if host exists + HOSTNAME=$(ssh $SSH_PARAMS "${remote_server}" "${EXEC} uname -n") if [ "$?" -ne 0 ]; then - echo "Error while ssh ${1}" + echo "Error while ssh ${remote_server}" exit 2 fi if [ "$TRUNCATE" -eq 1 ]; then HOSTNAME="${HOSTNAME%%.*}" fi -fi - -# $1 = directory name -# $2 = remote server -copy_files() { - # -l = keep symlink / -D = special device - if [ -d "${1}" ] - then - LIST=$(mktemp /tmp/drist-rsync.XXXXXXXXXX) - if [ -f "$LIST" ] - then - printf 'Copying files from folder "%s":\n' "$1" - find "${1}"/ -type f -or -type l | cut -d '/' -f 2- | tee "${LIST}" | sed 's/^/ \//' - if [ "$SIMULATE" -ne 1 ] - then - rsync -e "ssh $SSH_PARAMS" --rsync-path="${EXEC} rsync" -lDp --files-from="${LIST}" "${1}/" "${2}":/ - fi - rm "$LIST" - fi - fi -} -# $1 = script filename -# $2 = remote server -remote_script() { - if [ -f "${1}" ] - then - printf 'Executing file "%s":\n' "$1" - if [ "$SIMULATE" -ne 1 ] - then - dr="$(mktemp ./drist.XXXXXXXXXXXX)" - ssh $SSH_PARAMS "${2}" "DRIST=${dr} && - cat - > \$DRIST && - chmod u+x \$DRIST && - ${EXEC} \$DRIST ; - rm \$DRIST" < "$1" - rm "$dr" - fi - fi -} + create_temp "${remote_server}" + copy_files "files" "${remote_server}" "$TEMPDIR" + copy_files "files-${HOSTNAME}" "${remote_server}" "$TEMPDIR" + remote_script "script" "${remote_server}" "$TEMPDIR" + remote_script "script-${HOSTNAME}" "${remote_server}" "$TEMPDIR" + delete_temp "${remote_server}" "$TEMPDIR" -# $1 = directory name -# $2 = remote server -delete_files() { - if [ -d "${1}" ] + # close socket if persistance is actived + if [ "$SSHONCE" -eq 1 ] then - LIST=$(mktemp /tmp/drist-rsync.XXXXXXXXXX) - if [ -f "$LIST" ] - then - printf 'Removing files from folder "%s":\n' "$1" - find "$1" -type f | sed 's/"/\\&/' | \ - awk -v path="${1}" '{ printf "\"%s\" ",substr($0,length(path)+1)}' | \ - tee "${LIST}" | sed 's/^/ /' - printf '\n' # add a new line - - if [ "$SIMULATE" -ne 1 ] - then - test -s "$LIST" && ssh $SSH_PARAMS "$2" "${EXEC} rm $(cat $LIST)" - fi - rm $LIST - fi + ssh $SSH_PARAMS -O exit -N "$1" fi -} - - -copy_files "files" "$1" -copy_files "files-${HOSTNAME}" "$1" -delete_files "absent" "$1" -delete_files "absent-${HOSTNAME}" "$1" -remote_script "script" "$1" -remote_script "script-${HOSTNAME}" "$1" -# close socket if persistance is actived -if [ "$SSHONCE" -eq 1 ] -then - ssh $SSH_PARAMS -O exit -N "$1" -fi + unset TEMPDIR HOSTNAME +done diff --git a/drist.1 b/drist.1 @@ -10,7 +10,7 @@ .Op Fl n .Op Fl d .Op Fl s Op Fl e Ar sudo|doas -.Ar server +.Ar server ... .Sh OPTIONS .Op Fl p to use persistent ssh connection, allowing to ssh only once @@ -59,41 +59,33 @@ by calling After that following steps will be executed: .Bl -enum -offset indent -compact .It -If folder +If directory .Ar files exists, its content is copied to .Ar server using -.Xr rsync 1 . +.Xr rsync 1 +in a temporary directory in ~/.drist_files_XXXXXXXX .It -If folder +If directory .Ar files- Ns Em HOSTNAME exists, its content is copied to .Ar server using -.Xr rsync 1 . -.It -If folder -.Ar absent -exists, filenames in it are deleted on -.Ar server . -.It -If folder -.Ar absent- Ns Em HOSTNAME -exists, filenames in it are deleted on -.Ar server . +.Xr rsync 1 +in a temporary directory in ~/.drist_files_XXXXXXXX . .It If file .Ar script exists, it is copied to .Ar server -and executed there. +and executed from the temporary directory. .It If file .Ar script- Ns Em HOSTNAME exists, it is copied to .Ar server -and executed there. +and executed from the temporary directory. .El .Pp The presence of each of those files or directories is optional. @@ -101,8 +93,6 @@ The presence of each of those files or directories is optional. All files in either .Ar files or -.Ar absent -or .Ar files- Ns Em HOSTNAME etc. are relative to the root (/) directory. The specific files for