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:
M | drist | | | 165 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
M | drist.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