| #!/bin/bash |
| # Copyright 2013 The Flutter Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| |
| ### Serves the out directory |
| ## usage: |
| ## --out <out_dir> Required. The out directory (ex: out/fuchsia_debug_x64). |
| ## -p <port> Optional. The port for "pm serve" to listen on. Defaults to 8084. |
| ## -d <device_name> Required for local workflows. The device_name to use for connecting. |
| ## -r Optional. Serve to a remote target. |
| ## --only-serve-runners Optional. Only serve the flutter and dart runners. |
| |
| #TODO: Take an out directory and use that to find the list of packages to publish |
| |
| source "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/lib/vars.sh || exit $? |
| |
| # We need to use the fuchsia checkout still, make sure it is there |
| ensure_fuchsia_dir |
| |
| out="" |
| port="8084" |
| component_framework_version=2 |
| device_name="" |
| remote=false |
| only_serve_runners=false |
| while (($#)); do |
| case "$1" in |
| --out) |
| out="$2" |
| shift |
| ;; |
| -c) |
| component_framework_version="$2" |
| # for `pm serve` `config.json` and if "2" (the default for this script) |
| # use `pkgctl add` (which is not supported on older instances of fuchsia) |
| # instead of `amberctl add_src`. |
| shift |
| ;; |
| -p) |
| port="$2" |
| shift |
| ;; |
| -d) |
| device_name="$2" |
| shift |
| ;; |
| -r) |
| remote=true |
| ;; |
| --only-serve-runners) |
| only_serve_runners=true |
| ;; |
| *) |
| echo 2>&1 "Unknown argument: \"${1}\" ignored" |
| ;; |
| esac |
| shift |
| done |
| |
| if [[ -z "${out}" ]]; then |
| engine-error "Must specify an out directory, such as out/fuchsia_debug_x64" |
| exit 1 |
| fi |
| |
| if [[ ${component_framework_version} != [12] ]]; then |
| engine-error "valid values for -c are 1 or 2" |
| exit 1 |
| fi |
| |
| fuchsia_build_dir="$(<"${FUCHSIA_DIR}/.fx-build-dir")" |
| if [[ "${fuchsia_build_dir:0:1}" != "/" ]]; then |
| fuchsia_build_dir="${FUCHSIA_DIR}/${fuchsia_build_dir}" |
| fi |
| |
| # If remote, there is currently no equivalent check, but perhaps there could be? |
| if [[ $remote != true ]]; then |
| # Warn if the package server for the fuchsia packages is not running. Test |
| # runners and any fuchsia package dependencies not included in the fuchsia |
| # system image (via `--with-base` instead of `--with`) typically require |
| # running `fx serve` (or equivalent commands), for the default `fuchsia.com` |
| # (`devhost`) package URL domain. |
| active_fuchsia_repo=$( |
| ps -eo args \ |
| | sed -nre \ |
| "s#.*\bpm .*\bserve\b.* -repo ($FUCHSIA_DIR/out/.*)/amber-files.*#\1#p" |
| ) |
| if [[ "${active_fuchsia_repo}" == "" ]]; then |
| engine-warning 'The default fuchsia package server may not be running.' |
| echo 'If your test requires packages or test runners from fuchsia, those' |
| echo 'packages will need to be bundled in the fuchsia system image (such as' |
| echo 'via `fx set ... --with-base <package_target> ...). If your test' |
| echo 'includes fuchsia package dependencies that need to be served, kill' |
| echo 'this flutter "engine" package server first, run `fx serve` (in' |
| echo 'another window or shell), and then re-run this `serve.sh` script.' |
| echo '(The launch order is important.)' |
| elif [[ "${active_fuchsia_repo}" != "${fuchsia_build_dir}" ]]; then |
| engine-warning 'There default fuchsia package server may be' |
| echo 'serving packages from the wrong build directory:' |
| echo " ${active_fuchsia_repo}" |
| echo 'which does not match your current build directory:' |
| echo " ${fuchsia_build_dir}" |
| echo 'It may be serving the wrong packages. If so, kill all package' |
| echo 'servers, and restart them. Make sure you start the fuchsia package' |
| echo 'server (for example, via `fx serve`) **before** starting this' |
| echo '`serve.sh` script' |
| fi |
| fi |
| |
| # Start our package server |
| # TODO: Need to ask for the out directory to find the package list |
| # TODO: Generate the all_packages.list file |
| cd "${FLUTTER_ENGINE_SRC_DIR}/${out}" || exit |
| |
| if ! [[ -d "${FLUTTER_ENGINE_SRC_DIR}/${out}/tuf" ]]; then |
| # Create the repository to serve |
| "${FLUTTER_ENGINE_FUCHSIA_SDK_DIR}/tools/pm" newrepo -vt \ |
| -repo "${FLUTTER_ENGINE_SRC_DIR}/${out}/tuf" |
| fi |
| |
| # Serve packages (run as a background process) |
| "${FLUTTER_ENGINE_FUCHSIA_SDK_DIR}/tools/pm" serve -vt \ |
| -repo "${FLUTTER_ENGINE_SRC_DIR}/${out}/tuf" \ |
| -l ":${port}" \ |
| -c "${component_framework_version}" \ |
| -p "${FLUTTER_ENGINE_SRC_DIR}/flutter/tools/fuchsia/all_packages.list" \ |
| & |
| serve_pid=$! |
| |
| # Add debug symbols to the symbol index. |
| "${FLUTTER_ENGINE_FUCHSIA_SDK_DIR}/tools/symbol-index" add \ |
| "${FLUTTER_ENGINE_SRC_DIR}/${out}/.build-id" \ |
| "${FLUTTER_ENGINE_SRC_DIR}/${out}" |
| |
| # Start our server and loop to check if our device is up give some slack time |
| # to ensure that pm has started |
| sleep 1 |
| |
| ffx="${FLUTTER_ENGINE_FUCHSIA_SDK_DIR}/tools/x64/ffx" |
| |
| serve_updates_target_addr="" |
| resolve_local_target() { |
| if [[ -z "${device_name}" ]]; then |
| engine-error "Must specify a device name with -d if using a local workflow" |
| exit 1 |
| fi |
| result=$("${ffx}" target list "${device_name}" --format a 2> /dev/null) |
| |
| if [[ $? == 0 ]]; then |
| serve_updates_target_addr=$result |
| fi |
| } |
| |
| resolve_target() { |
| if [[ $remote == true ]]; then |
| serve_updates_target_addr="-p 8022 ::1" |
| else |
| resolve_local_target |
| fi |
| } |
| |
| clear_target_addr() { |
| serve_updates_target_addr="" |
| } |
| |
| kill_child_processes() { |
| child_pids=$(jobs -p) |
| if [[ -n "${child_pids}" ]]; then |
| # Note: child_pids must be expanded to args here. |
| kill ${child_pids} 2> /dev/null |
| wait 2> /dev/null |
| fi |
| } |
| trap kill_child_processes EXIT |
| |
| run_ssh_command() { |
| # Enusre we have a target to ssh to |
| if [[ -z $serve_updates_target_addr ]]; then |
| return 1 |
| fi |
| |
| ssh_config="${fuchsia_build_dir}/ssh-keys/ssh_config" |
| if [[ ! -e $ssh_config ]]; then |
| engine-error "No valid ssh_config at $ssh_config" |
| fi |
| |
| if [[ $remote == true ]]; then |
| ssh -F "${ssh_config}" -p 8022 ::1 "$@" |
| else |
| ssh -F "${ssh_config}" "$serve_updates_target_addr" "$@" |
| fi |
| } |
| |
| if [[ $remote != true && -z "${device_name}" ]]; then |
| device_name="$(cat ${fuchsia_build_dir}.device)" |
| fi |
| |
| echo -n "Connecting to " |
| if $remote; then |
| echo -n "remote device via ssh tunnel on port 8022..." |
| else |
| echo -n "device '${device_name}', port ${port}..." |
| fi |
| # State is used to prevent too much output |
| state="discover" |
| while true; do |
| if ! kill -0 "${serve_pid}" 2> /dev/null; then |
| echo "Server died, exiting" |
| serve_pid= |
| exit 1 |
| fi |
| |
| if [[ "$state" == "discover" ]]; then |
| # While we're still trying to connect to the device, clear the target |
| # address state so we re-resolve. |
| clear_target_addr |
| resolve_target |
| run_ssh_command exit 2>/dev/null |
| ping_result=$? |
| else |
| run_ssh_command -O check > /dev/null 2>&1 |
| ping_result=$? |
| fi |
| |
| if [[ "$state" == "discover" && "$ping_result" == 0 ]]; then |
| echo |
| echo "Device up" |
| state="config" |
| fi |
| |
| if [[ "$state" == "config" ]]; then |
| echo "Registering engine as update source" |
| |
| # Get our ssh host address |
| addr=$(run_ssh_command 'echo $SSH_CONNECTION' | cut -d ' ' -f 1) |
| if [[ $? -ne 0 || -z "${addr}" ]]; then |
| engine-error "unable to determine host address as seen from the target. Is the target up?" |
| exit 1 |
| fi |
| |
| addr="$(echo "${addr}" | sed 's/%/%25/g')" |
| if [[ "${addr}" =~ : ]]; then |
| addr="[${addr}]" |
| fi |
| |
| config_url="http://${addr}:${port}/config.json" |
| |
| if [[ ${component_framework_version} == 2 ]]; then |
| run_ssh_command pkgctl repo add url \ |
| -n "engine" \ |
| "${config_url}" |
| else |
| run_ssh_command amberctl add_src \ |
| -n "engine" \ |
| -f "${config_url}" |
| fi |
| err=$? |
| |
| if [[ $err -ne 0 ]]; then |
| engine-error "Failed to add update source" |
| exit 1 |
| fi |
| |
| if [[ $only_serve_runners == true ]]; then |
| run_ssh_command "pkgctl rule replace json '$(cat <<EOF |
| { |
| "version": "1", |
| "content": [ |
| { |
| "host_match": "fuchsia.com", "host_replacement": "engine", |
| "path_prefix_match": "/flutter_jit_runner/", "path_prefix_replacement": "/flutter_jit_runner/" |
| }, |
| { |
| "host_match": "fuchsia.com", "host_replacement": "engine", |
| "path_prefix_match": "/flutter_jit_runner", "path_prefix_replacement": "/flutter_jit_runner" |
| }, |
| { |
| "host_match": "fuchsia.com", "host_replacement": "engine", |
| "path_prefix_match": "/flutter_aot_runner/", "path_prefix_replacement": "/flutter_aot_runner/" |
| }, |
| { |
| "host_match": "fuchsia.com", "host_replacement": "engine", |
| "path_prefix_match": "/flutter_aot_runner", "path_prefix_replacement": "/flutter_aot_runner" |
| }, |
| { |
| "host_match": "fuchsia.com", "host_replacement": "engine", |
| "path_prefix_match": "/dart_jit_runner/", "path_prefix_replacement": "/dart_jit_runner/" |
| }, |
| { |
| "host_match": "fuchsia.com", "host_replacement": "engine", |
| "path_prefix_match": "/dart_jit_runner", "path_prefix_replacement": "/dart_jit_runner" |
| }, |
| { |
| "host_match": "fuchsia.com", "host_replacement": "engine", |
| "path_prefix_match": "/dart_aot_runner/", "path_prefix_replacement": "/dart_aot_runner/" |
| }, |
| { |
| "host_match": "fuchsia.com", "host_replacement": "engine", |
| "path_prefix_match": "/dart_aot_runner", "path_prefix_replacement": "/dart_aot_runner" |
| }, |
| { |
| "host_match": "fuchsia.com", "host_replacement": "devhost", |
| "path_prefix_match": "/", "path_prefix_replacement": "/" |
| } |
| ] |
| } |
| EOF |
| )'" |
| |
| err=$? |
| if [[ $err -ne 0 ]]; then |
| engine-error "Failed to add runner rewrite rules" |
| exit 1 |
| fi |
| fi |
| |
| state="ready" |
| fi |
| |
| if [[ "$state" == "ready" ]]; then |
| if [[ "$ping_result" != 0 ]]; then |
| echo "Device lost" |
| state="discover" |
| else |
| sleep 1 |
| fi |
| else |
| sleep 1 |
| echo -n "." |
| fi |
| done |