summaryrefslogtreecommitdiff
path: root/remote-exec.sh
blob: 4e4d06b22de7935372ed0efb4f0bd812a948b3a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/env bash
set -eu
set -o pipefail
[[ ${DEBUG:-} != true ]] || set -x

function error() { echo "ERROR: $1" >&2 ; exit 1; }
function info() { echo "INFO: $1"; }
function q1() { printf "%q" "$1"; }
function q() { local sep=""; [[ $# -gt 0 ]] || return; for i in "$@"; do printf "%s%q" "$sep" "$i"; sep=" "; done; }

function cleanup()
{
    local code=$?
    trap - INT TERM QUIT EXIT
    [[ -z ${tmpdir:-} ]] || rm -rf $tmpdir
    [[ -z ${remote_tmpdir:-} ]] || $SSH $HOSTNAME -- rm -rf $remote_tmpdir </dev/null
    [[ -z ${remote_msg:-} ]] || rm -f $remote_msg
    exit $code
}

HOSTNAME="${1:-}"
[[ -n $HOSTNAME ]] || error "missing hostname argument"
HOSTNAME=$HOSTNAME
shift

trap cleanup INT TERM QUIT EXIT

SSH_OPTS="-oConnectTimeout=30 -oConnectionAttempts=10 -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oLogLevel=ERROR -oBatchMode=yes -oControlPath=none"

# Allow overriding timeout value externally. Setting TIMEOUT to "0"
# disables the use of timeout. Default value: 3m.
if [ ${TIMEOUT:=3m} != 0 ]; then
    T_OUT="timeout $TIMEOUT"
else
    T_OUT=""
fi
SSH="$T_OUT ssh $SSH_OPTS"
SCP="$T_OUT scp $SSH_OPTS"

info ""
info "===================================================================="
info "Execute remotely on host: $HOSTNAME: $(q "$@")"
info "===================================================================="
tmpdir=$(mktemp -d)
find . -mindepth 1 -maxdepth 1 -type f -exec cp -a {} $tmpdir/ \;

# Debug traces
#uname -a
#ls $HOME/.ssh
#cat $HOME/.ssh/config
#ssh-add -l
#$SSH $HOSTNAME -- true

# Check that the remote host is accessible
remote_ok=false
remote_msg=$(mktemp)

# Wait until it has booted
while ! $remote_ok
do
    $SSH $HOSTNAME -- true >& $remote_msg || break
    grep "System is booting up. See pam_nologin" $remote_msg || remote_ok=true
    [ $remote_ok ] && break
    sleep 30
done

if ! $remote_ok; then
    error "SSH connexion to $HOSTNAME failed."
fi

remote_tmpdir=$($SSH $HOSTNAME -- mktemp -d </dev/null) || error "Connexion to $HOSTNAME failed (error code: $?)."
$SCP -pr $tmpdir/* $HOSTNAME:$remote_tmpdir/ || error "Failed to copy files to $HOSTNAME (error code: $?)."
result=0
$SSH $HOSTNAME -- bash -c "\"cd $remote_tmpdir && $(q "$@")\"" </dev/null || result=$?

if [ $result -eq 255 ]; then
    error "SSH connexion to $HOSTNAME failed."
fi

exit $result