Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 1 | # Copyright (c) 2016 The Chromium Authors. All rights reserved.
|
| 2 | # Use of this source code is governed by a BSD-style license that can be
|
| 3 | # found in the LICENSE file.
|
| 4 |
|
Vadim Shtayura | dfedcc0 | 2018-09-14 19:47:37 +0000 | [diff] [blame] | 5 | # Note: to run this on e.g. OSX for adhoc testing or debugging in case Windows
|
| 6 | # is not around:
|
| 7 | #
|
| 8 | # pwsh cipd.ps1 \
|
| 9 | # -CipdBinary _cipd.exe \
|
| 10 | # -BackendURL https://chrome-infra-packages.appspot.com \
|
| 11 | # -VersionFile ./cipd_client_version
|
| 12 | # file _cipd.exe
|
| 13 |
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 14 | Param(
|
| 15 | # Path to download the CIPD binary to.
|
| 16 | [parameter(Mandatory=$true)][string]$CipdBinary,
|
| 17 | # E.g. "https://chrome-infra-packages.appspot.com".
|
| 18 | [parameter(Mandatory=$true)][string]$BackendURL,
|
| 19 | # Path to the cipd_client_version file with the client version.
|
| 20 | [parameter(Mandatory=$true)][string]$VersionFile
|
| 21 | )
|
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 22 |
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 23 | $DepotToolsPath = Split-Path $MyInvocation.MyCommand.Path -Parent
|
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 24 |
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 25 | if ([System.IntPtr]::Size -eq 8) {
|
| 26 | $Platform = "windows-amd64"
|
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 27 | } else {
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 28 | $Platform = "windows-386"
|
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 29 | }
|
| 30 |
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 31 | # Put depot_tool's git revision into the user agent string.
|
Robert Iannucci | 78628da | 2017-04-24 18:21:39 -0700 | [diff] [blame] | 32 | try {
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 33 | $DepotToolsVersion = &git -C $DepotToolsPath rev-parse HEAD 2>&1
|
Robert Iannucci | 78628da | 2017-04-24 18:21:39 -0700 | [diff] [blame] | 34 | if ($LastExitCode -eq 0) {
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 35 | $UserAgent = "depot_tools/$DepotToolsVersion"
|
Robert Iannucci | 78628da | 2017-04-24 18:21:39 -0700 | [diff] [blame] | 36 | } else {
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 37 | $UserAgent = "depot_tools/???"
|
Robert Iannucci | 78628da | 2017-04-24 18:21:39 -0700 | [diff] [blame] | 38 | }
|
| 39 | } catch [System.Management.Automation.CommandNotFoundException] {
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 40 | $UserAgent = "depot_tools/no_git/???"
|
| 41 | }
|
| 42 | $Env:CIPD_HTTP_USER_AGENT_PREFIX = $UserAgent
|
| 43 |
|
| 44 |
|
| 45 | # Tries to delete the file, ignoring errors. Used for best-effort cleanups.
|
| 46 | function Delete-If-Possible($path) {
|
| 47 | try {
|
| 48 | [System.IO.File]::Delete($path)
|
| 49 | } catch {
|
| 50 | $err = $_.Exception.Message
|
| 51 | echo "Warning: error when deleting $path - $err. Ignoring."
|
| 52 | }
|
Robert Iannucci | 2188fe9 | 2016-12-02 11:15:57 -0800 | [diff] [blame] | 53 | }
|
| 54 |
|
Dan Jacques | 7c2e05b | 2017-07-06 10:03:30 -0700 | [diff] [blame] | 55 |
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 56 | # Returns the expected SHA256 hex digest for the given platform reading it from
|
| 57 | # *.digests file.
|
| 58 | function Get-Expected-SHA256($platform) {
|
| 59 | $digestsFile = $VersionFile+".digests"
|
| 60 | foreach ($line in Get-Content $digestsFile) {
|
| 61 | if ($line -match "^([0-9a-z\-]+)\s+sha256\s+([0-9a-f]+)$") {
|
| 62 | if ($Matches[1] -eq $platform) {
|
| 63 | return $Matches[2]
|
| 64 | }
|
| 65 | }
|
| 66 | }
|
| 67 | throw "No SHA256 digests for $platform in $digestsFile"
|
| 68 | }
|
| 69 |
|
| 70 |
|
| 71 | # Returns SHA256 hex digest of a binary file at the given path.
|
| 72 | function Get-Actual-SHA256($path) {
|
| 73 | # Note: we don't use Get-FileHash to be compatible with PowerShell v3.0
|
| 74 | $file = [System.IO.File]::Open($path, [System.IO.FileMode]::Open)
|
Dan Jacques | 7c2e05b | 2017-07-06 10:03:30 -0700 | [diff] [blame] | 75 | try {
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 76 | $algo = New-Object System.Security.Cryptography.SHA256Managed
|
| 77 | $hash = $algo.ComputeHash($file)
|
| 78 | } finally {
|
| 79 | $file.Close()
|
| 80 | }
|
| 81 | $hex = ""
|
| 82 | foreach ($byte in $hash) {
|
| 83 | $hex += $byte.ToString("x2")
|
| 84 | }
|
| 85 | return $hex
|
| 86 | }
|
Dan Jacques | 7c2e05b | 2017-07-06 10:03:30 -0700 | [diff] [blame] | 87 |
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 88 |
|
| 89 | $ExpectedSHA256 = Get-Expected-SHA256 $Platform
|
| 90 | $Version = (Get-Content $VersionFile).Trim()
|
| 91 | $URL = "$BackendURL/client?platform=$Platform&version=$Version"
|
| 92 |
|
| 93 |
|
Vadim Shtayura | dfedcc0 | 2018-09-14 19:47:37 +0000 | [diff] [blame] | 94 | # Grab a lock to prevent simultaneous processes from stepping on each other.
|
| 95 | # This depends on "exclusive write" file sharing mode used by OpenWrite.
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 96 | $CipdLockPath = Join-Path $DepotToolsPath -ChildPath ".cipd_client.lock"
|
Vadim Shtayura | dfedcc0 | 2018-09-14 19:47:37 +0000 | [diff] [blame] | 97 | $CipdLockFile = $null
|
| 98 | while ($CipdLockFile -eq $null) {
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 99 | try {
|
| 100 | $CipdLockFile = [System.IO.File]::OpenWrite($CipdLockPath)
|
Vadim Shtayura | 7e50ee3 | 2018-07-26 17:43:51 +0000 | [diff] [blame] | 101 | } catch [System.IO.IOException] {
|
Vadim Shtayura | 95fb6dc | 2018-08-16 19:01:27 +0000 | [diff] [blame] | 102 | echo "CIPD bootstrap lock is held, trying again after delay..."
|
| 103 | Start-Sleep -s 1
|
Dan Jacques | 7c2e05b | 2017-07-06 10:03:30 -0700 | [diff] [blame] | 104 | }
|
Dan Jacques | eb1feb9 | 2017-07-28 13:04:28 +0200 | [diff] [blame] | 105 | }
|
Vadim Shtayura | dfedcc0 | 2018-09-14 19:47:37 +0000 | [diff] [blame] | 106 |
|
| 107 | # Fetch the binary now that the lock is ours.
|
| 108 | $TmpPath = $CipdBinary + ".tmp"
|
| 109 | try {
|
| 110 | echo "Downloading CIPD client for $Platform from $URL..."
|
| 111 | $wc = (New-Object System.Net.WebClient)
|
| 112 | $wc.Headers.Add("User-Agent", $UserAgent)
|
| 113 | try {
|
| 114 | $wc.DownloadFile($URL, $TmpPath)
|
| 115 | } catch {
|
| 116 | throw "Failed to download the file, check your network connection"
|
| 117 | }
|
| 118 |
|
| 119 | $ActualSHA256 = Get-Actual-SHA256 $TmpPath
|
| 120 | if ($ActualSHA256 -ne $ExpectedSHA256) {
|
| 121 | throw "Invalid SHA256 digest: $ActualSHA256 != $ExpectedSHA256"
|
| 122 | }
|
| 123 |
|
| 124 | Move-Item -LiteralPath $TmpPath -Destination $CipdBinary -Force
|
| 125 | } finally {
|
| 126 | $CipdLockFile.Close()
|
| 127 | Delete-If-Possible $CipdLockPath
|
| 128 | Delete-If-Possible $TmpPath
|
| 129 | }
|