blob: 0f85f4e620fd0406d52ab67676d7ca494d5c24ee [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=Device management
### start a remote interactive shell in the target device
## usage: fx shell [-h|--help] [--check | [<ssh flags>] <command>]
##
## Creates an SSH connection with a device and executes a command.
##
## Arguments:
## -h|--help Print out this message.
## --check Diagnose SSH keys and show relevant information about SSH keys
## and the target device and exit.
## <ssh flags> Flags and command are passed to SSH as is. Consult SSH help
## for a list of available flags.
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/vars.sh || exit $?
check=false
case $1 in
--check)
check=true
shift
;;
-h | --help)
fx-command-help
exit 0
;;
esac
${FUCHSIA_DIR}/tools/ssh-keys/gen-ssh-keys.sh || exit $?
if $check; then
privkey="$(get-ssh-privkey)"
has_error=false
# private key doesn't exist, should not happen because of gen-ssh-keys.sh above
if [[ ! -f "${privkey}" ]]; then
fx-error "Unexpected error: Private key does not exist: ${privkey}"
exit 1
fi
pubkey="$(ssh-keygen -y -f "${privkey}")" || exit $?
# ignore stderr in case the authkeys file doesn't exist, as we will attempt
# to create it below.
authkeys="$(get-ssh-authkeys 2>/dev/null)"
# auth key doesn't exist
if [[ ! -f "${authkeys}" ]]; then
has_error=true
fx-warn "Authorized keys file does not exist, attempting to create it: ${authkeys}"
echo "${pubkey}" >"${authkeys}"
echo "ok, created ${authkeys}"
fi
if ! grep -q "$pubkey" "$authkeys"; then
has_error=true
fx-warn "Authorized keys file does not contain your Fuchsia public key, attempting to fix: ${authkeys}"
echo "${pubkey}" >>"${authkeys}"
echo "ok, fixed ${authkeys}"
fi
fx-config-read
conffile="${FUCHSIA_BUILD_DIR}/ssh-keys/ssh_config"
if [[ ! -f "${conffile}" ]] || ! grep -q "IdentityFile\s*$privkey" "$conffile"; then
has_error=true
fx-warn "ssh_config file doesn't exist or does not contain the correct private key, attempting to fix: ${conffile}"
fx build ssh-keys/ssh_config
if [[ $? -ne 0 || ! -f "${conffile}" ]] || ! grep -q "IdentityFile\s*$privkey" "$conffile"; then
fx-error "Unexpected error, cannot regenerate ssh_config: ${conffile}"
exit 1
fi
echo "ok, created ${conffile}"
fi
# ignore stderr in case ffx is not built yet
deviceaddr="$(get-fuchsia-device-addr 2>/dev/null)"
deviceport="$(get-fuchsia-device-port 2>/dev/null)"
echo "Device address: ${deviceaddr:-"unknown"}"
echo "Device SSH port: ${deviceport:-"default"}"
echo "SSH config: ${conffile}"
echo "SSH private key file: ${privkey}"
echo "SSH authorized keys file: ${authkeys}"
echo
if $has_error; then
fx-warn "Some issues were found and fixed. Please look above for more information"
else
echo "SSH configuration is in good shape, no issues detected"
fi
exit 0
fi
args=()
device_port="$(get-fuchsia-device-port)" || exit $?
if [[ -n "${device_port}" ]]; then
args+=("-p" "${device_port}")
fi
device_addr="$(get-fuchsia-device-addr)" || exit $?
if [[ -z "${device_addr}" ]]; then
device_name="$(get-device-name)" || exit $?
if [[ -n "${device_name}" ]]; then
fx-error "Cannot find the device '${device_name}'. If necessary, run 'fx unset-device' to allow device discovery."
else
fx-error "Cannot connect to a device, either no device or multiple devices are discoverable. Run 'fx list-devices' and if necessary run 'fx set-device'."
fi
exit 1
fi
args+=("${device_addr}")
args+=("$@")
# Note: I know there are people who don't like the host-key message, but DO NOT
# apply -q here, it silences error messages and makes network and configuration
# failures much harder to diagnose when helping people. The control master will
# mean you only get one per TCP socket, which is once per newly booted host.
# It's not a huge burden compared to end user support.
fx-command-exec ssh "${args[@]}"