blob: bc43ce555eb3c0b259ac5b5cd40c515f31e49e2b [file] [log] [blame]
# 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.
function package-server-mode {
# Next try to determine what server mode we should actually be using.
local mode=$(fx-command-run ffx config get repository.server.mode 2>/dev/null)
err=$?
if [[ "${err}" -ne 0 ]]; then
fx-error "Unable to get the configured repository server mode"
return "${err}"
fi
# If unspecified, default to using `pm`.
if [[ "${mode}" = "" || "${mode}" = "null" ]]; then
mode="pm"
else
# Regex: Remove the leading and trailing quotes from the server mode.
if [[ $mode =~ \"(.*)\" ]]; then
mode="${BASH_REMATCH[1]}"
else
fx-error "could not parse ffx server mode: ${mode}"
return 1
fi
fi
# Check that the server mode is known.
case "${mode}" in
"pm") echo pm ;;
"ffx") echo ffx ;;
*)
fx-error "Unknown repository server mode: ${mode}"
return 1
esac
return 0
}
# Determines if a package server can be started.
#
# This depends on our package server mode:
#
# * If we are using pm, return 0 if the specified port is available.
# * If we are using ffx, return 0 if ffx is configured to listen on the
# specified port.
function check-if-we-can-start-package-server {
local mode=$1
local expected_ip=$2
local expected_port=$3
# Checks if a pm package server process appears to be running.
if [[ -z "$(pgrep -f 'pm serve')" ]]; then
local is_pm_running=1 # 1 means that pm is not running
else
local is_pm_running=0 # 0 means that pm is running
fi
# Check that the server mode is known, and that we have the ability to use this server mode.
if [[ "${mode}" = "pm" ]]; then
# We can run if nothing is listening on our port.
if ! is-listening-on-port "${expected_port}"; then
return 0
fi
# Something is using the port. Try to determine if it's another pm server, or ffx.
if [[ "${is_pm_running}" -eq 0 ]]; then
fx-error "It looks like another \"fx serve-updates\" process may be running."
fx-error "It may be the ffx repository server. Try shutting it down with:"
fx-error ""
fx-error "$ ffx repository server stop"
fx-error ""
fx-error "Otherwise, try stopping that process, and re-run \"fx serve\"."
return 1
fi
configured_mode="$(package-server-mode)"
if [[ "${configured_mode}" == "ffx" ]]; then
fx-error "Even though we are trying to start a pm package server, it appears"
fx-error "we are configured to use the ffx repository server. Try shutting it"
fx-error "down with:"
fx-error ""
fx-error "$ ffx repository server stop"
fx-error "$ ffx config set repository.server.mode pm"
fx-error "$ fx serve"
return 1
else
# Check if the ffx package repository server is enabled. If so, shut it
# down if it's configured to use the port we're trying to use.
local ffx_enabled=$(ffx-repository-server-enabled)
local err=$?
if [[ "${err}" -eq 0 && "${ffx_enabled}" == "true" ]]; then
local ffx_port=$(ffx-repository-server-port)
err=$?
if [[ "${err}" -eq 0 && "${ffx_port}" == "${expected_port}" ]]; then
fx-warn "The ffx repository server may be running, and is configured"
fx-warn "to run on ${expected_port}. Trying to shut it down..."
fx-command-run ffx repository server stop
err=$?
if [[ "${err}" -ne 0 ]]; then
fx-warn "Failed to stop ffx repository server. Checking if the port"
fx-warn "freed up anyway."
fi
if ! is-listening-on-port "${expected_port}"; then
fx-info "ffx repository server shut down"
return 0
fi
fi
fi
fx-error "It looks like some process is listening on ${port}."
fx-error "You probably need to stop that and start a new one here with \"fx serve\""
fi
return 1
else
# Make sure ffx repository is configured to listen on this address.
ffx-repository-check-server-address "${expected_ip}" "${expected_port}"
local err=$?
if [[ "${err}" -ne 0 ]]; then
return 1
fi
# We can run if nothing is listening on our port.
if is-listening-on-port "${expected_port}"; then
local ffx_addr=$(ffx-repository-server-address)
fx-error "Another process is using port '${expected_port}', which"
fx-error "will block the ffx repository server from listening on ${ffx_addr}."
fx-error ""
fx-error "Try shutting down that process, and re-running \"fx serve\"."
return 1
fi
return 0
fi
}
function check-for-package-server {
local mode="$(package-server-mode)"
local err=$?
if [[ "${err}" -ne 0 ]]; then
return 1
fi
if [[ "${mode}" = "pm" ]]; then
# Make sure it is running.
if [[ -z "$(pgrep -f 'pm serve .*/amber-files')" ]]; then
fx-error "It looks like serve-updates is not running."
fx-error "You probably need to start \"fx serve\""
return 1
fi
# Warn if it is using the wrong repository.
if [[ -z "$(pgrep -f "pm serve .*${FUCHSIA_BUILD_DIR}/amber-files")" ]]; then
fx-warn "WARNING: It looks like serve-updates is running in a different workspace."
fx-warn "WARNING: You probably need to stop that one and start a new one here with \"fx serve\""
fi
# Warn if incremental is enabled for this shell, but the server is not auto publishing packages.
if is_feature_enabled "incremental"; then
# Regex terminates with a space to avoid matching the -persist option.
if [[ -z "$(pgrep -f "pm serve .*${FUCHSIA_BUILD_DIR}/amber-files .*-p ")" ]]; then
fx-warn "WARNING: Incremental build is enabled, but it looks like incremental build is disabled for serve-updates."
fx-warn "WARNING: You probably need to stop serve-updates, and restart it with incremental build enabled."
fx-warn "WARNING: You can enable incremental build in the shell running serve-updates with 'export FUCHSIA_DISABLED_incremental=0'"
fi
fi
else
local ffx_addr=$(ffx-repository-server-address)
local err=$?
if [[ "${err}" -ne 0 ]]; then
return $err
fi
if [[ -z "${ffx_addr}" ]]; then
fx-error "repository server is currently disabled. to re-enable, run:"
fx-error ""
fx-error "$ ffx config set repository.server.mode ffx"
fx-error "$ ffx config set repository.server.listen \"[::]:8083\""
fx-error "$ ffx doctor --restart-daemon"
return 1
fi
# Regex: zero or more characters, a colon, then at least one digit, matching
# the digits.
if [[ ${ffx_addr} =~ .*:([0-9]+) ]]; then
local ffx_port="${BASH_REMATCH[1]}"
else
fx-error "could not parse ip and port from ffx server address: $actual_addr"
return 1
fi
if ! is-listening-on-port "${ffx_port}"; then
fx-error "It looks like the ffx package server is not running."
fx-error "You probably need to run \"fx add-update-source\""
return 1
fi
# FIXME(http://fxbug.dev/80431): Check if the current `devhost` points at
# '${FUCHSIA_BUILD_DIR}/amber-files'.
fi
return 0
}
function is-listening-on-port {
local port=$1
if [[ "$(uname -s)" == "Darwin" ]]; then
if netstat -anp tcp | awk '{print $4}' | grep "\.${port}$" > /dev/null; then
return 0
fi
else
if ss -f inet -f inet6 -an | awk '{print $5}' | grep ":${port}$" > /dev/null; then
return 0
fi
fi
return 1
}
function ffx-default-repository-name {
# Use the build directory's name by default. Note that package URLs are not
# allowed to have underscores, so replace them with hyphens.
basename "${FUCHSIA_BUILD_DIR}" | tr '_' '-'
}
function ffx-start-server {
fx-command-run ffx repository server start
err=$?
if [[ "${err}" -ne 0 ]]; then
fx-error "The repository server was unable to be started"
return "${err}"
fi
return 0
}
function ffx-stop-server {
fx-command-run ffx repository server stop
err=$?
if [[ "${err}" -ne 0 ]]; then
fx-error "The repository server was unable to be stopped"
return "${err}"
fi
return 0
}
function ffx-add-repository {
local repo_name=$1
shift
if [[ -z "${repo_name}" ]]; then
fx-error "The repository name was not specified"
return 1
fi
fx-command-run ffx repository add-from-pm \
--repository "${repo_name}" \
"${FUCHSIA_BUILD_DIR}/amber-files"
err=$?
if [[ "${err}" -ne 0 ]]; then
fx-error "The repository was not able to be added to ffx"
return $err
fi
return 0
}
function ffx-register-repository {
local repo_name=$1
shift
ffx-add-repository "${repo_name}" || return $?
# Start the server before registering a repository. While `register`
# technically also automatically starts the server in the background, running
# it in the foreground gives us better error messages.
ffx-start-server || return $?
# FIXME(http://fxbug.dev/98589): ffx cannot yet parse targets that may
# include the ssh port. We'll explicitly specify the target here with
# `get-device-name`, which strips out the port if present.
fx-command-run ffx \
--target "$(get-device-name)" \
target repository register \
--repository "${repo_name}" \
--alias "fuchsia.com" \
--alias "chromium.org" \
"$@"
err=$?
if [[ "${err}" -ne 0 ]]; then
fx-error "The repository was unable to be added to the target device"
fx-error ""
fx-error "If you recently enabled the ffx server, you may need to restart"
fx-error "the ffx daemon with"
fx-error ""
fx-error "$ ffx doctor --restart-daemon"
return $err
fi
return 0
}
function ffx-repository-server-enabled {
local enabled=$(fx-command-run ffx config get repository.server.enabled)
err=$?
if [[ "${err}" -ne 0 ]]; then
fx-error "Unable to get the configured repository server enabled."
return "${err}"
fi
case "${enabled}" in
"true") echo true ;;
"false") echo false ;;
"null") echo false ;;
*)
fx-error "Unknown repository.server.enabled: ${enabled}"
return 1
esac
return 0
}
function ffx-repository-server-address {
local addr=$(fx-command-run ffx config get repository.server.listen)
err=$?
if [[ "${err}" -ne 0 ]]; then
fx-error "Unable to get the configured repository server address."
return "${err}"
fi
if [[ "${addr}" = "null" ]]; then
echo ""
else
# Regex: Remove the leading and trailing quotes from the address.
if [[ $addr =~ \"(.*)\" ]]; then
echo "${BASH_REMATCH[1]}"
else
fx-error "could not parse ffx server address: ${addr}"
return 1
fi
fi
return 0
}
function ffx-repository-server-port {
local addr=$(ffx-repository-server-address)
err=$?
if [[ "${err}" -ne 0 ]]; then
fx-error "Unable to get the configured repository server address."
return "${err}"
fi
if [[ ${addr} =~ .*:([0-9]+) ]]; then
echo "${BASH_REMATCH[1]}"
else
fx-error "could not parse port from ffx server address: $addr"
return 1
fi
return 0
}
function ffx-repository-check-server-address {
local expected_ip=$1
local expected_port=$2
local actual_addr=$(ffx-repository-server-address)
local err=$?
if [[ "${err}" -ne 0 ]]; then
return "${err}"
fi
if [[ -z "${actual_addr}" ]]; then
fx-error "repository server is currently disabled. to re-enable, run:"
fx-error ""
fx-error "$ ffx config set repository.server.listen \"[::]:8083\""
fx-error "$ ffx doctor --restart-daemon"
return 1
fi
if [[ $actual_addr =~ (.*):([0-9]+) ]]; then
local actual_ip="${BASH_REMATCH[1]}"
local actual_port="${BASH_REMATCH[2]}"
else
fx-error "could not parse ip and port from ffx server address: $actual_addr"
return 1
fi
if [[ -z "${expected_ip}" ]]; then
expected_ip="${actual_ip}"
elif [[ ${expected_ip} =~ : ]]; then
expected_ip="[${expected_ip}]"
fi
if [[ -z "${expected_port}" ]]; then
expected_port="${actual_port}"
fi
local expected_addr="${expected_ip}:${expected_port}"
if [[ "${expected_addr}" != "${actual_addr}" ]]; then
fx-error "The repository server is configured to use \"${actual_addr}\", not \"${expected_addr}\""
fx-error "To switch to a different address, run:"
fx-error ""
fx-error "$ ffx config set repository.server.listen \"${expected_addr}\""
fx-error "$ ffx doctor --restart-daemon"
fx-error ""
fx-error "Note: this will change the address for all repositories served by ffx"
return 1
fi
return 0
}
function default-repository-url {
local mode="$(package-server-mode)"
local err=$?
if [[ "${err}" -ne 0 ]]; then
return 1
fi
if [[ "${mode}" = "pm" ]]; then
echo "fuchsia-pkg://devhost"
else
local ffx_repo="$(ffx-default-repository-name)" || return $?
echo "fuchsia-pkg://${ffx_repo}"
fi
return 0
}