mirror of
				https://github.com/actions/setup-dotnet.git
				synced 2025-10-31 23:23:46 +00:00 
			
		
		
		
	Updated dotnet-install scripts to latest version
This commit is contained in:
		
							parent
							
								
									c20f59e04a
								
							
						
					
					
						commit
						e54e706650
					
				
							
								
								
									
										714
									
								
								externals/install-dotnet.ps1
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										714
									
								
								externals/install-dotnet.ps1
									
									
									
									
										vendored
									
									
								
							| @ -66,11 +66,13 @@ | ||||
|     Displays diagnostics information. | ||||
| .PARAMETER AzureFeed | ||||
|     Default: https://dotnetcli.azureedge.net/dotnet | ||||
|     This parameter typically is not changed by the user. | ||||
|     It allows changing the URL for the Azure feed used by this installer. | ||||
|     For internal use only. | ||||
|     Allows using a different storage to download SDK archives from. | ||||
|     This parameter is only used if $NoCdn is false. | ||||
| .PARAMETER UncachedFeed | ||||
|     This parameter typically is not changed by the user. | ||||
|     It allows changing the URL for the Uncached feed used by this installer. | ||||
|     For internal use only. | ||||
|     Allows using a different storage to download SDK archives from. | ||||
|     This parameter is only used if $NoCdn is true. | ||||
| .PARAMETER ProxyAddress | ||||
|     If set, the installer will use the proxy when making web requests | ||||
| .PARAMETER ProxyUseDefaultCredentials | ||||
| @ -104,8 +106,8 @@ param( | ||||
|    [switch]$SharedRuntime, | ||||
|    [switch]$DryRun, | ||||
|    [switch]$NoPath, | ||||
|    [string]$AzureFeed="https://dotnetcli.azureedge.net/dotnet", | ||||
|    [string]$UncachedFeed="https://dotnetcli.blob.core.windows.net/dotnet", | ||||
|    [string]$AzureFeed, | ||||
|    [string]$UncachedFeed, | ||||
|    [string]$FeedCredential, | ||||
|    [string]$ProxyAddress, | ||||
|    [switch]$ProxyUseDefaultCredentials, | ||||
| @ -119,20 +121,6 @@ Set-StrictMode -Version Latest | ||||
| $ErrorActionPreference="Stop" | ||||
| $ProgressPreference="SilentlyContinue" | ||||
| 
 | ||||
| if ($NoCdn) { | ||||
|     $AzureFeed = $UncachedFeed | ||||
| } | ||||
| 
 | ||||
| $BinFolderRelativePath="" | ||||
| 
 | ||||
| if ($SharedRuntime -and (-not $Runtime)) { | ||||
|     $Runtime = "dotnet" | ||||
| } | ||||
| 
 | ||||
| # example path with regex: shared/1.0.0-beta-12345/somepath | ||||
| $VersionRegEx="/\d+\.\d+[^/]+/" | ||||
| $OverrideNonVersionedFiles = !$SkipNonVersionedFiles | ||||
| 
 | ||||
| function Say($str) { | ||||
|     try { | ||||
|         Write-Host "dotnet-install: $str" | ||||
| @ -207,9 +195,7 @@ function Get-Machine-Architecture() { | ||||
|     # To get the correct architecture, we need to use PROCESSOR_ARCHITEW6432. | ||||
|     # PS x64 doesn't define this, so we fall back to PROCESSOR_ARCHITECTURE. | ||||
|     # Possible values: amd64, x64, x86, arm64, arm | ||||
| 
 | ||||
|     if( $ENV:PROCESSOR_ARCHITEW6432 -ne $null ) | ||||
|     {     | ||||
|     if( $ENV:PROCESSOR_ARCHITEW6432 -ne $null ) { | ||||
|         return $ENV:PROCESSOR_ARCHITEW6432 | ||||
|     } | ||||
| 
 | ||||
| @ -219,8 +205,11 @@ function Get-Machine-Architecture() { | ||||
| function Get-CLIArchitecture-From-Architecture([string]$Architecture) { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     if ($Architecture -eq "<auto>") { | ||||
|         $Architecture = Get-Machine-Architecture | ||||
|     } | ||||
| 
 | ||||
|     switch ($Architecture.ToLowerInvariant()) { | ||||
|         { $_ -eq "<auto>" } { return Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture) } | ||||
|         { ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" } | ||||
|         { $_ -eq "x86" } { return "x86" } | ||||
|         { $_ -eq "arm" } { return "arm" } | ||||
| @ -229,7 +218,25 @@ function Get-CLIArchitecture-From-Architecture([string]$Architecture) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function ValidateFeedCredential([string] $FeedCredential) | ||||
| { | ||||
|     if ($Internal -and [string]::IsNullOrWhitespace($FeedCredential)) { | ||||
|         $message = "Provide credentials via -FeedCredential parameter." | ||||
|         if ($DryRun) { | ||||
|             Say-Warning "$message" | ||||
|         } else { | ||||
|             throw "$message" | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     #FeedCredential should start with "?", for it to be added to the end of the link. | ||||
|     #adding "?" at the beginning of the FeedCredential if needed. | ||||
|     if ((![string]::IsNullOrWhitespace($FeedCredential)) -and ($FeedCredential[0] -ne '?')) { | ||||
|         $FeedCredential = "?" + $FeedCredential | ||||
|     } | ||||
| 
 | ||||
|     return $FeedCredential | ||||
| } | ||||
| function Get-NormalizedQuality([string]$Quality) { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
| @ -282,7 +289,7 @@ function Get-NormalizedProduct([string]$Runtime) { | ||||
| # Line 2: # 4-part version | ||||
| # For the aspnetcore runtime (1 line): | ||||
| # Line 1: # 4-part version | ||||
| function Get-Version-Info-From-Version-Text([string]$VersionText) { | ||||
| function Get-Version-From-LatestVersion-File-Content([string]$VersionText) { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     $Data = -split $VersionText | ||||
| @ -321,7 +328,11 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, | ||||
|                     # Despite no proxy being explicitly specified, we may still be behind a default proxy | ||||
|                     $DefaultProxy = [System.Net.WebRequest]::DefaultWebProxy; | ||||
|                     if($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))) { | ||||
|                         if ($null -ne $DefaultProxy.GetProxy($Uri)) { | ||||
|                             $ProxyAddress = $DefaultProxy.GetProxy($Uri).OriginalString | ||||
|                         } else { | ||||
|                             $ProxyAddress = $null | ||||
|                         } | ||||
|                         $ProxyUseDefaultCredentials = $true | ||||
|                     } | ||||
|                 } catch { | ||||
| @ -424,21 +435,21 @@ function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel) { | ||||
| function Get-Version-From-LatestVersion-File([string]$AzureFeed, [string]$Channel) { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     $VersionFileUrl = $null | ||||
|     if ($Runtime -eq "dotnet") { | ||||
|         $VersionFileUrl = "$UncachedFeed/Runtime/$Channel/latest.version" | ||||
|         $VersionFileUrl = "$AzureFeed/Runtime/$Channel/latest.version" | ||||
|     } | ||||
|     elseif ($Runtime -eq "aspnetcore") { | ||||
|         $VersionFileUrl = "$UncachedFeed/aspnetcore/Runtime/$Channel/latest.version" | ||||
|         $VersionFileUrl = "$AzureFeed/aspnetcore/Runtime/$Channel/latest.version" | ||||
|     } | ||||
|     elseif ($Runtime -eq "windowsdesktop") { | ||||
|         $VersionFileUrl = "$UncachedFeed/WindowsDesktop/$Channel/latest.version" | ||||
|         $VersionFileUrl = "$AzureFeed/WindowsDesktop/$Channel/latest.version" | ||||
|     } | ||||
|     elseif (-not $Runtime) { | ||||
|         $VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.version" | ||||
|         $VersionFileUrl = "$AzureFeed/Sdk/$Channel/latest.version" | ||||
|     } | ||||
|     else { | ||||
|         throw "Invalid value for `$Runtime" | ||||
| @ -450,7 +461,7 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel) { | ||||
|         $Response = GetHTTPResponse -Uri $VersionFileUrl | ||||
|     } | ||||
|     catch { | ||||
|         Say-Error "Could not resolve version information." | ||||
|         Say-Verbose "Failed to download latest.version file." | ||||
|         throw | ||||
|     } | ||||
|     $StringContent = $Response.Content.ReadAsStringAsync().Result | ||||
| @ -462,7 +473,7 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel) { | ||||
|         default { throw "``$Response.Content.Headers.ContentType`` is an unknown .version file content type." } | ||||
|     } | ||||
| 
 | ||||
|     $VersionInfo = Get-Version-Info-From-Version-Text $VersionText | ||||
|     $VersionInfo = Get-Version-From-LatestVersion-File-Content $VersionText | ||||
| 
 | ||||
|     return $VersionInfo | ||||
| } | ||||
| @ -509,7 +520,7 @@ function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel, | ||||
| 
 | ||||
|     if (-not $JSonFile) { | ||||
|         if ($Version.ToLowerInvariant() -eq "latest") { | ||||
|             $LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel | ||||
|             $LatestVersionInfo = Get-Version-From-LatestVersion-File -AzureFeed $AzureFeed -Channel $Channel | ||||
|             return $LatestVersionInfo.Version | ||||
|         } | ||||
|         else { | ||||
| @ -722,7 +733,8 @@ function Get-Absolute-Path([string]$RelativeOrAbsolutePath) { | ||||
| } | ||||
| 
 | ||||
| function Get-Path-Prefix-With-Version($path) { | ||||
|     $match = [regex]::match($path, $VersionRegEx) | ||||
|     # example path with regex: shared/1.0.0-beta-12345/somepath | ||||
|     $match = [regex]::match($path, "/\d+\.\d+[^/]+/") | ||||
|     if ($match.Success) { | ||||
|         return $entry.FullName.Substring(0, $match.Index + $match.Length) | ||||
|     } | ||||
| @ -736,7 +748,7 @@ function Get-List-Of-Directories-And-Versions-To-Unpack-From-Dotnet-Package([Sys | ||||
|     $ret = @() | ||||
|     foreach ($entry in $Zip.Entries) { | ||||
|         $dir = Get-Path-Prefix-With-Version $entry.FullName | ||||
|         if ($dir -ne $null) { | ||||
|         if ($null -ne $dir) { | ||||
|             $path = Get-Absolute-Path $(Join-Path -Path $OutPath -ChildPath $dir) | ||||
|             if (-Not (Test-Path $path -PathType Container)) { | ||||
|                 $ret += $dir | ||||
| @ -777,7 +789,7 @@ function Extract-Dotnet-Package([string]$ZipPath, [string]$OutPath) { | ||||
| 
 | ||||
|         foreach ($entry in $Zip.Entries) { | ||||
|             $PathWithVersion = Get-Path-Prefix-With-Version $entry.FullName | ||||
|             if (($PathWithVersion -eq $null) -Or ($DirectoriesToUnpack -contains $PathWithVersion)) { | ||||
|             if (($null -eq $PathWithVersion) -Or ($DirectoriesToUnpack -contains $PathWithVersion)) { | ||||
|                 $DestinationPath = Get-Absolute-Path $(Join-Path -Path $OutPath -ChildPath $entry.FullName) | ||||
|                 $DestinationDir = Split-Path -Parent $DestinationPath | ||||
|                 $OverrideFiles=$OverrideNonVersionedFiles -Or (-Not (Test-Path $DestinationPath)) | ||||
| @ -789,7 +801,7 @@ function Extract-Dotnet-Package([string]$ZipPath, [string]$OutPath) { | ||||
|         } | ||||
|     } | ||||
|     finally { | ||||
|         if ($Zip -ne $null) { | ||||
|         if ($null -ne $Zip) { | ||||
|             $Zip.Dispose() | ||||
|         } | ||||
|     } | ||||
| @ -818,7 +830,7 @@ function DownloadFile($Source, [string]$OutPath) { | ||||
|         $File.Close() | ||||
|     } | ||||
|     finally { | ||||
|         if ($Stream -ne $null) { | ||||
|         if ($null -ne $Stream) { | ||||
|             $Stream.Dispose() | ||||
|         } | ||||
|     } | ||||
| @ -841,8 +853,8 @@ function SafeRemoveFile($Path) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolderRelativePath) { | ||||
|     $BinPath = Get-Absolute-Path $(Join-Path -Path $InstallRoot -ChildPath $BinFolderRelativePath) | ||||
| function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot) { | ||||
|     $BinPath = Get-Absolute-Path $(Join-Path -Path $InstallRoot -ChildPath "") | ||||
|     if (-Not $NoPath) { | ||||
|         $SuffixedBinPath = "$BinPath;" | ||||
|         if (-Not $env:path.Contains($SuffixedBinPath)) { | ||||
| @ -857,6 +869,36 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolde | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function PrintDryRunOutput($Invocation, $DownloadLinks) | ||||
| { | ||||
|     Say "Payload URLs:" | ||||
|      | ||||
|     for ($linkIndex=0; $linkIndex -lt $DownloadLinks.count; $linkIndex++) { | ||||
|         Say "URL #$linkIndex - $($DownloadLinks[$linkIndex].type): $($DownloadLinks[$linkIndex].downloadLink)" | ||||
|     } | ||||
|     $RepeatableCommand = ".\$ScriptName -Version `"$SpecificVersion`" -InstallDir `"$InstallRoot`" -Architecture `"$CLIArchitecture`"" | ||||
|     if ($Runtime -eq "dotnet") { | ||||
|        $RepeatableCommand+=" -Runtime `"dotnet`"" | ||||
|     } | ||||
|     elseif ($Runtime -eq "aspnetcore") { | ||||
|        $RepeatableCommand+=" -Runtime `"aspnetcore`"" | ||||
|     } | ||||
| 
 | ||||
|     foreach ($key in $Invocation.BoundParameters.Keys) { | ||||
|         if (-not (@("Architecture","Channel","DryRun","InstallDir","Runtime","SharedRuntime","Version","Quality","FeedCredential") -contains $key)) { | ||||
|             $RepeatableCommand+=" -$key `"$($Invocation.BoundParameters[$key])`"" | ||||
|         } | ||||
|     } | ||||
|     if ($Invocation.BoundParameters.Keys -contains "FeedCredential") { | ||||
|         $RepeatableCommand+=" -FeedCredential `"<feedCredential>`"" | ||||
|     } | ||||
|     Say "Repeatable invocation: $RepeatableCommand" | ||||
|     if ($SpecificVersion -ne $EffectiveVersion) | ||||
|     { | ||||
|         Say "NOTE: Due to finding a version manifest with this runtime, it would actually install with version '$EffectiveVersion'" | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Internal, [string]$Product, [string]$Architecture) { | ||||
|     Say-Invocation $MyInvocation  | ||||
| 
 | ||||
| @ -930,118 +972,69 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| Say "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 "- 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.`r`n" | ||||
| 
 | ||||
| if ($Internal -and [string]::IsNullOrWhitespace($FeedCredential)) { | ||||
|     $message = "Provide credentials via -FeedCredential parameter." | ||||
|     if ($DryRun) { | ||||
|         Say-Warning "$message" | ||||
|     } else { | ||||
|         throw "$message" | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #FeedCredential should start with "?", for it to be added to the end of the link. | ||||
| #adding "?" at the beginning of the FeedCredential if needed. | ||||
| if ((![string]::IsNullOrWhitespace($FeedCredential)) -and ($FeedCredential[0] -ne '?')) { | ||||
|     $FeedCredential = "?" + $FeedCredential | ||||
| } | ||||
| 
 | ||||
| $CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture | ||||
| $NormalizedQuality = Get-NormalizedQuality $Quality | ||||
| Say-Verbose "Normalized quality: '$NormalizedQuality'" | ||||
| $NormalizedChannel = Get-NormalizedChannel $Channel | ||||
| Say-Verbose "Normalized channel: '$NormalizedChannel'" | ||||
| $NormalizedProduct = Get-NormalizedProduct $Runtime | ||||
| Say-Verbose "Normalized product: '$NormalizedProduct'" | ||||
| $DownloadLink = $null | ||||
| 
 | ||||
| #try to get download location from aka.ms link | ||||
| #not applicable when exact version is specified via command or json file | ||||
| if ([string]::IsNullOrEmpty($JSonFile) -and ($Version -eq "latest")) { | ||||
|     $AkaMsDownloadLink = Get-AkaMSDownloadLink -Channel $NormalizedChannel -Quality $NormalizedQuality -Internal $Internal -Product $NormalizedProduct -Architecture $CLIArchitecture | ||||
| function Get-AkaMsLink-And-Version([string] $NormalizedChannel, [string] $NormalizedQuality, [bool] $Internal, [string] $ProductName, [string] $Architecture) { | ||||
|     $AkaMsDownloadLink = Get-AkaMSDownloadLink -Channel $NormalizedChannel -Quality $NormalizedQuality -Internal $Internal -Product $ProductName -Architecture $Architecture | ||||
|     | ||||
|     if ([string]::IsNullOrEmpty($AkaMsDownloadLink)){ | ||||
|         if (-not [string]::IsNullOrEmpty($NormalizedQuality)) { | ||||
|             # if quality is specified - exit with error - there is no fallback approach | ||||
|             Say-Error "Failed to locate the latest version in the channel '$NormalizedChannel' with '$NormalizedQuality' quality for '$NormalizedProduct', os: 'win', architecture: '$CLIArchitecture'." | ||||
|             Say-Error "Failed to locate the latest version in the channel '$NormalizedChannel' with '$NormalizedQuality' quality for '$ProductName', os: 'win', architecture: '$Architecture'." | ||||
|             Say-Error "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support." | ||||
|             throw "aka.ms link resolution failure" | ||||
|         } | ||||
|         Say-Verbose "Falling back to latest.version file approach." | ||||
|         return ($null, $null, $null) | ||||
|     } | ||||
|     else { | ||||
|         Say-Verbose "Retrieved primary named payload URL from aka.ms link: '$AkaMsDownloadLink'." | ||||
|         $DownloadLink = $AkaMsDownloadLink | ||||
|         Say-Verbose  "Downloading using legacy url will not be attempted." | ||||
|         $LegacyDownloadLink = $null | ||||
| 
 | ||||
|         #get version from the path | ||||
|         $pathParts = $DownloadLink.Split('/') | ||||
|         $pathParts = $AkaMsDownloadLink.Split('/') | ||||
|         if ($pathParts.Length -ge 2) {  | ||||
|             $SpecificVersion = $pathParts[$pathParts.Length - 2] | ||||
|             Say-Verbose "Version: '$SpecificVersion'." | ||||
|         } | ||||
|         else { | ||||
|             Say-Error "Failed to extract the version from download link '$DownloadLink'." | ||||
|             Say-Error "Failed to extract the version from download link '$AkaMsDownloadLink'." | ||||
|             return ($null, $null, $null) | ||||
|         } | ||||
| 
 | ||||
|         #retrieve effective (product) version | ||||
|         $EffectiveVersion = Get-Product-Version -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -PackageDownloadLink $DownloadLink | ||||
|         $EffectiveVersion = Get-Product-Version -SpecificVersion $SpecificVersion -PackageDownloadLink $AkaMsDownloadLink | ||||
|         Say-Verbose "Product version: '$EffectiveVersion'." | ||||
| 
 | ||||
|         return ($AkaMsDownloadLink, $SpecificVersion, $EffectiveVersion); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| if ([string]::IsNullOrEmpty($DownloadLink)) { | ||||
|     $SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version -JSonFile $JSonFile | ||||
|     $DownloadLink, $EffectiveVersion = Get-Download-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture | ||||
|     $LegacyDownloadLink = Get-LegacyDownload-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| $InstallRoot = Resolve-Installation-Path $InstallDir | ||||
| Say-Verbose "InstallRoot: $InstallRoot" | ||||
| $ScriptName = $MyInvocation.MyCommand.Name | ||||
| 
 | ||||
| if ($DryRun) { | ||||
|     Say "Payload URLs:" | ||||
|     Say "Primary named payload URL: ${DownloadLink}" | ||||
|     if ($LegacyDownloadLink) { | ||||
|         Say "Legacy named payload URL: ${LegacyDownloadLink}" | ||||
|     } | ||||
|     $RepeatableCommand = ".\$ScriptName -Version `"$SpecificVersion`" -InstallDir `"$InstallRoot`" -Architecture `"$CLIArchitecture`"" | ||||
|     if ($Runtime -eq "dotnet") { | ||||
|        $RepeatableCommand+=" -Runtime `"dotnet`"" | ||||
|     } | ||||
|     elseif ($Runtime -eq "aspnetcore") { | ||||
|        $RepeatableCommand+=" -Runtime `"aspnetcore`"" | ||||
|     } | ||||
| 
 | ||||
|     if (-not [string]::IsNullOrEmpty($NormalizedQuality)) | ||||
| function Get-Feeds-To-Use() | ||||
| { | ||||
|         $RepeatableCommand+=" -Quality `"$NormalizedQuality`"" | ||||
|     $feeds = @( | ||||
|     "https://dotnetcli.azureedge.net/dotnet", | ||||
|     "https://dotnetbuilds.azureedge.net/public" | ||||
|     ) | ||||
| 
 | ||||
|     if (-not [string]::IsNullOrEmpty($AzureFeed)) { | ||||
|         $feeds = @($AzureFeed) | ||||
|     } | ||||
| 
 | ||||
|     foreach ($key in $MyInvocation.BoundParameters.Keys) { | ||||
|         if (-not (@("Architecture","Channel","DryRun","InstallDir","Runtime","SharedRuntime","Version","Quality","FeedCredential") -contains $key)) { | ||||
|             $RepeatableCommand+=" -$key `"$($MyInvocation.BoundParameters[$key])`"" | ||||
|     if ($NoCdn) { | ||||
|         $feeds = @( | ||||
|         "https://dotnetcli.blob.core.windows.net/dotnet", | ||||
|         "https://dotnetbuilds.blob.core.windows.net/public" | ||||
|         ) | ||||
| 
 | ||||
|         if (-not [string]::IsNullOrEmpty($UncachedFeed)) { | ||||
|             $feeds = @($UncachedFeed) | ||||
|         } | ||||
|     } | ||||
|     if ($MyInvocation.BoundParameters.Keys -contains "FeedCredential") { | ||||
|         $RepeatableCommand+=" -FeedCredential `"<feedCredential>`"" | ||||
|     } | ||||
|     Say "Repeatable invocation: $RepeatableCommand" | ||||
|     if ($SpecificVersion -ne $EffectiveVersion) | ||||
|     { | ||||
|         Say "NOTE: Due to finding a version manifest with this runtime, it would actually install with version '$EffectiveVersion'" | ||||
|     } | ||||
| 
 | ||||
|     return | ||||
|     return $feeds | ||||
| } | ||||
| 
 | ||||
| function Resolve-AssetName-And-RelativePath([string] $Runtime) { | ||||
|      | ||||
|     if ($Runtime -eq "dotnet") { | ||||
|         $assetName = ".NET Core Runtime" | ||||
|         $dotnetPackageRelativePath = "shared\Microsoft.NETCore.App" | ||||
| @ -1062,20 +1055,10 @@ else { | ||||
|         throw "Invalid value for `$Runtime" | ||||
|     } | ||||
| 
 | ||||
| if ($SpecificVersion -ne $EffectiveVersion) | ||||
| { | ||||
|    Say "Performing installation checks for effective version: $EffectiveVersion" | ||||
|    $SpecificVersion = $EffectiveVersion | ||||
| } | ||||
| 
 | ||||
| #  Check if the SDK version is already installed. | ||||
| $isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $SpecificVersion | ||||
| if ($isAssetInstalled) { | ||||
|     Say "$assetName version $SpecificVersion is already installed." | ||||
|     Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath | ||||
|     return | ||||
|     return ($assetName, $dotnetPackageRelativePath) | ||||
| } | ||||
| 
 | ||||
| function Prepare-Install-Directory { | ||||
|     New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null | ||||
| 
 | ||||
|     $installDrive = $((Get-Item $InstallRoot -Force).PSDrive.Name); | ||||
| @ -1087,164 +1070,223 @@ catch{ | ||||
|         Say-Warning "Failed to check the disk space. Installation will continue, but it may fail if you do not have enough disk space." | ||||
|     } | ||||
|      | ||||
| if ( ($diskInfo -ne $null) -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}:" | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| Say "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 "- 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.`r`n" | ||||
| 
 | ||||
| if ($SharedRuntime -and (-not $Runtime)) { | ||||
|     $Runtime = "dotnet" | ||||
| } | ||||
| 
 | ||||
| $OverrideNonVersionedFiles = !$SkipNonVersionedFiles | ||||
| 
 | ||||
| $CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture | ||||
| $NormalizedQuality = Get-NormalizedQuality $Quality | ||||
| Say-Verbose "Normalized quality: '$NormalizedQuality'" | ||||
| $NormalizedChannel = Get-NormalizedChannel $Channel | ||||
| Say-Verbose "Normalized channel: '$NormalizedChannel'" | ||||
| $NormalizedProduct = Get-NormalizedProduct $Runtime | ||||
| Say-Verbose "Normalized product: '$NormalizedProduct'" | ||||
| $FeedCredential = ValidateFeedCredential $FeedCredential | ||||
| 
 | ||||
| $InstallRoot = Resolve-Installation-Path $InstallDir | ||||
| Say-Verbose "InstallRoot: $InstallRoot" | ||||
| $ScriptName = $MyInvocation.MyCommand.Name | ||||
| ($assetName, $dotnetPackageRelativePath) = Resolve-AssetName-And-RelativePath -Runtime $Runtime | ||||
| 
 | ||||
| $feeds = Get-Feeds-To-Use | ||||
| $DownloadLinks = @() | ||||
| 
 | ||||
| # 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")) { | ||||
|     ($DownloadLink, $SpecificVersion, $EffectiveVersion) = Get-AkaMsLink-And-Version $NormalizedChannel $NormalizedQuality $Internal $NormalizedProduct $CLIArchitecture | ||||
|      | ||||
|     if ($null -ne $DownloadLink) { | ||||
|         $DownloadLinks += New-Object PSObject -Property @{downloadLink="$DownloadLink";specificVersion="$SpecificVersion";effectiveVersion="$EffectiveVersion";type='aka.ms'} | ||||
|         Say-Verbose "Generated aka.ms link $DownloadLink with version $EffectiveVersion" | ||||
|          | ||||
|         if (-Not $DryRun) { | ||||
|             Say-Verbose "Checking if the version $EffectiveVersion is already installed" | ||||
|             if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion) | ||||
|             { | ||||
|                 Say "$assetName with version '$EffectiveVersion' is already installed." | ||||
|                 Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot | ||||
|                 return | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| # 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 ([string]::IsNullOrEmpty($NormalizedQuality) -and 0 -eq $DownloadLinks.count) | ||||
| { | ||||
|     foreach ($feed in $feeds) { | ||||
|         try { | ||||
|             $SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $feed -Channel $Channel -Version $Version -JSonFile $JSonFile | ||||
|             $DownloadLink, $EffectiveVersion = Get-Download-Link -AzureFeed $feed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture | ||||
|             $LegacyDownloadLink = Get-LegacyDownload-Link -AzureFeed $feed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture | ||||
|              | ||||
|             $DownloadLinks += New-Object PSObject -Property @{downloadLink="$DownloadLink";specificVersion="$SpecificVersion";effectiveVersion="$EffectiveVersion";type='primary'} | ||||
|             Say-Verbose "Generated primary link $DownloadLink with version $EffectiveVersion" | ||||
|      | ||||
|             if (-not [string]::IsNullOrEmpty($LegacyDownloadLink)) { | ||||
|                 $DownloadLinks += New-Object PSObject -Property @{downloadLink="$LegacyDownloadLink";specificVersion="$SpecificVersion";effectiveVersion="$EffectiveVersion";type='legacy'} | ||||
|                 Say-Verbose "Generated legacy link $LegacyDownloadLink with version $EffectiveVersion" | ||||
|             } | ||||
|      | ||||
|             if (-Not $DryRun) { | ||||
|                 Say-Verbose "Checking if the version $EffectiveVersion is already installed" | ||||
|                 if (Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $EffectiveVersion) | ||||
|                 { | ||||
|                     Say "$assetName with version '$EffectiveVersion' is already installed." | ||||
|                     Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot | ||||
|                     return | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         catch | ||||
|         { | ||||
|             Say-Verbose "Failed to acquire download links from feed $feed. Exception: $_" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| if ($DownloadLinks.count -eq 0) { | ||||
|     throw "Failed to resolve the exact version number." | ||||
| } | ||||
| 
 | ||||
| if ($DryRun) { | ||||
|     PrintDryRunOutput $MyInvocation $DownloadLinks | ||||
|     return | ||||
| } | ||||
| 
 | ||||
| Prepare-Install-Directory | ||||
| 
 | ||||
| $ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) | ||||
| Say-Verbose "Zip path: $ZipPath" | ||||
| 
 | ||||
| $DownloadFailed = $false | ||||
| $DownloadSucceeded = $false | ||||
| $DownloadedLink = $null | ||||
| $ErrorMessages = @() | ||||
| 
 | ||||
| $PrimaryDownloadStatusCode = 0 | ||||
| $LegacyDownloadStatusCode = 0 | ||||
| foreach ($link in $DownloadLinks) | ||||
| { | ||||
|     Say-Verbose "Downloading `"$($link.type)`" link $($link.downloadLink)" | ||||
| 
 | ||||
| $PrimaryDownloadFailedMsg = "" | ||||
| $LegacyDownloadFailedMsg = "" | ||||
| 
 | ||||
| Say "Downloading primary link $DownloadLink" | ||||
|     try { | ||||
|     DownloadFile -Source $DownloadLink -OutPath $ZipPath | ||||
|         DownloadFile -Source $link.downloadLink -OutPath $ZipPath | ||||
|         Say-Verbose "Download succeeded." | ||||
|         $DownloadSucceeded = $true | ||||
|         $DownloadedLink = $link | ||||
|         break | ||||
|     } | ||||
|     catch { | ||||
|         $StatusCode = $null | ||||
|         $ErrorMessage = $null | ||||
| 
 | ||||
|         if ($PSItem.Exception.Data.Contains("StatusCode")) { | ||||
|         $PrimaryDownloadStatusCode = $PSItem.Exception.Data["StatusCode"] | ||||
|             $StatusCode = $PSItem.Exception.Data["StatusCode"] | ||||
|         } | ||||
|      | ||||
|         if ($PSItem.Exception.Data.Contains("ErrorMessage")) { | ||||
|         $PrimaryDownloadFailedMsg = $PSItem.Exception.Data["ErrorMessage"] | ||||
|             $ErrorMessage = $PSItem.Exception.Data["ErrorMessage"] | ||||
|         } else { | ||||
|         $PrimaryDownloadFailedMsg = $PSItem.Exception.Message | ||||
|             $ErrorMessage = $PSItem.Exception.Message | ||||
|         } | ||||
| 
 | ||||
|     if ($PrimaryDownloadStatusCode -eq 404) { | ||||
|         Say "The resource at $DownloadLink is not available." | ||||
|     } else { | ||||
|         Say $PSItem.Exception.Message | ||||
|         Say-Verbose "Download failed with status code $StatusCode. Error message: $ErrorMessage" | ||||
|         $ErrorMessages += "Downloading from `"$($link.type)`" link has failed with error:`nUri: $($link.downloadLink)`nStatusCode: $StatusCode`nError: $ErrorMessage" | ||||
|     } | ||||
| 
 | ||||
|     # This link failed. Clean up before trying the next one. | ||||
|     SafeRemoveFile -Path $ZipPath | ||||
| 
 | ||||
|     if ($LegacyDownloadLink) { | ||||
|         $DownloadLink = $LegacyDownloadLink | ||||
|         $ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()) | ||||
|         Say-Verbose "Legacy zip path: $ZipPath" | ||||
|         Say "Downloading legacy link $DownloadLink" | ||||
|         try { | ||||
|             DownloadFile -Source $DownloadLink -OutPath $ZipPath | ||||
|         } | ||||
|         catch { | ||||
|             if ($PSItem.Exception.Data.Contains("StatusCode")) { | ||||
|                 $LegacyDownloadStatusCode = $PSItem.Exception.Data["StatusCode"] | ||||
| } | ||||
| 
 | ||||
|             if ($PSItem.Exception.Data.Contains("ErrorMessage")) { | ||||
|                 $LegacyDownloadFailedMsg = $PSItem.Exception.Data["ErrorMessage"] | ||||
|             } else { | ||||
|                 $LegacyDownloadFailedMsg = $PSItem.Exception.Message | ||||
| if (-not $DownloadSucceeded) { | ||||
|     foreach ($ErrorMessage in $ErrorMessages) { | ||||
|         Say-Error $ErrorMessages | ||||
|     } | ||||
| 
 | ||||
|             if ($LegacyDownloadStatusCode -eq 404) { | ||||
|                 Say "The resource at $DownloadLink is not available." | ||||
|             } else { | ||||
|                 Say $PSItem.Exception.Message | ||||
|     throw "Could not find `"$assetName`" with version = $($DownloadLinks[0].effectiveVersion)`nRefer to: https://aka.ms/dotnet-os-lifecycle for information on .NET support" | ||||
| } | ||||
| 
 | ||||
|             SafeRemoveFile -Path $ZipPath | ||||
|             $DownloadFailed = $true | ||||
|         } | ||||
|     } | ||||
|     else { | ||||
|         $DownloadFailed = $true | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| if ($DownloadFailed) { | ||||
|     if (($PrimaryDownloadStatusCode -eq 404) -and ((-not $LegacyDownloadLink) -or ($LegacyDownloadStatusCode -eq 404))) { | ||||
|         throw "Could not find `"$assetName`" with version = $SpecificVersion`nRefer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support" | ||||
|     } else { | ||||
|         # 404-NotFound is an expected response if it goes from only one of the links, do not show that error. | ||||
|         # If primary path is available (not 404-NotFound) then show the primary error else show the legacy error. | ||||
|         if ($PrimaryDownloadStatusCode -ne 404) { | ||||
|             throw "Could not download `"$assetName`" with version = $SpecificVersion`r`n$PrimaryDownloadFailedMsg" | ||||
|         } | ||||
|         if (($LegacyDownloadLink) -and ($LegacyDownloadStatusCode -ne 404)) { | ||||
|             throw "Could not download `"$assetName`" with version = $SpecificVersion`r`n$LegacyDownloadFailedMsg" | ||||
|         } | ||||
|         throw "Could not download `"$assetName`" with version = $SpecificVersion" | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| Say "Extracting zip from $DownloadLink" | ||||
| Say "Extracting the archive." | ||||
| Extract-Dotnet-Package -ZipPath $ZipPath -OutPath $InstallRoot | ||||
| 
 | ||||
| #  Check if the SDK version is installed; if not, fail the installation. | ||||
| $isAssetInstalled = $false | ||||
| 
 | ||||
| # if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed. | ||||
| if ($SpecificVersion -Match "rtm" -or $SpecificVersion -Match "servicing") { | ||||
|     $ReleaseVersion = $SpecificVersion.Split("-")[0] | ||||
| if ($DownloadedLink.effectiveVersion -Match "rtm" -or $DownloadedLink.effectiveVersion -Match "servicing") { | ||||
|     $ReleaseVersion = $DownloadedLink.effectiveVersion.Split("-")[0] | ||||
|     Say-Verbose "Checking installation: version = $ReleaseVersion" | ||||
|     $isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $ReleaseVersion | ||||
| } | ||||
| 
 | ||||
| #  Check if the SDK version is installed. | ||||
| if (!$isAssetInstalled) { | ||||
|     Say-Verbose "Checking installation: version = $SpecificVersion" | ||||
|     $isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $SpecificVersion | ||||
|     Say-Verbose "Checking installation: version = $($DownloadedLink.effectiveVersion)" | ||||
|     $isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $DownloadedLink.effectiveVersion | ||||
| } | ||||
| 
 | ||||
| # Version verification failed. More likely something is wrong either with the downloaded content or with the verification algorithm. | ||||
| if (!$isAssetInstalled) { | ||||
|     Say-Error "Failed to verify the version of installed `"$assetName`".`nInstallation source: $DownloadLink.`nInstallation location: $InstallRoot.`nReport the bug at https://github.com/dotnet/install-scripts/issues." | ||||
|     throw "`"$assetName`" with version = $SpecificVersion failed to install with an unknown error." | ||||
|     Say-Error "Failed to verify the version of installed `"$assetName`".`nInstallation source: $($DownloadedLink.downloadLink).`nInstallation location: $InstallRoot.`nReport the bug at https://github.com/dotnet/install-scripts/issues." | ||||
|     throw "`"$assetName`" with version = $($DownloadedLink.effectiveVersion) failed to install with an unknown error." | ||||
| } | ||||
| 
 | ||||
| SafeRemoveFile -Path $ZipPath | ||||
| 
 | ||||
| Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath | ||||
| Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot | ||||
| 
 | ||||
| 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/windows#dependencies" | ||||
| Say "Installation finished" | ||||
| 
 | ||||
| # SIG # Begin signature block | ||||
| # MIIjhgYJKoZIhvcNAQcCoIIjdzCCI3MCAQExDzANBglghkgBZQMEAgEFADB5Bgor | ||||
| # MIInoQYJKoZIhvcNAQcCoIInkjCCJ44CAQExDzANBglghkgBZQMEAgEFADB5Bgor | ||||
| # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG | ||||
| # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDO8obeUp97UA1H | ||||
| # qy3NSLDwxxLLlEbGxeCzMOcKVT/3eKCCDYEwggX/MIID56ADAgECAhMzAAAB32vw | ||||
| # LpKnSrTQAAAAAAHfMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD | ||||
| # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAuo3sRWvfrJ+Bd | ||||
| # sIQ2zLeO20Ij33Vb5ljtEhxAYYSEc6CCDYEwggX/MIID56ADAgECAhMzAAACUosz | ||||
| # qviV8znbAAAAAAJSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD | ||||
| # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy | ||||
| # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p | ||||
| # bmcgUENBIDIwMTEwHhcNMjAxMjE1MjEzMTQ1WhcNMjExMjAyMjEzMTQ1WjB0MQsw | ||||
| # bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMjU5WhcNMjIwOTAxMTgzMjU5WjB0MQsw | ||||
| # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u | ||||
| # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy | ||||
| # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB | ||||
| # AQC2uxlZEACjqfHkuFyoCwfL25ofI9DZWKt4wEj3JBQ48GPt1UsDv834CcoUUPMn | ||||
| # s/6CtPoaQ4Thy/kbOOg/zJAnrJeiMQqRe2Lsdb/NSI2gXXX9lad1/yPUDOXo4GNw | ||||
| # PjXq1JZi+HZV91bUr6ZjzePj1g+bepsqd/HC1XScj0fT3aAxLRykJSzExEBmU9eS | ||||
| # yuOwUuq+CriudQtWGMdJU650v/KmzfM46Y6lo/MCnnpvz3zEL7PMdUdwqj/nYhGG | ||||
| # 3UVILxX7tAdMbz7LN+6WOIpT1A41rwaoOVnv+8Ua94HwhjZmu1S73yeV7RZZNxoh | ||||
| # EegJi9YYssXa7UZUUkCCA+KnAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE | ||||
| # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUOPbML8IdkNGtCfMmVPtvI6VZ8+Mw | ||||
| # AQDQ5M+Ps/X7BNuv5B/0I6uoDwj0NJOo1KrVQqO7ggRXccklyTrWL4xMShjIou2I | ||||
| # sbYnF67wXzVAq5Om4oe+LfzSDOzjcb6ms00gBo0OQaqwQ1BijyJ7NvDf80I1fW9O | ||||
| # L76Kt0Wpc2zrGhzcHdb7upPrvxvSNNUvxK3sgw7YTt31410vpEp8yfBEl/hd8ZzA | ||||
| # v47DCgJ5j1zm295s1RVZHNp6MoiQFVOECm4AwK2l28i+YER1JO4IplTH44uvzX9o | ||||
| # RnJHaMvWzZEpozPy4jNO2DDqbcNs4zh7AWMhE1PWFVA+CHI/En5nASvCvLmuR/t8 | ||||
| # q4bc8XR8QIZJQSp+2U6m2ldNAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE | ||||
| # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUNZJaEUGL2Guwt7ZOAu4efEYXedEw | ||||
| # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 | ||||
| # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDYzMDA5MB8GA1UdIwQYMBaAFEhu | ||||
| # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDY3NTk3MB8GA1UdIwQYMBaAFEhu | ||||
| # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu | ||||
| # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w | ||||
| # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 | ||||
| # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx | ||||
| # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAnnqH | ||||
| # tDyYUFaVAkvAK0eqq6nhoL95SZQu3RnpZ7tdQ89QR3++7A+4hrr7V4xxmkB5BObS | ||||
| # 0YK+MALE02atjwWgPdpYQ68WdLGroJZHkbZdgERG+7tETFl3aKF4KpoSaGOskZXp | ||||
| # TPnCaMo2PXoAMVMGpsQEQswimZq3IQ3nRQfBlJ0PoMMcN/+Pks8ZTL1BoPYsJpok | ||||
| # t6cql59q6CypZYIwgyJ892HpttybHKg1ZtQLUlSXccRMlugPgEcNZJagPEgPYni4 | ||||
| # b11snjRAgf0dyQ0zI9aLXqTxWUU5pCIFiPT0b2wsxzRqCtyGqpkGM8P9GazO8eao | ||||
| # mVItCYBcJSByBx/pS0cSYwBBHAZxJODUqxSXoSGDvmTfqUJXntnWkL4okok1FiCD | ||||
| # Z4jpyXOQunb6egIXvkgQ7jb2uO26Ow0m8RwleDvhOMrnHsupiOPbozKroSa6paFt | ||||
| # VSh89abUSooR8QdZciemmoFhcWkEwFg4spzvYNP4nIs193261WyTaRMZoceGun7G | ||||
| # CT2Rl653uUj+F+g94c63AhzSq4khdL4HlFIP2ePv29smfUnHtGq6yYFDLnT0q/Y+ | ||||
| # Di3jwloF8EWkkHRtSuXlFUbTmwr/lDDgbpZiKhLS7CBTDj32I0L5i532+uHczw82 | ||||
| # oZDmYmYmIUSMbZOgS65h797rj5JJ6OkeEUJoAVwwggd6MIIFYqADAgECAgphDpDS | ||||
| # 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 | ||||
| @ -1284,119 +1326,141 @@ Say "Installation finished" | ||||
| # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 | ||||
| # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 | ||||
| # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I | ||||
| # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVWzCCFVcCAQEwgZUwfjELMAkG | ||||
| # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIZdjCCGXICAQEwgZUwfjELMAkG | ||||
| # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx | ||||
| # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z | ||||
| # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAd9r8C6Sp0q00AAAAAAB3zAN | ||||
| # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAlKLM6r4lfM52wAAAAACUjAN | ||||
| # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor | ||||
| # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg7EExOCvj | ||||
| # ZDkub0Fc7HAVivJIlz+Omt11fROkTFKR+KQwQgYKKwYBBAGCNwIBDDE0MDKgFIAS | ||||
| # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgBzhh8wf+ | ||||
| # /kA/CamFNwS1K9Nt0wsjATKS8Y66iHQTKrIwQgYKKwYBBAGCNwIBDDE0MDKgFIAS | ||||
| # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN | ||||
| # BgkqhkiG9w0BAQEFAASCAQBPvflyU+HQEIM4XvImAK2eQp74ABDaxeWVbl21ZF0L | ||||
| # cKf5GkIzdvlCoKxforXBkRIBtLxU9Sb4ff+AO3jiw2M36ZLwZQRYcn003FTR3BAY | ||||
| # 3XVGdxb64vCEMUb6Dzh9Hb1lmJjyn2NHsB514ZuUez4v/UIsV9e3TV731kY6gcQV | ||||
| # 3ridn3IKj3RMJGtPD5qxVMZohvVIy1Xiz4n/9BpBkk4HHsSuGPmBj08jWnIcI5TF | ||||
| # eXYC4LonTOFZLcsKiW4eMRaDt0fXxJjhQF8DSJX3PAxCC73YkPrJJyXAkGNHcXCg | ||||
| # 2Lyi9Yd6oV0nbJlCSLWK7jcn5lxUIgsrb+U6F8yXoNsXoYIS5TCCEuEGCisGAQQB | ||||
| # gjcDAwExghLRMIISzQYJKoZIhvcNAQcCoIISvjCCEroCAQMxDzANBglghkgBZQME | ||||
| # BgkqhkiG9w0BAQEFAASCAQAruzFwahFXWsJ9eny7iY/KyWolnqJ9+cvDD1QaJ0qJ | ||||
| # tHlTLP8pr0GPPtitwuk+3JME7wkx80+AZXl/ocO39tdhy1Ucd6yiyV3M1Ub/Eo4D | ||||
| # 37L1saazNomWeeMD6oX3FboVe1Ql17MX1SscTW5QRx8ytYgUOUIbrxFybODcdVn9 | ||||
| # YG7mlkgsJr2lhUhTnHtq7jV/jEu6Sk9o+g15Pbu90VncsCoNerg9aEziui6/W3/g | ||||
| # Wvt4WhfCPanppzWVmsvTUp5MAt5cpdNBr9b8CV/alI3TGnNwC8RuWMCK6CS4963l | ||||
| # f4AiLZW/fgD8UQYtl+tAyYfSerpX0sDB039jymj1FkqHoYIXADCCFvwGCisGAQQB | ||||
| # gjcDAwExghbsMIIW6AYJKoZIhvcNAQcCoIIW2TCCFtUCAQMxDzANBglghkgBZQME | ||||
| # AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB | ||||
| # MDEwDQYJYIZIAWUDBAIBBQAEIEwFz8qgqbYKKOXyaZMOTE0/ve/rpdJjnq1eyDVG | ||||
| # mWB6AgZhHpsDT9wYEzIwMjEwODIzMTUxNzA2LjAyMVowBIACAfSggdCkgc0wgcox | ||||
| # MDEwDQYJYIZIAWUDBAIBBQAEIEcy5EvHdubbPngOS1BSZ6xt9xSMrt3OLtUyfQaT | ||||
| # IyRBAgZh+unPYkgYEzIwMjIwMjA4MTAyMjE5LjM1OVowBIACAfSggdCkgc0wgcox | ||||
| # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt | ||||
| # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p | ||||
| # Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg | ||||
| # RVNOOjhBODItRTM0Ri05RERBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt | ||||
| # cCBTZXJ2aWNloIIOPDCCBPEwggPZoAMCAQICEzMAAAFLT7KmSNXkwlEAAAAAAUsw | ||||
| # RVNOOkREOEMtRTMzNy0yRkFFMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt | ||||
| # cCBTZXJ2aWNloIIRVzCCBwwwggT0oAMCAQICEzMAAAGcD6ZNYdKeSygAAQAAAZww | ||||
| # DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0 | ||||
| # b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh | ||||
| # dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN | ||||
| # MjAxMTEyMTgyNTU5WhcNMjIwMjExMTgyNTU5WjCByjELMAkGA1UEBhMCVVMxEzAR | ||||
| # MjExMjAyMTkwNTE5WhcNMjMwMjI4MTkwNTE5WjCByjELMAkGA1UEBhMCVVMxEzAR | ||||
| # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p | ||||
| # Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg | ||||
| # T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046OEE4Mi1FMzRGLTlE | ||||
| # REExJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggEiMA0G | ||||
| # CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChNnpQx3YuJr/ivobPoLtpQ9egUFl8 | ||||
| # THdWZ6SAKIJdtP3L24D3/d63ommmjZjCyrQm+j/1tHDAwjQGuOwYvn79ecPCQfAB | ||||
| # 91JnEp/wP4BMF2SXyMf8k9R84RthIdfGHPXTWqzpCCfNWolVEcUVm8Ad/r1LrikR | ||||
| # O+4KKo6slDQJKsgKApfBU/9J7Rudvhw1rEQw0Nk1BRGWjrIp7/uWoUIfR4rcl6U1 | ||||
| # utOiYIonC87PPpAJQXGRsDdKnVFF4NpWvMiyeuksn5t/Otwz82sGlne/HNQpmMzi | ||||
| # gR8cZ8eXEDJJNIZxov9WAHHj28gUE29D8ivAT706ihxvTv50ZY8W51uxAgMBAAGj | ||||
| # ggEbMIIBFzAdBgNVHQ4EFgQUUqpqftASlue6K3LePlTTn01K68YwHwYDVR0jBBgw | ||||
| # FoAU1WM6XIoxkPNDe3xGG8UzaFqFbVUwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDov | ||||
| # L2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljVGltU3RhUENB | ||||
| # XzIwMTAtMDctMDEuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0 | ||||
| # cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNUaW1TdGFQQ0FfMjAx | ||||
| # MC0wNy0wMS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDCDAN | ||||
| # BgkqhkiG9w0BAQsFAAOCAQEAFtq51Zc/O1AfJK4tEB2Nr8bGEVD5qQ8l8gXIQMrM | ||||
| # ZYtddHH+cGiqgF/4GmvmPfl5FAYh+gf/8Yd3q4/iD2+K4LtJbs/3v6mpyBl1mQ4v | ||||
| # usK65dAypWmiT1W3FiXjsmCIkjSDDsKLFBYH5yGFnNFOEMgL+O7u4osH42f80nc2 | ||||
| # WdnZV6+OvW035XPV6ZttUBfFWHdIbUkdOG1O2n4yJm10OfacItZ08fzgMMqE+f/S | ||||
| # TgVWNCHbR2EYqTWayrGP69jMwtVD9BGGTWti1XjpvE6yKdO8H9nuRi3L+C6jYntf | ||||
| # aEmBTbnTFEV+kRx1CNcpSb9os86CAUehZU1aRzQ6CQ/pjzCCBnEwggRZoAMCAQIC | ||||
| # CmEJgSoAAAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYD | ||||
| # 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 | ||||
| # b3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRp | ||||
| # ZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTEwMDcwMTIxMzY1NVoXDTI1MDcwMTIx | ||||
| # NDY1NVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV | ||||
| # BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQG | ||||
| # A1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggEiMA0GCSqGSIb3 | ||||
| # DQEBAQUAA4IBDwAwggEKAoIBAQCpHQ28dxGKOiDs/BOX9fp/aZRrdFQQ1aUKAIKF | ||||
| # ++18aEssX8XD5WHCdrc+Zitb8BVTJwQxH0EbGpUdzgkTjnxhMFmxMEQP8WCIhFRD | ||||
| # DNdNuDgIs0Ldk6zWczBXJoKjRQ3Q6vVHgc2/JGAyWGBG8lhHhjKEHnRhZ5FfgVSx | ||||
| # z5NMksHEpl3RYRNuKMYa+YaAu99h/EbBJx0kZxJyGiGKr0tkiVBisV39dx898Fd1 | ||||
| # rL2KQk1AUdEPnAY+Z3/1ZsADlkR+79BL/W7lmsqxqPJ6Kgox8NpOBpG2iAg16Hgc | ||||
| # sOmZzTznL0S6p/TcZL2kAcEgCZN4zfy8wMlEXV4WnAEFTyJNAgMBAAGjggHmMIIB | ||||
| # 4jAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU1WM6XIoxkPNDe3xGG8UzaFqF | ||||
| # bVUwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud | ||||
| # EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYD | ||||
| # VR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwv | ||||
| # cHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEB | ||||
| # BE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9j | ||||
| # ZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwgaAGA1UdIAEB/wSBlTCB | ||||
| # kjCBjwYJKwYBBAGCNy4DMIGBMD0GCCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jv | ||||
| # c29mdC5jb20vUEtJL2RvY3MvQ1BTL2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQe | ||||
| # MiAdAEwAZQBnAGEAbABfAFAAbwBsAGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQA | ||||
| # LiAdMA0GCSqGSIb3DQEBCwUAA4ICAQAH5ohRDeLG4Jg/gXEDPZ2joSFvs+umzPUx | ||||
| # vs8F4qn++ldtGTCzwsVmyWrf9efweL3HqJ4l4/m87WtUVwgrUYJEEvu5U4zM9GAS | ||||
| # inbMQEBBm9xcF/9c+V4XNZgkVkt070IQyK+/f8Z/8jd9Wj8c8pl5SpFSAK84Dxf1 | ||||
| # L3mBZdmptWvkx872ynoAb0swRCQiPM/tA6WWj1kpvLb9BOFwnzJKJ/1Vry/+tuWO | ||||
| # M7tiX5rbV0Dp8c6ZZpCM/2pif93FSguRJuI57BlKcWOdeyFtw5yjojz6f32WapB4 | ||||
| # pm3S4Zz5Hfw42JT0xqUKloakvZ4argRCg7i1gJsiOCC1JeVk7Pf0v35jWSUPei45 | ||||
| # V3aicaoGig+JFrphpxHLmtgOR5qAxdDNp9DvfYPw4TtxCd9ddJgiCGHasFAeb73x | ||||
| # 4QDf5zEHpJM692VHeOj4qEir995yfmFrb3epgcunCaw5u+zGy9iCtHLNHfS4hQEe | ||||
| # gPsbiSpUObJb2sgNVZl6h3M7COaYLeqN4DMuEin1wC9UJyH3yKxO2ii4sanblrKn | ||||
| # QqLJzxlBTeCG+SqaoxFmMNO7dDJL32N79ZmKLxvHIa9Zta7cRDyXUHHXodLFVeNp | ||||
| # 3lfB0d4wwP3M5k37Db9dT+mdHhk4L7zPWAUu7w2gUDXa7wknHNWzfjUeCLraNtvT | ||||
| # X4/edIhJEqGCAs4wggI3AgEBMIH4oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEG | ||||
| # A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj | ||||
| # cm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBP | ||||
| # cGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4QTgyLUUzNEYtOURE | ||||
| # QTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcG | ||||
| # BSsOAwIaAxUAkToz97fseHxNOUSQ5O/bBVSF+e6ggYMwgYCkfjB8MQswCQYDVQQG | ||||
| # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG | ||||
| # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg | ||||
| # VGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIFAOTNtrcwIhgPMjAy | ||||
| # MTA4MjMxMzU1MDNaGA8yMDIxMDgyNDEzNTUwM1owdzA9BgorBgEEAYRZCgQBMS8w | ||||
| # LTAKAgUA5M22twIBADAKAgEAAgIcfAIB/zAHAgEAAgIQOTAKAgUA5M8INwIBADA2 | ||||
| # BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIB | ||||
| # AAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBADrUnASEIEovjIFdqxhyYsyiBSfNeD7e | ||||
| # W4qeRl1B4DTAY8Z/U1SpnK8yy7r6oZn0D8og+QJmnWEnCPqNXAreyg8tlFyTF1TV | ||||
| # K6uUlslIY4WCmrAECIFua/DuksTerny66SBw4aSEeQHtGiynnR87WcdqItBJxxRA | ||||
| # pElXzs8QzC0EMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT | ||||
| # Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m | ||||
| # dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB | ||||
| # IDIwMTACEzMAAAFLT7KmSNXkwlEAAAAAAUswDQYJYIZIAWUDBAIBBQCgggFKMBoG | ||||
| # CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQg87M/Jiqh | ||||
| # MlaXNWAIAn7CM9CZw6QCPgBx3voUSIH6+qUwgfoGCyqGSIb3DQEJEAIvMYHqMIHn | ||||
| # MIHkMIG9BCBr9u6EInnsZYEts/Fj/rIFv0YZW1ynhXKOP2hVPUU5IzCBmDCBgKR+ | ||||
| # MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS | ||||
| # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT | ||||
| # HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABS0+ypkjV5MJRAAAA | ||||
| # AAFLMCIEIGs9Mn51TUGRleeUO5lQCRHZSu0G/8Ir92l3NgMGq1/GMA0GCSqGSIb3 | ||||
| # DQEBCwUABIIBAA1oBIiM3guh89/Pvwwcn4hdZGGBsMk56MRMvOir8XQM0Je/rSwP | ||||
| # P11S2VwYUMmBjfFX1QK7r280k3k9xcDWW79ZC4Kn2UsV7jxuUwFHgdVlgDNjg6QL | ||||
| # unGuwFX5lStgNevwUH9DotoASXxgtwNNmtZNDB4NYVCxQLS7RtVSbxP+xFYXbokG | ||||
| # G4DFVHBr3CGPga3OduE/YUBpxIRxtiDF/9WHo0tJEdS95tfdnsyaGo8eHNzyfTdS | ||||
| # kjrNsAlqpJRT0Va/ooBXCV7Uny7PlCkRIQRTSJDy/kSXpsL22CTEHw6mU0jEU99k | ||||
| # OL4uwu+aVnolWFlpbiJjQxBqfT3plBLIg88= | ||||
| # 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 | ||||
|  | ||||
							
								
								
									
										543
									
								
								externals/install-dotnet.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										543
									
								
								externals/install-dotnet.sh
									
									
									
									
										vendored
									
									
								
							| @ -135,6 +135,31 @@ get_legacy_os_name_from_platform() { | ||||
|     return 1 | ||||
| } | ||||
| 
 | ||||
| get_legacy_os_name() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local uname=$(uname) | ||||
|     if [ "$uname" = "Darwin" ]; then | ||||
|         echo "osx" | ||||
|         return 0 | ||||
|     elif [ -n "$runtime_id" ]; then | ||||
|         echo $(get_legacy_os_name_from_platform "${runtime_id%-*}" || echo "${runtime_id%-*}") | ||||
|         return 0 | ||||
|     else | ||||
|         if [ -e /etc/os-release ]; then | ||||
|             . /etc/os-release | ||||
|             os=$(get_legacy_os_name_from_platform "$ID${VERSION_ID:+.${VERSION_ID}}" || echo "") | ||||
|             if [ -n "$os" ]; then | ||||
|                 echo "$os" | ||||
|                 return 0 | ||||
|             fi | ||||
|         fi | ||||
|     fi | ||||
| 
 | ||||
|     say_verbose "Distribution specific OS name and version could not be detected: UName = $uname" | ||||
|     return 1 | ||||
| } | ||||
| 
 | ||||
| get_linux_platform_name() { | ||||
|     eval $invocation | ||||
| 
 | ||||
| @ -174,8 +199,8 @@ get_current_os_name() { | ||||
|         echo "freebsd" | ||||
|         return 0 | ||||
|     elif [ "$uname" = "Linux" ]; then | ||||
|         local linux_platform_name | ||||
|         linux_platform_name="$(get_linux_platform_name)" || { echo "linux" && return 0 ; } | ||||
|         local linux_platform_name="" | ||||
|         linux_platform_name="$(get_linux_platform_name)" || true | ||||
| 
 | ||||
|         if [ "$linux_platform_name" = "rhel.6" ]; then | ||||
|             echo $linux_platform_name | ||||
| @ -196,31 +221,6 @@ get_current_os_name() { | ||||
|     return 1 | ||||
| } | ||||
| 
 | ||||
| get_legacy_os_name() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local uname=$(uname) | ||||
|     if [ "$uname" = "Darwin" ]; then | ||||
|         echo "osx" | ||||
|         return 0 | ||||
|     elif [ -n "$runtime_id" ]; then | ||||
|         echo $(get_legacy_os_name_from_platform "${runtime_id%-*}" || echo "${runtime_id%-*}") | ||||
|         return 0 | ||||
|     else | ||||
|         if [ -e /etc/os-release ]; then | ||||
|             . /etc/os-release | ||||
|             os=$(get_legacy_os_name_from_platform "$ID${VERSION_ID:+.${VERSION_ID}}" || echo "") | ||||
|             if [ -n "$os" ]; then | ||||
|                 echo "$os" | ||||
|                 return 0 | ||||
|             fi | ||||
|         fi | ||||
|     fi | ||||
| 
 | ||||
|     say_verbose "Distribution specific OS name and version could not be detected: UName = $uname" | ||||
|     return 1 | ||||
| } | ||||
| 
 | ||||
| machine_has() { | ||||
|     eval $invocation | ||||
| 
 | ||||
| @ -228,7 +228,6 @@ machine_has() { | ||||
|     return $? | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| check_min_reqs() { | ||||
|     local hasMinimum=false | ||||
|     if machine_has "curl"; then | ||||
| @ -321,11 +320,13 @@ get_normalized_architecture_from_architecture() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local architecture="$(to_lowercase "$1")" | ||||
|     case "$architecture" in | ||||
|         \<auto\>) | ||||
|             echo "$(get_normalized_architecture_from_architecture "$(get_machine_architecture)")" | ||||
| 
 | ||||
|     if [[ $architecture == \<auto\> ]]; then | ||||
|         echo "$(get_machine_architecture)" | ||||
|         return 0 | ||||
|             ;; | ||||
|     fi | ||||
| 
 | ||||
|     case "$architecture" in | ||||
|         amd64|x64) | ||||
|             echo "x64" | ||||
|             return 0 | ||||
| @ -425,6 +426,7 @@ get_normalized_channel() { | ||||
| get_normalized_product() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local product="" | ||||
|     local runtime="$(to_lowercase "$1")" | ||||
|     if [[ "$runtime" == "dotnet" ]]; then | ||||
|         product="dotnet-runtime" | ||||
| @ -446,7 +448,7 @@ get_normalized_product() { | ||||
| 
 | ||||
| # args: | ||||
| # version_text - stdin | ||||
| get_version_from_version_info() { | ||||
| get_version_from_latestversion_file_content() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     cat | tail -n 1 | sed 's/\r$//' | ||||
| @ -478,7 +480,7 @@ is_dotnet_package_installed() { | ||||
| # azure_feed - $1 | ||||
| # channel - $2 | ||||
| # normalized_architecture - $3 | ||||
| get_latest_version_info() { | ||||
| get_version_from_latestversion_file() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local azure_feed="$1" | ||||
| @ -487,24 +489,24 @@ get_latest_version_info() { | ||||
| 
 | ||||
|     local version_file_url=null | ||||
|     if [[ "$runtime" == "dotnet" ]]; then | ||||
|         version_file_url="$uncached_feed/Runtime/$channel/latest.version" | ||||
|         version_file_url="$azure_feed/Runtime/$channel/latest.version" | ||||
|     elif [[ "$runtime" == "aspnetcore" ]]; then | ||||
|         version_file_url="$uncached_feed/aspnetcore/Runtime/$channel/latest.version" | ||||
|         version_file_url="$azure_feed/aspnetcore/Runtime/$channel/latest.version" | ||||
|     elif [ -z "$runtime" ]; then | ||||
|          version_file_url="$uncached_feed/Sdk/$channel/latest.version" | ||||
|          version_file_url="$azure_feed/Sdk/$channel/latest.version" | ||||
|     else | ||||
|         say_err "Invalid value for \$runtime" | ||||
|         return 1 | ||||
|     fi | ||||
|     say_verbose "get_latest_version_info: latest url: $version_file_url" | ||||
|     say_verbose "get_version_from_latestversion_file: latest url: $version_file_url" | ||||
| 
 | ||||
|     download "$version_file_url" | ||||
|     return $? | ||||
|     download "$version_file_url" || return $? | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| # args: | ||||
| # json_file - $1 | ||||
| parse_jsonfile_for_version() { | ||||
| parse_globaljson_file_for_version() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local json_file="$1" | ||||
| @ -560,9 +562,9 @@ get_specific_version_from_version() { | ||||
|     if [ -z "$json_file" ]; then | ||||
|         if [[ "$version" == "latest" ]]; then | ||||
|             local version_info | ||||
|             version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1 | ||||
|             version_info="$(get_version_from_latestversion_file "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1 | ||||
|             say_verbose "get_specific_version_from_version: version_info=$version_info" | ||||
|             echo "$version_info" | get_version_from_version_info | ||||
|             echo "$version_info" | get_version_from_latestversion_file_content | ||||
|             return 0 | ||||
|         else | ||||
|             echo "$version" | ||||
| @ -570,7 +572,7 @@ get_specific_version_from_version() { | ||||
|         fi | ||||
|     else | ||||
|         local version_info | ||||
|         version_info="$(parse_jsonfile_for_version "$json_file")" || return 1 | ||||
|         version_info="$(parse_globaljson_file_for_version "$json_file")" || return 1 | ||||
|         echo "$version_info" | ||||
|         return 0 | ||||
|     fi | ||||
| @ -635,14 +637,14 @@ get_specific_product_version() { | ||||
| 
 | ||||
|         if machine_has "curl" | ||||
|         then | ||||
|             specific_product_version=$(curl -s --fail "${download_link}${feed_credential}") | ||||
|             specific_product_version=$(curl -s --fail "${download_link}${feed_credential}" 2>&1) | ||||
|             if [ $? = 0 ]; then | ||||
|                 echo "${specific_product_version//[$'\t\r\n']}" | ||||
|                 return 0 | ||||
|             fi | ||||
|         elif machine_has "wget" | ||||
|         then | ||||
|             specific_product_version=$(wget -qO- "${download_link}${feed_credential}") | ||||
|             specific_product_version=$(wget -qO- "${download_link}${feed_credential}" 2>&1) | ||||
|             if [ $? = 0 ]; then | ||||
|                 echo "${specific_product_version//[$'\t\r\n']}" | ||||
|                 return 0 | ||||
| @ -907,7 +909,7 @@ get_http_header_curl() { | ||||
|     fi | ||||
| 
 | ||||
|     curl_options="-I -sSL --retry 5 --retry-delay 2 --connect-timeout 15 " | ||||
|     curl $curl_options "$remote_path_with_credential" || return 1 | ||||
|     curl $curl_options "$remote_path_with_credential" 2>&1 || return 1 | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| @ -918,15 +920,26 @@ get_http_header_wget() { | ||||
|     eval $invocation | ||||
|     local remote_path="$1" | ||||
|     local disable_feed_credential="$2" | ||||
|     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_result='' | ||||
| 
 | ||||
|     remote_path_with_credential="$remote_path" | ||||
|     if [ "$disable_feed_credential" = false ]; then | ||||
|         remote_path_with_credential+="$feed_credential" | ||||
|     fi | ||||
| 
 | ||||
|     wget_options="-q -S --spider --tries 5 --waitretry 2 --connect-timeout 15 " | ||||
|     wget $wget_options "$remote_path_with_credential" 2>&1 || return 1 | ||||
|     return 0 | ||||
|     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 $? | ||||
|     fi | ||||
| 
 | ||||
|     return $wget_result | ||||
| } | ||||
| 
 | ||||
| # args: | ||||
| @ -988,9 +1001,9 @@ downloadcurl() { | ||||
|     local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs " | ||||
|     local failed=false | ||||
|     if [ -z "$out_path" ]; then | ||||
|         curl $curl_options "$remote_path_with_credential" || failed=true | ||||
|         curl $curl_options "$remote_path_with_credential" 2>&1 || failed=true | ||||
|     else | ||||
|         curl $curl_options -o "$out_path" "$remote_path_with_credential" || failed=true | ||||
|         curl $curl_options -o "$out_path" "$remote_path_with_credential" 2>&1 || failed=true | ||||
|     fi | ||||
|     if [ "$failed" = true ]; then | ||||
|         local disable_feed_credential=false | ||||
| @ -1016,14 +1029,31 @@ downloadwget() { | ||||
|     local out_path="${2:-}" | ||||
|     # 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 wget_options="--tries 20 --waitretry 2 --connect-timeout 15 " | ||||
|     local failed=false | ||||
|     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_result='' | ||||
| 
 | ||||
|     if [ -z "$out_path" ]; then | ||||
|         wget -q $wget_options -O - "$remote_path_with_credential" || failed=true | ||||
|         wget -q $wget_options $wget_options_extra -O - "$remote_path_with_credential" 2>&1 | ||||
|         wget_result=$? | ||||
|     else | ||||
|         wget $wget_options -O "$out_path" "$remote_path_with_credential" || failed=true | ||||
|         wget $wget_options $wget_options_extra -O "$out_path" "$remote_path_with_credential" 2>&1 | ||||
|         wget_result=$? | ||||
|     fi | ||||
|     if [ "$failed" = true ]; then | ||||
| 
 | ||||
|     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 | ||||
|         local disable_feed_credential=false | ||||
|         local response=$(get_http_header_wget $remote_path $disable_feed_credential) | ||||
|         http_code=$( echo "$response" | awk '/^  HTTP/{print $2}' | tail -1 ) | ||||
| @ -1034,6 +1064,7 @@ downloadwget() { | ||||
|         say_verbose "$download_error_msg" | ||||
|         return 1 | ||||
|     fi | ||||
| 
 | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| @ -1090,11 +1121,197 @@ get_download_link_from_aka_ms() { | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| get_feeds_to_use() | ||||
| { | ||||
|     feeds=( | ||||
|     "https://dotnetcli.azureedge.net/dotnet" | ||||
|     "https://dotnetbuilds.azureedge.net/public" | ||||
|     ) | ||||
| 
 | ||||
|     if [[ -n "$azure_feed" ]]; then | ||||
|         feeds=("$azure_feed") | ||||
|     fi | ||||
| 
 | ||||
|     if [[ "$no_cdn" == "true" ]]; then | ||||
|         feeds=( | ||||
|         "https://dotnetcli.blob.core.windows.net/dotnet" | ||||
|         "https://dotnetbuilds.blob.core.windows.net/public" | ||||
|         ) | ||||
| 
 | ||||
|         if [[ -n "$uncached_feed" ]]; then | ||||
|             feeds=("$uncached_feed") | ||||
|         fi | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| # THIS FUNCTION MAY EXIT (if the determined version is already installed). | ||||
| generate_download_links() { | ||||
| 
 | ||||
|     download_links=() | ||||
|     specific_versions=() | ||||
|     effective_versions=() | ||||
|     link_types=() | ||||
| 
 | ||||
|     # If generate_akams_links returns false, no fallback to old links. Just terminate. | ||||
|     # This function may also 'exit' (if the determined version is already installed). | ||||
|     generate_akams_links || return | ||||
| 
 | ||||
|     # Check other feeds only if we haven't been able to find an aka.ms link. | ||||
|     if [[ "${#download_links[@]}" -lt 1 ]]; then | ||||
|         for feed in ${feeds[@]} | ||||
|         do | ||||
|             # generate_regular_links may also 'exit' (if the determined version is already installed). | ||||
|             generate_regular_links $feed || return | ||||
|         done | ||||
|     fi | ||||
| 
 | ||||
|     if [[ "${#download_links[@]}" -eq 0 ]]; then | ||||
|         say_err "Failed to resolve the exact version number." | ||||
|         return 1 | ||||
|     fi | ||||
| 
 | ||||
|     say_verbose "Generated ${#download_links[@]} links." | ||||
|     for link_index in ${!download_links[@]} | ||||
|     do | ||||
|         say_verbose "Link $link_index: ${link_types[$link_index]}, ${effective_versions[$link_index]}, ${download_links[$link_index]}" | ||||
|     done | ||||
| } | ||||
| 
 | ||||
| # THIS FUNCTION MAY EXIT (if the determined version is already installed). | ||||
| generate_akams_links() { | ||||
|     local valid_aka_ms_link=true; | ||||
| 
 | ||||
|     normalized_version="$(to_lowercase "$version")" | ||||
|     if [[ -n "$json_file" || "$normalized_version" != "latest" ]]; then | ||||
|         # aka.ms links are not needed when exact version is specified via command or json file | ||||
|         return | ||||
|     fi | ||||
| 
 | ||||
|     get_download_link_from_aka_ms || valid_aka_ms_link=false | ||||
| 
 | ||||
|     if [[ "$valid_aka_ms_link" == true ]]; then | ||||
|         say_verbose "Retrieved primary payload URL from aka.ms link: '$aka_ms_download_link'." | ||||
|         say_verbose "Downloading using legacy url will not be attempted." | ||||
| 
 | ||||
|         download_link=$aka_ms_download_link | ||||
| 
 | ||||
|         #get version from the path | ||||
|         IFS='/' | ||||
|         read -ra pathElems <<< "$download_link" | ||||
|         count=${#pathElems[@]} | ||||
|         specific_version="${pathElems[count-2]}" | ||||
|         unset IFS; | ||||
|         say_verbose "Version: '$specific_version'." | ||||
| 
 | ||||
|         #Retrieve effective version | ||||
|         effective_version="$(get_specific_product_version "$azure_feed" "$specific_version" "$download_link")" | ||||
| 
 | ||||
|         # Add link info to arrays | ||||
|         download_links+=($download_link) | ||||
|         specific_versions+=($specific_version) | ||||
|         effective_versions+=($effective_version) | ||||
|         link_types+=("aka.ms") | ||||
| 
 | ||||
|         #  Check if the SDK version is already installed. | ||||
|         if [[ "$dry_run" != true ]] && is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then | ||||
|             say "$asset_name with version '$effective_version' is already installed." | ||||
|             exit 0 | ||||
|         fi | ||||
| 
 | ||||
|         return 0 | ||||
|     fi | ||||
| 
 | ||||
|     # if quality is specified - exit with error - there is no fallback approach | ||||
|     if [ ! -z "$normalized_quality" ]; then | ||||
|         say_err "Failed to locate the latest version in the channel '$normalized_channel' with '$normalized_quality' quality for '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'." | ||||
|         say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support." | ||||
|         return 1 | ||||
|     fi | ||||
|     say_verbose "Falling back to latest.version file approach." | ||||
| } | ||||
| 
 | ||||
| # THIS FUNCTION MAY EXIT (if the determined version is already installed) | ||||
| # args: | ||||
| # feed - $1 | ||||
| generate_regular_links() { | ||||
|     local feed="$1" | ||||
|     local valid_legacy_download_link=true | ||||
| 
 | ||||
|     specific_version=$(get_specific_version_from_version "$feed" "$channel" "$normalized_architecture" "$version" "$json_file") || specific_version='0' | ||||
| 
 | ||||
|     if [[ "$specific_version" == '0' ]]; then | ||||
|         say_verbose "Failed to resolve the specific version number using feed '$feed'" | ||||
|         return | ||||
|     fi | ||||
| 
 | ||||
|     effective_version="$(get_specific_product_version "$feed" "$specific_version")" | ||||
|     say_verbose "specific_version=$specific_version" | ||||
| 
 | ||||
|     download_link="$(construct_download_link "$feed" "$channel" "$normalized_architecture" "$specific_version" "$normalized_os")" | ||||
|     say_verbose "Constructed primary named payload URL: $download_link" | ||||
| 
 | ||||
|     # Add link info to arrays | ||||
|     download_links+=($download_link) | ||||
|     specific_versions+=($specific_version) | ||||
|     effective_versions+=($effective_version) | ||||
|     link_types+=("primary") | ||||
| 
 | ||||
|     legacy_download_link="$(construct_legacy_download_link "$feed" "$channel" "$normalized_architecture" "$specific_version")" || valid_legacy_download_link=false | ||||
| 
 | ||||
|     if [ "$valid_legacy_download_link" = true ]; then | ||||
|         say_verbose "Constructed legacy named payload URL: $legacy_download_link" | ||||
|      | ||||
|         download_links+=($legacy_download_link) | ||||
|         specific_versions+=($specific_version) | ||||
|         effective_versions+=($effective_version) | ||||
|         link_types+=("legacy") | ||||
|     else | ||||
|         legacy_download_link="" | ||||
|         say_verbose "Cound not construct a legacy_download_link; omitting..." | ||||
|     fi | ||||
| 
 | ||||
|     #  Check if the SDK version is already installed. | ||||
|     if [[ "$dry_run" != true ]] && is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then | ||||
|         say "$asset_name with version '$effective_version' is already installed." | ||||
|         exit 0 | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| print_dry_run() { | ||||
| 
 | ||||
|     say "Payload URLs:" | ||||
| 
 | ||||
|     for link_index in "${!download_links[@]}" | ||||
|         do | ||||
|             say "URL #$link_index - ${link_types[$link_index]}: ${download_links[$link_index]}" | ||||
|     done | ||||
| 
 | ||||
|     resolved_version=${specific_versions[0]} | ||||
|     repeatable_command="./$script_name --version "\""$resolved_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"" --os "\""$normalized_os"\""" | ||||
|      | ||||
|     if [ ! -z "$normalized_quality" ]; then | ||||
|         repeatable_command+=" --quality "\""$normalized_quality"\""" | ||||
|     fi | ||||
| 
 | ||||
|     if [[ "$runtime" == "dotnet" ]]; then | ||||
|         repeatable_command+=" --runtime "\""dotnet"\""" | ||||
|     elif [[ "$runtime" == "aspnetcore" ]]; then | ||||
|         repeatable_command+=" --runtime "\""aspnetcore"\""" | ||||
|     fi | ||||
| 
 | ||||
|     repeatable_command+="$non_dynamic_parameters" | ||||
| 
 | ||||
|     if [ -n "$feed_credential" ]; then | ||||
|         repeatable_command+=" --feed-credential "\""<feed_credential>"\""" | ||||
|     fi | ||||
| 
 | ||||
|     say "Repeatable invocation: $repeatable_command" | ||||
| } | ||||
| 
 | ||||
| calculate_vars() { | ||||
|     eval $invocation | ||||
|     valid_legacy_download_link=true | ||||
| 
 | ||||
|     #normalize input variables | ||||
|     script_name=$(basename "$0") | ||||
|     normalized_architecture="$(get_normalized_architecture_from_architecture "$architecture")" | ||||
|     say_verbose "Normalized architecture: '$normalized_architecture'." | ||||
|     normalized_os="$(get_normalized_os "$user_defined_os")" | ||||
| @ -1105,76 +1322,8 @@ calculate_vars() { | ||||
|     say_verbose "Normalized channel: '$normalized_channel'." | ||||
|     normalized_product="$(get_normalized_product "$runtime")" | ||||
|     say_verbose "Normalized product: '$normalized_product'." | ||||
| 
 | ||||
|     #try to get download location from aka.ms link | ||||
|     #not applicable when exact version is specified via command or json file | ||||
|     normalized_version="$(to_lowercase "$version")" | ||||
|     if [[ -z "$json_file" && "$normalized_version" == "latest" ]]; then | ||||
| 
 | ||||
|             valid_aka_ms_link=true; | ||||
|             get_download_link_from_aka_ms || valid_aka_ms_link=false | ||||
|              | ||||
|             if [ "$valid_aka_ms_link" == false ]; then | ||||
|                 # if quality is specified - exit with error - there is no fallback approach | ||||
|                 if [ ! -z "$normalized_quality" ]; then | ||||
|                     say_err "Failed to locate the latest version in the channel '$normalized_channel' with '$normalized_quality' quality for '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'." | ||||
|                     say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support." | ||||
|                     return 1 | ||||
|                 fi | ||||
|                 say_verbose "Falling back to latest.version file approach." | ||||
|             else | ||||
|                 say_verbose "Retrieved primary payload URL from aka.ms link: '$aka_ms_download_link'." | ||||
|                 download_link=$aka_ms_download_link | ||||
| 
 | ||||
|                 say_verbose "Downloading using legacy url will not be attempted." | ||||
|                 valid_legacy_download_link=false | ||||
| 
 | ||||
|                 #get version from the path | ||||
|                 IFS='/' | ||||
|                 read -ra pathElems <<< "$download_link" | ||||
|                 count=${#pathElems[@]} | ||||
|                 specific_version="${pathElems[count-2]}" | ||||
|                 unset IFS; | ||||
|                 say_verbose "Version: '$specific_version'." | ||||
| 
 | ||||
|                 #Retrieve product specific version | ||||
|                 specific_product_version="$(get_specific_product_version "$azure_feed" "$specific_version" "$download_link")" | ||||
|                 say_verbose "Product specific version: '$specific_product_version'." | ||||
|    | ||||
|     install_root="$(resolve_installation_path "$install_dir")" | ||||
|     say_verbose "InstallRoot: '$install_root'." | ||||
|                 return  | ||||
|             fi | ||||
|     fi | ||||
| 
 | ||||
|     specific_version="$(get_specific_version_from_version "$azure_feed" "$channel" "$normalized_architecture" "$version" "$json_file")" | ||||
|     specific_product_version="$(get_specific_product_version "$azure_feed" "$specific_version")" | ||||
|     say_verbose "specific_version=$specific_version" | ||||
|     if [ -z "$specific_version" ]; then | ||||
|         say_err "Could not resolve version information." | ||||
|         return 1 | ||||
|     fi | ||||
| 
 | ||||
|     download_link="$(construct_download_link "$azure_feed" "$channel" "$normalized_architecture" "$specific_version" "$normalized_os")" | ||||
|     say_verbose "Constructed primary named payload URL: $download_link" | ||||
| 
 | ||||
|     legacy_download_link="$(construct_legacy_download_link "$azure_feed" "$channel" "$normalized_architecture" "$specific_version")" || valid_legacy_download_link=false | ||||
| 
 | ||||
|     if [ "$valid_legacy_download_link" = true ]; then | ||||
|         say_verbose "Constructed legacy named payload URL: $legacy_download_link" | ||||
|     else | ||||
|         say_verbose "Cound not construct a legacy_download_link; omitting..." | ||||
|     fi | ||||
| 
 | ||||
|     install_root="$(resolve_installation_path "$install_dir")" | ||||
|     say_verbose "InstallRoot: $install_root" | ||||
| } | ||||
| 
 | ||||
| install_dotnet() { | ||||
|     eval $invocation | ||||
|     local download_failed=false | ||||
|     local asset_name='' | ||||
|     local asset_relative_path='' | ||||
| 
 | ||||
|     if [[ "$runtime" == "dotnet" ]]; then | ||||
|         asset_relative_path="shared/Microsoft.NETCore.App" | ||||
| @ -1185,84 +1334,52 @@ install_dotnet() { | ||||
|     elif [ -z "$runtime" ]; then | ||||
|         asset_relative_path="sdk" | ||||
|         asset_name=".NET Core SDK" | ||||
|     else | ||||
|         say_err "Invalid value for \$runtime" | ||||
|         return 1 | ||||
|     fi | ||||
| 
 | ||||
|     #  Check if the SDK version is already installed. | ||||
|     if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$specific_version"; then | ||||
|         say "$asset_name version $specific_version is already installed." | ||||
|         return 0 | ||||
|     fi | ||||
|     get_feeds_to_use | ||||
| } | ||||
| 
 | ||||
| install_dotnet() { | ||||
|     eval $invocation | ||||
|     local download_failed=false | ||||
|     local download_completed=false | ||||
| 
 | ||||
|     mkdir -p "$install_root" | ||||
|     zip_path="$(mktemp "$temporary_file_template")" | ||||
|     say_verbose "Zip path: $zip_path" | ||||
| 
 | ||||
|     for link_index in "${!download_links[@]}" | ||||
|     do | ||||
|         download_link="${download_links[$link_index]}" | ||||
|         specific_version="${specific_versions[$link_index]}" | ||||
|         effective_version="${effective_versions[$link_index]}" | ||||
|         link_type="${link_types[$link_index]}" | ||||
| 
 | ||||
|     # Failures are normal in the non-legacy case for ultimately legacy downloads. | ||||
|     # Do not output to stderr, since output to stderr is considered an error. | ||||
|     say "Downloading primary link $download_link" | ||||
|         say "Attempting to download using $link_type link $download_link" | ||||
| 
 | ||||
|         # The download function will set variables $http_code and $download_error_msg in case of failure. | ||||
|     download "$download_link" "$zip_path" 2>&1 || download_failed=true | ||||
| 
 | ||||
|     #  if the download fails, download the legacy_download_link | ||||
|     if [ "$download_failed" = true ]; then | ||||
|         primary_path_http_code="$http_code"; primary_path_download_error_msg="$download_error_msg" | ||||
|         case $primary_path_http_code in | ||||
|         404) | ||||
|             say "The resource at $download_link is not available." | ||||
|             ;; | ||||
|         *) | ||||
|             say "$primary_path_download_error_msg" | ||||
|             ;; | ||||
|         esac | ||||
|         rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed" | ||||
|         if [ "$valid_legacy_download_link" = true ]; then | ||||
|         download_failed=false | ||||
|             download_link="$legacy_download_link" | ||||
|             zip_path="$(mktemp "$temporary_file_template")" | ||||
|             say_verbose "Legacy zip path: $zip_path" | ||||
| 
 | ||||
|             say "Downloading legacy link $download_link" | ||||
| 
 | ||||
|             # The download function will set variables $http_code and $download_error_msg in case of failure. | ||||
|         download "$download_link" "$zip_path" 2>&1 || download_failed=true | ||||
| 
 | ||||
|         if [ "$download_failed" = true ]; then | ||||
|                 legacy_path_http_code="$http_code";  legacy_path_download_error_msg="$download_error_msg" | ||||
|                 case $legacy_path_http_code in | ||||
|             case $http_code in | ||||
|             404) | ||||
|                     say "The resource at $download_link is not available." | ||||
|                 say "The resource at $link_type link '$download_link' is not available." | ||||
|                 ;; | ||||
|             *) | ||||
|                     say "$legacy_path_download_error_msg" | ||||
|                 say "Failed to download $link_type link '$download_link': $download_error_msg" | ||||
|                 ;; | ||||
|             esac | ||||
|             rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed" | ||||
|         else | ||||
|             download_completed=true | ||||
|             break | ||||
|         fi | ||||
|         fi | ||||
|     fi | ||||
|     done | ||||
| 
 | ||||
|     if [ "$download_failed" = true ]; then | ||||
|         if [[ "$primary_path_http_code" = "404" && ( "$valid_legacy_download_link" = false || "$legacy_path_http_code" = "404") ]]; then | ||||
|     if [[ "$download_completed" == false ]]; then | ||||
|         say_err "Could not find \`$asset_name\` with version = $specific_version" | ||||
|         say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support" | ||||
|         else | ||||
|             say_err "Could not download: \`$asset_name\` with version = $specific_version" | ||||
|             # 404-NotFound is an expected response if it goes from only one of the links, do not show that error. | ||||
|             # If primary path is available (not 404-NotFound) then show the primary error else show the legacy error. | ||||
|             if [ "$primary_path_http_code" != "404" ]; then | ||||
|                 say_err "$primary_path_download_error_msg" | ||||
|                 return 1 | ||||
|             fi | ||||
|             if [[ "$valid_legacy_download_link" = true  && "$legacy_path_http_code" != "404" ]]; then | ||||
|                 say_err "$legacy_path_download_error_msg" | ||||
|                 return 1 | ||||
|             fi | ||||
|         fi | ||||
|         return 1 | ||||
|     fi | ||||
| 
 | ||||
| @ -1283,14 +1400,14 @@ install_dotnet() { | ||||
|     fi | ||||
| 
 | ||||
|     #  Check if the standard SDK version is installed. | ||||
|     say_verbose "Checking installation: version = $specific_product_version" | ||||
|     if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$specific_product_version"; then | ||||
|     say_verbose "Checking installation: version = $effective_version" | ||||
|     if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then | ||||
|         return 0 | ||||
|     fi | ||||
| 
 | ||||
|     # Version verification failed. More likely something is wrong either with the downloaded content or with the verification algorithm. | ||||
|     say_err "Failed to verify the version of installed \`$asset_name\`.\nInstallation source: $download_link.\nInstallation location: $install_root.\nReport the bug at https://github.com/dotnet/install-scripts/issues." | ||||
|     say_err "\`$asset_name\` with version = $specific_product_version failed to install with an unknown error." | ||||
|     say_err "\`$asset_name\` with version = $effective_version failed to install with an error." | ||||
|     return 1 | ||||
| } | ||||
| 
 | ||||
| @ -1308,8 +1425,8 @@ architecture="<auto>" | ||||
| dry_run=false | ||||
| no_path=false | ||||
| no_cdn=false | ||||
| azure_feed="https://dotnetcli.azureedge.net/dotnet" | ||||
| uncached_feed="https://dotnetcli.blob.core.windows.net/dotnet" | ||||
| azure_feed="" | ||||
| uncached_feed="" | ||||
| feed_credential="" | ||||
| verbose=false | ||||
| runtime="" | ||||
| @ -1434,7 +1551,7 @@ do | ||||
|             echo "          - 3-part version in a format A.B.Cxx - represents a specific SDK release" | ||||
|             echo "              examples: 5.0.1xx, 5.0.2xx." | ||||
|             echo "              Supported since 5.0 release" | ||||
|             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 "      -Version" | ||||
|             echo "          Possible values:" | ||||
| @ -1447,7 +1564,7 @@ do | ||||
|             echo "          Works only in combination with channel. Not applicable for current 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 "          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." | ||||
|             echo "  --internal,-Internal               Download internal builds. Requires providing credentials via --feed-credential parameter." | ||||
|             echo "  --feed-credential <FEEDCREDENTIAL> Token to access Azure feed. Used as a query string to append to the Azure feed." | ||||
|             echo "      -FeedCredential                This parameter typically is not specified." | ||||
| @ -1469,8 +1586,12 @@ do | ||||
|             echo "  --dry-run,-DryRun                  Do not perform installation. Display download link." | ||||
|             echo "  --no-path, -NoPath                 Do not set PATH for the current process." | ||||
|             echo "  --verbose,-Verbose                 Display diagnostics information." | ||||
|             echo "  --azure-feed,-AzureFeed            Azure feed location. Defaults to $azure_feed, This parameter typically is not changed by the user." | ||||
|             echo "  --uncached-feed,-UncachedFeed      Uncached feed location. This parameter typically is not changed by the user." | ||||
|             echo "  --azure-feed,-AzureFeed            For internal use only." | ||||
|             echo "                                     Allows using a different storage to download SDK archives from." | ||||
|             echo "                                     This parameter is only used if --no-cdn is false." | ||||
|             echo "  --uncached-feed,-UncachedFeed      For internal use only." | ||||
|             echo "                                     Allows using a different storage to download SDK archives from." | ||||
|             echo "                                     This parameter is only used if --no-cdn is true." | ||||
|             echo "  --skip-non-versioned-files         Skips non-versioned files if they already exist, such as the dotnet executable." | ||||
|             echo "      -SkipNonVersionedFiles" | ||||
|             echo "  --no-cdn,-NoCdn                    Disable downloading from the Azure CDN, and use the uncached feed directly." | ||||
| @ -1478,14 +1599,6 @@ do | ||||
|             echo "                                     Note: global.json must have a value for 'SDK:Version'" | ||||
|             echo "  -?,--?,-h,--help,-Help             Shows this help message" | ||||
|             echo "" | ||||
|             echo "Obsolete parameters:" | ||||
|             echo "  --shared-runtime                   The recommended alternative is '--runtime dotnet'." | ||||
|             echo "                                     This parameter is obsolete and may be removed in a future version of this script." | ||||
|             echo "                                     Installs just the shared runtime bits, not the entire SDK." | ||||
|             echo "  --runtime-id                       Installs the .NET Tools for the given platform (use linux-x64 for portable linux)." | ||||
|             echo "      -RuntimeId"                    The parameter is obsolete and may be removed in a future version of this script. Should be used only for versions below 2.1. | ||||
|             echo "                                     For primary links to override OS or/and architecture, use --os and --architecture option instead." | ||||
|             echo "" | ||||
|             echo "Install Location:" | ||||
|             echo "  Location is chosen in following order:" | ||||
|             echo "    - --install-dir option" | ||||
| @ -1502,10 +1615,6 @@ do | ||||
|     shift | ||||
| done | ||||
| 
 | ||||
| if [ "$no_cdn" = true ]; then | ||||
|     azure_feed="$uncached_feed" | ||||
| fi | ||||
| 
 | ||||
| say "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 "- The SDK installation doesn't need to persist across multiple CI runs." | ||||
| @ -1523,33 +1632,11 @@ fi | ||||
| 
 | ||||
| check_min_reqs | ||||
| calculate_vars | ||||
| script_name=$(basename "$0") | ||||
| # generate_regular_links call below will 'exit' if the determined version is already installed. | ||||
| generate_download_links | ||||
| 
 | ||||
| if [ "$dry_run" = true ]; then | ||||
|     say "Payload URLs:" | ||||
|     say "Primary named payload URL: ${download_link}" | ||||
|     if [ "$valid_legacy_download_link" = true ]; then | ||||
|         say "Legacy named payload URL: ${legacy_download_link}" | ||||
|     fi | ||||
|     repeatable_command="./$script_name --version "\""$specific_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"" --os "\""$normalized_os"\""" | ||||
|      | ||||
|     if [ ! -z "$normalized_quality" ]; then | ||||
|         repeatable_command+=" --quality "\""$normalized_quality"\""" | ||||
|     fi | ||||
| 
 | ||||
|     if [[ "$runtime" == "dotnet" ]]; then | ||||
|         repeatable_command+=" --runtime "\""dotnet"\""" | ||||
|     elif [[ "$runtime" == "aspnetcore" ]]; then | ||||
|         repeatable_command+=" --runtime "\""aspnetcore"\""" | ||||
|     fi | ||||
| 
 | ||||
|     repeatable_command+="$non_dynamic_parameters" | ||||
| 
 | ||||
|     if [ -n "$feed_credential" ]; then | ||||
|         repeatable_command+=" --feed-credential "\""<feed_credential>"\""" | ||||
|     fi | ||||
| 
 | ||||
|     say "Repeatable invocation: $repeatable_command" | ||||
| if [[ "$dry_run" = true ]]; then | ||||
|     print_dry_run | ||||
|     exit 0 | ||||
| fi | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user