| #!/usr/bin/env 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. |
| |
| set -eo pipefail; [[ "${TRACE}" ]] && set -x |
| |
| readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| |
| readonly VERSION_FILE="${SCRIPT_DIR}/.cipd_version" |
| readonly CIPD_BACKEND="https://chrome-infra-packages.appspot.com" |
| |
| declare HOST_PLATFORM="$(uname -s | tr '[:upper:]' '[:lower:]')" |
| case "${HOST_PLATFORM}" in |
| linux) |
| readonly HOST_PLATFORM="linux" |
| ;; |
| darwin) |
| readonly HOST_PLATFORM="mac" |
| ;; |
| *) |
| echo "Unknown operating system." >&2 |
| exit 1 |
| esac |
| |
| HOST_ARCH="$(uname -m | tr '[:upper:]' '[:lower:]')" |
| case "${HOST_ARCH}" in |
| x86_64|amd64) |
| readonly HOST_ARCH="amd64" |
| ;; |
| arm*) |
| readonly HOST_ARCH="${HOST_ARCH}" |
| ;; |
| aarch64) |
| readonly HOST_ARCH="arm64" |
| ;; |
| *86) |
| readonly HOST_ARCH=386 |
| ;; |
| *) |
| echo "Unknown machine architecture." >&2 |
| exit 1 |
| esac |
| |
| readonly PLATFORM="${HOST_PLATFORM}-${HOST_ARCH}" |
| readonly VERSION="$(cat ${VERSION_FILE})" |
| readonly URL="${CIPD_BACKEND}/client?platform=${PLATFORM}&version=${VERSION}" |
| readonly CLIENT="${SCRIPT_DIR}/.cipd_client" |
| |
| readonly USER_AGENT="buildtools/$(git -C ${SCRIPT_DIR} rev-parse HEAD 2>/dev/null || echo "???")" |
| |
| function actual_sha256() { |
| if type shasum >/dev/null ; then |
| shasum -a 256 "$1" | cut -d' ' -f1 |
| else |
| echo "The \`shasum\` command is missing. Please use your package manager to install it." >&2 |
| return 1 |
| fi |
| } |
| |
| function expected_sha256() { |
| local line |
| while read -r line; do |
| if [[ "${line}" =~ ^([0-9a-z\-]+)[[:blank:]]+sha256[[:blank:]]+([0-9a-f]+)$ ]] ; then |
| local platform="${BASH_REMATCH[1]}" |
| local hash="${BASH_REMATCH[2]}" |
| if [[ "${platform}" == "$1" ]]; then |
| echo "${hash}" |
| return 0 |
| fi |
| fi |
| done < "${VERSION_FILE}.digests" |
| |
| echo "Platform $1 is not supported by the CIPD client bootstrap. There's no pinned hash for it in the *.digests file." >&2 |
| |
| return 1 |
| } |
| |
| # bootstraps the client from scratch using 'curl'. |
| function bootstrap() { |
| local expected_hash="$(expected_sha256 "${PLATFORM}")" |
| if [[ -z "${expected_hash}" ]] ; then |
| exit 1 |
| fi |
| |
| echo "Bootstrapping cipd client for ${HOST_PLATFORM}-${HOST_ARCH}..." |
| local CLIENT_TMP="$(mktemp -p "${SCRIPT_DIR}" 2>/dev/null || mktemp "${SCRIPT_DIR}/.cipd_client.XXXXXXX")" |
| if type curl >/dev/null ; then |
| curl -f --progress-bar "${URL}" -A "${USER_AGENT}" -L -o "${CLIENT_TMP}" |
| else |
| echo "The \`curl\` command is missing. Please use your package manager to install it." >&2 |
| exit 1 |
| fi |
| trap "rm -f '${CLIENT_TMP}'" EXIT ERR HUP INT TERM |
| |
| local actual_hash="$(actual_sha256 "${CLIENT_TMP}")" |
| if [[ -z "${actual_hash}" ]] ; then |
| exit 1 |
| fi |
| |
| if [[ "${actual_hash}" != "${expected_hash}" ]]; then |
| echo "SHA256 digest of the downloaded CIPD client is incorrect. Check that *.digests file is up-to-date." >&2 |
| exit 1 |
| fi |
| |
| chmod +x "${CLIENT_TMP}" |
| mv -f "${CLIENT_TMP}" "${CLIENT}" |
| trap - EXIT |
| } |
| |
| # self_update asks the existing client to update itself, if necessary. |
| function self_update() { |
| "${CLIENT}" selfupdate -version-file "${VERSION_FILE}" -service-url "${CIPD_BACKEND}" |
| } |
| |
| if [[ ! -x "${CLIENT}" ]]; then |
| bootstrap |
| fi |
| |
| export CIPD_HTTP_USER_AGENT_PREFIX="${USER_AGENT}" |
| if ! self_update ; then |
| echo "CIPD selfupdate failed. Trying to bootstrap the CIPD client from scratch..." >&2 |
| bootstrap |
| if ! self_update ; then # we need to run it again to setup .cipd_version file |
| echo "Bootstrap from scratch failed. Run \`CIPD_HTTP_USER_AGENT_PREFIX=${USER_AGENT}/manual ${CLIENT} selfupdate -version-file '${VERSION_FILE}'\` to diagnose if this is repeating." >&2 |
| fi |
| fi |
| |
| exec "${CLIENT}" "${@}" |