| # Copyright (c) 2016 The Chromium Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| # Note: to run this on e.g. OSX for adhoc testing or debugging in case Windows | |
| # is not around: | |
| # | |
| # pwsh | |
| # PS ...> $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage" | |
| # PS ...> ./.cipd_impl.ps1 -CipdBinary _cipd.exe ` | |
| # -BackendURL https://chrome-infra-packages.appspot.com ` | |
| # -VersionFile ./cipd_client_version | |
| # file _cipd.exe | |
| param( | |
| # Path to download the CIPD binary to. | |
| [Parameter(Mandatory = $true)] | |
| [string] | |
| $CipdBinary, | |
| # CIPD platform to download the client for. | |
| [string] | |
| $Platform = "windows-amd64", | |
| # E.g. "https://chrome-infra-packages.appspot.com". | |
| [Parameter(Mandatory = $true)] | |
| [string] | |
| $BackendURL, | |
| # Path to the cipd_client_version file with the client version. | |
| [Parameter(Mandatory = $true)] | |
| [string] | |
| $VersionFile | |
| ) | |
| # Import PowerShell<=5 Get-Filehash from Microsoft.PowerShell.Utility. | |
| # This prevents loading of incompatible Get-FileHash from PowerShell 6+ $PSModulePath. | |
| # See: crbug.com/1443163. | |
| Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash | |
| $DepotToolsPath = Split-Path $MyInvocation.MyCommand.Path -Parent | |
| # Put depot_tool's git revision into the user agent string. | |
| try { | |
| $DepotToolsVersion = &git -C $DepotToolsPath rev-parse HEAD 2>&1 | |
| if ($LastExitCode -eq 0) { | |
| $UserAgent = "depot_tools/$DepotToolsVersion" | |
| } else { | |
| $UserAgent = "depot_tools/???" | |
| } | |
| } catch [System.Management.Automation.CommandNotFoundException] { | |
| $UserAgent = "depot_tools/no_git/???" | |
| } | |
| $Env:CIPD_HTTP_USER_AGENT_PREFIX = $UserAgent | |
| # Returns the expected SHA256 hex digest for the given platform reading it from | |
| # *.digests file. | |
| function Get-Expected-SHA256($platform) { | |
| $digestsFile = $VersionFile+".digests" | |
| foreach ($line in Get-Content $digestsFile) { | |
| if ($line -match "^([0-9a-z\-]+)\s+sha256\s+([0-9a-f]+)$") { | |
| if ($Matches[1] -eq $platform) { | |
| return $Matches[2] | |
| } | |
| } | |
| } | |
| throw "No SHA256 digests for $platform in $digestsFile" | |
| } | |
| # Retry a command with a delay between each. | |
| function Retry-Command { | |
| [CmdletBinding()] | |
| param ( | |
| [Parameter(Mandatory = $true)] | |
| [scriptblock] | |
| $Command, | |
| [int] | |
| $MaxAttempts = 3, | |
| [timespan] | |
| $Delay = (New-TimeSpan -Seconds 5) | |
| ) | |
| $attempt = 0 | |
| while ($attempt -lt $MaxAttempts) { | |
| try { | |
| Invoke-Command -ScriptBlock $Command | |
| return | |
| } | |
| catch { | |
| $attempt += 1 | |
| $exception = $_.Exception.InnerException | |
| if ($attempt -lt $MaxAttempts) { | |
| Write-Output "FAILURE: " + $_ | |
| Write-Output "Retrying after a short nap..." | |
| Start-Sleep -Seconds $Delay.TotalSeconds | |
| } else { | |
| throw $exception | |
| } | |
| } | |
| } | |
| } | |
| # Check is url in the NO_PROXY of Environment? | |
| function Is-UrlInNoProxy { | |
| [CmdletBinding()] | |
| param ( | |
| [Parameter(Mandatory)] | |
| [string]$Url | |
| ) | |
| $NoProxy = $Env:NO_PROXY | |
| if ([string]::IsNullOrEmpty($NoProxy)) { | |
| return $false | |
| } | |
| $NoProxyList = $NoProxy -split ',' | ForEach-Object { $_.Trim().ToLower() } | |
| $UriHost = ([uri]$Url).Host.ToLower() | |
| foreach ($entry in $NoProxyList) { | |
| if ($entry.StartsWith('.')) { | |
| if ($UriHost.EndsWith($entry.Substring(1))) { | |
| return $true | |
| } | |
| } elseif ($entry -eq $UriHost) { | |
| return $true | |
| } | |
| } | |
| return $false | |
| } | |
| $ExpectedSHA256 = Get-Expected-SHA256 $Platform | |
| $Version = (Get-Content $VersionFile).Trim() | |
| $URL = "$BackendURL/client?platform=$Platform&version=$Version" | |
| # Fetch the binary now that the lock is ours. | |
| $TmpPath = $CipdBinary + ".tmp." + $PID | |
| try { | |
| Write-Output "Downloading CIPD client for $Platform from $URL..." | |
| $Parameters = @{ | |
| UserAgent = $UserAgent | |
| Uri = $URL | |
| OutFile = $TmpPath | |
| } | |
| if ($Env:HTTPS_PROXY) { | |
| $Proxy = $Env:HTTPS_PROXY | |
| } elseif ($Env:HTTP_PROXY) { | |
| $Proxy = $Env:HTTP_PROXY | |
| } elseif ($Env:ALL_PROXY) { | |
| $Proxy = $Env:ALL_PROXY | |
| } else { | |
| $Proxy = $null | |
| } | |
| $UrlNotInNoProxy = -not (Is-UrlInNoProxy -Url $URL) | |
| if ($UrlNotInNoProxy -and $Proxy) { | |
| Write-Output "Using Proxy $Proxy..." | |
| $Parameters.Proxy = $Proxy | |
| } | |
| Retry-Command { | |
| $ProgressPreference = "SilentlyContinue" | |
| Invoke-WebRequest @Parameters | |
| } | |
| $ActualSHA256 = (Get-FileHash -Path $TmpPath -Algorithm "SHA256").Hash.toLower() | |
| if ($ActualSHA256 -ne $ExpectedSHA256) { | |
| throw "Invalid SHA256 digest: $ActualSHA256 != $ExpectedSHA256" | |
| } | |
| Move-Item -LiteralPath $TmpPath -Destination $CipdBinary -Force | |
| } catch { | |
| Remove-Item -Path $TmpPath -ErrorAction Ignore | |
| throw # Re raise any error | |
| } |