blob: e7b39e3f49f18ab2f8e00a31fce774cdad4bfec2 [file] [log] [blame]
Robert Nagy059f26b2019-05-10 14:58:03 +00001#!/usr/bin/env bash
Robert Iannucci2188fe92016-12-02 11:15:57 -08002
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
Vadim Shtayura5e5c2172018-08-15 21:11:10 +00009MYPATH=$(dirname "${BASH_SOURCE[0]}")
Vadim Shtayura3d429cf2018-08-16 00:15:08 +000010CYGWIN=false
Robert Iannucci2188fe92016-12-02 11:15:57 -080011
12UNAME=`uname -s | tr '[:upper:]' '[:lower:]'`
Vadim Shtayura3d429cf2018-08-16 00:15:08 +000013case "${UNAME}" in
Robert Iannucci2188fe92016-12-02 11:15:57 -080014 linux)
Vadim Shtayura3d429cf2018-08-16 00:15:08 +000015 OS=linux
Robert Iannucci2188fe92016-12-02 11:15:57 -080016 ;;
Brian White361822c2018-04-04 15:21:45 -040017 cygwin*)
Vadim Shtayura3d429cf2018-08-16 00:15:08 +000018 OS=windows
Brian White361822c2018-04-04 15:21:45 -040019 CYGWIN=true
20 ;;
21 msys*|mingw*)
Vadim Shtayura3d429cf2018-08-16 00:15:08 +000022 OS=windows
Robert Iannucci2188fe92016-12-02 11:15:57 -080023 ;;
24 darwin)
Vadim Shtayura3d429cf2018-08-16 00:15:08 +000025 OS=mac
Robert Iannucci2188fe92016-12-02 11:15:57 -080026 ;;
27 *)
Vadim Shtayura3d429cf2018-08-16 00:15:08 +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 Shtayura3d429cf2018-08-16 00:15:08 +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 Shtayura3d429cf2018-08-16 00:15:08 +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 Shtayura3d429cf2018-08-16 00:15:08 +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 Shtayura3d429cf2018-08-16 00:15:08 +000066 >&2 echo "UNKNOWN Machine architecture: ${UNAME}"
Robert Iannucci2188fe92016-12-02 11:15:57 -080067 exit 1
68esac
69
Vadim Shtayura3d429cf2018-08-16 00:15:08 +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 Shtayura3d429cf2018-08-16 00:15:08 +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 'shasum -a 256' otherwise (for OSX).
84#
85# Args:
86# Path to a file.
87# Stdout:
88# Lowercase SHA256 hex digest of the file.
89function calc_sha256() {
90 if hash sha256sum 2> /dev/null ; then
91 sha256sum "$1" | cut -d' ' -f1
92 elif hash shasum 2> /dev/null ; then
93 shasum -a 256 "$1" | cut -d' ' -f1
94 else
95 >&2 echo -n ""
96 >&2 echo -n "Don't know how to calculate SHA256 on your platform. "
97 >&2 echo -n "Please use your package manager to install one before continuing:"
98 >&2 echo
99 >&2 echo " sha256sum"
100 >&2 echo -n " shasum"
101 >&2 echo ""
102 return 1
103 fi
104}
105
106
107# expected_sha256 reads the expected SHA256 hex digest from *.digests file.
108#
109# Args:
110# Name of the platform to get client's digest for.
111# Stdout:
112# Lowercase SHA256 hex digest.
113function expected_sha256() {
114 local line
115 while read -r line; do
116 if [[ "${line}" =~ ^([0-9a-z\-]+)[[:blank:]]+sha256[[:blank:]]+([0-9a-f]+)$ ]] ; then
117 local plat="${BASH_REMATCH[1]}"
118 local hash="${BASH_REMATCH[2]}"
119 if [ "${plat}" == "$1" ]; then
120 echo "${hash}"
121 return 0
122 fi
123 fi
124 done < "${VERSION_FILE}.digests"
125
126 >&2 echo -n ""
127 >&2 echo -n "Platform $1 is not supported by the CIPD client bootstrap: "
128 >&2 echo -n "there's no pinned SHA256 hash for it in the *.digests file."
129 >&2 echo ""
130
131 return 1
132}
133
Robert Iannucci2188fe92016-12-02 11:15:57 -0800134
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000135# clean_bootstrap bootstraps the client from scratch using 'curl' or 'wget'.
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000136#
137# It checks that the SHA256 of the downloaded file is known. Exits the script
138# if the client can't be downloaded or its hash doesn't match the expected one.
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000139function clean_bootstrap() {
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000140 local expected_hash=$(expected_sha256 "${PLATFORM}")
141 if [ -z "${expected_hash}" ] ; then
142 exit 1
143 fi
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000144
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000145 # Download the client into a temporary file, check its hash, then move it into
146 # the final location.
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000147 #
148 # This wonky tempdir method works on Linux and Mac.
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000149 local CIPD_CLIENT_TMP=$(\
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000150 mktemp -p "${MYPATH}" 2>/dev/null || \
151 mktemp "${MYPATH}/.cipd_client.XXXXXXX")
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000152
Robert Iannucci2188fe92016-12-02 11:15:57 -0800153 if hash curl 2> /dev/null ; then
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000154 curl "${URL}" -s --show-error -f -A "${USER_AGENT}" -L -o "${CIPD_CLIENT_TMP}"
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000155 elif hash wget 2> /dev/null ; then
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000156 wget "${URL}" -q -U "${USER_AGENT}" -O "${CIPD_CLIENT_TMP}"
Robert Iannucci2188fe92016-12-02 11:15:57 -0800157 else
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000158 >&2 echo -n ""
159 >&2 echo -n "Your platform is missing a supported fetch command. "
160 >&2 echo "Please use your package manager to install one before continuing:"
161 >&2 echo
162 >&2 echo " curl"
163 >&2 echo " wget"
164 >&2 echo
165 >&2 echo "Alternately, manually download:"
166 >&2 echo " ${URL}"
167 >&2 echo -n "To ${CLIENT}, and then re-run this command."
168 >&2 echo ""
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000169 rm "${CIPD_CLIENT_TMP}"
Robert Iannucci2188fe92016-12-02 11:15:57 -0800170 exit 1
171 fi
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000172
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000173 local actual_hash=$(calc_sha256 "${CIPD_CLIENT_TMP}")
174 if [ -z "${actual_hash}" ] ; then
175 rm "${CIPD_CLIENT_TMP}"
176 exit 1
177 fi
178
179 if [ "${actual_hash}" != "${expected_hash}" ]; then
180 >&2 echo -n ""
181 >&2 echo "SHA256 digest of the downloaded CIPD client is incorrect:"
182 >&2 echo " Expecting ${expected_hash}"
183 >&2 echo " Got ${actual_hash}"
184 >&2 echo -n "Refusing to run it. Check that *.digests file is up-to-date."
185 >&2 echo ""
186 rm "${CIPD_CLIENT_TMP}"
187 exit 1
188 fi
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000189
190 set +e
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000191 chmod +x "${CIPD_CLIENT_TMP}"
192 mv "${CIPD_CLIENT_TMP}" "${CLIENT}"
Pawel Hajdan, Jr8c8a0a52017-09-06 19:40:18 +0000193 set -e
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000194}
195
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000196
197# self_update launches CIPD client's built-in selfupdate mechanism.
198#
199# It is more efficient that redownloading the binary all the time.
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000200function self_update() {
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000201 "${CLIENT}" selfupdate -version-file "${VERSION_FILE}" -service-url "${CIPD_BACKEND}"
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000202}
203
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000204
205if [ ! -x "${CLIENT}" ]; then
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000206 clean_bootstrap
Robert Iannucci2188fe92016-12-02 11:15:57 -0800207fi
208
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000209export CIPD_HTTP_USER_AGENT_PREFIX="${USER_AGENT}"
210if ! self_update 2> /dev/null ; then
211 >&2 echo -n ""
212 >&2 echo -n "CIPD selfupdate failed. "
213 >&2 echo -n "Trying to bootstrap the CIPD client from scratch..."
214 >&2 echo ""
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000215 clean_bootstrap
216 if ! self_update ; then # need to run it again to setup .cipd_version file
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000217 >&2 echo -n ""
218 >&2 echo -n "Bootstrap from scratch failed, something is seriously broken. "
219 >&2 echo "Run the following commands to diagnose if this is repeating:"
220 >&2 echo " export CIPD_HTTP_USER_AGENT_PREFIX=${USER_AGENT}/manual"
221 >&2 echo -n " ${CLIENT} selfupdate -version-file ${VERSION_FILE}"
222 >&2 echo ""
223 exit 1
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000224 fi
Robert Iannucci2188fe92016-12-02 11:15:57 -0800225fi
226
Brian White361822c2018-04-04 15:21:45 -0400227# CygWin requires changing absolute paths to Windows form. Relative paths
228# are typically okay as Windows generally accepts both forward and back
229# slashes. This could possibly be constrained to only /tmp/ and /cygdrive/.
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000230if ${CYGWIN}; then
Brian White361822c2018-04-04 15:21:45 -0400231 args=("$@")
232 for i in `seq 2 $#`; do
233 arg="${@:$i:1}"
234 if [ "${arg:0:1}" == "/" ]; then
235 last=$((i-1))
236 next=$((i+1))
237 set -- "${@:1:$last}" `cygpath -w "$arg"` "${@:$next}"
238 fi
239 done
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000240 echo "${CLIENT}" "${@}"
Brian White361822c2018-04-04 15:21:45 -0400241fi
242
Vadim Shtayura3d429cf2018-08-16 00:15:08 +0000243exec "${CLIENT}" "${@}"