|
@@ -6,34 +6,31 @@
|
|
|
|
|
|
set -e -o pipefail
|
|
set -e -o pipefail
|
|
|
|
|
|
-CYGWIN=false
|
|
|
|
MYPATH=$(dirname "${BASH_SOURCE[0]}")
|
|
MYPATH=$(dirname "${BASH_SOURCE[0]}")
|
|
-
|
|
|
|
-: ${CIPD_CLIENT_VER:=`cat $MYPATH/cipd_client_version`}
|
|
|
|
-: ${CIPD_CLIENT_SRV:='https://chrome-infra-packages.appspot.com'}
|
|
|
|
|
|
+CYGWIN=false
|
|
|
|
|
|
UNAME=`uname -s | tr '[:upper:]' '[:lower:]'`
|
|
UNAME=`uname -s | tr '[:upper:]' '[:lower:]'`
|
|
-case $UNAME in
|
|
|
|
|
|
+case "${UNAME}" in
|
|
linux)
|
|
linux)
|
|
- PLAT=linux
|
|
|
|
|
|
+ OS=linux
|
|
;;
|
|
;;
|
|
cygwin*)
|
|
cygwin*)
|
|
- PLAT=windows
|
|
|
|
|
|
+ OS=windows
|
|
CYGWIN=true
|
|
CYGWIN=true
|
|
;;
|
|
;;
|
|
msys*|mingw*)
|
|
msys*|mingw*)
|
|
- PLAT=windows
|
|
|
|
|
|
+ OS=windows
|
|
;;
|
|
;;
|
|
darwin)
|
|
darwin)
|
|
- PLAT=mac
|
|
|
|
|
|
+ OS=mac
|
|
;;
|
|
;;
|
|
*)
|
|
*)
|
|
- echo "cipd not supported on $UNAME"
|
|
|
|
|
|
+ >&2 echo "CIPD not supported on ${UNAME}"
|
|
exit 1
|
|
exit 1
|
|
esac
|
|
esac
|
|
|
|
|
|
UNAME=`uname -m | tr '[:upper:]' '[:lower:]'`
|
|
UNAME=`uname -m | tr '[:upper:]' '[:lower:]'`
|
|
-case $UNAME in
|
|
|
|
|
|
+case "${UNAME}" in
|
|
x86_64|amd64)
|
|
x86_64|amd64)
|
|
ARCH=amd64
|
|
ARCH=amd64
|
|
;;
|
|
;;
|
|
@@ -53,89 +50,185 @@ case $UNAME in
|
|
ARCH=armv6l
|
|
ARCH=armv6l
|
|
;;
|
|
;;
|
|
arm*)
|
|
arm*)
|
|
- ARCH=$UNAME
|
|
|
|
|
|
+ ARCH="${UNAME}"
|
|
;;
|
|
;;
|
|
*86)
|
|
*86)
|
|
ARCH=386
|
|
ARCH=386
|
|
;;
|
|
;;
|
|
mips*)
|
|
mips*)
|
|
# detect mips64le vs mips64.
|
|
# detect mips64le vs mips64.
|
|
- ARCH=$UNAME
|
|
|
|
|
|
+ ARCH="${UNAME}"
|
|
if lscpu | grep -q "Little Endian"; then
|
|
if lscpu | grep -q "Little Endian"; then
|
|
ARCH+=le
|
|
ARCH+=le
|
|
fi
|
|
fi
|
|
;;
|
|
;;
|
|
*)
|
|
*)
|
|
- echo "UNKNOWN Machine architecture: $UNAME"
|
|
|
|
|
|
+ >&2 echo "UNKNOWN Machine architecture: ${UNAME}"
|
|
exit 1
|
|
exit 1
|
|
esac
|
|
esac
|
|
|
|
|
|
-URL="$CIPD_CLIENT_SRV/client?platform=${PLAT}-${ARCH}&version=$CIPD_CLIENT_VER"
|
|
|
|
-CLIENT="$MYPATH/.cipd_client"
|
|
|
|
|
|
+# CIPD_BACKEND can be changed to ...-dev for manual testing.
|
|
|
|
+CIPD_BACKEND="https://chrome-infra-packages.appspot.com"
|
|
|
|
+VERSION_FILE="${MYPATH}/cipd_client_version"
|
|
|
|
+
|
|
|
|
+CLIENT="${MYPATH}/.cipd_client"
|
|
|
|
+VERSION=`cat "${VERSION_FILE}"`
|
|
|
|
+PLATFORM="${OS}-${ARCH}"
|
|
|
|
+
|
|
|
|
+URL="${CIPD_BACKEND}/client?platform=${PLATFORM}&version=${VERSION}"
|
|
|
|
+USER_AGENT="depot_tools/$(git -C ${MYPATH} rev-parse HEAD 2>/dev/null || echo "???")"
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+# calc_sha256 is "portable" variant of sha256sum. It uses sha256sum when
|
|
|
|
+# available (most Linuxes and cygwin) and falls back to openssl otherwise
|
|
|
|
+# (mostly for OSX sake).
|
|
|
|
+#
|
|
|
|
+# Args:
|
|
|
|
+# Path to a file.
|
|
|
|
+# Stdout:
|
|
|
|
+# Lowercase SHA256 hex digest of the file.
|
|
|
|
+function calc_sha256() {
|
|
|
|
+ if hash sha256sum 2> /dev/null ; then
|
|
|
|
+ sha256sum "$1" | cut -d' ' -f1
|
|
|
|
+ elif hash openssl 2> /dev/null ; then
|
|
|
|
+ cat "$1" | openssl dgst -sha256
|
|
|
|
+ else
|
|
|
|
+ >&2 echo -n "[31;1m"
|
|
|
|
+ >&2 echo -n "Don't know how to calculate SHA256 on your platform. "
|
|
|
|
+ >&2 echo -n "Please use your package manager to install one before continuing:"
|
|
|
|
+ >&2 echo
|
|
|
|
+ >&2 echo " sha256sum"
|
|
|
|
+ >&2 echo -n " openssl"
|
|
|
|
+ >&2 echo "[0m"
|
|
|
|
+ return 1
|
|
|
|
+ fi
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+# expected_sha256 reads the expected SHA256 hex digest from *.digests file.
|
|
|
|
+#
|
|
|
|
+# Args:
|
|
|
|
+# Name of the platform to get client's digest for.
|
|
|
|
+# Stdout:
|
|
|
|
+# Lowercase SHA256 hex digest.
|
|
|
|
+function expected_sha256() {
|
|
|
|
+ local line
|
|
|
|
+ while read -r line; do
|
|
|
|
+ if [[ "${line}" =~ ^([0-9a-z\-]+)[[:blank:]]+sha256[[:blank:]]+([0-9a-f]+)$ ]] ; then
|
|
|
|
+ local plat="${BASH_REMATCH[1]}"
|
|
|
|
+ local hash="${BASH_REMATCH[2]}"
|
|
|
|
+ if [ "${plat}" == "$1" ]; then
|
|
|
|
+ echo "${hash}"
|
|
|
|
+ return 0
|
|
|
|
+ fi
|
|
|
|
+ fi
|
|
|
|
+ done < "${VERSION_FILE}.digests"
|
|
|
|
+
|
|
|
|
+ >&2 echo -n "[31;1m"
|
|
|
|
+ >&2 echo -n "Platform $1 is not supported by the CIPD client bootstrap: "
|
|
|
|
+ >&2 echo -n "there's no pinned SHA256 hash for it in the *.digests file."
|
|
|
|
+ >&2 echo "[0m"
|
|
|
|
+
|
|
|
|
+ return 1
|
|
|
|
+}
|
|
|
|
|
|
-USER_AGENT="depot_tools/$(git -C $MYPATH rev-parse HEAD 2>/dev/null || echo "???")"
|
|
|
|
|
|
|
|
# clean_bootstrap bootstraps the client from scratch using 'curl' or 'wget'.
|
|
# clean_bootstrap bootstraps the client from scratch using 'curl' or 'wget'.
|
|
|
|
+#
|
|
|
|
+# It checks that the SHA256 of the downloaded file is known. Exits the script
|
|
|
|
+# if the client can't be downloaded or its hash doesn't match the expected one.
|
|
function clean_bootstrap() {
|
|
function clean_bootstrap() {
|
|
- echo "Bootstrapping cipd client for ${PLAT}-${ARCH} from ${URL}..."
|
|
|
|
|
|
+ local expected_hash=$(expected_sha256 "${PLATFORM}")
|
|
|
|
+ if [ -z "${expected_hash}" ] ; then
|
|
|
|
+ exit 1
|
|
|
|
+ fi
|
|
|
|
|
|
- # Download the client into a temporary file, then move it into the final
|
|
|
|
- # location atomically.
|
|
|
|
|
|
+ # Download the client into a temporary file, check its hash, then move it into
|
|
|
|
+ # the final location.
|
|
#
|
|
#
|
|
# This wonky tempdir method works on Linux and Mac.
|
|
# This wonky tempdir method works on Linux and Mac.
|
|
local CIPD_CLIENT_TMP=$(\
|
|
local CIPD_CLIENT_TMP=$(\
|
|
- mktemp -p "$MYPATH" 2>/dev/null || \
|
|
|
|
- mktemp "$MYPATH/.cipd_client.XXXXXXX")
|
|
|
|
|
|
+ mktemp -p "${MYPATH}" 2>/dev/null || \
|
|
|
|
+ mktemp "${MYPATH}/.cipd_client.XXXXXXX")
|
|
|
|
|
|
if hash curl 2> /dev/null ; then
|
|
if hash curl 2> /dev/null ; then
|
|
- curl "$URL" -s --show-error -f -A "$USER_AGENT" -L -o "$CIPD_CLIENT_TMP"
|
|
|
|
|
|
+ curl "${URL}" -s --show-error -f -A "${USER_AGENT}" -L -o "${CIPD_CLIENT_TMP}"
|
|
elif hash wget 2> /dev/null ; then
|
|
elif hash wget 2> /dev/null ; then
|
|
- wget "$URL" -q -U "${USER_AGENT}" -O "${CIPD_CLIENT_TMP}"
|
|
|
|
|
|
+ wget "${URL}" -q -U "${USER_AGENT}" -O "${CIPD_CLIENT_TMP}"
|
|
else
|
|
else
|
|
- echo Your platform is missing a supported fetch command. Please use your package
|
|
|
|
- echo manager to install one before continuing:
|
|
|
|
- echo
|
|
|
|
- echo curl
|
|
|
|
- echo wget
|
|
|
|
- echo
|
|
|
|
- echo Alternately, manually download:
|
|
|
|
- echo "$URL"
|
|
|
|
- echo To $CLIENT, and then re-run this command.
|
|
|
|
|
|
+ >&2 echo -n "[31;1m"
|
|
|
|
+ >&2 echo -n "Your platform is missing a supported fetch command. "
|
|
|
|
+ >&2 echo "Please use your package manager to install one before continuing:"
|
|
|
|
+ >&2 echo
|
|
|
|
+ >&2 echo " curl"
|
|
|
|
+ >&2 echo " wget"
|
|
|
|
+ >&2 echo
|
|
|
|
+ >&2 echo "Alternately, manually download:"
|
|
|
|
+ >&2 echo " ${URL}"
|
|
|
|
+ >&2 echo -n "To ${CLIENT}, and then re-run this command."
|
|
|
|
+ >&2 echo "[0m"
|
|
|
|
+ rm "${CIPD_CLIENT_TMP}"
|
|
|
|
+ exit 1
|
|
|
|
+ fi
|
|
|
|
+
|
|
|
|
+ local actual_hash=$(calc_sha256 "${CIPD_CLIENT_TMP}")
|
|
|
|
+ if [ -z "${actual_hash}" ] ; then
|
|
rm "${CIPD_CLIENT_TMP}"
|
|
rm "${CIPD_CLIENT_TMP}"
|
|
exit 1
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
|
|
- chmod +x "$CIPD_CLIENT_TMP"
|
|
|
|
|
|
+ if [ "${actual_hash}" != "${expected_hash}" ]; then
|
|
|
|
+ >&2 echo -n "[31;1m"
|
|
|
|
+ >&2 echo "SHA256 digest of the downloaded CIPD client is incorrect:"
|
|
|
|
+ >&2 echo " Expecting ${expected_hash}"
|
|
|
|
+ >&2 echo " Got ${actual_hash}"
|
|
|
|
+ >&2 echo -n "Refusing to run it. Check that *.digests file is up-to-date."
|
|
|
|
+ >&2 echo "[0m"
|
|
|
|
+ rm "${CIPD_CLIENT_TMP}"
|
|
|
|
+ exit 1
|
|
|
|
+ fi
|
|
|
|
|
|
set +e
|
|
set +e
|
|
- mv "$CIPD_CLIENT_TMP" "$CLIENT"
|
|
|
|
|
|
+ chmod +x "${CIPD_CLIENT_TMP}"
|
|
|
|
+ mv "${CIPD_CLIENT_TMP}" "${CLIENT}"
|
|
set -e
|
|
set -e
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+# self_update launches CIPD client's built-in selfupdate mechanism.
|
|
|
|
+#
|
|
|
|
+# It is more efficient that redownloading the binary all the time.
|
|
function self_update() {
|
|
function self_update() {
|
|
- "$CLIENT" selfupdate -version "$CIPD_CLIENT_VER" -service-url "$CIPD_CLIENT_SRV"
|
|
|
|
|
|
+ "${CLIENT}" selfupdate -version-file "${VERSION_FILE}" -service-url "${CIPD_BACKEND}"
|
|
}
|
|
}
|
|
|
|
|
|
-if [ ! -x "$CLIENT" ]; then
|
|
|
|
|
|
+
|
|
|
|
+if [ ! -x "${CLIENT}" ]; then
|
|
clean_bootstrap
|
|
clean_bootstrap
|
|
fi
|
|
fi
|
|
|
|
|
|
-export CIPD_HTTP_USER_AGENT_PREFIX=$USER_AGENT
|
|
|
|
-if ! self_update ; then
|
|
|
|
- echo -n "[31;1mCIPD selfupdate failed. " 1>&2
|
|
|
|
- echo "Trying to bootstrap the CIPD client from scratch... [0m" 1>&2
|
|
|
|
|
|
+export CIPD_HTTP_USER_AGENT_PREFIX="${USER_AGENT}"
|
|
|
|
+if ! self_update 2> /dev/null ; then
|
|
|
|
+ >&2 echo -n "[31;1m"
|
|
|
|
+ >&2 echo -n "CIPD selfupdate failed. "
|
|
|
|
+ >&2 echo -n "Trying to bootstrap the CIPD client from scratch..."
|
|
|
|
+ >&2 echo "[0m"
|
|
clean_bootstrap
|
|
clean_bootstrap
|
|
if ! self_update ; then # need to run it again to setup .cipd_version file
|
|
if ! self_update ; then # need to run it again to setup .cipd_version file
|
|
- echo -n "[31;1mBootstrap from scratch failed, something is seriously broken[0m " 1>&2
|
|
|
|
- echo "run \`CIPD_HTTP_USER_AGENT_PREFIX=$USER_AGENT/manual $CLIENT selfupdate -version '$CIPD_CLIENT_VER'\` to diagnose if this is repeating." 1>&2
|
|
|
|
- echo "[0m" 1>&2
|
|
|
|
|
|
+ >&2 echo -n "[31;1m"
|
|
|
|
+ >&2 echo -n "Bootstrap from scratch failed, something is seriously broken. "
|
|
|
|
+ >&2 echo "Run the following commands to diagnose if this is repeating:"
|
|
|
|
+ >&2 echo " export CIPD_HTTP_USER_AGENT_PREFIX=${USER_AGENT}/manual"
|
|
|
|
+ >&2 echo -n " ${CLIENT} selfupdate -version-file ${VERSION_FILE}"
|
|
|
|
+ >&2 echo "[0m"
|
|
|
|
+ exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
|
|
# CygWin requires changing absolute paths to Windows form. Relative paths
|
|
# CygWin requires changing absolute paths to Windows form. Relative paths
|
|
# are typically okay as Windows generally accepts both forward and back
|
|
# are typically okay as Windows generally accepts both forward and back
|
|
# slashes. This could possibly be constrained to only /tmp/ and /cygdrive/.
|
|
# slashes. This could possibly be constrained to only /tmp/ and /cygdrive/.
|
|
-if $CYGWIN; then
|
|
|
|
|
|
+if ${CYGWIN}; then
|
|
args=("$@")
|
|
args=("$@")
|
|
for i in `seq 2 $#`; do
|
|
for i in `seq 2 $#`; do
|
|
arg="${@:$i:1}"
|
|
arg="${@:$i:1}"
|
|
@@ -145,7 +238,7 @@ if $CYGWIN; then
|
|
set -- "${@:1:$last}" `cygpath -w "$arg"` "${@:$next}"
|
|
set -- "${@:1:$last}" `cygpath -w "$arg"` "${@:$next}"
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
- echo "$CLIENT" "${@}"
|
|
|
|
|
|
+ echo "${CLIENT}" "${@}"
|
|
fi
|
|
fi
|
|
|
|
|
|
-exec "$CLIENT" "${@}"
|
|
|
|
|
|
+exec "${CLIENT}" "${@}"
|