blob: 1154e4ef828ff2157b2541195ac50aef5e403c26 [file] [log] [blame]
Robert Iannucci2188fe92016-12-02 11:15:57 -08001# 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 Shtayura95fb6dc2018-08-16 19:01:27 +00005Param(
6 # Path to download the CIPD binary to.
7 [parameter(Mandatory=$true)][string]$CipdBinary,
8 # E.g. "https://chrome-infra-packages.appspot.com".
9 [parameter(Mandatory=$true)][string]$BackendURL,
10 # Path to the cipd_client_version file with the client version.
11 [parameter(Mandatory=$true)][string]$VersionFile
12)
Robert Iannucci2188fe92016-12-02 11:15:57 -080013
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000014$DepotToolsPath = Split-Path $MyInvocation.MyCommand.Path -Parent
Robert Iannucci2188fe92016-12-02 11:15:57 -080015
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000016if ([System.IntPtr]::Size -eq 8) {
17 $Platform = "windows-amd64"
Robert Iannucci2188fe92016-12-02 11:15:57 -080018} else {
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000019 $Platform = "windows-386"
Robert Iannucci2188fe92016-12-02 11:15:57 -080020}
21
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000022# Put depot_tool's git revision into the user agent string.
Robert Iannucci78628da2017-04-24 18:21:39 -070023try {
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000024 $DepotToolsVersion = &git -C $DepotToolsPath rev-parse HEAD 2>&1
Robert Iannucci78628da2017-04-24 18:21:39 -070025 if ($LastExitCode -eq 0) {
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000026 $UserAgent = "depot_tools/$DepotToolsVersion"
Robert Iannucci78628da2017-04-24 18:21:39 -070027 } else {
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000028 $UserAgent = "depot_tools/???"
Robert Iannucci78628da2017-04-24 18:21:39 -070029 }
30} catch [System.Management.Automation.CommandNotFoundException] {
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000031 $UserAgent = "depot_tools/no_git/???"
32}
33$Env:CIPD_HTTP_USER_AGENT_PREFIX = $UserAgent
34
35
36# Tries to delete the file, ignoring errors. Used for best-effort cleanups.
37function Delete-If-Possible($path) {
38 try {
39 [System.IO.File]::Delete($path)
40 } catch {
41 $err = $_.Exception.Message
42 echo "Warning: error when deleting $path - $err. Ignoring."
43 }
Robert Iannucci2188fe92016-12-02 11:15:57 -080044}
45
Dan Jacques7c2e05b2017-07-06 10:03:30 -070046
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000047# Returns the expected SHA256 hex digest for the given platform reading it from
48# *.digests file.
49function Get-Expected-SHA256($platform) {
50 $digestsFile = $VersionFile+".digests"
51 foreach ($line in Get-Content $digestsFile) {
52 if ($line -match "^([0-9a-z\-]+)\s+sha256\s+([0-9a-f]+)$") {
53 if ($Matches[1] -eq $platform) {
54 return $Matches[2]
55 }
56 }
57 }
58 throw "No SHA256 digests for $platform in $digestsFile"
59}
60
61
62# Returns SHA256 hex digest of a binary file at the given path.
63function Get-Actual-SHA256($path) {
64 # Note: we don't use Get-FileHash to be compatible with PowerShell v3.0
65 $file = [System.IO.File]::Open($path, [System.IO.FileMode]::Open)
Dan Jacques7c2e05b2017-07-06 10:03:30 -070066 try {
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000067 $algo = New-Object System.Security.Cryptography.SHA256Managed
68 $hash = $algo.ComputeHash($file)
69 } finally {
70 $file.Close()
71 }
72 $hex = ""
73 foreach ($byte in $hash) {
74 $hex += $byte.ToString("x2")
75 }
76 return $hex
77}
Dan Jacques7c2e05b2017-07-06 10:03:30 -070078
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +000079
80$ExpectedSHA256 = Get-Expected-SHA256 $Platform
81$Version = (Get-Content $VersionFile).Trim()
82$URL = "$BackendURL/client?platform=$Platform&version=$Version"
83
84
85# Use a lock file to prevent simultaneous processes from stepping on each other.
86$CipdLockPath = Join-Path $DepotToolsPath -ChildPath ".cipd_client.lock"
87$TmpPath = $CipdBinary + ".tmp"
88while ($true) {
89 $CipdLockFile = $null
90 try {
91 $CipdLockFile = [System.IO.File]::OpenWrite($CipdLockPath)
92
93 echo "Downloading CIPD client for $Platform from $URL..."
94 $wc = (New-Object System.Net.WebClient)
95 $wc.Headers.Add("User-Agent", $UserAgent)
96 $wc.DownloadFile($URL, $TmpPath)
97
98 $ActualSHA256 = Get-Actual-SHA256 $TmpPath
99 if ($ActualSHA256 -ne $ExpectedSHA256) {
100 throw "Invalid SHA256 digest: $ActualSHA256 != $ExpectedSHA256"
101 }
102
103 Move-Item -LiteralPath $TmpPath -Destination $CipdBinary -Force
104 break
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000105
106 } catch [System.IO.IOException] {
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +0000107 echo "CIPD bootstrap lock is held, trying again after delay..."
108 Start-Sleep -s 1
Vadim Shtayura7e50ee32018-07-26 17:43:51 +0000109 } catch {
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +0000110 throw # for some reason this is needed to exit while(...) loop on errors
Dan Jacques7c2e05b2017-07-06 10:03:30 -0700111 } finally {
Vadim Shtayura95fb6dc2018-08-16 19:01:27 +0000112 Delete-If-Possible $TmpPath
113 if ($CipdLockFile) {
114 $CipdLockFile.Close()
115 Delete-If-Possible $CipdLockPath
116 }
Dan Jacques7c2e05b2017-07-06 10:03:30 -0700117 }
Dan Jacqueseb1feb92017-07-28 13:04:28 +0200118}