blob: 3114f8e5fc6226774076e83cdb1f315a330e65c0 [file] [log] [blame]
Robert Iannucci2188fe92016-12-02 11:15:57 -08001#!/bin/bash -e
2
3# Copyright (c) 2016 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
Dan Jacquese82c0de2017-07-05 18:10:23 -07007set -e -o pipefail
8
Robert Iannucci2188fe92016-12-02 11:15:57 -08009MYPATH=$(dirname "${BASH_SOURCE[0]}")
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000010CYGWIN=false
Robert Iannucci2188fe92016-12-02 11:15:57 -080011
12UNAME=`uname -s | tr '[:upper:]' '[:lower:]'`
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000013case "${UNAME}" in
Robert Iannucci2188fe92016-12-02 11:15:57 -080014 linux)
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000015 OS=linux
Robert Iannucci2188fe92016-12-02 11:15:57 -080016 ;;
Brian White361822c2018-04-04 15:21:45 -040017 cygwin*)
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000018 OS=windows
Brian White361822c2018-04-04 15:21:45 -040019 CYGWIN=true
20 ;;
21 msys*|mingw*)
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000022 OS=windows
Robert Iannucci2188fe92016-12-02 11:15:57 -080023 ;;
24 darwin)
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000025 OS=mac
Robert Iannucci2188fe92016-12-02 11:15:57 -080026 ;;
27 *)
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000028 >&2 echo "CIPD not supported on ${UNAME}"
Robert Iannucci2188fe92016-12-02 11:15:57 -080029 exit 1
30esac
31
32UNAME=`uname -m | tr '[:upper:]' '[:lower:]'`
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000033case "${UNAME}" in
Robert Iannucci2188fe92016-12-02 11:15:57 -080034 x86_64|amd64)
35 ARCH=amd64
36 ;;
Robert Iannucciff2bf092017-09-11 16:27:26 -070037 s390x) # best-effort support for IBM s390x: crbug.com/764087
38 ARCH=s390x
39 ;;
Dan Jacques63421282017-10-16 15:05:59 -040040 ppc64) # best-effort support for 64-bit PowerPC: crbug.com/773857
41 ARCH=ppc64
42 ;;
Dan Jacques1e0b7a52017-10-17 11:19:18 -040043 ppc64le) # best-effort support for 64-bit PowerPC/LE: crbug.com/773857
Dan Jacques63421282017-10-16 15:05:59 -040044 ARCH=ppc64le
45 ;;
William Hesse6fd24842017-10-10 13:55:22 +020046 aarch64)
47 ARCH=arm64
48 ;;
Benjamin Pastenee346e412017-10-20 12:57:43 -070049 armv7l)
50 ARCH=armv6l
51 ;;
Robert Iannucci2188fe92016-12-02 11:15:57 -080052 arm*)
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000053 ARCH="${UNAME}"
Robert Iannucci2188fe92016-12-02 11:15:57 -080054 ;;
55 *86)
56 ARCH=386
57 ;;
Wang Qing254538b2018-07-26 02:23:53 +000058 mips*)
Wang Qing82bb7562018-08-03 21:45:46 +000059 # detect mips64le vs mips64.
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000060 ARCH="${UNAME}"
Wang Qing82bb7562018-08-03 21:45:46 +000061 if lscpu | grep -q "Little Endian"; then
62 ARCH+=le
63 fi
Wang Qing254538b2018-07-26 02:23:53 +000064 ;;
Robert Iannucci2188fe92016-12-02 11:15:57 -080065 *)
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000066 >&2 echo "UNKNOWN Machine architecture: ${UNAME}"
Robert Iannucci2188fe92016-12-02 11:15:57 -080067 exit 1
68esac
69
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000070# CIPD_BACKEND can be changed to ...-dev for manual testing.
71CIPD_BACKEND="https://chrome-infra-packages.appspot.com"
72VERSION_FILE="${MYPATH}/cipd_client_version"
Robert Iannucci2188fe92016-12-02 11:15:57 -080073
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +000074CLIENT="${MYPATH}/.cipd_client"
75VERSION=`cat "${VERSION_FILE}"`
76PLATFORM="${OS}-${ARCH}"
77
78URL="${CIPD_BACKEND}/client?platform=${PLATFORM}&version=${VERSION}"
79USER_AGENT="depot_tools/$(git -C ${MYPATH} rev-parse HEAD 2>/dev/null || echo "???")"
80
81
82# calc_sha256 is "portable" variant of sha256sum. It uses sha256sum when
83# available (most Linuxes and cygwin) and falls back to openssl otherwise
84# (mostly for OSX sake).
85#
86# Args:
87# Path to a file.
88# Stdout:
89# Lowercase SHA256 hex digest of the file.
90function calc_sha256() {
91 if hash sha256sum 2> /dev/null ; then
92 sha256sum "$1" | cut -d' ' -f1
93 elif hash openssl 2> /dev/null ; then
94 cat "$1" | openssl dgst -sha256
95 else
96 >&2 echo -n ""
97 >&2 echo -n "Don't know how to calculate SHA256 on your platform. "
98 >&2 echo -n "Please use your package manager to install one before continuing:"
99 >&2 echo
100 >&2 echo " sha256sum"
101 >&2 echo -n " openssl"
102 >&2 echo ""
103 return 1
104 fi
105}
106
107
108# expected_sha256 reads the expected SHA256 hex digest from *.digests file.
109#
110# Args:
111# Name of the platform to get client's digest for.
112# Stdout:
113# Lowercase SHA256 hex digest.
114function expected_sha256() {
115 local line
116 while read -r line; do
117 if [[ "${line}" =~ ^([0-9a-z\-]+)[[:blank:]]+sha256[[:blank:]]+([0-9a-f]+)$ ]] ; then
118 local plat="${BASH_REMATCH[1]}"
119 local hash="${BASH_REMATCH[2]}"
120 if [ "${plat}" == "$1" ]; then
121 echo "${hash}"
122 return 0
123 fi
124 fi
125 done < "${VERSION_FILE}.digests"
126
127 >&2 echo -n ""
128 >&2 echo -n "Platform $1 is not supported by the CIPD client bootstrap: "
129 >&2 echo -n "there's no pinned SHA256 hash for it in the *.digests file."
130 >&2 echo ""
131
132 return 1
133}
134
Robert Iannucci2188fe92016-12-02 11:15:57 -0800135
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000136# clean_bootstrap bootstraps the client from scratch using 'curl' or 'wget'.
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000137#
138# It checks that the SHA256 of the downloaded file is known. Exits the script
139# if the client can't be downloaded or its hash doesn't match the expected one.
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000140function clean_bootstrap() {
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000141 local expected_hash=$(expected_sha256 "${PLATFORM}")
142 if [ -z "${expected_hash}" ] ; then
143 exit 1
144 fi
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000145
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000146 # Download the client into a temporary file, check its hash, then move it into
147 # the final location.
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000148 #
149 # This wonky tempdir method works on Linux and Mac.
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000150 local CIPD_CLIENT_TMP=$(\
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000151 mktemp -p "${MYPATH}" 2>/dev/null || \
152 mktemp "${MYPATH}/.cipd_client.XXXXXXX")
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000153
Robert Iannucci2188fe92016-12-02 11:15:57 -0800154 if hash curl 2> /dev/null ; then
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000155 curl "${URL}" -s --show-error -f -A "${USER_AGENT}" -L -o "${CIPD_CLIENT_TMP}"
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000156 elif hash wget 2> /dev/null ; then
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000157 wget "${URL}" -q -U "${USER_AGENT}" -O "${CIPD_CLIENT_TMP}"
Robert Iannucci2188fe92016-12-02 11:15:57 -0800158 else
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000159 >&2 echo -n ""
160 >&2 echo -n "Your platform is missing a supported fetch command. "
161 >&2 echo "Please use your package manager to install one before continuing:"
162 >&2 echo
163 >&2 echo " curl"
164 >&2 echo " wget"
165 >&2 echo
166 >&2 echo "Alternately, manually download:"
167 >&2 echo " ${URL}"
168 >&2 echo -n "To ${CLIENT}, and then re-run this command."
169 >&2 echo ""
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000170 rm "${CIPD_CLIENT_TMP}"
Robert Iannucci2188fe92016-12-02 11:15:57 -0800171 exit 1
172 fi
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000173
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000174 local actual_hash=$(calc_sha256 "${CIPD_CLIENT_TMP}")
175 if [ -z "${actual_hash}" ] ; then
176 rm "${CIPD_CLIENT_TMP}"
177 exit 1
178 fi
179
180 if [ "${actual_hash}" != "${expected_hash}" ]; then
181 >&2 echo -n ""
182 >&2 echo "SHA256 digest of the downloaded CIPD client is incorrect:"
183 >&2 echo " Expecting ${expected_hash}"
184 >&2 echo " Got ${actual_hash}"
185 >&2 echo -n "Refusing to run it. Check that *.digests file is up-to-date."
186 >&2 echo ""
187 rm "${CIPD_CLIENT_TMP}"
188 exit 1
189 fi
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000190
191 set +e
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000192 chmod +x "${CIPD_CLIENT_TMP}"
193 mv "${CIPD_CLIENT_TMP}" "${CLIENT}"
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000194 set -e
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000195}
196
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000197
198# self_update launches CIPD client's built-in selfupdate mechanism.
199#
200# It is more efficient that redownloading the binary all the time.
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000201function self_update() {
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000202 "${CLIENT}" selfupdate -version-file "${VERSION_FILE}" -service-url "${CIPD_BACKEND}"
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000203}
204
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000205
206if [ ! -x "${CLIENT}" ]; then
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000207 clean_bootstrap
Robert Iannucci2188fe92016-12-02 11:15:57 -0800208fi
209
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000210export CIPD_HTTP_USER_AGENT_PREFIX="${USER_AGENT}"
211if ! self_update 2> /dev/null ; then
212 >&2 echo -n ""
213 >&2 echo -n "CIPD selfupdate failed. "
214 >&2 echo -n "Trying to bootstrap the CIPD client from scratch..."
215 >&2 echo ""
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000216 clean_bootstrap
217 if ! self_update ; then # need to run it again to setup .cipd_version file
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000218 >&2 echo -n ""
219 >&2 echo -n "Bootstrap from scratch failed, something is seriously broken. "
220 >&2 echo "Run the following commands to diagnose if this is repeating:"
221 >&2 echo " export CIPD_HTTP_USER_AGENT_PREFIX=${USER_AGENT}/manual"
222 >&2 echo -n " ${CLIENT} selfupdate -version-file ${VERSION_FILE}"
223 >&2 echo ""
224 exit 1
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000225 fi
Robert Iannucci2188fe92016-12-02 11:15:57 -0800226fi
227
Brian White361822c2018-04-04 15:21:45 -0400228# CygWin requires changing absolute paths to Windows form. Relative paths
229# are typically okay as Windows generally accepts both forward and back
230# slashes. This could possibly be constrained to only /tmp/ and /cygdrive/.
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000231if ${CYGWIN}; then
Brian White361822c2018-04-04 15:21:45 -0400232 args=("$@")
233 for i in `seq 2 $#`; do
234 arg="${@:$i:1}"
235 if [ "${arg:0:1}" == "/" ]; then
236 last=$((i-1))
237 next=$((i+1))
238 set -- "${@:1:$last}" `cygpath -w "$arg"` "${@:$next}"
239 fi
240 done
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000241 echo "${CLIENT}" "${@}"
Brian White361822c2018-04-04 15:21:45 -0400242fi
243
Vadim Shtayuraeebc3d82018-08-14 20:39:46 +0000244exec "${CLIENT}" "${@}"