Files
chromium_depot_tools/.cipd_impl.ps1
Vadim Shtayura 4f3b322a39 [cipd] Add windows-arm64 support to CIPD client bootstrap.
This actually updates the CIPD client to a version that has
a windows-arm64 build, as well as modifies the bootstrap script
to support multiple possible Windows platforms (which is very
similar to what was done to support mac-arm64 on OSX).

By default windows-amd64 is still used everywhere, even on arm64 OS.
To opt-in into windows-arm64, create a file .cipd_client_platform
under depot_tools directory with a single line "windows-arm64".

The bootstrap script now recognizes this file (if it exists) and
rebootstraps the CIPD client if the platform changes. Since this
check needs to happen on every CIPD invocation, it is done in
the batch file, to avoid hitting relatively heavy Powershell on
the hot path.

Finally, do some minor style cleanup in the powershell script to
make it look more consistent.

CIPD client change log:
9cc9fd49..5252f4fc7/cipd

R=bryner@google.com

Change-Id: I4fe5c4ea5e0b5cbb43e7b8c4702dc9fb0627c056
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/4153336
Reviewed-by: Brian Ryner <bryner@google.com>
Commit-Queue: Vadim Shtayura <vadimsh@chromium.org>
2023-01-12 00:11:03 +00:00

203 lines
5.3 KiB
PowerShell

# 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 cipd.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
)
$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
# Tries to delete the file, ignoring errors. Used for best-effort cleanups.
function Delete-If-Possible($path) {
try {
[System.IO.File]::Delete($path)
} catch {
$err = $_.Exception.Message
echo "Warning: error when deleting $path - $err. Ignoring."
}
}
# 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"
}
# Returns SHA256 hex digest of a binary file at the given path.
function Get-Actual-SHA256($path) {
# Note: we don't use Get-FileHash to be compatible with PowerShell v3.0
$file = [System.IO.File]::Open($path, [System.IO.FileMode]::Open)
try {
$algo = New-Object System.Security.Cryptography.SHA256Managed
$hash = $algo.ComputeHash($file)
} finally {
$file.Close()
}
$hex = ""
foreach ($byte in $hash) {
$hex += $byte.ToString("x2")
}
return $hex
}
# Download a file to a particular path.
function Download-File {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]
$UserAgent,
[Parameter(Mandatory = $true)]
[string]
$Url,
[Parameter(Mandatory = $true)]
[string]
$Path
)
$wc = (New-Object System.Net.WebClient)
$wc.Headers.Add("User-Agent", $UserAgent)
try {
# Download failures were reported on Windows 8.1 without this line.
[System.Net.ServicePointManager]::SecurityProtocol = `
[System.Net.SecurityProtocolType]::Tls12
$wc.DownloadFile($Url, $Path)
}
catch {
$err = $_.Exception.Message
throw "Failed to download the file, check your network connection, $err"
}
finally {
$wc.Dispose()
}
}
# 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 {
$Command.Invoke()
return
}
catch {
$attempt += 1
$exception = $_.Exception.InnerException
if ($attempt -lt $MaxAttempts) {
echo $exception.Message
echo "Retrying after a short nap..."
Start-Sleep -Seconds $Delay.TotalSeconds
} else {
throw $exception
}
}
}
}
$ExpectedSHA256 = Get-Expected-SHA256 $Platform
$Version = (Get-Content $VersionFile).Trim()
$URL = "$BackendURL/client?platform=$Platform&version=$Version"
# Grab a lock to prevent simultaneous processes from stepping on each other.
# This depends on "exclusive write" file sharing mode used by OpenWrite.
$CipdLockPath = Join-Path $DepotToolsPath -ChildPath ".cipd_client.lock"
$CipdLockFile = $null
while ($CipdLockFile -eq $null) {
try {
$CipdLockFile = [System.IO.File]::OpenWrite($CipdLockPath)
} catch [System.IO.IOException] {
echo "CIPD bootstrap lock is held, trying again after delay..."
Start-Sleep -s 1
}
}
# Fetch the binary now that the lock is ours.
$TmpPath = $CipdBinary + ".tmp"
try {
echo "Downloading CIPD client for $Platform from $URL..."
Retry-Command -Command {
Download-File -UserAgent $UserAgent -Url $URL -Path $TmpPath
}
$ActualSHA256 = Get-Actual-SHA256 $TmpPath
if ($ActualSHA256 -ne $ExpectedSHA256) {
throw "Invalid SHA256 digest: $ActualSHA256 != $ExpectedSHA256"
}
Move-Item -LiteralPath $TmpPath -Destination $CipdBinary -Force
} finally {
$CipdLockFile.Close()
Delete-If-Possible $CipdLockPath
Delete-If-Possible $TmpPath
}