#!/bin/bash
#########################################################################
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the version 3 of the GNU General Public License #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
# General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see . #
# #
# Written by and Copyright (C) Francois Fleuret #
# Contact for comments & bug reports #
#########################################################################
set -e
# set -o pipefail
######################################################################
function check_remote_is_defined () {
if [[ "${REMOTE_HOST}" ]] && [[ "${REMOTE_DIR}" ]]
then
return 0
else
echo "@XREMOTE_HOST should come first." >&2
exit 1
fi
}
function help () {
cat <
This script takes a script as argument and executes it remotely in a
temporary directory on a ssh-accessible server.
It parses the script first to find embedded arguments which defines
the hostname on which to run, the files to send, the files to get
back when the execution is over, and commands to execute before
running the executable remotely.
These arguments can appear multiple times, except the one that
specifies the remote host.
Example:
@XREMOTE_HOST: elk.fleuret.org
@XREMOTE_EXEC: python3
@XREMOTE_SEND: main.cf
@XREMOTE_GET: *.dat
@XREMOTE_PRE: ln -s /home/fleuret/data/pytorch ./data
If no argument is provided to @XREMOTE_HOST, the environment
variable $XREMOTE_HOST is used instead
Contact for comments.
EOF
return 0
}
function cleanup_remote_tmp () {
if [[ "${REMOTE_HOST}" ]] && [[ "${REMOTE_DIR}" ]]
then
echo "xremote: Clean up remote workdir."
ssh "${REMOTE_HOST}" "rm -rf \"${REMOTE_DIR}\""
fi
}
######################################################################
[[ -x "$1" ]] || (help && exit 1)
main="$(basename "$1")"
cd "$(dirname "$1")"
shift
trap cleanup_remote_tmp EXIT
######################################################################
while read line
do
if [[ "${line}" =~ '@XREMOTE' ]]
then
label=$(echo "${line}" | sed -e 's/^.*@XREMOTE_\([^:]*\):.*$/\1/')
value=$(echo "${line}" | sed -e 's/^.*@XREMOTE_[^:]*: *\(.*\)$/\1/')
case "${label}" in
EXEC)
check_remote_is_defined
[[ "${REMOTE_EXEC}" ]] && (exit "Remote executable already defined!" >&2 && exit 1)
REMOTE_EXEC="${value}"
;;
PRE)
check_remote_is_defined
echo "xremote: ${value}"
ssh < /dev/null "${REMOTE_HOST}" "cd \"${REMOTE_DIR}\" && ${value}"
;;
SEND)
check_remote_is_defined
echo "xremote: -- sending files --------------------------------------------"
tar ch ${value} | ssh "${REMOTE_HOST}" "cd \"${REMOTE_DIR}\" && tar mxv"
;;
HOST)
[[ "${REMOTE_DIR}" ]] && (exit "Remote host already defined!" >&2 && exit 1)
REMOTE_HOST="${value}"
[[ "${REMOTE_HOST}" ]] || REMOTE_HOST="${XREMOTE_HOST}"
[[ "${REMOTE_HOST}" ]] || (echo "xremote: No remote host specified." >&2 && exit 1)
REMOTE_DIR="$(ssh /dev/null c ${value}" | tar mxv
;;
esac
fi
done < "${main}"
set +f
echo "xremote: -- finished -------------------------------------------------"
######################################################################