blob: 57d1652dd97054779ffaba86dda92d7316046f96 [file] [log] [blame]
#!/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}" "${@}"