chiark / gitweb /
Apply https://sourceware.org/git/?p=glibc.git;a=commit;h=d5dd6189d506068ed11c8bfa1e1e...
[eglibc.git] / scripts / cross-test-ssh.sh
1 #!/usr/bin/env bash
2 # usage: cross-test-ssh.sh [--ssh SSH] HOST COMMAND ...
3 # Run with --help flag to get more detailed help.
4
5 progname="$(basename $0)"
6 env_blacklist='HOME LOGNAME MAIL PATH SHELL SHLVL SSH_CLIENT SSH_CONNECTION USER TERM TERMCAP PWD'
7
8 usage="usage: ${progname} [--ssh SSH] HOST COMMAND ..."
9 help="Run an EGLIBC test COMMAND on the remote machine HOST, via ssh,
10 passing environment variables, preserving the current working directory,
11 and respecting quoting.
12
13 If the '--ssh SSH' flag is present, use SSH as the SSH command,
14 instead of ordinary 'ssh'.
15
16 To use this to run EGLIBC tests, invoke the tests as follows:
17
18   $ make cross-test-wrapper='ABSPATH/cross-test-ssh.sh HOST' tests
19
20 where ABSPATH is the absolute path to this script, and HOST is the
21 name of the machine to connect to via ssh.
22
23 If you need to connect to the test machine as a different user, you
24 may specify that just as you would to SSH:
25
26   $ make cross-test-wrapper='ABSPATH/cross-test-ssh.sh USER@HOST' tests
27
28 Naturally, the remote user must have an appropriate public key, and
29 you will want to ensure that SSH does not prompt interactively for a
30 password on each connection.
31
32 HOST and the build machines (on which 'make check' is being run) must
33 share a filesystem; all files needed by the tests must be visible at
34 the same paths on both machines.
35
36 ${progname} runs COMMAND in the same directory on the HOST that
37 ${progname} itself is run in on the build machine.
38
39 The command and arguments are passed to the remote host in a way that
40 avoids any further shell substitution or expansion, on the assumption
41 that the shell on the build machine has already done them
42 appropriately.
43
44 ${progname} propagates the values all environment variables through to
45 the remote target, except the following:
46 ${env_blacklist}"
47
48 ssh='ssh'
49 while true; do
50     case "$1" in
51
52         "--ssh")
53             shift; ssh="$1"
54             ;;
55
56         "--help")
57             echo "$usage"
58             echo "$help"
59             exit 0
60             ;;
61
62         *)
63             break
64             ;;
65     esac
66     shift
67 done
68
69 if [ $# -lt 1 ]; then
70     echo "$usage" >&2
71     echo "Type '${progname} --help' for more detailed help." >&2
72     exit 1
73 fi
74
75 host="$1"; shift
76
77 # Return all input as a properly quoted Bourne shell string.
78 bourne_quote () {
79     printf '%s' '"'
80     sed -n \
81         -e '1h' \
82         -e '2,$H' \
83         -e '${g
84               s/["$\`]/\\&/g
85               p
86              }'
87     printf '%s' '"'
88 }
89
90 # Remove unnecessary newlines from a Bourne shell command sequence.
91 remove_newlines () {
92     sed -n \
93         -e '1h' \
94         -e '2,$H' \
95         -e '${g
96               s/\([^\]\)\n/\1; /g
97               p
98              }'
99 }
100
101 # Unset all variables from the blacklist.  Then echo all exported
102 # variables.  This should be run in a subshell.  The 'export -p'
103 # command adds backslashes for environment variables which contain
104 # newlines.
105 blacklist_exports () {
106     local var
107     for var in ${env_blacklist}; do
108         unset $var
109     done
110     export -p
111 }
112
113 # Produce properly quoted Bourne shell arguments for 'env' to carry
114 # over the current environment, less blacklisted variables.
115 exports="$( (blacklist_exports) | sed -e 's|^declare -x |export |')"
116
117 # Transform the current argument list into a properly quoted Bourne shell
118 # command string.
119 command="$(for word in "$@"; do
120                printf '%s' "$word" | bourne_quote
121                printf '%s' ' '
122            done)"
123
124 # Add commands to set environment variables and the current directory.
125 command="${exports}
126 cd $PWD
127 ${command}"
128
129 # HOST's sshd simply concatenates its arguments with spaces and
130 # passes them to some shell.  We want to force the use of /bin/sh,
131 # so we need to re-quote the whole command to ensure it appears as
132 # the sole argument of the '-c' option.
133 $ssh "$host" /bin/sh -c "$(printf '%s\n' "${command}" | bourne_quote | remove_newlines)"