]>
Commit | Line | Data |
---|---|---|
df381762 JM |
1 | #! /bin/bash |
2 | # Run a testcase on a remote system, via ssh. | |
3 | # Copyright (C) 2012 Free Software Foundation, Inc. | |
4 | # This file is part of the GNU C Library. | |
5 | ||
6 | # The GNU C Library is free software; you can redistribute it and/or | |
7 | # modify it under the terms of the GNU Lesser General Public | |
8 | # License as published by the Free Software Foundation; either | |
9 | # version 2.1 of the License, or (at your option) any later version. | |
10 | ||
11 | # The GNU C Library is distributed in the hope that it will be useful, | |
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | # Lesser General Public License for more details. | |
15 | ||
16 | # You should have received a copy of the GNU Lesser General Public | |
17 | # License along with the GNU C Library; if not, see | |
18 | # <http://www.gnu.org/licenses/>. | |
19 | ||
20 | # usage: cross-test-ssh.sh [--ssh SSH] HOST COMMAND ... | |
21 | # Run with --help flag to get more detailed help. | |
22 | ||
23 | progname="$(basename $0)" | |
24 | env_blacklist='HOME LOGNAME MAIL PATH SHELL SHLVL SSH_CLIENT SSH_CONNECTION | |
25 | USER TERM TERMCAP PWD' | |
26 | ||
27 | usage="usage: ${progname} [--ssh SSH] HOST COMMAND ..." | |
28 | help="Run a glibc test COMMAND on the remote machine HOST, via ssh, | |
29 | passing environment variables, preserving the current working directory, | |
30 | and respecting quoting. | |
31 | ||
32 | If the '--ssh SSH' flag is present, use SSH as the SSH command, | |
33 | instead of ordinary 'ssh'. | |
34 | ||
35 | To use this to run glibc tests, invoke the tests as follows: | |
36 | ||
37 | $ make test-wrapper='ABSPATH/cross-test-ssh.sh HOST' tests | |
38 | ||
39 | where ABSPATH is the absolute path to this script, and HOST is the | |
40 | name of the machine to connect to via ssh. | |
41 | ||
42 | If you need to connect to the test machine as a different user, you | |
43 | may specify that just as you would to SSH: | |
44 | ||
45 | $ make test-wrapper='ABSPATH/cross-test-ssh.sh USER@HOST' tests | |
46 | ||
47 | Naturally, the remote user must have an appropriate public key, and | |
48 | you will want to ensure that SSH does not prompt interactively for a | |
49 | password on each connection. | |
50 | ||
51 | HOST and the build machines (on which 'make check' is being run) must | |
52 | share a filesystem; all files needed by the tests must be visible at | |
53 | the same paths on both machines. | |
54 | ||
55 | ${progname} runs COMMAND in the same directory on the HOST that | |
56 | ${progname} itself is run in on the build machine. | |
57 | ||
58 | The command and arguments are passed to the remote host in a way that | |
59 | avoids any further shell substitution or expansion, on the assumption | |
60 | that the shell on the build machine has already done them | |
61 | appropriately. | |
62 | ||
63 | ${progname} propagates the values all environment variables through to | |
64 | the remote target, except the following: | |
65 | ${env_blacklist}" | |
66 | ||
67 | ssh='ssh' | |
68 | while [ $# -gt 0 ]; do | |
69 | case "$1" in | |
70 | ||
71 | "--ssh") | |
72 | shift | |
73 | if [ $# -lt 1 ]; then | |
74 | break | |
75 | fi | |
76 | ssh="$1" | |
77 | ;; | |
78 | ||
79 | "--help") | |
80 | echo "$usage" | |
81 | echo "$help" | |
82 | exit 0 | |
83 | ;; | |
84 | ||
85 | *) | |
86 | break | |
87 | ;; | |
88 | esac | |
89 | shift | |
90 | done | |
91 | ||
92 | if [ $# -lt 1 ]; then | |
93 | echo "$usage" >&2 | |
94 | echo "Type '${progname} --help' for more detailed help." >&2 | |
95 | exit 1 | |
96 | fi | |
97 | ||
98 | host="$1"; shift | |
99 | ||
100 | # Print the sequence of arguments as strings properly quoted for the | |
101 | # Bourne shell, separated by spaces. | |
102 | bourne_quote () | |
103 | { | |
104 | local arg qarg | |
105 | for arg in "$@"; do | |
106 | qarg=${arg//\'/\'\\\'\'} | |
107 | echo -n "'$qarg' " | |
108 | done | |
109 | } | |
110 | ||
111 | # Remove unnecessary newlines from a Bourne shell command sequence. | |
112 | remove_newlines () | |
113 | { | |
114 | sed -n \ | |
115 | -e '1h' \ | |
116 | -e '2,$H' \ | |
117 | -e '${g | |
118 | s/\([^\]\)\n/\1; /g | |
119 | p | |
120 | }' | |
121 | } | |
122 | ||
123 | # Unset all variables from the blacklist. Then echo all exported | |
124 | # variables. The 'export -p' command adds backslashes for environment | |
125 | # variables which contain newlines. | |
126 | blacklist_exports () | |
127 | { | |
128 | (unset ${env_blacklist}; export -p) | remove_newlines | |
129 | } | |
130 | ||
131 | # Produce properly quoted Bourne shell arguments for 'env' to carry | |
132 | # over the current environment, less blacklisted variables. | |
133 | exports="$(blacklist_exports)" | |
134 | exports="${exports:+${exports}; }" | |
135 | ||
136 | # Transform the current argument list into a properly quoted Bourne shell | |
137 | # command string. | |
138 | command="$(bourne_quote "$@")" | |
139 | ||
140 | # Add commands to set environment variables and the current directory. | |
141 | command="${exports}cd $PWD; ${command}" | |
142 | ||
143 | # HOST's sshd simply concatenates its arguments with spaces and | |
144 | # passes them to some shell. We want to force the use of /bin/sh, | |
145 | # so we need to re-quote the whole command to ensure it appears as | |
146 | # the sole argument of the '-c' option. | |
147 | full_command="$(bourne_quote "${command}")" | |
148 | $ssh "$host" /bin/sh -c "$full_command" |