1#!/bin/bash 2# Run a testcase on a remote system, via ssh. 3# Copyright (C) 2012-2022 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# <https://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 23progname="$(basename $0)" 24 25usage="usage: ${progname} [--ssh SSH] [--allow-time-setting] HOST COMMAND ..." 26help="Run a glibc test COMMAND on the remote machine HOST, via ssh, 27preserving the current working directory, and respecting quoting. 28 29If the '--ssh SSH' flag is present, use SSH as the SSH command, 30instead of ordinary 'ssh'. 31 32If the '--timeoutfactor FACTOR' flag is present, set TIMEOUTFACTOR on 33the remote machine to the specified FACTOR. 34 35If the '--allow-time-setting' flag is present, set 36GLIBC_TEST_ALLOW_TIME_SETTING on the remote machine to indicate that 37time can be safely adjusted (e.g. on a virtual machine). 38 39To use this to run glibc tests, invoke the tests as follows: 40 41 $ make test-wrapper='ABSPATH/cross-test-ssh.sh HOST' tests 42 43where ABSPATH is the absolute path to this script, and HOST is the 44name of the machine to connect to via ssh. 45 46If you need to connect to the test machine as a different user, you 47may specify that just as you would to SSH: 48 49 $ make test-wrapper='ABSPATH/cross-test-ssh.sh USER@HOST' tests 50 51Naturally, the remote user must have an appropriate public key, and 52you will want to ensure that SSH does not prompt interactively for a 53password on each connection. 54 55HOST and the build machines (on which 'make check' is being run) must 56share a filesystem; all files needed by the tests must be visible at 57the same paths on both machines. 58 59${progname} runs COMMAND in the same directory on the HOST that 60${progname} itself is run in on the build machine. 61 62The command and arguments are passed to the remote host in a way that 63avoids any further shell substitution or expansion, on the assumption 64that the shell on the build machine has already done them 65appropriately." 66 67ssh='ssh' 68timeoutfactor=$TIMEOUTFACTOR 69while [ $# -gt 0 ]; do 70 case "$1" in 71 72 "--ssh") 73 shift 74 if [ $# -lt 1 ]; then 75 break 76 fi 77 ssh="$1" 78 ;; 79 80 "--timeoutfactor") 81 shift 82 if [ $# -lt 1 ]; then 83 break 84 fi 85 timeoutfactor="$1" 86 ;; 87 88 "--allow-time-setting") 89 settimeallowed="1" 90 ;; 91 92 "--help") 93 echo "$usage" 94 echo "$help" 95 exit 0 96 ;; 97 98 *) 99 break 100 ;; 101 esac 102 shift 103done 104 105if [ $# -lt 1 ]; then 106 echo "$usage" >&2 107 echo "Type '${progname} --help' for more detailed help." >&2 108 exit 1 109fi 110 111host="$1"; shift 112 113# Print the sequence of arguments as strings properly quoted for the 114# Bourne shell, separated by spaces. 115bourne_quote () 116{ 117 local arg qarg 118 for arg in "$@"; do 119 qarg=${arg//\'/\'\\\'\'} 120 echo -n "'$qarg' " 121 done 122} 123 124# Transform the current argument list into a properly quoted Bourne shell 125# command string. 126command="$(bourne_quote "$@")" 127 128# Add command to set the current directory. 129command="cd $(bourne_quote "$PWD") 130${command}" 131 132# Add command to set the timeout factor, if required. 133if [ "$timeoutfactor" ]; then 134 command="export TIMEOUTFACTOR=$(bourne_quote "$timeoutfactor") 135${command}" 136fi 137 138# Add command to set the info that time on target can be adjusted, 139# if required. 140# Serialize execution of this script on target to prevent from unintended 141# change of target time. 142FLOCK_PATH="${FLOCK_PATH:-/var/lock/clock_settime}" 143FLOCK_TIMEOUT="${FLOCK_TIMEOUT:-20}" 144FLOCK_FD="${FLOCK_FD:-99}" 145if [ "$settimeallowed" ]; then 146 command="exec ${FLOCK_FD}<>${FLOCK_PATH} 147flock -w ${FLOCK_TIMEOUT} ${FLOCK_FD} 148if [ $? -ne 0 ]; then exit 1; fi 149export GLIBC_TEST_ALLOW_TIME_SETTING=1 150${command}" 151fi 152 153# HOST's sshd simply concatenates its arguments with spaces and 154# passes them to some shell. We want to force the use of /bin/sh, 155# so we need to re-quote the whole command to ensure it appears as 156# the sole argument of the '-c' option. 157full_command="$(bourne_quote "${command}")" 158$ssh "$host" /bin/sh -c "$full_command" 159