blob: b36385698310f51143803f95bec56cc9bd35086d [file] [log] [blame]
Ken Mixter689b9ee2010-01-07 18:23:52 -08001# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5# Library for setting up remote access and running remote commands.
6
Sean O'Connora6db82e2010-01-27 12:11:08 -08007DEFAULT_PRIVATE_KEY="${GCLIENT_ROOT}/src/scripts/mod_for_test_scripts/\
8ssh_keys/testing_rsa"
Ken Mixter689b9ee2010-01-07 18:23:52 -08009
10DEFINE_string remote "" "remote hostname/IP of running Chromium OS instance"
11DEFINE_string private_key "$DEFAULT_PRIVATE_KEY" \
12 "Private key of root account on remote host"
Zelidrag Hornung61d97682010-06-15 11:55:21 -070013DEFINE_integer ssh_port 22 \
14 "SSH port of the remote machine running Chromium OS instance"
Ken Mixter689b9ee2010-01-07 18:23:52 -080015
David Jamesf5850902011-09-30 10:51:48 -070016SSH_CONNECT_SETTINGS="-o Protocol=2 -o ConnectTimeout=30 \
17 -o ConnectionAttempts=4 -o ServerAliveInterval=10 \
18 -o ServerAliveCountMax=3 -o StrictHostKeyChecking=no"
19
Chris Sosaef964302010-04-27 13:21:08 -070020# Copies $1 to $2 on remote host
Ken Mixtercc4f1dd2010-08-31 12:07:11 -070021function remote_cp_to() {
David Jamesf5850902011-09-30 10:51:48 -070022 REMOTE_OUT=$(scp -P ${FLAGS_ssh_port} $SSH_CONNECT_SETTINGS \
23 -o UserKnownHostsFile=$TMP_KNOWN_HOSTS -i $TMP_PRIVATE_KEY $1 \
24 root@$FLAGS_remote:$2)
Chris Sosaef964302010-04-27 13:21:08 -070025 return ${PIPESTATUS[0]}
26}
27
Ken Mixtercc4f1dd2010-08-31 12:07:11 -070028# Copies a list of remote files specified in file $1 to local location
29# $2. Directory paths in $1 are collapsed into $2.
30function remote_rsync_from() {
David Jamesf5850902011-09-30 10:51:48 -070031 rsync -e "ssh -p ${FLAGS_ssh_port} $SSH_CONNECT_SETTINGS \
32 -o UserKnownHostsFile=$TMP_KNOWN_HOSTS -i $TMP_PRIVATE_KEY" \
Mandeep Singh Bainesaef91ad2011-01-14 14:17:25 -080033 --no-R --files-from=$1 root@${FLAGS_remote}:/ $2
Ken Mixtercc4f1dd2010-08-31 12:07:11 -070034}
35
Chris Sosafaeee5f2011-09-26 16:08:14 -070036function _verbose_remote_sh() {
David Jamesf5850902011-09-30 10:51:48 -070037 REMOTE_OUT=$(ssh -vp ${FLAGS_ssh_port} $SSH_CONNECT_SETTINGS \
38 -o UserKnownHostsFile=$TMP_KNOWN_HOSTS -i $TMP_PRIVATE_KEY \
39 root@$FLAGS_remote "$@")
Chris Sosafaeee5f2011-09-26 16:08:14 -070040 return ${PIPESTATUS[0]}
41}
42
43function _non_verbose_remote_sh() {
David Jamesf5850902011-09-30 10:51:48 -070044 REMOTE_OUT=$(ssh -p ${FLAGS_ssh_port} $SSH_CONNECT_SETTINGS \
45 -o UserKnownHostsFile=$TMP_KNOWN_HOSTS -i $TMP_PRIVATE_KEY \
46 root@$FLAGS_remote "$@")
Ken Mixter689b9ee2010-01-07 18:23:52 -080047 return ${PIPESTATUS[0]}
48}
49
Chris Sosafaeee5f2011-09-26 16:08:14 -070050# Wrapper for ssh that runs the commmand given by the args on the remote host
51# If an ssh error occurs, re-runs the ssh command with verbose flag set.
52function remote_sh() {
53 local ssh_status=0
54 _non_verbose_remote_sh "$@" || ssh_status=$?
55 # 255 indicates an ssh error.
56 if [ ${ssh_status} -eq 255 ]; then
57 _verbose_remote_sh "$@"
58 else
59 return ${ssh_status}
60 fi
61}
62
Andrew de los Reyese08639b2011-09-21 15:44:05 -070063function remote_sh_raw() {
David Jamesf5850902011-09-30 10:51:48 -070064 ssh -p ${FLAGS_ssh_port} $SSH_CONNECT_SETTINGS \
65 -o UserKnownHostsFile=$TMP_KNOWN_HOSTS -i $TMP_PRIVATE_KEY \
66 $EXTRA_REMOTE_SH_ARGS root@$FLAGS_remote "$@"
Andrew de los Reyese08639b2011-09-21 15:44:05 -070067 return $?
68}
69
Ken Mixter689b9ee2010-01-07 18:23:52 -080070function remote_sh_allow_changed_host_key() {
71 rm -f $TMP_KNOWN_HOSTS
72 remote_sh "$@"
73}
74
75function set_up_remote_access() {
Ken Mixter689b9ee2010-01-07 18:23:52 -080076 cp $FLAGS_private_key $TMP_PRIVATE_KEY
77 chmod 0400 $TMP_PRIVATE_KEY
Ken Mixter689b9ee2010-01-07 18:23:52 -080078
79 # Verify the client is reachable before continuing
Gaurav Shahaf7d5d12011-09-21 16:42:16 -070080 local output
81 local status=0
82 if output=$(remote_sh "true" 2>&1); then
83 :
84 else
85 status=$?
86 echo "Could not initiate first contact with remote host"
87 echo "$output"
88 fi
89 return $status
Ken Mixter689b9ee2010-01-07 18:23:52 -080090}
91
Ken Mixtercc4f1dd2010-08-31 12:07:11 -070092# Ask the target what board it is
93function learn_board() {
94 [ -n "${FLAGS_board}" ] && return
95 remote_sh grep CHROMEOS_RELEASE_BOARD /etc/lsb-release
96 FLAGS_board=$(echo "${REMOTE_OUT}" | cut -d '=' -f 2)
97 if [ -z "${FLAGS_board}" ]; then
98 error "Board required"
99 exit 1
100 fi
101 info "Target reports board is ${FLAGS_board}"
102}
103
Olof Johanssonf53fa0d2011-01-26 13:06:46 -0800104function learn_arch() {
105 [ -n "${FLAGS_arch}" ] && return
106 remote_sh uname -m
Mandeep Singh Baines175422f2011-05-31 10:51:02 -0700107 FLAGS_arch=$(echo "${REMOTE_OUT}" | sed -e s/armv7l/arm/ -e s/i686/x86/ )
Olof Johanssonf53fa0d2011-01-26 13:06:46 -0800108 if [ -z "${FLAGS_arch}" ]; then
109 error "Arch required"
110 exit 1
111 fi
112 info "Target reports arch is ${FLAGS_arch}"
113}
114
Chris Sosa24da49e2011-02-01 17:06:12 -0800115# Checks to see if pid $1 is running.
116function is_pid_running() {
117 ps -p ${1} 2>&1 > /dev/null
118}
Mandeep Singh Bainesa63cd2d2010-12-02 11:58:26 -0800119
Chris Sosa24da49e2011-02-01 17:06:12 -0800120# Wait function given an additional timeout argument.
121# $1 - pid to wait on.
122# $2 - timeout to wait for.
123function wait_with_timeout() {
124 local pid=$1
125 local timeout=$2
126 local -r TIMEOUT_INC=1
127 local current_timeout=0
128 while is_pid_running ${pid} && [ ${current_timeout} -lt ${timeout} ]; do
129 sleep ${TIMEOUT_INC}
130 current_timeout=$((current_timeout + TIMEOUT_INC))
131 done
132 ! is_pid_running ${pid}
133}
134
135# Checks to see if a machine has rebooted using the presence of a tmp file.
136function check_if_rebooted() {
137 local output_file="${TMP}/output"
Mandeep Singh Bainesa63cd2d2010-12-02 11:58:26 -0800138 while true; do
139 REMOTE_OUT=""
140 # This may fail while the machine is down so generate output and a
141 # boolean result to distinguish between down/timeout and real failure
142 ! remote_sh_allow_changed_host_key \
143 "echo 0; [ -e /tmp/awaiting_reboot ] && echo '1'; true"
144 echo "${REMOTE_OUT}" > "${output_file}"
145 if grep -q "0" "${output_file}"; then
146 if grep -q "1" "${output_file}"; then
147 info "Not yet rebooted"
Chris Sosa24da49e2011-02-01 17:06:12 -0800148 sleep .5
Mandeep Singh Bainesa63cd2d2010-12-02 11:58:26 -0800149 else
150 info "Rebooted and responding"
151 break
152 fi
153 fi
Chris Sosa24da49e2011-02-01 17:06:12 -0800154 done
155}
156
157function remote_reboot() {
158 info "Rebooting."
159 remote_sh "touch /tmp/awaiting_reboot; reboot"
160 while true; do
161 check_if_rebooted &
162 local pid=$!
163 wait_with_timeout ${pid} 30 && break
164 ! kill -9 ${pid} 2> /dev/null
Mandeep Singh Bainesa63cd2d2010-12-02 11:58:26 -0800165 done
166}
167
Mandeep Singh Bainesaef91ad2011-01-14 14:17:25 -0800168# Called by clients before exiting.
169# Part of the remote_access.sh interface but now empty.
Sean O'Connor9969ce92010-02-01 17:10:03 -0800170function cleanup_remote_access() {
Mandeep Singh Bainesaef91ad2011-01-14 14:17:25 -0800171 true
Sean O'Connor9969ce92010-02-01 17:10:03 -0800172}
173
Ken Mixter689b9ee2010-01-07 18:23:52 -0800174function remote_access_init() {
175 TMP_PRIVATE_KEY=$TMP/private_key
176 TMP_KNOWN_HOSTS=$TMP/known_hosts
177 if [ -z "$FLAGS_remote" ]; then
178 echo "Please specify --remote=<IP-or-hostname> of the Chromium OS instance"
179 exit 1
180 fi
181 set_up_remote_access
182}