Robert Nagy | 059f26b | 2019-05-10 14:58:03 +0000 | [diff] [blame] | 1 | #!/usr/bin/env bash |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 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 Jacques | e82c0de | 2017-07-05 18:10:23 -0700 | [diff] [blame] | 7 | set -e -o pipefail |
| 8 | |
Vadim Shtayura | 5e5c217 | 2018-08-15 21:11:10 +0000 | [diff] [blame] | 9 | MYPATH=$(dirname "${BASH_SOURCE[0]}") |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 10 | CYGWIN=false |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 11 | |
| 12 | UNAME=`uname -s | tr '[:upper:]' '[:lower:]'` |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 13 | case "${UNAME}" in |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 14 | linux) |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 15 | OS=linux |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 16 | ;; |
Brian White | 361822c | 2018-04-04 15:21:45 -0400 | [diff] [blame] | 17 | cygwin*) |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 18 | OS=windows |
Brian White | 361822c | 2018-04-04 15:21:45 -0400 | [diff] [blame] | 19 | CYGWIN=true |
| 20 | ;; |
| 21 | msys*|mingw*) |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 22 | OS=windows |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 23 | ;; |
| 24 | darwin) |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 25 | OS=mac |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 26 | ;; |
| 27 | *) |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 28 | >&2 echo "CIPD not supported on ${UNAME}" |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 29 | exit 1 |
| 30 | esac |
| 31 | |
| 32 | UNAME=`uname -m | tr '[:upper:]' '[:lower:]'` |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 33 | case "${UNAME}" in |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 34 | x86_64|amd64) |
| 35 | ARCH=amd64 |
| 36 | ;; |
Robert Iannucci | ff2bf09 | 2017-09-11 16:27:26 -0700 | [diff] [blame] | 37 | s390x) # best-effort support for IBM s390x: crbug.com/764087 |
| 38 | ARCH=s390x |
| 39 | ;; |
Dan Jacques | 6342128 | 2017-10-16 15:05:59 -0400 | [diff] [blame] | 40 | ppc64) # best-effort support for 64-bit PowerPC: crbug.com/773857 |
| 41 | ARCH=ppc64 |
| 42 | ;; |
Dan Jacques | 1e0b7a5 | 2017-10-17 11:19:18 -0400 | [diff] [blame] | 43 | ppc64le) # best-effort support for 64-bit PowerPC/LE: crbug.com/773857 |
Dan Jacques | 6342128 | 2017-10-16 15:05:59 -0400 | [diff] [blame] | 44 | ARCH=ppc64le |
| 45 | ;; |
William Hesse | 6fd2484 | 2017-10-10 13:55:22 +0200 | [diff] [blame] | 46 | aarch64) |
| 47 | ARCH=arm64 |
| 48 | ;; |
Benjamin Pastene | e346e41 | 2017-10-20 12:57:43 -0700 | [diff] [blame] | 49 | armv7l) |
| 50 | ARCH=armv6l |
| 51 | ;; |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 52 | arm*) |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 53 | ARCH="${UNAME}" |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 54 | ;; |
| 55 | *86) |
| 56 | ARCH=386 |
| 57 | ;; |
Wang Qing | 254538b | 2018-07-26 02:23:53 +0000 | [diff] [blame] | 58 | mips*) |
Wang Qing | 82bb756 | 2018-08-03 21:45:46 +0000 | [diff] [blame] | 59 | # detect mips64le vs mips64. |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 60 | ARCH="${UNAME}" |
Wang Qing | 82bb756 | 2018-08-03 21:45:46 +0000 | [diff] [blame] | 61 | if lscpu | grep -q "Little Endian"; then |
| 62 | ARCH+=le |
| 63 | fi |
Wang Qing | 254538b | 2018-07-26 02:23:53 +0000 | [diff] [blame] | 64 | ;; |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 65 | *) |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 66 | >&2 echo "UNKNOWN Machine architecture: ${UNAME}" |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 67 | exit 1 |
| 68 | esac |
| 69 | |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 70 | # CIPD_BACKEND can be changed to ...-dev for manual testing. |
| 71 | CIPD_BACKEND="https://chrome-infra-packages.appspot.com" |
| 72 | VERSION_FILE="${MYPATH}/cipd_client_version" |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 73 | |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 74 | CLIENT="${MYPATH}/.cipd_client" |
| 75 | VERSION=`cat "${VERSION_FILE}"` |
| 76 | PLATFORM="${OS}-${ARCH}" |
| 77 | |
| 78 | URL="${CIPD_BACKEND}/client?platform=${PLATFORM}&version=${VERSION}" |
| 79 | USER_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. |
| 89 | function 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 "[31;1m" |
| 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 "[0m" |
| 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. |
| 113 | function 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 "[31;1m" |
| 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 "[0m" |
| 130 | |
| 131 | return 1 |
| 132 | } |
| 133 | |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 134 | |
Vadim Shtayura | 7e50ee3 | 2018-07-26 17:43:51 +0000 | [diff] [blame] | 135 | # clean_bootstrap bootstraps the client from scratch using 'curl' or 'wget'. |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 136 | # |
| 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 Shtayura | 7e50ee3 | 2018-07-26 17:43:51 +0000 | [diff] [blame] | 139 | function clean_bootstrap() { |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 140 | local expected_hash=$(expected_sha256 "${PLATFORM}") |
| 141 | if [ -z "${expected_hash}" ] ; then |
| 142 | exit 1 |
| 143 | fi |
Pawel Hajdan, Jr | 8c8a0a5 | 2017-09-06 19:40:18 +0000 | [diff] [blame] | 144 | |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 145 | # Download the client into a temporary file, check its hash, then move it into |
| 146 | # the final location. |
Pawel Hajdan, Jr | 8c8a0a5 | 2017-09-06 19:40:18 +0000 | [diff] [blame] | 147 | # |
| 148 | # This wonky tempdir method works on Linux and Mac. |
Vadim Shtayura | 7e50ee3 | 2018-07-26 17:43:51 +0000 | [diff] [blame] | 149 | local CIPD_CLIENT_TMP=$(\ |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 150 | mktemp -p "${MYPATH}" 2>/dev/null || \ |
| 151 | mktemp "${MYPATH}/.cipd_client.XXXXXXX") |
Pawel Hajdan, Jr | 8c8a0a5 | 2017-09-06 19:40:18 +0000 | [diff] [blame] | 152 | |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 153 | if hash curl 2> /dev/null ; then |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 154 | curl "${URL}" -s --show-error -f -A "${USER_AGENT}" -L -o "${CIPD_CLIENT_TMP}" |
Pawel Hajdan, Jr | 8c8a0a5 | 2017-09-06 19:40:18 +0000 | [diff] [blame] | 155 | elif hash wget 2> /dev/null ; then |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 156 | wget "${URL}" -q -U "${USER_AGENT}" -O "${CIPD_CLIENT_TMP}" |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 157 | else |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 158 | >&2 echo -n "[31;1m" |
| 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 "[0m" |
Pawel Hajdan, Jr | 8c8a0a5 | 2017-09-06 19:40:18 +0000 | [diff] [blame] | 169 | rm "${CIPD_CLIENT_TMP}" |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 170 | exit 1 |
| 171 | fi |
Pawel Hajdan, Jr | 8c8a0a5 | 2017-09-06 19:40:18 +0000 | [diff] [blame] | 172 | |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 173 | 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 "[31;1m" |
| 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 "[0m" |
| 186 | rm "${CIPD_CLIENT_TMP}" |
| 187 | exit 1 |
| 188 | fi |
Pawel Hajdan, Jr | 8c8a0a5 | 2017-09-06 19:40:18 +0000 | [diff] [blame] | 189 | |
| 190 | set +e |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 191 | chmod +x "${CIPD_CLIENT_TMP}" |
| 192 | mv "${CIPD_CLIENT_TMP}" "${CLIENT}" |
Pawel Hajdan, Jr | 8c8a0a5 | 2017-09-06 19:40:18 +0000 | [diff] [blame] | 193 | set -e |
Vadim Shtayura | 7e50ee3 | 2018-07-26 17:43:51 +0000 | [diff] [blame] | 194 | } |
| 195 | |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 196 | |
| 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 Shtayura | 7e50ee3 | 2018-07-26 17:43:51 +0000 | [diff] [blame] | 200 | function self_update() { |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 201 | "${CLIENT}" selfupdate -version-file "${VERSION_FILE}" -service-url "${CIPD_BACKEND}" |
Vadim Shtayura | 7e50ee3 | 2018-07-26 17:43:51 +0000 | [diff] [blame] | 202 | } |
| 203 | |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 204 | |
| 205 | if [ ! -x "${CLIENT}" ]; then |
Vadim Shtayura | 7e50ee3 | 2018-07-26 17:43:51 +0000 | [diff] [blame] | 206 | clean_bootstrap |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 207 | fi |
| 208 | |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 209 | export CIPD_HTTP_USER_AGENT_PREFIX="${USER_AGENT}" |
| 210 | if ! self_update 2> /dev/null ; then |
| 211 | >&2 echo -n "[31;1m" |
| 212 | >&2 echo -n "CIPD selfupdate failed. " |
| 213 | >&2 echo -n "Trying to bootstrap the CIPD client from scratch..." |
| 214 | >&2 echo "[0m" |
Vadim Shtayura | 7e50ee3 | 2018-07-26 17:43:51 +0000 | [diff] [blame] | 215 | clean_bootstrap |
| 216 | if ! self_update ; then # need to run it again to setup .cipd_version file |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 217 | >&2 echo -n "[31;1m" |
| 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 "[0m" |
| 223 | exit 1 |
Vadim Shtayura | 7e50ee3 | 2018-07-26 17:43:51 +0000 | [diff] [blame] | 224 | fi |
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 225 | fi |
| 226 | |
Brian White | 361822c | 2018-04-04 15:21:45 -0400 | [diff] [blame] | 227 | # 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 Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 230 | if ${CYGWIN}; then |
Brian White | 361822c | 2018-04-04 15:21:45 -0400 | [diff] [blame] | 231 | 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 Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 240 | echo "${CLIENT}" "${@}" |
Brian White | 361822c | 2018-04-04 15:21:45 -0400 | [diff] [blame] | 241 | fi |
| 242 | |
Vadim Shtayura | 3d429cf | 2018-08-16 00:15:08 +0000 | [diff] [blame] | 243 | exec "${CLIENT}" "${@}" |