mirror of
https://github.com/actions/setup-dotnet.git
synced 2025-01-31 12:37:12 +07:00
New cdn url changes
This commit is contained in:
parent
608ee757cf
commit
713c507045
2
.github/workflows/check-dist.yml
vendored
2
.github/workflows/check-dist.yml
vendored
@ -44,7 +44,7 @@ jobs:
|
|||||||
id: diff
|
id: diff
|
||||||
|
|
||||||
# If index.js was different than expected, upload the expected version as an artifact
|
# If index.js was different than expected, upload the expected version as an artifact
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v4
|
||||||
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||||
with:
|
with:
|
||||||
name: dist
|
name: dist
|
||||||
|
2
.github/workflows/test-dotnet.yml
vendored
2
.github/workflows/test-dotnet.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||||
dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0']
|
dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0']
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
24
.github/workflows/workflow.yml
vendored
24
.github/workflows/workflow.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -38,7 +38,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -61,7 +61,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
operating-system: [ubuntu-22.04, windows-latest, macos-13]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -94,7 +94,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -119,7 +119,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -143,7 +143,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -163,18 +163,20 @@ jobs:
|
|||||||
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
||||||
|
|
||||||
test-proxy:
|
test-proxy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
container:
|
container:
|
||||||
image: mcr.microsoft.com/dotnet/core/runtime-deps:3.0-bionic
|
image: ubuntu:latest
|
||||||
options: --dns 127.0.0.1
|
options: --dns 127.0.0.1
|
||||||
services:
|
services:
|
||||||
squid-proxy:
|
squid-proxy:
|
||||||
image: datadog/squid:latest
|
image: ubuntu/squid:latest
|
||||||
ports:
|
ports:
|
||||||
- 3128:3128
|
- 3128:3128
|
||||||
env:
|
env:
|
||||||
https_proxy: http://squid-proxy:3128
|
https_proxy: http://squid-proxy:3128
|
||||||
http_proxy: http://squid-proxy:3128
|
http_proxy: http://squid-proxy:3128
|
||||||
|
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: true
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -183,7 +185,7 @@ jobs:
|
|||||||
- name: Install curl
|
- name: Install curl
|
||||||
run: |
|
run: |
|
||||||
apt update
|
apt update
|
||||||
apt -y install curl
|
apt -y install curl libssl-dev
|
||||||
- name: Setup dotnet 3.1.201
|
- name: Setup dotnet 3.1.201
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
@ -195,7 +197,7 @@ jobs:
|
|||||||
run: __tests__/verify-dotnet.sh 3.1.201
|
run: __tests__/verify-dotnet.sh 3.1.201
|
||||||
|
|
||||||
test-bypass-proxy:
|
test-bypass-proxy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-22.04
|
||||||
env:
|
env:
|
||||||
https_proxy: http://no-such-proxy:3128
|
https_proxy: http://no-such-proxy:3128
|
||||||
no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net
|
no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net
|
||||||
|
531
externals/install-dotnet.ps1
vendored
531
externals/install-dotnet.ps1
vendored
@ -9,27 +9,34 @@
|
|||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Installs dotnet cli. If dotnet installation already exists in the given directory
|
Installs dotnet cli. If dotnet installation already exists in the given directory
|
||||||
it will update it only if the requested version differs from the one already installed.
|
it will update it only if the requested version differs from the one already installed.
|
||||||
|
|
||||||
|
Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:
|
||||||
|
- The SDK needs to be installed without user interaction and without admin rights.
|
||||||
|
- The SDK installation doesn't need to persist across multiple CI runs.
|
||||||
|
To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.
|
||||||
|
|
||||||
.PARAMETER Channel
|
.PARAMETER Channel
|
||||||
Default: LTS
|
Default: LTS
|
||||||
Download from the Channel specified. Possible values:
|
Download from the Channel specified. Possible values:
|
||||||
- Current - most current release
|
- STS - the most recent Standard Term Support release
|
||||||
- LTS - most current supported release
|
- LTS - the most recent Long Term Support release
|
||||||
- 2-part version in a format A.B - represents a specific release
|
- 2-part version in a format A.B - represents a specific release
|
||||||
examples: 2.0, 1.0
|
examples: 2.0, 1.0
|
||||||
- 3-part version in a format A.B.Cxx - represents a specific SDK release
|
- 3-part version in a format A.B.Cxx - represents a specific SDK release
|
||||||
examples: 5.0.1xx, 5.0.2xx
|
examples: 5.0.1xx, 5.0.2xx
|
||||||
Supported since 5.0 release
|
Supported since 5.0 release
|
||||||
|
Warning: Value "Current" is deprecated for the Channel parameter. Use "STS" instead.
|
||||||
Note: The version parameter overrides the channel parameter when any version other than 'latest' is used.
|
Note: The version parameter overrides the channel parameter when any version other than 'latest' is used.
|
||||||
.PARAMETER Quality
|
.PARAMETER Quality
|
||||||
Download the latest build of specified quality in the channel. The possible values are: daily, signed, validated, preview, GA.
|
Download the latest build of specified quality in the channel. The possible values are: daily, signed, validated, preview, GA.
|
||||||
Works only in combination with channel. Not applicable for current and LTS channels and will be ignored if those channels are used.
|
Works only in combination with channel. Not applicable for STS and LTS channels and will be ignored if those channels are used.
|
||||||
For SDK use channel in A.B.Cxx format: using quality together with channel in A.B format is not supported.
|
For SDK use channel in A.B.Cxx format: using quality together with channel in A.B format is not supported.
|
||||||
Supported since 5.0 release.
|
Supported since 5.0 release.
|
||||||
Note: The version parameter overrides the channel parameter when any version other than 'latest' is used, and therefore overrides the quality.
|
Note: The version parameter overrides the channel parameter when any version other than 'latest' is used, and therefore overrides the quality.
|
||||||
.PARAMETER Version
|
.PARAMETER Version
|
||||||
Default: latest
|
Default: latest
|
||||||
Represents a build version on specific channel. Possible values:
|
Represents a build version on specific channel. Possible values:
|
||||||
- latest - most latest build on specific channel
|
- latest - the latest build on specific channel
|
||||||
- 3-part version in a format A.B.C - represents specific version of build
|
- 3-part version in a format A.B.C - represents specific version of build
|
||||||
examples: 2.0.0-preview2-006120, 1.1.0
|
examples: 2.0.0-preview2-006120, 1.1.0
|
||||||
.PARAMETER Internal
|
.PARAMETER Internal
|
||||||
@ -91,6 +98,16 @@
|
|||||||
.PARAMETER DownloadTimeout
|
.PARAMETER DownloadTimeout
|
||||||
Determines timeout duration in seconds for dowloading of the SDK file
|
Determines timeout duration in seconds for dowloading of the SDK file
|
||||||
Default: 1200 seconds (20 minutes)
|
Default: 1200 seconds (20 minutes)
|
||||||
|
.PARAMETER KeepZip
|
||||||
|
If set, downloaded file is kept
|
||||||
|
.PARAMETER ZipPath
|
||||||
|
Use that path to store installer, generated by default
|
||||||
|
.EXAMPLE
|
||||||
|
dotnet-install.ps1 -Version 7.0.401
|
||||||
|
Installs the .NET SDK version 7.0.401
|
||||||
|
.EXAMPLE
|
||||||
|
dotnet-install.ps1 -Channel 8.0 -Quality GA
|
||||||
|
Installs the latest GA (general availability) version of the .NET 8.0 SDK
|
||||||
#>
|
#>
|
||||||
[cmdletbinding()]
|
[cmdletbinding()]
|
||||||
param(
|
param(
|
||||||
@ -114,7 +131,10 @@ param(
|
|||||||
[string[]]$ProxyBypassList = @(),
|
[string[]]$ProxyBypassList = @(),
|
||||||
[switch]$SkipNonVersionedFiles,
|
[switch]$SkipNonVersionedFiles,
|
||||||
[switch]$NoCdn,
|
[switch]$NoCdn,
|
||||||
[int]$DownloadTimeout=1200
|
[int]$DownloadTimeout = 1200,
|
||||||
|
[switch]$KeepZip,
|
||||||
|
[string]$ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()),
|
||||||
|
[switch]$Help
|
||||||
)
|
)
|
||||||
|
|
||||||
Set-StrictMode -Version Latest
|
Set-StrictMode -Version Latest
|
||||||
@ -163,6 +183,29 @@ function Say-Verbose($str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Measure-Action($name, $block) {
|
||||||
|
$time = Measure-Command $block
|
||||||
|
$totalSeconds = $time.TotalSeconds
|
||||||
|
Say-Verbose "Action '$name' took $totalSeconds seconds"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-Remote-File-Size($zipUri) {
|
||||||
|
try {
|
||||||
|
$response = Invoke-WebRequest -Uri $zipUri -Method Head
|
||||||
|
$fileSize = $response.Headers["Content-Length"]
|
||||||
|
if ((![string]::IsNullOrEmpty($fileSize))) {
|
||||||
|
Say "Remote file $zipUri size is $fileSize bytes."
|
||||||
|
|
||||||
|
return $fileSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Say-Verbose "Content-Length header was not extracted for $zipUri."
|
||||||
|
}
|
||||||
|
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
function Say-Invocation($Invocation) {
|
function Say-Invocation($Invocation) {
|
||||||
$command = $Invocation.MyCommand;
|
$command = $Invocation.MyCommand;
|
||||||
$args = (($Invocation.BoundParameters.Keys | foreach { "-$_ `"$($Invocation.BoundParameters[$_])`"" }) -join " ")
|
$args = (($Invocation.BoundParameters.Keys | foreach { "-$_ `"$($Invocation.BoundParameters[$_])`"" }) -join " ")
|
||||||
@ -171,6 +214,7 @@ function Say-Invocation($Invocation) {
|
|||||||
|
|
||||||
function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [System.Threading.CancellationToken]$cancellationToken = [System.Threading.CancellationToken]::None, [int]$MaxAttempts = 3, [int]$SecondsBetweenAttempts = 1) {
|
function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [System.Threading.CancellationToken]$cancellationToken = [System.Threading.CancellationToken]::None, [int]$MaxAttempts = 3, [int]$SecondsBetweenAttempts = 1) {
|
||||||
$Attempts = 0
|
$Attempts = 0
|
||||||
|
$local:startTime = $(get-date)
|
||||||
|
|
||||||
while ($true) {
|
while ($true) {
|
||||||
try {
|
try {
|
||||||
@ -182,7 +226,11 @@ function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [System.Threading.Cancella
|
|||||||
Start-Sleep $SecondsBetweenAttempts
|
Start-Sleep $SecondsBetweenAttempts
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw
|
$local:elapsedTime = $(get-date) - $local:startTime
|
||||||
|
if (($local:elapsedTime.TotalSeconds - $DownloadTimeout) -gt 0 -and -not $cancellationToken.IsCancellationRequested) {
|
||||||
|
throw New-Object System.TimeoutException("Failed to reach the server: connection timeout: default timeout is $DownloadTimeout second(s)");
|
||||||
|
}
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,6 +247,18 @@ function Get-Machine-Architecture() {
|
|||||||
return $ENV:PROCESSOR_ARCHITEW6432
|
return $ENV:PROCESSOR_ARCHITEW6432
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ( ((Get-CimInstance -ClassName CIM_OperatingSystem).OSArchitecture) -like "ARM*") {
|
||||||
|
if ( [Environment]::Is64BitOperatingSystem ) {
|
||||||
|
return "arm64"
|
||||||
|
}
|
||||||
|
return "arm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
# Machine doesn't support Get-CimInstance
|
||||||
|
}
|
||||||
|
|
||||||
return $ENV:PROCESSOR_ARCHITECTURE
|
return $ENV:PROCESSOR_ARCHITECTURE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,13 +278,13 @@ function Get-CLIArchitecture-From-Architecture([string]$Architecture) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ValidateFeedCredential([string] $FeedCredential)
|
function ValidateFeedCredential([string] $FeedCredential) {
|
||||||
{
|
|
||||||
if ($Internal -and [string]::IsNullOrWhitespace($FeedCredential)) {
|
if ($Internal -and [string]::IsNullOrWhitespace($FeedCredential)) {
|
||||||
$message = "Provide credentials via -FeedCredential parameter."
|
$message = "Provide credentials via -FeedCredential parameter."
|
||||||
if ($DryRun) {
|
if ($DryRun) {
|
||||||
Say-Warning "$message"
|
Say-Warning "$message"
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw "$message"
|
throw "$message"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,13 +319,18 @@ function Get-NormalizedChannel([string]$Channel) {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($Channel.Contains("Current")) {
|
||||||
|
Say-Warning 'Value "Current" is deprecated for -Channel option. Use "STS" instead.'
|
||||||
|
}
|
||||||
|
|
||||||
if ($Channel.StartsWith('release/')) {
|
if ($Channel.StartsWith('release/')) {
|
||||||
Say-Warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead, such as "-Channel 5.0 -Quality Daily."'
|
Say-Warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead, such as "-Channel 5.0 -Quality Daily."'
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($Channel) {
|
switch ($Channel) {
|
||||||
{ $_ -eq "lts" } { return "LTS" }
|
{ $_ -eq "lts" } { return "LTS" }
|
||||||
{ $_ -eq "current" } { return "current" }
|
{ $_ -eq "sts" } { return "STS" }
|
||||||
|
{ $_ -eq "current" } { return "STS" }
|
||||||
default { return $Channel.ToLowerInvariant() }
|
default { return $Channel.ToLowerInvariant() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,8 +376,7 @@ function Load-Assembly([string] $Assembly) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, [bool]$DisableFeedCredential)
|
function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, [bool]$DisableFeedCredential) {
|
||||||
{
|
|
||||||
$cts = New-Object System.Threading.CancellationTokenSource
|
$cts = New-Object System.Threading.CancellationTokenSource
|
||||||
|
|
||||||
$downloadScript = {
|
$downloadScript = {
|
||||||
@ -330,12 +394,14 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect,
|
|||||||
if ($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))) {
|
if ($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))) {
|
||||||
if ($null -ne $DefaultProxy.GetProxy($Uri)) {
|
if ($null -ne $DefaultProxy.GetProxy($Uri)) {
|
||||||
$ProxyAddress = $DefaultProxy.GetProxy($Uri).OriginalString
|
$ProxyAddress = $DefaultProxy.GetProxy($Uri).OriginalString
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
$ProxyAddress = $null
|
$ProxyAddress = $null
|
||||||
}
|
}
|
||||||
$ProxyUseDefaultCredentials = $true
|
$ProxyUseDefaultCredentials = $true
|
||||||
}
|
}
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
# Eat the exception and move forward as the above code is an attempt
|
# Eat the exception and move forward as the above code is an attempt
|
||||||
# at resolving the DefaultProxy that may not have been a problem.
|
# at resolving the DefaultProxy that may not have been a problem.
|
||||||
$ProxyAddress = $null
|
$ProxyAddress = $null
|
||||||
@ -351,8 +417,7 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect,
|
|||||||
BypassList = $ProxyBypassList;
|
BypassList = $ProxyBypassList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($DisableRedirect)
|
if ($DisableRedirect) {
|
||||||
{
|
|
||||||
$HttpClientHandler.AllowAutoRedirect = $false
|
$HttpClientHandler.AllowAutoRedirect = $false
|
||||||
}
|
}
|
||||||
$HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler
|
$HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler
|
||||||
@ -386,8 +451,7 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect,
|
|||||||
$DownloadException.Data["StatusCode"] = [int] $Response.StatusCode
|
$DownloadException.Data["StatusCode"] = [int] $Response.StatusCode
|
||||||
$DownloadException.Data["ErrorMessage"] = "Unable to download $Uri. Returned HTTP status code: " + $DownloadException.Data["StatusCode"]
|
$DownloadException.Data["ErrorMessage"] = "Unable to download $Uri. Returned HTTP status code: " + $DownloadException.Data["StatusCode"]
|
||||||
|
|
||||||
if (404 -eq [int] $Response.StatusCode)
|
if (404 -eq [int] $Response.StatusCode) {
|
||||||
{
|
|
||||||
$cts.Cancel()
|
$cts.Cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -426,10 +490,8 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect,
|
|||||||
try {
|
try {
|
||||||
return Invoke-With-Retry $downloadScript $cts.Token
|
return Invoke-With-Retry $downloadScript $cts.Token
|
||||||
}
|
}
|
||||||
finally
|
finally {
|
||||||
{
|
if ($null -ne $cts) {
|
||||||
if ($null -ne $cts)
|
|
||||||
{
|
|
||||||
$cts.Dispose()
|
$cts.Dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,11 +609,9 @@ function Get-Download-Link([string]$AzureFeed, [string]$SpecificVersion, [string
|
|||||||
elseif ($Runtime -eq "windowsdesktop") {
|
elseif ($Runtime -eq "windowsdesktop") {
|
||||||
# The windows desktop runtime is part of the core runtime layout prior to 5.0
|
# The windows desktop runtime is part of the core runtime layout prior to 5.0
|
||||||
$PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
|
$PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
|
||||||
if ($SpecificVersion -match '^(\d+)\.(.*)$')
|
if ($SpecificVersion -match '^(\d+)\.(.*)$') {
|
||||||
{
|
|
||||||
$majorVersion = [int]$Matches[1]
|
$majorVersion = [int]$Matches[1]
|
||||||
if ($majorVersion -ge 5)
|
if ($majorVersion -ge 5) {
|
||||||
{
|
|
||||||
$PayloadURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
|
$PayloadURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -601,8 +661,7 @@ function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion, [stri
|
|||||||
|
|
||||||
if ($productVersionResponse.StatusCode -eq 200) {
|
if ($productVersionResponse.StatusCode -eq 200) {
|
||||||
$productVersion = $productVersionResponse.Content.ReadAsStringAsync().Result.Trim()
|
$productVersion = $productVersionResponse.Content.ReadAsStringAsync().Result.Trim()
|
||||||
if ($productVersion -ne $SpecificVersion)
|
if ($productVersion -ne $SpecificVersion) {
|
||||||
{
|
|
||||||
Say "Using alternate version $productVersion found in $ProductVersionTxtURL"
|
Say "Using alternate version $productVersion found in $ProductVersionTxtURL"
|
||||||
}
|
}
|
||||||
return $productVersion
|
return $productVersion
|
||||||
@ -617,8 +676,7 @@ function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion, [stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number.
|
# Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number.
|
||||||
if ([string]::IsNullOrEmpty($PackageDownloadLink))
|
if ([string]::IsNullOrEmpty($PackageDownloadLink)) {
|
||||||
{
|
|
||||||
Say-Verbose "Using the default value '$SpecificVersion' as the product version."
|
Say-Verbose "Using the default value '$SpecificVersion' as the product version."
|
||||||
return $SpecificVersion
|
return $SpecificVersion
|
||||||
}
|
}
|
||||||
@ -678,16 +736,14 @@ function Get-Product-Version-Url([string]$AzureFeed, [string]$SpecificVersion, [
|
|||||||
return $ProductVersionTxtURL
|
return $ProductVersionTxtURL
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-ProductVersionFromDownloadLink([string]$PackageDownloadLink, [string]$SpecificVersion)
|
function Get-ProductVersionFromDownloadLink([string]$PackageDownloadLink, [string]$SpecificVersion) {
|
||||||
{
|
|
||||||
Say-Invocation $MyInvocation
|
Say-Invocation $MyInvocation
|
||||||
|
|
||||||
#product specific version follows the product name
|
#product specific version follows the product name
|
||||||
#for filename 'dotnet-sdk-3.1.404-win-x64.zip': the product version is 3.1.400
|
#for filename 'dotnet-sdk-3.1.404-win-x64.zip': the product version is 3.1.400
|
||||||
$filename = $PackageDownloadLink.Substring($PackageDownloadLink.LastIndexOf("/") + 1)
|
$filename = $PackageDownloadLink.Substring($PackageDownloadLink.LastIndexOf("/") + 1)
|
||||||
$filenameParts = $filename.Split('-')
|
$filenameParts = $filename.Split('-')
|
||||||
if ($filenameParts.Length -gt 2)
|
if ($filenameParts.Length -gt 2) {
|
||||||
{
|
|
||||||
$productVersion = $filenameParts[2]
|
$productVersion = $filenameParts[2]
|
||||||
Say-Verbose "Extracted product version '$productVersion' from download link '$PackageDownloadLink'."
|
Say-Verbose "Extracted product version '$productVersion' from download link '$PackageDownloadLink'."
|
||||||
}
|
}
|
||||||
@ -705,6 +761,9 @@ function Get-User-Share-Path() {
|
|||||||
if (!$InstallRoot) {
|
if (!$InstallRoot) {
|
||||||
$InstallRoot = "$env:LocalAppData\Microsoft\dotnet"
|
$InstallRoot = "$env:LocalAppData\Microsoft\dotnet"
|
||||||
}
|
}
|
||||||
|
elseif ($InstallRoot -like "$env:ProgramFiles\dotnet\?*") {
|
||||||
|
Say-Warning "The install root specified by the environment variable DOTNET_INSTALL_DIR points to the sub folder of $env:ProgramFiles\dotnet which is the default dotnet install root using .NET SDK installer. It is better to keep aligned with .NET SDK installer."
|
||||||
|
}
|
||||||
return $InstallRoot
|
return $InstallRoot
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,6 +776,19 @@ function Resolve-Installation-Path([string]$InstallDir) {
|
|||||||
return $InstallDir
|
return $InstallDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Test-User-Write-Access([string]$InstallDir) {
|
||||||
|
try {
|
||||||
|
$tempFileName = [guid]::NewGuid().ToString()
|
||||||
|
$tempFilePath = Join-Path -Path $InstallDir -ChildPath $tempFileName
|
||||||
|
New-Item -Path $tempFilePath -ItemType File -Force
|
||||||
|
Remove-Item $tempFilePath -Force
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Is-Dotnet-Package-Installed([string]$InstallRoot, [string]$RelativePathToPackage, [string]$SpecificVersion) {
|
function Is-Dotnet-Package-Installed([string]$InstallRoot, [string]$RelativePathToPackage, [string]$SpecificVersion) {
|
||||||
Say-Invocation $MyInvocation
|
Say-Invocation $MyInvocation
|
||||||
|
|
||||||
@ -800,6 +872,10 @@ function Extract-Dotnet-Package([string]$ZipPath, [string]$OutPath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Say-Error "Failed to extract package. Exception: $_"
|
||||||
|
throw;
|
||||||
|
}
|
||||||
finally {
|
finally {
|
||||||
if ($null -ne $Zip) {
|
if ($null -ne $Zip) {
|
||||||
$Zip.Dispose()
|
$Zip.Dispose()
|
||||||
@ -828,6 +904,8 @@ function DownloadFile($Source, [string]$OutPath) {
|
|||||||
$File = [System.IO.File]::Create($OutPath)
|
$File = [System.IO.File]::Create($OutPath)
|
||||||
$Stream.CopyTo($File)
|
$Stream.CopyTo($File)
|
||||||
$File.Close()
|
$File.Close()
|
||||||
|
|
||||||
|
ValidateRemoteLocalFileSizes -LocalFileOutPath $OutPath -SourceUri $Source
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if ($null -ne $Stream) {
|
if ($null -ne $Stream) {
|
||||||
@ -836,19 +914,40 @@ function DownloadFile($Source, [string]$OutPath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ValidateRemoteLocalFileSizes([string]$LocalFileOutPath, $SourceUri) {
|
||||||
|
try {
|
||||||
|
$remoteFileSize = Get-Remote-File-Size -zipUri $SourceUri
|
||||||
|
$fileSize = [long](Get-Item $LocalFileOutPath).Length
|
||||||
|
Say "Downloaded file $SourceUri size is $fileSize bytes."
|
||||||
|
|
||||||
|
if ((![string]::IsNullOrEmpty($remoteFileSize)) -and !([string]::IsNullOrEmpty($fileSize)) ) {
|
||||||
|
if ($remoteFileSize -ne $fileSize) {
|
||||||
|
Say "The remote and local file sizes are not equal. Remote file size is $remoteFileSize bytes and local size is $fileSize bytes. The local package may be corrupted."
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Say "The remote and local file sizes are equal."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Say "Either downloaded or local package size can not be measured. One of them may be corrupted."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Say "Either downloaded or local package size can not be measured. One of them may be corrupted."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function SafeRemoveFile($Path) {
|
function SafeRemoveFile($Path) {
|
||||||
try {
|
try {
|
||||||
if (Test-Path $Path) {
|
if (Test-Path $Path) {
|
||||||
Remove-Item $Path
|
Remove-Item $Path
|
||||||
Say-Verbose "The temporary file `"$Path`" was removed."
|
Say-Verbose "The temporary file `"$Path`" was removed."
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
Say-Verbose "The temporary file `"$Path`" does not exist, therefore is not removed."
|
Say-Verbose "The temporary file `"$Path`" does not exist, therefore is not removed."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch {
|
||||||
{
|
|
||||||
Say-Warning "Failed to remove the temporary file: `"$Path`", remove it manually."
|
Say-Warning "Failed to remove the temporary file: `"$Path`", remove it manually."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -860,7 +959,8 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot) {
|
|||||||
if (-Not $env:path.Contains($SuffixedBinPath)) {
|
if (-Not $env:path.Contains($SuffixedBinPath)) {
|
||||||
Say "Adding to current process PATH: `"$BinPath`". Note: This change will not be visible if PowerShell was run as a child process."
|
Say "Adding to current process PATH: `"$BinPath`". Note: This change will not be visible if PowerShell was run as a child process."
|
||||||
$env:path = $SuffixedBinPath + $env:path
|
$env:path = $SuffixedBinPath + $env:path
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Say-Verbose "Current process PATH already contains `"$BinPath`""
|
Say-Verbose "Current process PATH already contains `"$BinPath`""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -869,8 +969,7 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function PrintDryRunOutput($Invocation, $DownloadLinks)
|
function PrintDryRunOutput($Invocation, $DownloadLinks) {
|
||||||
{
|
|
||||||
Say "Payload URLs:"
|
Say "Payload URLs:"
|
||||||
|
|
||||||
for ($linkIndex = 0; $linkIndex -lt $DownloadLinks.count; $linkIndex++) {
|
for ($linkIndex = 0; $linkIndex -lt $DownloadLinks.count; $linkIndex++) {
|
||||||
@ -893,19 +992,44 @@ function PrintDryRunOutput($Invocation, $DownloadLinks)
|
|||||||
$RepeatableCommand += " -FeedCredential `"<feedCredential>`""
|
$RepeatableCommand += " -FeedCredential `"<feedCredential>`""
|
||||||
}
|
}
|
||||||
Say "Repeatable invocation: $RepeatableCommand"
|
Say "Repeatable invocation: $RepeatableCommand"
|
||||||
if ($SpecificVersion -ne $EffectiveVersion)
|
if ($SpecificVersion -ne $EffectiveVersion) {
|
||||||
{
|
|
||||||
Say "NOTE: Due to finding a version manifest with this runtime, it would actually install with version '$EffectiveVersion'"
|
Say "NOTE: Due to finding a version manifest with this runtime, it would actually install with version '$EffectiveVersion'"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# grab the 'stem' of the redirect and check it against all of our configured feeds,
|
||||||
|
# if it matches, we can be sure that the redirect is valid and we should use it for
|
||||||
|
# subsequent processing
|
||||||
|
function Sanitize-RedirectUrl([string]$url) {
|
||||||
|
$urlSegments = ([System.Uri]$url).Segments;
|
||||||
|
$urlStem = $urlSegments[2..($urlSegments.Length - 1)] -join "";
|
||||||
|
Write-Verbose "Checking configured feeds for the asset at $urlStem"
|
||||||
|
foreach ($prospectiveFeed in $feeds) {
|
||||||
|
$trialUrl = "$prospectiveFeed/$urlStem";
|
||||||
|
Write-Verbose "Checking $trialUrl"
|
||||||
|
try {
|
||||||
|
$trialResponse = Invoke-WebRequest -Uri $trialUrl -Method HEAD
|
||||||
|
if ($trialResponse.StatusCode -eq 200) {
|
||||||
|
Write-Verbose "Found a match at $trialUrl"
|
||||||
|
return $trialUrl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Verbose "No match at $trialUrl"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Verbose "Failed to check $trialUrl"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Internal, [string]$Product, [string]$Architecture) {
|
function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Internal, [string]$Product, [string]$Architecture) {
|
||||||
Say-Invocation $MyInvocation
|
Say-Invocation $MyInvocation
|
||||||
|
|
||||||
#quality is not supported for LTS or current channel
|
#quality is not supported for LTS or STS channel
|
||||||
if (![string]::IsNullOrEmpty($Quality) -and (@("LTS", "current") -contains $Channel)) {
|
if (![string]::IsNullOrEmpty($Quality) -and (@("LTS", "STS") -contains $Channel)) {
|
||||||
$Quality = ""
|
$Quality = ""
|
||||||
Say-Warning "Specifying quality for current or LTS channel is not supported, the quality will be ignored."
|
Say-Warning "Specifying quality for STS or LTS channel is not supported, the quality will be ignored."
|
||||||
}
|
}
|
||||||
Say-Verbose "Retrieving primary payload URL from aka.ms link for channel: '$Channel', quality: '$Quality' product: '$Product', os: 'win', architecture: '$Architecture'."
|
Say-Verbose "Retrieving primary payload URL from aka.ms link for channel: '$Channel', quality: '$Quality' product: '$Product', os: 'win', architecture: '$Architecture'."
|
||||||
|
|
||||||
@ -922,8 +1046,7 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern
|
|||||||
Say-Verbose "Constructed aka.ms link: '$akaMsLink'."
|
Say-Verbose "Constructed aka.ms link: '$akaMsLink'."
|
||||||
$akaMsDownloadLink = $null
|
$akaMsDownloadLink = $null
|
||||||
|
|
||||||
for ($maxRedirections = 9; $maxRedirections -ge 0; $maxRedirections--)
|
for ($maxRedirections = 9; $maxRedirections -ge 0; $maxRedirections--) {
|
||||||
{
|
|
||||||
#get HTTP response
|
#get HTTP response
|
||||||
#do not pass credentials as a part of the $akaMsLink and do not apply credentials in the GetHTTPResponse function
|
#do not pass credentials as a part of the $akaMsLink and do not apply credentials in the GetHTTPResponse function
|
||||||
#otherwise the redirect link would have credentials as well
|
#otherwise the redirect link would have credentials as well
|
||||||
@ -937,8 +1060,7 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if HTTP code is 301 (Moved Permanently), the redirect link exists
|
#if HTTP code is 301 (Moved Permanently), the redirect link exists
|
||||||
if ($Response.StatusCode -eq 301)
|
if ($Response.StatusCode -eq 301) {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
$akaMsDownloadLink = $Response.Headers.GetValues("Location")[0]
|
$akaMsDownloadLink = $Response.Headers.GetValues("Location")[0]
|
||||||
|
|
||||||
@ -957,9 +1079,13 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern
|
|||||||
return $null
|
return $null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif ((($Response.StatusCode -lt 300) -or ($Response.StatusCode -ge 400)) -and (-not [string]::IsNullOrEmpty($akaMsDownloadLink)))
|
elseif ((($Response.StatusCode -lt 300) -or ($Response.StatusCode -ge 400)) -and (-not [string]::IsNullOrEmpty($akaMsDownloadLink))) {
|
||||||
{
|
|
||||||
# Redirections have ended.
|
# Redirections have ended.
|
||||||
|
$actualRedirectUrl = Sanitize-RedirectUrl $akaMsDownloadLink
|
||||||
|
if ($null -ne $actualRedirectUrl) {
|
||||||
|
$akaMsDownloadLink = $actualRedirectUrl
|
||||||
|
}
|
||||||
|
|
||||||
return $akaMsDownloadLink
|
return $akaMsDownloadLink
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,10 +1134,11 @@ function Get-AkaMsLink-And-Version([string] $NormalizedChannel, [string] $Normal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-Feeds-To-Use()
|
function Get-Feeds-To-Use() {
|
||||||
{
|
|
||||||
$feeds = @(
|
$feeds = @(
|
||||||
"https://dotnetcli.azureedge.net/dotnet",
|
"https://builds.dotnet.microsoft.com/dotnet"
|
||||||
|
"https://dotnetcli.azureedge.net/dotnet"
|
||||||
|
"https://ci.dot.net/public"
|
||||||
"https://dotnetbuilds.azureedge.net/public"
|
"https://dotnetbuilds.azureedge.net/public"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1030,6 +1157,8 @@ function Get-Feeds-To-Use()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Write-Verbose "Initialized feeds: $feeds"
|
||||||
|
|
||||||
return $feeds
|
return $feeds
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1059,6 +1188,13 @@ function Resolve-AssetName-And-RelativePath([string] $Runtime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Prepare-Install-Directory {
|
function Prepare-Install-Directory {
|
||||||
|
$diskSpaceWarning = "Failed to check the disk space. Installation will continue, but it may fail if you do not have enough disk space.";
|
||||||
|
|
||||||
|
if ($PSVersionTable.PSVersion.Major -lt 7) {
|
||||||
|
Say-Verbose $diskSpaceWarning
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
|
New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
|
||||||
|
|
||||||
$installDrive = $((Get-Item $InstallRoot -Force).PSDrive.Name);
|
$installDrive = $((Get-Item $InstallRoot -Force).PSDrive.Name);
|
||||||
@ -1067,18 +1203,24 @@ function Prepare-Install-Directory {
|
|||||||
$diskInfo = Get-PSDrive -Name $installDrive
|
$diskInfo = Get-PSDrive -Name $installDrive
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Say-Warning "Failed to check the disk space. Installation will continue, but it may fail if you do not have enough disk space."
|
Say-Warning $diskSpaceWarning
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# The check is relevant for PS version >= 7, the result can be irrelevant for older versions. See https://github.com/PowerShell/PowerShell/issues/12442.
|
||||||
if ( ($null -ne $diskInfo) -and ($diskInfo.Free / 1MB -le 100)) {
|
if ( ($null -ne $diskInfo) -and ($diskInfo.Free / 1MB -le 100)) {
|
||||||
throw "There is not enough disk space on drive ${installDrive}:"
|
throw "There is not enough disk space on drive ${installDrive}:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Say "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
if ($Help) {
|
||||||
Say "- The SDK needs to be installed without user interaction and without admin rights."
|
Get-Help $PSCommandPath -Examples
|
||||||
Say "- The SDK installation doesn't need to persist across multiple CI runs."
|
exit
|
||||||
Say "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.`r`n"
|
}
|
||||||
|
|
||||||
|
Say-Verbose "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
||||||
|
Say-Verbose "- The SDK needs to be installed without user interaction and without admin rights."
|
||||||
|
Say-Verbose "- The SDK installation doesn't need to persist across multiple CI runs."
|
||||||
|
Say-Verbose "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.`r`n"
|
||||||
|
|
||||||
if ($SharedRuntime -and (-not $Runtime)) {
|
if ($SharedRuntime -and (-not $Runtime)) {
|
||||||
$Runtime = "dotnet"
|
$Runtime = "dotnet"
|
||||||
@ -1086,16 +1228,22 @@ if ($SharedRuntime -and (-not $Runtime)) {
|
|||||||
|
|
||||||
$OverrideNonVersionedFiles = !$SkipNonVersionedFiles
|
$OverrideNonVersionedFiles = !$SkipNonVersionedFiles
|
||||||
|
|
||||||
$CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture
|
Measure-Action "Product discovery" {
|
||||||
$NormalizedQuality = Get-NormalizedQuality $Quality
|
$script:CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture
|
||||||
|
$script:NormalizedQuality = Get-NormalizedQuality $Quality
|
||||||
Say-Verbose "Normalized quality: '$NormalizedQuality'"
|
Say-Verbose "Normalized quality: '$NormalizedQuality'"
|
||||||
$NormalizedChannel = Get-NormalizedChannel $Channel
|
$script:NormalizedChannel = Get-NormalizedChannel $Channel
|
||||||
Say-Verbose "Normalized channel: '$NormalizedChannel'"
|
Say-Verbose "Normalized channel: '$NormalizedChannel'"
|
||||||
$NormalizedProduct = Get-NormalizedProduct $Runtime
|
$script:NormalizedProduct = Get-NormalizedProduct $Runtime
|
||||||
Say-Verbose "Normalized product: '$NormalizedProduct'"
|
Say-Verbose "Normalized product: '$NormalizedProduct'"
|
||||||
$FeedCredential = ValidateFeedCredential $FeedCredential
|
$script:FeedCredential = ValidateFeedCredential $FeedCredential
|
||||||
|
}
|
||||||
|
|
||||||
$InstallRoot = Resolve-Installation-Path $InstallDir
|
$InstallRoot = Resolve-Installation-Path $InstallDir
|
||||||
|
if (-not (Test-User-Write-Access $InstallRoot)) {
|
||||||
|
Say-Error "The current user doesn't have write access to the installation root '$InstallRoot' to install .NET. Please try specifying a different installation directory using the -InstallDir parameter, or ensure the selected directory has the appropriate permissions."
|
||||||
|
throw
|
||||||
|
}
|
||||||
Say-Verbose "InstallRoot: $InstallRoot"
|
Say-Verbose "InstallRoot: $InstallRoot"
|
||||||
$ScriptName = $MyInvocation.MyCommand.Name
|
$ScriptName = $MyInvocation.MyCommand.Name
|
||||||
($assetName, $dotnetPackageRelativePath) = Resolve-AssetName-And-RelativePath -Runtime $Runtime
|
($assetName, $dotnetPackageRelativePath) = Resolve-AssetName-And-RelativePath -Runtime $Runtime
|
||||||
@ -1103,6 +1251,10 @@ $ScriptName = $MyInvocation.MyCommand.Name
|
|||||||
$feeds = Get-Feeds-To-Use
|
$feeds = Get-Feeds-To-Use
|
||||||
$DownloadLinks = @()
|
$DownloadLinks = @()
|
||||||
|
|
||||||
|
if ($Version.ToLowerInvariant() -ne "latest" -and -not [string]::IsNullOrEmpty($Quality)) {
|
||||||
|
throw "Quality and Version options are not allowed to be specified simultaneously. See https:// learn.microsoft.com/dotnet/core/tools/dotnet-install-script#options for details."
|
||||||
|
}
|
||||||
|
|
||||||
# aka.ms links can only be used if the user did not request a specific version via the command line or a global.json file.
|
# aka.ms links can only be used if the user did not request a specific version via the command line or a global.json file.
|
||||||
if ([string]::IsNullOrEmpty($JSonFile) -and ($Version -eq "latest")) {
|
if ([string]::IsNullOrEmpty($JSonFile) -and ($Version -eq "latest")) {
|
||||||
($DownloadLink, $SpecificVersion, $EffectiveVersion) = Get-AkaMsLink-And-Version $NormalizedChannel $NormalizedQuality $Internal $NormalizedProduct $CLIArchitecture
|
($DownloadLink, $SpecificVersion, $EffectiveVersion) = Get-AkaMsLink-And-Version $NormalizedChannel $NormalizedQuality $Internal $NormalizedProduct $CLIArchitecture
|
||||||
@ -1113,8 +1265,7 @@ if ([string]::IsNullOrEmpty($JSonFile) -and ($Version -eq "latest")) {
|
|||||||
|
|
||||||
if (-Not $DryRun) {
|
if (-Not $DryRun) {
|
||||||
Say-Verbose "Checking if the version $EffectiveVersion is already installed"
|
Say-Verbose "Checking if the version $EffectiveVersion is already installed"
|
||||||
if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion)
|
if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion) {
|
||||||
{
|
|
||||||
Say "$assetName with version '$EffectiveVersion' is already installed."
|
Say "$assetName with version '$EffectiveVersion' is already installed."
|
||||||
Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot
|
Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot
|
||||||
return
|
return
|
||||||
@ -1125,8 +1276,7 @@ if ([string]::IsNullOrEmpty($JSonFile) -and ($Version -eq "latest")) {
|
|||||||
|
|
||||||
# Primary and legacy links cannot be used if a quality was specified.
|
# Primary and legacy links cannot be used if a quality was specified.
|
||||||
# If we already have an aka.ms link, no need to search the blob feeds.
|
# If we already have an aka.ms link, no need to search the blob feeds.
|
||||||
if ([string]::IsNullOrEmpty($NormalizedQuality) -and 0 -eq $DownloadLinks.count)
|
if ([string]::IsNullOrEmpty($NormalizedQuality) -and 0 -eq $DownloadLinks.count) {
|
||||||
{
|
|
||||||
foreach ($feed in $feeds) {
|
foreach ($feed in $feeds) {
|
||||||
try {
|
try {
|
||||||
$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $feed -Channel $Channel -Version $Version -JSonFile $JSonFile
|
$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $feed -Channel $Channel -Version $Version -JSonFile $JSonFile
|
||||||
@ -1143,16 +1293,14 @@ if ([string]::IsNullOrEmpty($NormalizedQuality) -and 0 -eq $DownloadLinks.count)
|
|||||||
|
|
||||||
if (-Not $DryRun) {
|
if (-Not $DryRun) {
|
||||||
Say-Verbose "Checking if the version $EffectiveVersion is already installed"
|
Say-Verbose "Checking if the version $EffectiveVersion is already installed"
|
||||||
if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion)
|
if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion) {
|
||||||
{
|
|
||||||
Say "$assetName with version '$EffectiveVersion' is already installed."
|
Say "$assetName with version '$EffectiveVersion' is already installed."
|
||||||
Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot
|
Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch {
|
||||||
{
|
|
||||||
Say-Verbose "Failed to acquire download links from feed $feed. Exception: $_"
|
Say-Verbose "Failed to acquire download links from feed $feed. Exception: $_"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1167,21 +1315,19 @@ if ($DryRun) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Prepare-Install-Directory
|
Measure-Action "Installation directory preparation" { Prepare-Install-Directory }
|
||||||
|
|
||||||
$ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
|
|
||||||
Say-Verbose "Zip path: $ZipPath"
|
Say-Verbose "Zip path: $ZipPath"
|
||||||
|
|
||||||
$DownloadSucceeded = $false
|
$DownloadSucceeded = $false
|
||||||
$DownloadedLink = $null
|
$DownloadedLink = $null
|
||||||
$ErrorMessages = @()
|
$ErrorMessages = @()
|
||||||
|
|
||||||
foreach ($link in $DownloadLinks)
|
foreach ($link in $DownloadLinks) {
|
||||||
{
|
|
||||||
Say-Verbose "Downloading `"$($link.type)`" link $($link.downloadLink)"
|
Say-Verbose "Downloading `"$($link.type)`" link $($link.downloadLink)"
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DownloadFile -Source $link.downloadLink -OutPath $ZipPath
|
Measure-Action "Package download" { DownloadFile -Source $link.downloadLink -OutPath $ZipPath }
|
||||||
Say-Verbose "Download succeeded."
|
Say-Verbose "Download succeeded."
|
||||||
$DownloadSucceeded = $true
|
$DownloadSucceeded = $true
|
||||||
$DownloadedLink = $link
|
$DownloadedLink = $link
|
||||||
@ -1197,7 +1343,8 @@ foreach ($link in $DownloadLinks)
|
|||||||
|
|
||||||
if ($PSItem.Exception.Data.Contains("ErrorMessage")) {
|
if ($PSItem.Exception.Data.Contains("ErrorMessage")) {
|
||||||
$ErrorMessage = $PSItem.Exception.Data["ErrorMessage"]
|
$ErrorMessage = $PSItem.Exception.Data["ErrorMessage"]
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
$ErrorMessage = $PSItem.Exception.Message
|
$ErrorMessage = $PSItem.Exception.Message
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1218,7 +1365,7 @@ if (-not $DownloadSucceeded) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Say "Extracting the archive."
|
Say "Extracting the archive."
|
||||||
Extract-Dotnet-Package -ZipPath $ZipPath -OutPath $InstallRoot
|
Measure-Action "Package extraction" { Extract-Dotnet-Package -ZipPath $ZipPath -OutPath $InstallRoot }
|
||||||
|
|
||||||
# Check if the SDK version is installed; if not, fail the installation.
|
# Check if the SDK version is installed; if not, fail the installation.
|
||||||
$isAssetInstalled = $false
|
$isAssetInstalled = $false
|
||||||
@ -1242,225 +1389,13 @@ if (!$isAssetInstalled) {
|
|||||||
throw "`"$assetName`" with version = $($DownloadedLink.effectiveVersion) failed to install with an unknown error."
|
throw "`"$assetName`" with version = $($DownloadedLink.effectiveVersion) failed to install with an unknown error."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (-not $KeepZip) {
|
||||||
SafeRemoveFile -Path $ZipPath
|
SafeRemoveFile -Path $ZipPath
|
||||||
|
}
|
||||||
|
|
||||||
Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot
|
Measure-Action "Setting up shell environment" { Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot }
|
||||||
|
|
||||||
Say "Note that the script does not resolve dependencies during installation."
|
Say "Note that the script does not ensure your Windows version is supported during the installation."
|
||||||
Say "To check the list of dependencies, go to https://docs.microsoft.com/dotnet/core/install/windows#dependencies"
|
Say "To check the list of supported versions, go to https://learn.microsoft.com/dotnet/core/install/windows#supported-versions"
|
||||||
|
Say "Installed version is $($DownloadedLink.effectiveVersion)"
|
||||||
Say "Installation finished"
|
Say "Installation finished"
|
||||||
|
|
||||||
# SIG # Begin signature block
|
|
||||||
# MIInoQYJKoZIhvcNAQcCoIInkjCCJ44CAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
|
||||||
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
|
||||||
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAuo3sRWvfrJ+Bd
|
|
||||||
# sIQ2zLeO20Ij33Vb5ljtEhxAYYSEc6CCDYEwggX/MIID56ADAgECAhMzAAACUosz
|
|
||||||
# qviV8znbAAAAAAJSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
|
||||||
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
|
||||||
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
|
||||||
# bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMjU5WhcNMjIwOTAxMTgzMjU5WjB0MQsw
|
|
||||||
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
|
||||||
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
|
||||||
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
|
||||||
# AQDQ5M+Ps/X7BNuv5B/0I6uoDwj0NJOo1KrVQqO7ggRXccklyTrWL4xMShjIou2I
|
|
||||||
# sbYnF67wXzVAq5Om4oe+LfzSDOzjcb6ms00gBo0OQaqwQ1BijyJ7NvDf80I1fW9O
|
|
||||||
# L76Kt0Wpc2zrGhzcHdb7upPrvxvSNNUvxK3sgw7YTt31410vpEp8yfBEl/hd8ZzA
|
|
||||||
# v47DCgJ5j1zm295s1RVZHNp6MoiQFVOECm4AwK2l28i+YER1JO4IplTH44uvzX9o
|
|
||||||
# RnJHaMvWzZEpozPy4jNO2DDqbcNs4zh7AWMhE1PWFVA+CHI/En5nASvCvLmuR/t8
|
|
||||||
# q4bc8XR8QIZJQSp+2U6m2ldNAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
|
|
||||||
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUNZJaEUGL2Guwt7ZOAu4efEYXedEw
|
|
||||||
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
|
|
||||||
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDY3NTk3MB8GA1UdIwQYMBaAFEhu
|
|
||||||
# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
|
|
||||||
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
|
|
||||||
# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
|
|
||||||
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
|
|
||||||
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAFkk3
|
|
||||||
# uSxkTEBh1NtAl7BivIEsAWdgX1qZ+EdZMYbQKasY6IhSLXRMxF1B3OKdR9K/kccp
|
|
||||||
# kvNcGl8D7YyYS4mhCUMBR+VLrg3f8PUj38A9V5aiY2/Jok7WZFOAmjPRNNGnyeg7
|
|
||||||
# l0lTiThFqE+2aOs6+heegqAdelGgNJKRHLWRuhGKuLIw5lkgx9Ky+QvZrn/Ddi8u
|
|
||||||
# TIgWKp+MGG8xY6PBvvjgt9jQShlnPrZ3UY8Bvwy6rynhXBaV0V0TTL0gEx7eh/K1
|
|
||||||
# o8Miaru6s/7FyqOLeUS4vTHh9TgBL5DtxCYurXbSBVtL1Fj44+Od/6cmC9mmvrti
|
|
||||||
# yG709Y3Rd3YdJj2f3GJq7Y7KdWq0QYhatKhBeg4fxjhg0yut2g6aM1mxjNPrE48z
|
|
||||||
# 6HWCNGu9gMK5ZudldRw4a45Z06Aoktof0CqOyTErvq0YjoE4Xpa0+87T/PVUXNqf
|
|
||||||
# 7Y+qSU7+9LtLQuMYR4w3cSPjuNusvLf9gBnch5RqM7kaDtYWDgLyB42EfsxeMqwK
|
|
||||||
# WwA+TVi0HrWRqfSx2olbE56hJcEkMjOSKz3sRuupFCX3UroyYf52L+2iVTrda8XW
|
|
||||||
# esPG62Mnn3T8AuLfzeJFuAbfOSERx7IFZO92UPoXE1uEjL5skl1yTZB3MubgOA4F
|
|
||||||
# 8KoRNhviFAEST+nG8c8uIsbZeb08SeYQMqjVEmkwggd6MIIFYqADAgECAgphDpDS
|
|
||||||
# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
|
|
||||||
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
|
|
||||||
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
|
|
||||||
# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla
|
|
||||||
# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
|
|
||||||
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT
|
|
||||||
# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB
|
|
||||||
# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG
|
|
||||||
# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S
|
|
||||||
# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz
|
|
||||||
# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7
|
|
||||||
# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u
|
|
||||||
# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33
|
|
||||||
# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl
|
|
||||||
# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP
|
|
||||||
# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB
|
|
||||||
# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF
|
|
||||||
# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM
|
|
||||||
# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ
|
|
||||||
# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
|
|
||||||
# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO
|
|
||||||
# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0
|
|
||||||
# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
|
|
||||||
# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p
|
|
||||||
# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
|
|
||||||
# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB
|
|
||||||
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw
|
|
||||||
# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA
|
|
||||||
# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY
|
|
||||||
# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj
|
|
||||||
# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd
|
|
||||||
# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ
|
|
||||||
# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf
|
|
||||||
# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ
|
|
||||||
# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j
|
|
||||||
# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B
|
|
||||||
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
|
|
||||||
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
|
|
||||||
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
|
|
||||||
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIZdjCCGXICAQEwgZUwfjELMAkG
|
|
||||||
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
|
|
||||||
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
|
|
||||||
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAlKLM6r4lfM52wAAAAACUjAN
|
|
||||||
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
|
|
||||||
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgBzhh8wf+
|
|
||||||
# /kA/CamFNwS1K9Nt0wsjATKS8Y66iHQTKrIwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
|
|
||||||
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
|
|
||||||
# BgkqhkiG9w0BAQEFAASCAQAruzFwahFXWsJ9eny7iY/KyWolnqJ9+cvDD1QaJ0qJ
|
|
||||||
# tHlTLP8pr0GPPtitwuk+3JME7wkx80+AZXl/ocO39tdhy1Ucd6yiyV3M1Ub/Eo4D
|
|
||||||
# 37L1saazNomWeeMD6oX3FboVe1Ql17MX1SscTW5QRx8ytYgUOUIbrxFybODcdVn9
|
|
||||||
# YG7mlkgsJr2lhUhTnHtq7jV/jEu6Sk9o+g15Pbu90VncsCoNerg9aEziui6/W3/g
|
|
||||||
# Wvt4WhfCPanppzWVmsvTUp5MAt5cpdNBr9b8CV/alI3TGnNwC8RuWMCK6CS4963l
|
|
||||||
# f4AiLZW/fgD8UQYtl+tAyYfSerpX0sDB039jymj1FkqHoYIXADCCFvwGCisGAQQB
|
|
||||||
# gjcDAwExghbsMIIW6AYJKoZIhvcNAQcCoIIW2TCCFtUCAQMxDzANBglghkgBZQME
|
|
||||||
# AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB
|
|
||||||
# MDEwDQYJYIZIAWUDBAIBBQAEIEcy5EvHdubbPngOS1BSZ6xt9xSMrt3OLtUyfQaT
|
|
||||||
# IyRBAgZh+unPYkgYEzIwMjIwMjA4MTAyMjE5LjM1OVowBIACAfSggdCkgc0wgcox
|
|
||||||
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
|
|
||||||
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p
|
|
||||||
# Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg
|
|
||||||
# RVNOOkREOEMtRTMzNy0yRkFFMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt
|
|
||||||
# cCBTZXJ2aWNloIIRVzCCBwwwggT0oAMCAQICEzMAAAGcD6ZNYdKeSygAAQAAAZww
|
|
||||||
# DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
|
|
||||||
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
|
|
||||||
# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN
|
|
||||||
# MjExMjAyMTkwNTE5WhcNMjMwMjI4MTkwNTE5WjCByjELMAkGA1UEBhMCVVMxEzAR
|
|
||||||
# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
|
|
||||||
# Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg
|
|
||||||
# T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046REQ4Qy1FMzM3LTJG
|
|
||||||
# QUUxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0G
|
|
||||||
# CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDbUioMGV1JFj+s612s02mKu23KPUNs
|
|
||||||
# 71OjDeJGtxkTF9rSWTiuA8XgYkAAi/5+2Ff7Ck7JcKQ9H/XD1OKwg1/bH3E1qO1z
|
|
||||||
# 8XRy0PlpGhmyilgE7KsOvW8PIZCf243KdldgOrxrL8HKiQodOwStyT5lLWYpMsuT
|
|
||||||
# 2fH8k8oihje4TlpWiFPaCKLnFDaAB0Ccy6vIdtHjYB1Ie3iOZPisquL+vNdCx7gO
|
|
||||||
# hB8iiTmTdsU8OSUpC8tBTeTIYPzmhaxQZd4moNk6qeCJyi7fiW4fyXdHrZ3otmgx
|
|
||||||
# xa5pXz5pUUr+cEjV+cwIYBMkaY5kHM9c6dEGkgHn0ZDJvdt/54FOdSG61WwHh4+e
|
|
||||||
# vUhwvXaB4LCMZIdCt5acOfNvtDjV3CHyFOp5AU/qgAwGftHU9brv4EUwcuteEAKH
|
|
||||||
# 46NufE20l/WjlNUh7gAvt2zKMjO4zXRxCUTh/prBQwXJiUZeFSrEXiOfkuvSlBni
|
|
||||||
# yAYYZp5kOnaxfCKdGYjvr4QLA93vQJ6p2Ox3IHvOdCPaCr8LsKVcFpyp8MEhhJTM
|
|
||||||
# +1LwqHJqFDF5O1Z9mjbYvm3R9vPhkG+RDLKoTpr7mTgkaTljd9xvm94Obp8BD9Hk
|
|
||||||
# 4mPi51mtgLiuN8/6aZVESVZXtvSuNkD5DnIJQerIy5jaRKW/W2rCe9ngNDJadS7R
|
|
||||||
# 96GGRl7IIE37lwIDAQABo4IBNjCCATIwHQYDVR0OBBYEFLtpCWdTXY5dtddkspy+
|
|
||||||
# oxjCA/qyMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRY
|
|
||||||
# MFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01p
|
|
||||||
# Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEF
|
|
||||||
# BQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w
|
|
||||||
# a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAo
|
|
||||||
# MSkuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZI
|
|
||||||
# hvcNAQELBQADggIBAKcAKqYjGEczTWMs9z0m7Yo23sgqVF3LyK6gOMz7TCHAJN+F
|
|
||||||
# vbvZkQ53VkvrZUd1sE6a9ToGldcJnOmBc6iuhBlpvdN1BLBRO8QSTD1433VTj4XC
|
|
||||||
# Qd737wND1+eqKG3BdjrzbDksEwfG4v57PgrN/T7s7PkEjUGXfIgFQQkr8TQi+/HZ
|
|
||||||
# Z9kRlNccgeACqlfb4uGPxn5sdhQPoxdMvmC3qG9DONJ5UsS9KtO+bey+ohUTDa9L
|
|
||||||
# vEToc4Qzy5fuHj2H1JsmCaKG78nXpfWpwBLBxZYSpfml29onN8jcG7KD8nGSS/76
|
|
||||||
# PDlb2GMQsvv+Ra0JgL6FtGRGgYmHCpM6zVrf4V/a+SoHcC+tcdGYk2aKU5KOlv+f
|
|
||||||
# FE3n024V+z54tDAKR9z78rejdCBWqfvy5cBUQ9c5+3unHD08BEp7qP2rgpoD856v
|
|
||||||
# NDgEwO77n7EWT76nl/IyrbK2kjbHLzUMphFpXKnV1fYWJI2+E/0LHvXFGGqF4OvM
|
|
||||||
# BRxbrJVn03T2Dy5db6s5TzJzSaQvCrXYqA4HKvstQWkqkpvBHTX8M09+/vyRbVXN
|
|
||||||
# xrPdeXw6oD2Q4DksykCFfn8N2j2LdixE9wG5iilv69dzsvHIN/g9A9+thkAQCVb9
|
|
||||||
# DUSOTaMIGgsOqDYFjhT6ze9lkhHHGv/EEIkxj9l6S4hqUQyWerFkaUWDXcnZMIIH
|
|
||||||
# cTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCB
|
|
||||||
# iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
|
|
||||||
# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMp
|
|
||||||
# TWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEw
|
|
||||||
# OTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UE
|
|
||||||
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
|
|
||||||
# b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ
|
|
||||||
# Q0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIh
|
|
||||||
# C3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNx
|
|
||||||
# WuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFc
|
|
||||||
# UTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAc
|
|
||||||
# nVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUo
|
|
||||||
# veO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyzi
|
|
||||||
# YrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9
|
|
||||||
# fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdH
|
|
||||||
# GO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7X
|
|
||||||
# KHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiE
|
|
||||||
# R9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/
|
|
||||||
# eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3
|
|
||||||
# FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAd
|
|
||||||
# BgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEE
|
|
||||||
# AYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
|
|
||||||
# L3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMI
|
|
||||||
# MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMB
|
|
||||||
# Af8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1Ud
|
|
||||||
# HwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3By
|
|
||||||
# b2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQRO
|
|
||||||
# MEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2Vy
|
|
||||||
# dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4IC
|
|
||||||
# AQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pk
|
|
||||||
# bHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gng
|
|
||||||
# ugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3
|
|
||||||
# lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHC
|
|
||||||
# gRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6
|
|
||||||
# MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEU
|
|
||||||
# BHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvsh
|
|
||||||
# VGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+
|
|
||||||
# fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrp
|
|
||||||
# NPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHI
|
|
||||||
# qzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAs4wggI3AgEBMIH4
|
|
||||||
# oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G
|
|
||||||
# A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUw
|
|
||||||
# IwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1U
|
|
||||||
# aGFsZXMgVFNTIEVTTjpERDhDLUUzMzctMkZBRTElMCMGA1UEAxMcTWljcm9zb2Z0
|
|
||||||
# IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAzdlp6t3ws/bnErbm
|
|
||||||
# 9c0M+9dvU0CggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
|
|
||||||
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
|
|
||||||
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAN
|
|
||||||
# BgkqhkiG9w0BAQUFAAIFAOWsqGYwIhgPMjAyMjAyMDgxNjI5MjZaGA8yMDIyMDIw
|
|
||||||
# OTE2MjkyNlowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA5ayoZgIBADAKAgEAAgIi
|
|
||||||
# 7QIB/zAHAgEAAgITmjAKAgUA5a355gIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgor
|
|
||||||
# BgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUA
|
|
||||||
# A4GBAKFiWA9Ov0L2rGOdPitNu60BAeztCagpqKBsGnKaaSmjA/XcSXrtIvcUBBsw
|
|
||||||
# WlflwqnKvPDv3ihqUXsxY84IZZaMecGWzN1mXLh00VftiZuzoLMDlSEtvzmxeWYg
|
|
||||||
# 4nFHTR5oMqxy06auAM08mVl3P4MywHz4Yp21OIs2KSWQg3DSMYIEDTCCBAkCAQEw
|
|
||||||
# gZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT
|
|
||||||
# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE
|
|
||||||
# AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAGcD6ZNYdKeSygA
|
|
||||||
# AQAAAZwwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0B
|
|
||||||
# CRABBDAvBgkqhkiG9w0BCQQxIgQg8oNFH9aqIpzxu29p4VzI2Hh6Hzv2T5HQOlhP
|
|
||||||
# W5ksqHkwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCA3D0WFII0syjoRd/Xe
|
|
||||||
# EIG0WUIKzzuy6P6hORrb0nqmvDCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD
|
|
||||||
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
|
||||||
# b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w
|
|
||||||
# IFBDQSAyMDEwAhMzAAABnA+mTWHSnksoAAEAAAGcMCIEIOSl7GUcmDL8AU+F0I3A
|
|
||||||
# iZQESHSkml1QPlOc3M8uqdF0MA0GCSqGSIb3DQEBCwUABIICAHV226l2xxnkjTdh
|
|
||||||
# Q6wi7u8betBvFNfYYn5cXwy+NoU30JjQ3ynnmNSB+TQVlmcthi8duP8dud+NU5xc
|
|
||||||
# +1jBTcJTHjWk/TDZUYpB/xNqsgUTJ8fnebVZhioPJhmFJMeQztT4NTD1ZbeJWO4O
|
|
||||||
# EABDpRqyns2eQptCrKcPIypjvdDeYfkwjgnUEyyaTZRHPZ2kNOLY6kO9feKfntFW
|
|
||||||
# 8YUIaas2IzI5GcGm+kw1efHveG0WvUpeGuFKsTUA6Jb18mOyamafu32ftD5t5LXV
|
|
||||||
# +GMgnaJLgdogAAGwK0GiB47YNIvPlKD6bGnyTR3KNYheI1GI38w0knOecCC4NW0k
|
|
||||||
# 21qROWJdnkKLKTtBX344yTnJbbKoIPzGgyWCzSINS2SD4JHzgTu8dsmMMJWwcEZh
|
|
||||||
# BLyrzmd/vWrjUFQFXVf6RZmJJVvF28s7LWrpXPVTR8Al75j8KqyZKou4fZvyaHtx
|
|
||||||
# S6K0jIqavLWqWd4wvx9seCtA0Pz1GWrBZADIRHG8d8cFoY95Z99z84NM81qXB246
|
|
||||||
# IsxU2iW+96zMJriMNEKaLHzlgFoWsoXLDQhuQItjwIvzwmwygwx0MxqoFYm+lDWG
|
|
||||||
# 8/KtSh47aZicAlwqNVGy3MZHDnX69kysQsrWoe2wDhJ3eHJ4zRL2WHVagz26L7xF
|
|
||||||
# oSkLphLv0GiFseJhPvXGQPypnyN8
|
|
||||||
# SIG # End signature block
|
|
||||||
|
438
externals/install-dotnet.sh
vendored
438
externals/install-dotnet.sh
vendored
@ -298,14 +298,43 @@ get_machine_architecture() {
|
|||||||
if command -v uname > /dev/null; then
|
if command -v uname > /dev/null; then
|
||||||
CPUName=$(uname -m)
|
CPUName=$(uname -m)
|
||||||
case $CPUName in
|
case $CPUName in
|
||||||
|
armv1*|armv2*|armv3*|armv4*|armv5*|armv6*)
|
||||||
|
echo "armv6-or-below"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
armv*l)
|
armv*l)
|
||||||
echo "arm"
|
echo "arm"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
aarch64|arm64)
|
aarch64|arm64)
|
||||||
|
if [ "$(getconf LONG_BIT)" -lt 64 ]; then
|
||||||
|
# This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS)
|
||||||
|
echo "arm"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
echo "arm64"
|
echo "arm64"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
s390x)
|
||||||
|
echo "s390x"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
ppc64le)
|
||||||
|
echo "ppc64le"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
loongarch64)
|
||||||
|
echo "loongarch64"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
riscv64)
|
||||||
|
echo "riscv64"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
powerpc|ppc)
|
||||||
|
echo "ppc"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -322,7 +351,13 @@ get_normalized_architecture_from_architecture() {
|
|||||||
local architecture="$(to_lowercase "$1")"
|
local architecture="$(to_lowercase "$1")"
|
||||||
|
|
||||||
if [[ $architecture == \<auto\> ]]; then
|
if [[ $architecture == \<auto\> ]]; then
|
||||||
echo "$(get_machine_architecture)"
|
machine_architecture="$(get_machine_architecture)"
|
||||||
|
if [[ "$machine_architecture" == "armv6-or-below" ]]; then
|
||||||
|
say_err "Architecture \`$machine_architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo $machine_architecture
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -339,12 +374,72 @@ get_normalized_architecture_from_architecture() {
|
|||||||
echo "arm64"
|
echo "arm64"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
s390x)
|
||||||
|
echo "s390x"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
ppc64le)
|
||||||
|
echo "ppc64le"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
loongarch64)
|
||||||
|
echo "loongarch64"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
|
say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# version - $1
|
||||||
|
# channel - $2
|
||||||
|
# architecture - $3
|
||||||
|
get_normalized_architecture_for_specific_sdk_version() {
|
||||||
|
eval $invocation
|
||||||
|
|
||||||
|
local is_version_support_arm64="$(is_arm64_supported "$1")"
|
||||||
|
local is_channel_support_arm64="$(is_arm64_supported "$2")"
|
||||||
|
local architecture="$3";
|
||||||
|
local osname="$(get_current_os_name)"
|
||||||
|
|
||||||
|
if [ "$osname" == "osx" ] && [ "$architecture" == "arm64" ] && { [ "$is_version_support_arm64" = false ] || [ "$is_channel_support_arm64" = false ]; }; then
|
||||||
|
#check if rosetta is installed
|
||||||
|
if [ "$(/usr/bin/pgrep oahd >/dev/null 2>&1;echo $?)" -eq 0 ]; then
|
||||||
|
say_verbose "Changing user architecture from '$architecture' to 'x64' because .NET SDKs prior to version 6.0 do not support arm64."
|
||||||
|
echo "x64"
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
say_err "Architecture \`$architecture\` is not supported for .NET SDK version \`$version\`. Please install Rosetta to allow emulation of the \`$architecture\` .NET SDK on this platform"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$architecture"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# version or channel - $1
|
||||||
|
is_arm64_supported() {
|
||||||
|
# Extract the major version by splitting on the dot
|
||||||
|
major_version="${1%%.*}"
|
||||||
|
|
||||||
|
# Check if the major version is a valid number and less than 6
|
||||||
|
case "$major_version" in
|
||||||
|
[0-9]*)
|
||||||
|
if [ "$major_version" -lt 6 ]; then
|
||||||
|
echo false
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo true
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
# args:
|
# args:
|
||||||
# user_defined_os - $1
|
# user_defined_os - $1
|
||||||
get_normalized_os() {
|
get_normalized_os() {
|
||||||
@ -357,8 +452,13 @@ get_normalized_os() {
|
|||||||
echo "$osname"
|
echo "$osname"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
macos)
|
||||||
|
osname='osx'
|
||||||
|
echo "$osname"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
|
say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, macos, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
|
||||||
return 1
|
return 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -401,6 +501,10 @@ get_normalized_channel() {
|
|||||||
|
|
||||||
local channel="$(to_lowercase "$1")"
|
local channel="$(to_lowercase "$1")"
|
||||||
|
|
||||||
|
if [[ $channel == current ]]; then
|
||||||
|
say_warning 'Value "Current" is deprecated for -Channel option. Use "STS" instead.'
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $channel == release/* ]]; then
|
if [[ $channel == release/* ]]; then
|
||||||
say_warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead.';
|
say_warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead.';
|
||||||
fi
|
fi
|
||||||
@ -411,6 +515,14 @@ get_normalized_channel() {
|
|||||||
echo "LTS"
|
echo "LTS"
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
sts)
|
||||||
|
echo "STS"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
current)
|
||||||
|
echo "STS"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "$channel"
|
echo "$channel"
|
||||||
return 0
|
return 0
|
||||||
@ -476,6 +588,40 @@ is_dotnet_package_installed() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# downloaded file - $1
|
||||||
|
# remote_file_size - $2
|
||||||
|
validate_remote_local_file_sizes()
|
||||||
|
{
|
||||||
|
eval $invocation
|
||||||
|
|
||||||
|
local downloaded_file="$1"
|
||||||
|
local remote_file_size="$2"
|
||||||
|
local file_size=''
|
||||||
|
|
||||||
|
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||||
|
file_size="$(stat -c '%s' "$downloaded_file")"
|
||||||
|
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
# hardcode in order to avoid conflicts with GNU stat
|
||||||
|
file_size="$(/usr/bin/stat -f '%z' "$downloaded_file")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$file_size" ]; then
|
||||||
|
say "Downloaded file size is $file_size bytes."
|
||||||
|
|
||||||
|
if [ -n "$remote_file_size" ] && [ -n "$file_size" ]; then
|
||||||
|
if [ "$remote_file_size" -ne "$file_size" ]; then
|
||||||
|
say "The remote and local file sizes are not equal. The remote file size is $remote_file_size bytes and the local size is $file_size bytes. The local package may be corrupted."
|
||||||
|
else
|
||||||
|
say "The remote and local file sizes are equal."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
say "Either downloaded or local package size can not be measured. One of them may be corrupted."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# args:
|
# args:
|
||||||
# azure_feed - $1
|
# azure_feed - $1
|
||||||
# channel - $2
|
# channel - $2
|
||||||
@ -515,7 +661,7 @@ parse_globaljson_file_for_version() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sdk_section=$(cat $json_file | awk '/"sdk"/,/}/')
|
sdk_section=$(cat $json_file | tr -d "\r" | awk '/"sdk"/,/}/')
|
||||||
if [ -z "$sdk_section" ]; then
|
if [ -z "$sdk_section" ]; then
|
||||||
say_err "Unable to parse the SDK node in \`$json_file\`"
|
say_err "Unable to parse the SDK node in \`$json_file\`"
|
||||||
return 1
|
return 1
|
||||||
@ -637,11 +783,13 @@ get_specific_product_version() {
|
|||||||
|
|
||||||
if machine_has "curl"
|
if machine_has "curl"
|
||||||
then
|
then
|
||||||
specific_product_version=$(curl -s --fail "${download_link}${feed_credential}" 2>&1)
|
if ! specific_product_version=$(curl -s --fail "${download_link}${feed_credential}" 2>&1); then
|
||||||
if [ $? = 0 ]; then
|
continue
|
||||||
|
else
|
||||||
echo "${specific_product_version//[$'\t\r\n']}"
|
echo "${specific_product_version//[$'\t\r\n']}"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
elif machine_has "wget"
|
elif machine_has "wget"
|
||||||
then
|
then
|
||||||
specific_product_version=$(wget -qO- "${download_link}${feed_credential}" 2>&1)
|
specific_product_version=$(wget -qO- "${download_link}${feed_credential}" 2>&1)
|
||||||
@ -808,6 +956,37 @@ get_absolute_path() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# override - $1 (boolean, true or false)
|
||||||
|
get_cp_options() {
|
||||||
|
eval $invocation
|
||||||
|
|
||||||
|
local override="$1"
|
||||||
|
local override_switch=""
|
||||||
|
|
||||||
|
if [ "$override" = false ]; then
|
||||||
|
override_switch="-n"
|
||||||
|
|
||||||
|
# create temporary files to check if 'cp -u' is supported
|
||||||
|
tmp_dir="$(mktemp -d)"
|
||||||
|
tmp_file="$tmp_dir/testfile"
|
||||||
|
tmp_file2="$tmp_dir/testfile2"
|
||||||
|
|
||||||
|
touch "$tmp_file"
|
||||||
|
|
||||||
|
# use -u instead of -n if it's available
|
||||||
|
if cp -u "$tmp_file" "$tmp_file2" 2>/dev/null; then
|
||||||
|
override_switch="-u"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# clean up
|
||||||
|
rm -f "$tmp_file" "$tmp_file2"
|
||||||
|
rm -rf "$tmp_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$override_switch"
|
||||||
|
}
|
||||||
|
|
||||||
# args:
|
# args:
|
||||||
# input_files - stdin
|
# input_files - stdin
|
||||||
# root_path - $1
|
# root_path - $1
|
||||||
@ -819,15 +998,7 @@ copy_files_or_dirs_from_list() {
|
|||||||
local root_path="$(remove_trailing_slash "$1")"
|
local root_path="$(remove_trailing_slash "$1")"
|
||||||
local out_path="$(remove_trailing_slash "$2")"
|
local out_path="$(remove_trailing_slash "$2")"
|
||||||
local override="$3"
|
local override="$3"
|
||||||
local osname="$(get_current_os_name)"
|
local override_switch="$(get_cp_options "$override")"
|
||||||
local override_switch=$(
|
|
||||||
if [ "$override" = false ]; then
|
|
||||||
if [ "$osname" = "linux-musl" ]; then
|
|
||||||
printf -- "-u";
|
|
||||||
else
|
|
||||||
printf -- "-n";
|
|
||||||
fi
|
|
||||||
fi)
|
|
||||||
|
|
||||||
cat | uniq | while read -r file_path; do
|
cat | uniq | while read -r file_path; do
|
||||||
local path="$(remove_beginning_slash "${file_path#$root_path}")"
|
local path="$(remove_beginning_slash "${file_path#$root_path}")"
|
||||||
@ -842,14 +1013,39 @@ copy_files_or_dirs_from_list() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# zip_uri - $1
|
||||||
|
get_remote_file_size() {
|
||||||
|
local zip_uri="$1"
|
||||||
|
|
||||||
|
if machine_has "curl"; then
|
||||||
|
file_size=$(curl -sI "$zip_uri" | grep -i content-length | awk '{ num = $2 + 0; print num }')
|
||||||
|
elif machine_has "wget"; then
|
||||||
|
file_size=$(wget --spider --server-response -O /dev/null "$zip_uri" 2>&1 | grep -i 'Content-Length:' | awk '{ num = $2 + 0; print num }')
|
||||||
|
else
|
||||||
|
say "Neither curl nor wget is available on this system."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$file_size" ]; then
|
||||||
|
say "Remote file $zip_uri size is $file_size bytes."
|
||||||
|
echo "$file_size"
|
||||||
|
else
|
||||||
|
say_verbose "Content-Length header was not extracted for $zip_uri."
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# args:
|
# args:
|
||||||
# zip_path - $1
|
# zip_path - $1
|
||||||
# out_path - $2
|
# out_path - $2
|
||||||
|
# remote_file_size - $3
|
||||||
extract_dotnet_package() {
|
extract_dotnet_package() {
|
||||||
eval $invocation
|
eval $invocation
|
||||||
|
|
||||||
local zip_path="$1"
|
local zip_path="$1"
|
||||||
local out_path="$2"
|
local out_path="$2"
|
||||||
|
local remote_file_size="$3"
|
||||||
|
|
||||||
local temp_out_path="$(mktemp -d "$temporary_file_template")"
|
local temp_out_path="$(mktemp -d "$temporary_file_template")"
|
||||||
|
|
||||||
@ -860,8 +1056,12 @@ extract_dotnet_package() {
|
|||||||
find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false
|
find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false
|
||||||
find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files"
|
find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files"
|
||||||
|
|
||||||
|
validate_remote_local_file_sizes "$zip_path" "$remote_file_size"
|
||||||
|
|
||||||
rm -rf "$temp_out_path"
|
rm -rf "$temp_out_path"
|
||||||
rm -f "$zip_path" && say_verbose "Temporary zip file $zip_path was removed"
|
if [ -z ${keep_zip+x} ]; then
|
||||||
|
rm -f "$zip_path" && say_verbose "Temporary archive file $zip_path was removed"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$failed" = true ]; then
|
if [ "$failed" = true ]; then
|
||||||
say_err "Extraction failed"
|
say_err "Extraction failed"
|
||||||
@ -921,9 +1121,15 @@ get_http_header_wget() {
|
|||||||
local remote_path="$1"
|
local remote_path="$1"
|
||||||
local disable_feed_credential="$2"
|
local disable_feed_credential="$2"
|
||||||
local wget_options="-q -S --spider --tries 5 "
|
local wget_options="-q -S --spider --tries 5 "
|
||||||
# Store options that aren't supported on all wget implementations separately.
|
|
||||||
local wget_options_extra="--waitretry 2 --connect-timeout 15 "
|
local wget_options_extra=''
|
||||||
local wget_result=''
|
|
||||||
|
# Test for options that aren't supported on all wget implementations.
|
||||||
|
if [[ $(wget -h 2>&1 | grep -E 'waitretry|connect-timeout') ]]; then
|
||||||
|
wget_options_extra="--waitretry 2 --connect-timeout 15 "
|
||||||
|
else
|
||||||
|
say "wget extra options are unavailable for this environment"
|
||||||
|
fi
|
||||||
|
|
||||||
remote_path_with_credential="$remote_path"
|
remote_path_with_credential="$remote_path"
|
||||||
if [ "$disable_feed_credential" = false ]; then
|
if [ "$disable_feed_credential" = false ]; then
|
||||||
@ -931,15 +1137,8 @@ get_http_header_wget() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
wget $wget_options $wget_options_extra "$remote_path_with_credential" 2>&1
|
wget $wget_options $wget_options_extra "$remote_path_with_credential" 2>&1
|
||||||
wget_result=$?
|
|
||||||
|
|
||||||
if [[ $wget_result == 2 ]]; then
|
|
||||||
# Parsing of the command has failed. Exclude potentially unrecognized options and retry.
|
|
||||||
wget $wget_options "$remote_path_with_credential" 2>&1
|
|
||||||
return $?
|
return $?
|
||||||
fi
|
|
||||||
|
|
||||||
return $wget_result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# args:
|
# args:
|
||||||
@ -979,8 +1178,6 @@ download() {
|
|||||||
sleep $((attempts*10))
|
sleep $((attempts*10))
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if [ "$failed" = true ]; then
|
if [ "$failed" = true ]; then
|
||||||
say_verbose "Download failed: $remote_path"
|
say_verbose "Download failed: $remote_path"
|
||||||
return 1
|
return 1
|
||||||
@ -999,20 +1196,28 @@ downloadcurl() {
|
|||||||
# Avoid passing URI with credentials to functions: note, most of them echoing parameters of invocation in verbose output.
|
# Avoid passing URI with credentials to functions: note, most of them echoing parameters of invocation in verbose output.
|
||||||
local remote_path_with_credential="${remote_path}${feed_credential}"
|
local remote_path_with_credential="${remote_path}${feed_credential}"
|
||||||
local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs "
|
local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs "
|
||||||
local failed=false
|
local curl_exit_code=0;
|
||||||
if [ -z "$out_path" ]; then
|
if [ -z "$out_path" ]; then
|
||||||
curl $curl_options "$remote_path_with_credential" 2>&1 || failed=true
|
curl $curl_options "$remote_path_with_credential" 2>&1
|
||||||
|
curl_exit_code=$?
|
||||||
else
|
else
|
||||||
curl $curl_options -o "$out_path" "$remote_path_with_credential" 2>&1 || failed=true
|
curl $curl_options -o "$out_path" "$remote_path_with_credential" 2>&1
|
||||||
|
curl_exit_code=$?
|
||||||
fi
|
fi
|
||||||
if [ "$failed" = true ]; then
|
|
||||||
|
if [ $curl_exit_code -gt 0 ]; then
|
||||||
|
download_error_msg="Unable to download $remote_path."
|
||||||
|
# Check for curl timeout codes
|
||||||
|
if [[ $curl_exit_code == 7 || $curl_exit_code == 28 ]]; then
|
||||||
|
download_error_msg+=" Failed to reach the server: connection timeout."
|
||||||
|
else
|
||||||
local disable_feed_credential=false
|
local disable_feed_credential=false
|
||||||
local response=$(get_http_header_curl $remote_path $disable_feed_credential)
|
local response=$(get_http_header_curl $remote_path $disable_feed_credential)
|
||||||
http_code=$( echo "$response" | awk '/^HTTP/{print $2}' | tail -1 )
|
http_code=$( echo "$response" | awk '/^HTTP/{print $2}' | tail -1 )
|
||||||
download_error_msg="Unable to download $remote_path."
|
if [[ ! -z $http_code && $http_code != 2* ]]; then
|
||||||
if [[ $http_code != 2* ]]; then
|
|
||||||
download_error_msg+=" Returned HTTP status code: $http_code."
|
download_error_msg+=" Returned HTTP status code: $http_code."
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
say_verbose "$download_error_msg"
|
say_verbose "$download_error_msg"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@ -1030,10 +1235,17 @@ downloadwget() {
|
|||||||
# Append feed_credential as late as possible before calling wget to avoid logging feed_credential
|
# Append feed_credential as late as possible before calling wget to avoid logging feed_credential
|
||||||
local remote_path_with_credential="${remote_path}${feed_credential}"
|
local remote_path_with_credential="${remote_path}${feed_credential}"
|
||||||
local wget_options="--tries 20 "
|
local wget_options="--tries 20 "
|
||||||
# Store options that aren't supported on all wget implementations separately.
|
|
||||||
local wget_options_extra="--waitretry 2 --connect-timeout 15 "
|
local wget_options_extra=''
|
||||||
local wget_result=''
|
local wget_result=''
|
||||||
|
|
||||||
|
# Test for options that aren't supported on all wget implementations.
|
||||||
|
if [[ $(wget -h 2>&1 | grep -E 'waitretry|connect-timeout') ]]; then
|
||||||
|
wget_options_extra="--waitretry 2 --connect-timeout 15 "
|
||||||
|
else
|
||||||
|
say "wget extra options are unavailable for this environment"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "$out_path" ]; then
|
if [ -z "$out_path" ]; then
|
||||||
wget -q $wget_options $wget_options_extra -O - "$remote_path_with_credential" 2>&1
|
wget -q $wget_options $wget_options_extra -O - "$remote_path_with_credential" 2>&1
|
||||||
wget_result=$?
|
wget_result=$?
|
||||||
@ -1042,24 +1254,16 @@ downloadwget() {
|
|||||||
wget_result=$?
|
wget_result=$?
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $wget_result == 2 ]]; then
|
|
||||||
# Parsing of the command has failed. Exclude potentially unrecognized options and retry.
|
|
||||||
if [ -z "$out_path" ]; then
|
|
||||||
wget -q $wget_options -O - "$remote_path_with_credential" 2>&1
|
|
||||||
wget_result=$?
|
|
||||||
else
|
|
||||||
wget $wget_options -O "$out_path" "$remote_path_with_credential" 2>&1
|
|
||||||
wget_result=$?
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $wget_result != 0 ]]; then
|
if [[ $wget_result != 0 ]]; then
|
||||||
local disable_feed_credential=false
|
local disable_feed_credential=false
|
||||||
local response=$(get_http_header_wget $remote_path $disable_feed_credential)
|
local response=$(get_http_header_wget $remote_path $disable_feed_credential)
|
||||||
http_code=$( echo "$response" | awk '/^ HTTP/{print $2}' | tail -1 )
|
http_code=$( echo "$response" | awk '/^ HTTP/{print $2}' | tail -1 )
|
||||||
download_error_msg="Unable to download $remote_path."
|
download_error_msg="Unable to download $remote_path."
|
||||||
if [[ $http_code != 2* ]]; then
|
if [[ ! -z $http_code && $http_code != 2* ]]; then
|
||||||
download_error_msg+=" Returned HTTP status code: $http_code."
|
download_error_msg+=" Returned HTTP status code: $http_code."
|
||||||
|
# wget exit code 4 stands for network-issue
|
||||||
|
elif [[ $wget_result == 4 ]]; then
|
||||||
|
download_error_msg+=" Failed to reach the server: connection timeout."
|
||||||
fi
|
fi
|
||||||
say_verbose "$download_error_msg"
|
say_verbose "$download_error_msg"
|
||||||
return 1
|
return 1
|
||||||
@ -1068,13 +1272,69 @@ downloadwget() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extract_stem() {
|
||||||
|
local url="$1"
|
||||||
|
# extract the protocol
|
||||||
|
proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')"
|
||||||
|
# remove the protocol
|
||||||
|
url="${1/$proto/}"
|
||||||
|
# extract the path (if any) - since we know all of our feeds have a first path segment, we can skip the first one. otherwise we'd use -f2- to get the full path
|
||||||
|
full_path="$(echo $url | grep / | cut -d/ -f2-)"
|
||||||
|
path="$(echo $full_path | cut -d/ -f2-)"
|
||||||
|
echo $path
|
||||||
|
}
|
||||||
|
|
||||||
|
check_url_exists() {
|
||||||
|
eval $invocation
|
||||||
|
local url="$1"
|
||||||
|
|
||||||
|
local code=""
|
||||||
|
if machine_has "curl"
|
||||||
|
then
|
||||||
|
code=$(curl --head -o /dev/null -w "%{http_code}" -s --fail "$url");
|
||||||
|
elif machine_has "wget"
|
||||||
|
then
|
||||||
|
# get the http response, grab the status code
|
||||||
|
server_response=$(wget -qO- --method=HEAD --server-response "$url" 2>&1)
|
||||||
|
code=$(echo "$server_response" | grep "HTTP/" | awk '{print $2}')
|
||||||
|
fi
|
||||||
|
if [ $code = "200" ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
sanitize_redirect_url() {
|
||||||
|
eval $invocation
|
||||||
|
|
||||||
|
local url_stem
|
||||||
|
url_stem=$(extract_stem "$1")
|
||||||
|
say_verbose "Checking configured feeds for the asset at ${yellow:-}$url_stem${normal:-}"
|
||||||
|
|
||||||
|
for feed in "${feeds[@]}"
|
||||||
|
do
|
||||||
|
local trial_url="$feed/$url_stem"
|
||||||
|
say_verbose "Checking ${yellow:-}$trial_url${normal:-}"
|
||||||
|
if check_url_exists "$trial_url"; then
|
||||||
|
say_verbose "Found a match at ${yellow:-}$trial_url${normal:-}"
|
||||||
|
echo "$trial_url"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
say_verbose "No match at ${yellow:-}$trial_url${normal:-}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
get_download_link_from_aka_ms() {
|
get_download_link_from_aka_ms() {
|
||||||
eval $invocation
|
eval $invocation
|
||||||
|
|
||||||
#quality is not supported for LTS or current channel
|
#quality is not supported for LTS or STS channel
|
||||||
if [[ ! -z "$normalized_quality" && ("$normalized_channel" == "LTS" || "$normalized_channel" == "current") ]]; then
|
#STS maps to current
|
||||||
|
if [[ ! -z "$normalized_quality" && ("$normalized_channel" == "LTS" || "$normalized_channel" == "STS") ]]; then
|
||||||
normalized_quality=""
|
normalized_quality=""
|
||||||
say_warning "Specifying quality for current or LTS channel is not supported, the quality will be ignored."
|
say_warning "Specifying quality for STS or LTS channel is not supported, the quality will be ignored."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
say_verbose "Retrieving primary payload URL from aka.ms for channel: '$normalized_channel', quality: '$normalized_quality', product: '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'."
|
say_verbose "Retrieving primary payload URL from aka.ms for channel: '$normalized_channel', quality: '$normalized_quality', product: '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'."
|
||||||
@ -1103,6 +1363,12 @@ get_download_link_from_aka_ms() {
|
|||||||
http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' )
|
http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' )
|
||||||
# They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404).
|
# They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404).
|
||||||
broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' )
|
broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' )
|
||||||
|
# The response may end without final code 2xx/4xx/5xx somehow, e.g. network restrictions on www.bing.com causes redirecting to bing.com fails with connection refused.
|
||||||
|
# In this case it should not exclude the last.
|
||||||
|
last_http_code=$( echo "$http_codes" | tail -n 1 )
|
||||||
|
if ! [[ $last_http_code =~ ^(2|4|5)[0-9][0-9]$ ]]; then
|
||||||
|
broken_redirects=$( echo "$http_codes" | grep -v '301' )
|
||||||
|
fi
|
||||||
|
|
||||||
# All HTTP codes are 301 (Moved Permanently), the redirect link exists.
|
# All HTTP codes are 301 (Moved Permanently), the redirect link exists.
|
||||||
if [[ -z "$broken_redirects" ]]; then
|
if [[ -z "$broken_redirects" ]]; then
|
||||||
@ -1113,6 +1379,11 @@ get_download_link_from_aka_ms() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
sanitized_redirect_url=$(sanitize_redirect_url "$aka_ms_download_link")
|
||||||
|
if [[ -n "$sanitized_redirect_url" ]]; then
|
||||||
|
aka_ms_download_link="$sanitized_redirect_url"
|
||||||
|
fi
|
||||||
|
|
||||||
say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
|
say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
@ -1124,7 +1395,9 @@ get_download_link_from_aka_ms() {
|
|||||||
get_feeds_to_use()
|
get_feeds_to_use()
|
||||||
{
|
{
|
||||||
feeds=(
|
feeds=(
|
||||||
|
"https://builds.dotnet.microsoft.com/dotnet"
|
||||||
"https://dotnetcli.azureedge.net/dotnet"
|
"https://dotnetcli.azureedge.net/dotnet"
|
||||||
|
"https://ci.dot.net/public"
|
||||||
"https://dotnetbuilds.azureedge.net/public"
|
"https://dotnetbuilds.azureedge.net/public"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1182,6 +1455,11 @@ generate_akams_links() {
|
|||||||
local valid_aka_ms_link=true;
|
local valid_aka_ms_link=true;
|
||||||
|
|
||||||
normalized_version="$(to_lowercase "$version")"
|
normalized_version="$(to_lowercase "$version")"
|
||||||
|
if [[ "$normalized_version" != "latest" ]] && [ -n "$normalized_quality" ]; then
|
||||||
|
say_err "Quality and Version options are not allowed to be specified simultaneously. See https://learn.microsoft.com/dotnet/core/tools/dotnet-install-script#options for details."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -n "$json_file" || "$normalized_version" != "latest" ]]; then
|
if [[ -n "$json_file" || "$normalized_version" != "latest" ]]; then
|
||||||
# aka.ms links are not needed when exact version is specified via command or json file
|
# aka.ms links are not needed when exact version is specified via command or json file
|
||||||
return
|
return
|
||||||
@ -1325,6 +1603,8 @@ calculate_vars() {
|
|||||||
install_root="$(resolve_installation_path "$install_dir")"
|
install_root="$(resolve_installation_path "$install_dir")"
|
||||||
say_verbose "InstallRoot: '$install_root'."
|
say_verbose "InstallRoot: '$install_root'."
|
||||||
|
|
||||||
|
normalized_architecture="$(get_normalized_architecture_for_specific_sdk_version "$version" "$normalized_channel" "$normalized_architecture")"
|
||||||
|
|
||||||
if [[ "$runtime" == "dotnet" ]]; then
|
if [[ "$runtime" == "dotnet" ]]; then
|
||||||
asset_relative_path="shared/Microsoft.NETCore.App"
|
asset_relative_path="shared/Microsoft.NETCore.App"
|
||||||
asset_name=".NET Core Runtime"
|
asset_name=".NET Core Runtime"
|
||||||
@ -1343,10 +1623,11 @@ install_dotnet() {
|
|||||||
eval $invocation
|
eval $invocation
|
||||||
local download_failed=false
|
local download_failed=false
|
||||||
local download_completed=false
|
local download_completed=false
|
||||||
|
local remote_file_size=0
|
||||||
|
|
||||||
mkdir -p "$install_root"
|
mkdir -p "$install_root"
|
||||||
zip_path="$(mktemp "$temporary_file_template")"
|
zip_path="${zip_path:-$(mktemp "$temporary_file_template")}"
|
||||||
say_verbose "Zip path: $zip_path"
|
say_verbose "Archive path: $zip_path"
|
||||||
|
|
||||||
for link_index in "${!download_links[@]}"
|
for link_index in "${!download_links[@]}"
|
||||||
do
|
do
|
||||||
@ -1370,7 +1651,7 @@ install_dotnet() {
|
|||||||
say "Failed to download $link_type link '$download_link': $download_error_msg"
|
say "Failed to download $link_type link '$download_link': $download_error_msg"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed"
|
rm -f "$zip_path" 2>&1 && say_verbose "Temporary archive file $zip_path was removed"
|
||||||
else
|
else
|
||||||
download_completed=true
|
download_completed=true
|
||||||
break
|
break
|
||||||
@ -1383,8 +1664,10 @@ install_dotnet() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
say "Extracting zip from $download_link"
|
remote_file_size="$(get_remote_file_size "$download_link")"
|
||||||
extract_dotnet_package "$zip_path" "$install_root" || return 1
|
|
||||||
|
say "Extracting archive from $download_link"
|
||||||
|
extract_dotnet_package "$zip_path" "$install_root" "$remote_file_size" || return 1
|
||||||
|
|
||||||
# Check if the SDK version is installed; if not, fail the installation.
|
# Check if the SDK version is installed; if not, fail the installation.
|
||||||
# if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed.
|
# if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed.
|
||||||
@ -1395,6 +1678,7 @@ install_dotnet() {
|
|||||||
unset IFS;
|
unset IFS;
|
||||||
say_verbose "Checking installation: version = $release_version"
|
say_verbose "Checking installation: version = $release_version"
|
||||||
if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$release_version"; then
|
if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$release_version"; then
|
||||||
|
say "Installed version is $effective_version"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -1402,6 +1686,7 @@ install_dotnet() {
|
|||||||
# Check if the standard SDK version is installed.
|
# Check if the standard SDK version is installed.
|
||||||
say_verbose "Checking installation: version = $effective_version"
|
say_verbose "Checking installation: version = $effective_version"
|
||||||
if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then
|
if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then
|
||||||
|
say "Installed version is $effective_version"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -1532,36 +1817,53 @@ do
|
|||||||
override_non_versioned_files=false
|
override_non_versioned_files=false
|
||||||
non_dynamic_parameters+=" $name"
|
non_dynamic_parameters+=" $name"
|
||||||
;;
|
;;
|
||||||
|
--keep-zip|-[Kk]eep[Zz]ip)
|
||||||
|
keep_zip=true
|
||||||
|
non_dynamic_parameters+=" $name"
|
||||||
|
;;
|
||||||
|
--zip-path|-[Zz]ip[Pp]ath)
|
||||||
|
shift
|
||||||
|
zip_path="$1"
|
||||||
|
;;
|
||||||
-?|--?|-h|--help|-[Hh]elp)
|
-?|--?|-h|--help|-[Hh]elp)
|
||||||
script_name="$(basename "$0")"
|
script_name="dotnet-install.sh"
|
||||||
echo ".NET Tools Installer"
|
echo ".NET Tools Installer"
|
||||||
echo "Usage: $script_name [-c|--channel <CHANNEL>] [-v|--version <VERSION>] [-p|--prefix <DESTINATION>]"
|
echo "Usage:"
|
||||||
|
echo " # Install a .NET SDK of a given Quality from a given Channel"
|
||||||
|
echo " $script_name [-c|--channel <CHANNEL>] [-q|--quality <QUALITY>]"
|
||||||
|
echo " # Install a .NET SDK of a specific public version"
|
||||||
|
echo " $script_name [-v|--version <VERSION>]"
|
||||||
echo " $script_name -h|-?|--help"
|
echo " $script_name -h|-?|--help"
|
||||||
echo ""
|
echo ""
|
||||||
echo "$script_name is a simple command line interface for obtaining dotnet cli."
|
echo "$script_name is a simple command line interface for obtaining dotnet cli."
|
||||||
|
echo " Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
||||||
|
echo " - The SDK needs to be installed without user interaction and without admin rights."
|
||||||
|
echo " - The SDK installation doesn't need to persist across multiple CI runs."
|
||||||
|
echo " To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer."
|
||||||
echo ""
|
echo ""
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " -c,--channel <CHANNEL> Download from the channel specified, Defaults to \`$channel\`."
|
echo " -c,--channel <CHANNEL> Download from the channel specified, Defaults to \`$channel\`."
|
||||||
echo " -Channel"
|
echo " -Channel"
|
||||||
echo " Possible values:"
|
echo " Possible values:"
|
||||||
echo " - Current - most current release"
|
echo " - STS - the most recent Standard Term Support release"
|
||||||
echo " - LTS - most current supported release"
|
echo " - LTS - the most recent Long Term Support release"
|
||||||
echo " - 2-part version in a format A.B - represents a specific release"
|
echo " - 2-part version in a format A.B - represents a specific release"
|
||||||
echo " examples: 2.0; 1.0"
|
echo " examples: 2.0; 1.0"
|
||||||
echo " - 3-part version in a format A.B.Cxx - represents a specific SDK release"
|
echo " - 3-part version in a format A.B.Cxx - represents a specific SDK release"
|
||||||
echo " examples: 5.0.1xx, 5.0.2xx."
|
echo " examples: 5.0.1xx, 5.0.2xx."
|
||||||
echo " Supported since 5.0 release"
|
echo " Supported since 5.0 release"
|
||||||
|
echo " Warning: Value 'Current' is deprecated for the Channel parameter. Use 'STS' instead."
|
||||||
echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used."
|
echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used."
|
||||||
echo " -v,--version <VERSION> Use specific VERSION, Defaults to \`$version\`."
|
echo " -v,--version <VERSION> Use specific VERSION, Defaults to \`$version\`."
|
||||||
echo " -Version"
|
echo " -Version"
|
||||||
echo " Possible values:"
|
echo " Possible values:"
|
||||||
echo " - latest - most latest build on specific channel"
|
echo " - latest - the latest build on specific channel"
|
||||||
echo " - 3-part version in a format A.B.C - represents specific version of build"
|
echo " - 3-part version in a format A.B.C - represents specific version of build"
|
||||||
echo " examples: 2.0.0-preview2-006120; 1.1.0"
|
echo " examples: 2.0.0-preview2-006120; 1.1.0"
|
||||||
echo " -q,--quality <quality> Download the latest build of specified quality in the channel."
|
echo " -q,--quality <quality> Download the latest build of specified quality in the channel."
|
||||||
echo " -Quality"
|
echo " -Quality"
|
||||||
echo " The possible values are: daily, signed, validated, preview, GA."
|
echo " The possible values are: daily, signed, validated, preview, GA."
|
||||||
echo " Works only in combination with channel. Not applicable for current and LTS channels and will be ignored if those channels are used."
|
echo " Works only in combination with channel. Not applicable for STS and LTS channels and will be ignored if those channels are used."
|
||||||
echo " For SDK use channel in A.B.Cxx format. Using quality for SDK together with channel in A.B format is not supported."
|
echo " For SDK use channel in A.B.Cxx format. Using quality for SDK together with channel in A.B format is not supported."
|
||||||
echo " Supported since 5.0 release."
|
echo " Supported since 5.0 release."
|
||||||
echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used, and therefore overrides the quality."
|
echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used, and therefore overrides the quality."
|
||||||
@ -1572,7 +1874,7 @@ do
|
|||||||
echo " -InstallDir"
|
echo " -InstallDir"
|
||||||
echo " --architecture <ARCHITECTURE> Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
|
echo " --architecture <ARCHITECTURE> Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
|
||||||
echo " --arch,-Architecture,-Arch"
|
echo " --arch,-Architecture,-Arch"
|
||||||
echo " Possible values: x64, arm, and arm64"
|
echo " Possible values: x64, arm, arm64, s390x, ppc64le and loongarch64"
|
||||||
echo " --os <system> Specifies operating system to be used when selecting the installer."
|
echo " --os <system> Specifies operating system to be used when selecting the installer."
|
||||||
echo " Overrides the OS determination approach used by the script. Supported values: osx, linux, linux-musl, freebsd, rhel.6."
|
echo " Overrides the OS determination approach used by the script. Supported values: osx, linux, linux-musl, freebsd, rhel.6."
|
||||||
echo " In case any other value is provided, the platform will be determined by the script based on machine configuration."
|
echo " In case any other value is provided, the platform will be determined by the script based on machine configuration."
|
||||||
@ -1597,6 +1899,8 @@ do
|
|||||||
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
|
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
|
||||||
echo " --jsonfile <JSONFILE> Determines the SDK version from a user specified global.json file."
|
echo " --jsonfile <JSONFILE> Determines the SDK version from a user specified global.json file."
|
||||||
echo " Note: global.json must have a value for 'SDK:Version'"
|
echo " Note: global.json must have a value for 'SDK:Version'"
|
||||||
|
echo " --keep-zip,-KeepZip If set, downloaded file is kept."
|
||||||
|
echo " --zip-path, -ZipPath If set, downloaded file is stored at the specified path."
|
||||||
echo " -?,--?,-h,--help,-Help Shows this help message"
|
echo " -?,--?,-h,--help,-Help Shows this help message"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Install Location:"
|
echo "Install Location:"
|
||||||
@ -1615,10 +1919,10 @@ do
|
|||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
say "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
say_verbose "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
||||||
say "- The SDK needs to be installed without user interaction and without admin rights."
|
say_verbose "- The SDK needs to be installed without user interaction and without admin rights."
|
||||||
say "- The SDK installation doesn't need to persist across multiple CI runs."
|
say_verbose "- The SDK installation doesn't need to persist across multiple CI runs."
|
||||||
say "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.\n"
|
say_verbose "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.\n"
|
||||||
|
|
||||||
if [ "$internal" = true ] && [ -z "$(echo $feed_credential)" ]; then
|
if [ "$internal" = true ] && [ -z "$(echo $feed_credential)" ]; then
|
||||||
message="Provide credentials via --feed-credential parameter."
|
message="Provide credentials via --feed-credential parameter."
|
||||||
@ -1651,5 +1955,5 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
say "Note that the script does not resolve dependencies during installation."
|
say "Note that the script does not resolve dependencies during installation."
|
||||||
say "To check the list of dependencies, go to https://docs.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section."
|
say "To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section."
|
||||||
say "Installation finished successfully."
|
say "Installation finished successfully."
|
Loading…
Reference in New Issue
Block a user