blob: 01440ad1171afad36ca4914598a4fb8ebd92ded1 [file] [log] [blame]
#!/bin/bash
# Copyright 2019 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.
# Enable error checking for all commands
err_print() {
echo "Error at $1"
stty sane
}
trap 'err_print $0:$LINENO' ERR
set -eu
SCRIPT_SRC_DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)"
# shellcheck disable=SC1090
source "${SCRIPT_SRC_DIR}/fuchsia-common.sh" || exit $?
# Note: DEFAULT_EMULATOR_NAME is defined in fuchsia-common.sh
VER_AEMU="$(cat "${SCRIPT_SRC_DIR}/aemu.version")"
VER_GRPCWEBPROXY="$(cat "${SCRIPT_SRC_DIR}/grpcwebproxy.version")"
ENABLE_GRPCWEBPROXY=0
PREBUILT_GRPCWEBPROXY_DIR=""
# Default architecture is x64, if the system image is arm64 then
# it requires --experiment-arm64 since there is no auto detection.
FUCHSIA_ARCH="x64"
readonly FUCHSIA_IMAGE_WORK_DIR="$(get-fuchsia-sdk-data-dir)"
readonly IMAGE_DIR="${FUCHSIA_IMAGE_WORK_DIR}/image"
readonly TOOL_DIR="$(get-fuchsia-sdk-tools-dir)"
readonly DEFAULT_FUCHSIA_IMAGE="qemu-x64"
readonly DEFAULT_FUCHSIA_AUTHKEYS="$(get-fuchsia-auth-keys-file)"
readonly ZIRCONA_NAME="zircon-a.zbi"
readonly QEMU_KERNEL_NAME="qemu-kernel.kernel"
readonly FVM_NAME="storage-full.blk"
# Download a URL $1 from CIPD, extract into directory $2
function download-extract-cipd {
CIPD_URL="${1}"
CIPD_DIR="${2}"
CIPD_FILE="${2}.zip"
if [ ! -f "${CIPD_FILE}" ]; then
echo "Downloading from ${CIPD_URL} ..."
curl -L "${CIPD_URL}" -o "${CIPD_FILE}" -#
echo "Verifying download ${CIPD_FILE}"
# CIPD will return a file containing "no such ref" if the URL is invalid, so need to check the ZIP file
if ! unzip -qq -t "${CIPD_FILE}" &> /dev/null; then
rm -f "${CIPD_FILE}"
fx-error "Downloaded archive from ${CIPD_URL} failed with invalid data - the version is probably invalid"
exit 1
fi
echo "Download complete."
fi
if [ ! -d "${CIPD_DIR}" ]; then
echo -e "Extracting archive to ${CIPD_DIR} ..."
rm -rf "${CIPD_DIR}" "${CIPD_DIR}-temp"
unzip -q "${CIPD_FILE}" -d "${CIPD_DIR}-temp"
mv "${CIPD_DIR}-temp" "${CIPD_DIR}"
echo "Extract complete."
else
echo "Using existing archive in ${CIPD_DIR}"
fi
}
emu_help () {
# Extract command-line argument help from emu script, similar to fx-print-command-help
sed -n -e 's/^## //p' -e 's/^##$//p' "${SCRIPT_SRC_DIR}/devshell/emu" | grep -v "usage: fx emu"
}
usage () {
echo "Usage: $(basename "$0")"
echo " [--work-dir <directory to store image assets>]"
echo " Defaults to ${FUCHSIA_IMAGE_WORK_DIR}"
echo " [--bucket <fuchsia gsutil bucket>]"
echo " Default is read using \`fconfig get ${DEFAULT_EMULATOR_NAME}.bucket\` if set. Otherwise defaults to ${DEFAULT_FUCHSIA_BUCKET}".
echo " [--image <image name>]"
echo " Default is read using \`fconfig get ${DEFAULT_EMULATOR_NAME}.image\` if set. Otherwise defaults to ${DEFAULT_FUCHSIA_IMAGE}".
echo " [--authorized-keys <file>]"
echo " The authorized public key file for securing the device. Defaults to"
echo " ${DEFAULT_FUCHSIA_AUTHKEYS}, which is generated if needed."
echo " [--version <version>]"
echo " Specify the CIPD version of AEMU to download."
echo " Defaults to aemu.version file with ${VER_AEMU}"
echo " [--experiment-arm64]"
echo " Override FUCHSIA_ARCH to arm64, instead of the default x64."
echo " This is required for *-arm64 system images, and is not auto detected."
echo " [--setup-ufw]"
echo " Set up ufw firewall rules needed for Fuchsia device discovery"
echo " and package serving, then exit. Only works on Linux with ufw"
echo " firewall, and requires sudo."
echo " [--help] [-h]"
echo " Show command line options for femu.sh and emu subscript"
echo
echo "Remaining arguments are passed to emu wrapper and emulator:"
emu_help
echo
echo "Invalid argument names are not flagged as errors, and are passed on to emulator"
}
AUTH_KEYS_FILE=""
FUCHSIA_BUCKET=""
IMAGE_NAME=""
EMU_ARGS=()
# Parse command line
while (( "$#" )); do
case $1 in
--work-dir)
shift
FUCHSIA_IMAGE_WORK_DIR="${1:-.}"
;;
--bucket)
shift
FUCHSIA_BUCKET="${1}"
;;
--image)
shift
IMAGE_NAME="${1}"
;;
--authorized-keys)
shift
AUTH_KEYS_FILE="${1}"
;;
--version)
shift
VER_AEMU="${1}"
;;
--setup-ufw)
set -xv
if is-mac; then
fx-error "--setup-ufw is only supported on Linux with ufw firewall"
exit 1
fi
# This should be the same as //tools/devshell/setup-ufw
sudo ufw allow proto udp from fe80::/10 to any port 33331:33340 comment 'Fuchsia Netboot Protocol'
sudo ufw allow proto tcp from fe80::/10 to any port 8083 comment 'Fuchsia Package Server'
sudo ufw allow proto udp from fe80::/10 port 33340 comment 'Fuchsia Netboot TFTP Source Port'
sudo ufw allow proto udp from fe80::/10 port 5353 comment 'Fuchsia MDNS'
sudo ufw allow proto udp from fc00::/7 to any port 33331:33340 comment 'Fuchsia Netboot Protocol'
sudo ufw allow proto tcp from fc00::/7 to any port 8083 comment 'Fuchsia Package Server'
sudo ufw allow proto udp from fc00::/7 port 33340 comment 'Fuchsia Netboot TFTP Source Port'
sudo ufw allow proto udp from fc00::/7 port 5353 comment 'Fuchsia MDNS'
set +xv
exit 0
;;
--help|-h)
usage
exit 0
;;
-x)
shift
ENABLE_GRPCWEBPROXY=1
EMU_ARGS+=( -x "$1" )
;;
-X)
shift
PREBUILT_GRPCWEBPROXY_DIR="$1"
;;
--experiment-arm64)
FUCHSIA_ARCH="arm64"
EMU_ARGS+=( "$1" )
;;
*)
# Unknown options are passed to emu
EMU_ARGS+=( "$1" )
;;
esac
shift
done
if [[ "${AUTH_KEYS_FILE}" != "" ]]; then
auth_keys_file="${AUTH_KEYS_FILE}"
else
auth_keys_file="${DEFAULT_FUCHSIA_AUTHKEYS}"
fi
if [[ "${FUCHSIA_BUCKET}" == "" ]]; then
FUCHSIA_BUCKET="$(get-fuchsia-property "${DEFAULT_EMULATOR_NAME}.bucket")"
if [[ "${FUCHSIA_BUCKET}" == "" ]]; then
FUCHSIA_BUCKET="${DEFAULT_FUCHSIA_BUCKET}"
fi
fi
if [[ "${IMAGE_NAME}" == "" ]]; then
IMAGE_NAME="$(get-fuchsia-property "${DEFAULT_EMULATOR_NAME}.image")"
if [[ "${IMAGE_NAME}" == "" ]]; then
IMAGE_NAME="${DEFAULT_FUCHSIA_IMAGE}"
fi
fi
# Download the system images and packages
echo "Checking for system image and packages for image ${IMAGE_NAME} and SDK version $(get-sdk-version)"
"${SCRIPT_SRC_DIR}/fpave.sh" --prepare --image "${IMAGE_NAME}" --bucket "${FUCHSIA_BUCKET}" --work-dir "${FUCHSIA_IMAGE_WORK_DIR}"
"${SCRIPT_SRC_DIR}/fserve.sh" --prepare --image "${IMAGE_NAME}" --bucket "${FUCHSIA_BUCKET}" --work-dir "${FUCHSIA_IMAGE_WORK_DIR}"
# Do not create directory names with : otherwise LD_PRELOAD usage in aemu will fail.
# Avoid / to prevent extra sub-directories being created.
LABEL_AEMU="$(echo "${VER_AEMU}" | tr ':/' '_')"
LABEL_GRPCWEBPROXY="$(echo "${VER_GRPCWEBPROXY}" | tr ':/' '_')"
# Download CIPD prebuilt binaries if not already present
DOWNLOADS_DIR="${FUCHSIA_IMAGE_WORK_DIR}/emulator"
mkdir -p "${DOWNLOADS_DIR}"
if is-mac; then
ARCH="mac-amd64"
else
ARCH="linux-amd64"
fi
readonly PREBUILT_AEMU_DIR="${DOWNLOADS_DIR}/aemu-${ARCH}-${LABEL_AEMU}"
download-extract-cipd \
"https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/aemu/${ARCH}/+/${VER_AEMU}" \
"${PREBUILT_AEMU_DIR}"
if (( ENABLE_GRPCWEBPROXY )); then
if [[ -z "$PREBUILT_GRPCWEBPROXY_DIR" ]]; then
PREBUILT_GRPCWEBPROXY_DIR="${DOWNLOADS_DIR}/grpcwebproxy-${ARCH}-${LABEL_GRPCWEBPROXY}"
download-extract-cipd \
"https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/grpcwebproxy/${ARCH}/+/${VER_GRPCWEBPROXY}" \
"${PREBUILT_GRPCWEBPROXY_DIR}"
fi
EMU_ARGS+=( "-X" "${PREBUILT_GRPCWEBPROXY_DIR}" )
fi
cmd=(
"${SCRIPT_SRC_DIR}/devshell/emu"
-e "${PREBUILT_AEMU_DIR}"
-A "${FUCHSIA_ARCH}"
-K "${IMAGE_DIR}/${QEMU_KERNEL_NAME}"
-z "${IMAGE_DIR}/${ZIRCONA_NAME}"
-f "${IMAGE_DIR}/${FVM_NAME}"
-k "${auth_keys_file}"
-Z "${TOOL_DIR}/zbi"
-F "${TOOL_DIR}/fvm"
)
if (( "${#EMU_ARGS[@]}" )) ; then
cmd+=("${EMU_ARGS[@]}")
fi
exec "${cmd[@]}"