blob: a898ba1b6995ecff47b9b8099ee9dd2cf5484665 [file] [log] [blame]
#!/bin/bash
# Copyright 2017 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#### CATEGORY=Other
### serve from a remote workstation
## usage: fx serve-remote [--no-serve] HOSTNAME [REMOTE-PATH]
##
## HOSTNAME the hostname of the workstation you want to serve from
## REMOTE-PATH defaults to ~/fuchsia. The path on the to FUCHSIA_DIR on the workstation.
##
## --no-serve only tunnel, do not start a package server
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/vars.sh || exit $?
fx-config-read
serve=true
verbose=false
host=""
dir=""
while [[ $# -ne 0 ]]; do
case "$1" in
--help|-h)
fx-command-help
exit 0
;;
--no-serve)
serve=false
;;
-v)
verbose=true
;;
-*)
fx-error "Unknown flag: $1"
fx-command-help
exit 1
;;
*)
if [[ -z "${host}" ]]; then
host="$1"
elif [[ -z "${dir}" ]]; then
dir="$1"
else
fx-error "unexpected argument: '$1'"
exit 1
fi
;;
esac
shift
done
if [[ -z "${host}" ]]; then
fx-error "HOSTNAME must be specified"
fx-command-help
exit 1
fi
if "${serve}"; then
if [[ -z "${dir}" ]]; then
if ssh "$host" ls \~/fuchsia/.jiri_root/bin/fx > /dev/null; then
dir="~/fuchsia"
else
fx-error "failed to find ~/fuchsia on $host, please specify REMOTE-DIR"
fx-command-help
exit 1
fi
fi
fi
target_addr=$(get-fuchsia-device-addr)
if [[ $? -ne 0 || -z "${target_addr}" ]]; then
fx-error "unable to discover device. Is the target up?"
exit 1
fi
echo "Using remote ${host}:${dir}"
echo "Using target device $(get-device-name)"
# Use a dedicated ControlPath so script can manage a connection seperately from the user's. We
# intentionally do not use %h/%p in the control path because there can only be one forwarding
# session at a time (due to the local forward of 8083).
ssh_base_args=(
"${host}"
-S "~/.ssh/control-fuchsia-fx-remote"
-o ControlMaster=auto
)
ssh_exit() {
ssh ${ssh_base_args[@]} -O exit > /dev/null 2>&1
}
# If there is already control master then exit it. We can't be sure its to the right host and it
# also could be stale.
ssh_exit
# When we exit the script, close the background ssh connection.
trap_exit() {
ssh_exit
exit
}
trap trap_exit EXIT
ssh_tunnel_args=(
-6 # We want ipv6 binds for the port forwards
-L "\*:8083:localhost:8083" # fx serve
-R "8022:[${target_addr}]:22" # fx shell
-R "2345:[${target_addr}]:2345" # fx debug
-R "8007:[${target_addr}]:8007" # Google-specific
-R "8443:[${target_addr}]:8443" # Google-specific
-R "9080:[${target_addr}]:80" # SL4F_HTTP_PORT
-o ExitOnForwardFailure=yes
# Match google default server timeout so in spotty network situations the client doesn't timeout
# before server (and leave the server process still holding on to tunneling port).
-o ServerAliveInterval=30
-o ServerAliveCountMax=20
)
# Start tunneling session in background. It's started seperately from the command invocations below
# to allow the script to be consistent on how it is exited for both serve and non-serve cases. It
# also allows script to explicitly close the control session (to better avoid stale sshd sessions).
# Use `&` in addition to `-f` so so ssh doesn't receive script's SIGINT. And then `wait` to ensure
# tunnels are established before continuing.
ssh ${ssh_base_args[@]} ${ssh_tunnel_args[@]} -nNTf &
wait $!
# If the user requested serving, then we'll check to see if there's a
# remote server already running and kill it, this prevents most cases where
# signal propagation seems to sometimes not make it to "pm".
# TODO(drees) This can be combined with the serve-updates call later to reduce ssh calls.
if "${serve}" && ssh ${ssh_base_args[@]} 'ss -ln | grep :8083' > /dev/null; then
ssh "${ssh_base_args[@]}" 'pkill -x -u $USER pm'
fi
if "${serve}"; then
# Ctrl-C will exit the ssh remote command and this ssh session. Then script exit will trigger
# `trap_exit` to close the ssh connection.
echo -e "Press Ctrl-C to stop remote serving and tunneling.\n"
if "${verbose}"; then
serve_verbose_arg=" -v"
else
serve_verbose_arg=""
fi
ssh_serve_args=(
"-tt" # explicitly force a pty, for HUP'ing on the remote
"cd ${dir} && ./.jiri_root/bin/fx set-device '[::1]:8022' && ./.jiri_root/bin/fx serve-updates${serve_verbose_arg}"
)
ssh ${ssh_base_args[@]} ${ssh_serve_args[@]}
else
echo "Press Ctrl-C to stop tunneling."
# Wait for user Ctrl-C. Then script exit will trigger trap_exit to close the ssh connection.
read -r -d '' _ </dev/tty
fi