mirror of
				https://github.com/actions/setup-dotnet.git
				synced 2025-10-31 23:23:46 +00:00 
			
		
		
		
	Update installers scripts
This commit is contained in:
		
							parent
							
								
									b8ab602c41
								
							
						
					
					
						commit
						12194cb2cd
					
				
							
								
								
									
										569
									
								
								externals/install-dotnet.ps1
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										569
									
								
								externals/install-dotnet.ps1
									
									
									
									
										vendored
									
									
								
							| @ -16,15 +16,27 @@ | ||||
|     - LTS - most current supported release | ||||
|     - 2-part version in a format A.B - represents a specific release | ||||
|           examples: 2.0, 1.0 | ||||
|     - Branch name | ||||
|           examples: release/2.0.0, Master | ||||
|     Note: The version parameter overrides the channel parameter. | ||||
|     - 3-part version in a format A.B.Cxx - represents a specific SDK release | ||||
|           examples: 5.0.1xx, 5.0.2xx | ||||
|           Supported since 5.0 release | ||||
|     Note: The version parameter overrides the channel parameter when any version other than 'latest' is used. | ||||
| .PARAMETER Quality | ||||
|     Download the latest build of specified quality in the channel. The possible values are: daily, signed, validated, preview, GA. | ||||
|     Works only in combination with channel. Not applicable for current and LTS channels and will be ignored if those channels are used.  | ||||
|     For SDK use channel in A.B.Cxx format: using quality together with channel in A.B format is not supported. | ||||
|     Supported since 5.0 release. | ||||
|     Note: The version parameter overrides the channel parameter when any version other than 'latest' is used, and therefore overrides the quality.      | ||||
| .PARAMETER Version | ||||
|     Default: latest | ||||
|     Represents a build version on specific channel. Possible values: | ||||
|     - latest - most latest build on specific channel | ||||
|     - 3-part version in a format A.B.C - represents specific version of build | ||||
|           examples: 2.0.0-preview2-006120, 1.1.0 | ||||
| .PARAMETER Internal | ||||
|     Download internal builds. Requires providing credentials via -FeedCredential parameter. | ||||
| .PARAMETER FeedCredential | ||||
|     Token to access Azure feed. Used as a query string to append to the Azure feed. | ||||
|     This parameter typically is not specified. | ||||
| .PARAMETER InstallDir | ||||
|     Default: %LocalAppData%\Microsoft\dotnet | ||||
|     Path to where to install dotnet. Note that binaries will be placed directly in a given directory. | ||||
| @ -59,9 +71,6 @@ | ||||
| .PARAMETER UncachedFeed | ||||
|     This parameter typically is not changed by the user. | ||||
|     It allows changing the URL for the Uncached feed used by this installer. | ||||
| .PARAMETER FeedCredential | ||||
|     Used as a query string to append to the Azure feed. | ||||
|     It allows changing the URL to use non-public blob storage accounts. | ||||
| .PARAMETER ProxyAddress | ||||
|     If set, the installer will use the proxy when making web requests | ||||
| .PARAMETER ProxyUseDefaultCredentials | ||||
| @ -81,11 +90,12 @@ | ||||
| [cmdletbinding()] | ||||
| param( | ||||
|    [string]$Channel="LTS", | ||||
|    [string]$Quality, | ||||
|    [string]$Version="Latest", | ||||
|    [switch]$Internal, | ||||
|    [string]$JSonFile, | ||||
|    [string]$InstallDir="<auto>", | ||||
|    [string]$Architecture="<auto>", | ||||
|    [ValidateSet("dotnet", "aspnetcore", "windowsdesktop", IgnoreCase = $false)] | ||||
|    [string]$Runtime, | ||||
|    [Obsolete("This parameter may be removed in a future version of this script. The recommended alternative is '-Runtime dotnet'.")] | ||||
|    [switch]$SharedRuntime, | ||||
| @ -205,7 +215,7 @@ function Get-Machine-Architecture() { | ||||
| function Get-CLIArchitecture-From-Architecture([string]$Architecture) { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     switch ($Architecture.ToLower()) { | ||||
|     switch ($Architecture.ToLowerInvariant()) { | ||||
|         { $_ -eq "<auto>" } { return Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture) } | ||||
|         { ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" } | ||||
|         { $_ -eq "x86" } { return "x86" } | ||||
| @ -215,6 +225,53 @@ function Get-CLIArchitecture-From-Architecture([string]$Architecture) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function Get-NormalizedQuality([string]$Quality) { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     if ([string]::IsNullOrEmpty($Quality)) { | ||||
|         return "" | ||||
|     } | ||||
| 
 | ||||
|     switch ($Quality) { | ||||
|         { @("daily", "signed", "validated", "preview") -contains $_ } { return $Quality.ToLowerInvariant() } | ||||
|         #ga quality is available without specifying quality, so normalizing it to empty | ||||
|         { $_ -eq "ga" } { return "" } | ||||
|         default { throw "'$Quality' is not a supported value for -Quality option. Supported values are: daily, signed, validated, preview, ga. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues." } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function Get-NormalizedChannel([string]$Channel) { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     if ([string]::IsNullOrEmpty($Channel)) { | ||||
|         return "" | ||||
|     } | ||||
| 
 | ||||
|     if ($Channel.StartsWith('release/')) { | ||||
|         Say-Warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead, such as "-Channel 5.0 -Quality Daily."' | ||||
|     } | ||||
| 
 | ||||
|     switch ($Channel) { | ||||
|         { $_ -eq "lts" } { return "LTS" } | ||||
|         { $_ -eq "current" } { return "current" } | ||||
|         default { return $Channel.ToLowerInvariant() } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function Get-NormalizedProduct([string]$Runtime) { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     switch ($Runtime) { | ||||
|         { $_ -eq "dotnet" } { return "dotnet-runtime" } | ||||
|         { $_ -eq "aspnetcore" } { return "aspnetcore-runtime" } | ||||
|         { $_ -eq "windowsdesktop" } { return "windowsdesktop-runtime" } | ||||
|         { [string]::IsNullOrEmpty($_) } { return "dotnet-sdk" } | ||||
|         default { throw "'$Runtime' is not a supported value for -Runtime option, supported values are: dotnet, aspnetcore, windowsdesktop. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues." } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| # The version text returned from the feeds is a 1-line or 2-line string: | ||||
| # For the SDK and the dotnet runtime (2 lines): | ||||
| # Line 1: # commit_hash | ||||
| @ -243,7 +300,7 @@ function Load-Assembly([string] $Assembly) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function GetHTTPResponse([Uri] $Uri) | ||||
| function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, [bool]$DisableFeedCredential) | ||||
| { | ||||
|     Invoke-With-Retry( | ||||
|     { | ||||
| @ -270,26 +327,42 @@ function GetHTTPResponse([Uri] $Uri) | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if($ProxyAddress) { | ||||
|             $HttpClientHandler = New-Object System.Net.Http.HttpClientHandler | ||||
|             if($ProxyAddress) { | ||||
|                 $HttpClientHandler.Proxy =  New-Object System.Net.WebProxy -Property @{ | ||||
|                     Address=$ProxyAddress; | ||||
|                     UseDefaultCredentials=$ProxyUseDefaultCredentials; | ||||
|                     BypassList = $ProxyBypassList; | ||||
|                 } | ||||
|             }        | ||||
|             if ($DisableRedirect) | ||||
|             { | ||||
|                 $HttpClientHandler.AllowAutoRedirect = $false | ||||
|             } | ||||
|             $HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler | ||||
|             } | ||||
|             else { | ||||
| 
 | ||||
|                 $HttpClient = New-Object System.Net.Http.HttpClient | ||||
|             } | ||||
|             # Default timeout for HttpClient is 100s.  For a 50 MB download this assumes 500 KB/s average, any less will time out | ||||
|             # 20 minutes allows it to work over much slower connections. | ||||
|             $HttpClient.Timeout = New-TimeSpan -Minutes 20 | ||||
|             $Task = $HttpClient.GetAsync("${Uri}${FeedCredential}").ConfigureAwait("false"); | ||||
| 
 | ||||
|             if ($HeaderOnly){ | ||||
|                 $completionOption = [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead | ||||
|             } | ||||
|             else { | ||||
|                 $completionOption = [System.Net.Http.HttpCompletionOption]::ResponseContentRead | ||||
|             } | ||||
| 
 | ||||
|             if ($DisableFeedCredential) { | ||||
|                 $UriWithCredential = $Uri | ||||
|             } | ||||
|             else { | ||||
|                 $UriWithCredential = "${Uri}${FeedCredential}" | ||||
|             } | ||||
| 
 | ||||
|             $Task = $HttpClient.GetAsync("$UriWithCredential", $completionOption).ConfigureAwait("false"); | ||||
|             $Response = $Task.GetAwaiter().GetResult(); | ||||
| 
 | ||||
|             if (($null -eq $Response) -or (-not ($Response.IsSuccessStatusCode))) { | ||||
|             if (($null -eq $Response) -or ((-not $HeaderOnly) -and (-not ($Response.IsSuccessStatusCode)))) { | ||||
|                 # The feed credential is potentially sensitive info. Do not log FeedCredential to console output. | ||||
|                 $DownloadException = [System.Exception] "Unable to download $Uri." | ||||
| 
 | ||||
| @ -349,6 +422,9 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel) { | ||||
|     else { | ||||
|         throw "Invalid value for `$Runtime" | ||||
|     } | ||||
| 
 | ||||
|     Say-Verbose "Constructed latest.version URL: $VersionFileUrl" | ||||
| 
 | ||||
|     try { | ||||
|         $Response = GetHTTPResponse -Uri $VersionFileUrl | ||||
|     } | ||||
| @ -411,7 +487,7 @@ function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel, | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     if (-not $JSonFile) { | ||||
|         if ($Version.ToLower() -eq "latest") { | ||||
|         if ($Version.ToLowerInvariant() -eq "latest") { | ||||
|             $LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel | ||||
|             return $LatestVersionInfo.Version | ||||
|         } | ||||
| @ -478,35 +554,15 @@ function Get-LegacyDownload-Link([string]$AzureFeed, [string]$SpecificVersion, [ | ||||
|     return $PayloadURL | ||||
| } | ||||
| 
 | ||||
| function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion) { | ||||
| function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion, [string]$PackageDownloadLink) { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     if ($Runtime -eq "dotnet") { | ||||
|         $ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/productVersion.txt" | ||||
|     } | ||||
|     elseif ($Runtime -eq "aspnetcore") { | ||||
|         $ProductVersionTxtURL = "$AzureFeed/aspnetcore/Runtime/$SpecificVersion/productVersion.txt" | ||||
|     } | ||||
|     elseif ($Runtime -eq "windowsdesktop") { | ||||
|         # The windows desktop runtime is part of the core runtime layout prior to 5.0 | ||||
|         $ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/productVersion.txt" | ||||
|         if ($SpecificVersion -match '^(\d+)\.(.*)') | ||||
|         { | ||||
|             $majorVersion = [int]$Matches[1] | ||||
|             if ($majorVersion -ge 5) | ||||
|             { | ||||
|                 $ProductVersionTxtURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/productVersion.txt" | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     elseif (-not $Runtime) { | ||||
|         $ProductVersionTxtURL = "$AzureFeed/Sdk/$SpecificVersion/productVersion.txt" | ||||
|     } | ||||
|     else { | ||||
|         throw "Invalid value '$Runtime' specified for `$Runtime" | ||||
|     } | ||||
|     # Try to get the version number, using the productVersion.txt file located next to the installer file. | ||||
|     $ProductVersionTxtURLs = (Get-Product-Version-Url $AzureFeed $SpecificVersion $PackageDownloadLink -Flattened $true), | ||||
|                              (Get-Product-Version-Url $AzureFeed $SpecificVersion $PackageDownloadLink -Flattened $false) | ||||
|      | ||||
|     Say-Verbose "Checking for existence of $ProductVersionTxtURL" | ||||
|     Foreach ($ProductVersionTxtURL in $ProductVersionTxtURLs) { | ||||
|         Say-Verbose "Checking for the existence of $ProductVersionTxtURL" | ||||
| 
 | ||||
|         try { | ||||
|             $productVersionResponse = GetHTTPResponse($productVersionTxtUrl) | ||||
| @ -517,18 +573,96 @@ function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion) { | ||||
|                 { | ||||
|                     Say "Using alternate version $productVersion found in $ProductVersionTxtURL" | ||||
|                 } | ||||
| 
 | ||||
|                 return $productVersion | ||||
|             } | ||||
|             else { | ||||
|             Say-Verbose "Got StatusCode $($productVersionResponse.StatusCode) trying to get productVersion.txt at $productVersionTxtUrl, so using default value of $SpecificVersion" | ||||
|             $productVersion = $SpecificVersion | ||||
|                 Say-Verbose "Got StatusCode $($productVersionResponse.StatusCode) when trying to get productVersion.txt at $productVersionTxtUrl." | ||||
|             } | ||||
|         }  | ||||
|         catch { | ||||
|             Say-Verbose "Could not read productVersion.txt at $productVersionTxtUrl (Exception: '$($_.Exception.Message)'. )" | ||||
|         } | ||||
|     } catch { | ||||
|         Say-Verbose "Could not read productVersion.txt at $productVersionTxtUrl, so using default value of $SpecificVersion (Exception: '$($_.Exception.Message)' )" | ||||
|         $productVersion = $SpecificVersion | ||||
|     } | ||||
| 
 | ||||
|     # Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number. | ||||
|     if ([string]::IsNullOrEmpty($PackageDownloadLink)) | ||||
|     { | ||||
|         Say-Verbose "Using the default value '$SpecificVersion' as the product version." | ||||
|         return $SpecificVersion | ||||
|     } | ||||
| 
 | ||||
|     $productVersion = Get-ProductVersionFromDownloadLink $PackageDownloadLink $SpecificVersion | ||||
|     return $productVersion | ||||
| } | ||||
| 
 | ||||
| function Get-Product-Version-Url([string]$AzureFeed, [string]$SpecificVersion, [string]$PackageDownloadLink, [bool]$Flattened) { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     $majorVersion=$null | ||||
|     if ($SpecificVersion -match '^(\d+)\.(.*)') { | ||||
|         $majorVersion = $Matches[1] -as[int] | ||||
|     } | ||||
| 
 | ||||
|     $pvFileName='productVersion.txt' | ||||
|     if($Flattened) { | ||||
|         if(-not $Runtime) { | ||||
|             $pvFileName='sdk-productVersion.txt' | ||||
|         } | ||||
|         elseif($Runtime -eq "dotnet") { | ||||
|             $pvFileName='runtime-productVersion.txt' | ||||
|         } | ||||
|         else { | ||||
|             $pvFileName="$Runtime-productVersion.txt" | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if ([string]::IsNullOrEmpty($PackageDownloadLink)) { | ||||
|         if ($Runtime -eq "dotnet") { | ||||
|             $ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/$pvFileName" | ||||
|         } | ||||
|         elseif ($Runtime -eq "aspnetcore") { | ||||
|             $ProductVersionTxtURL = "$AzureFeed/aspnetcore/Runtime/$SpecificVersion/$pvFileName" | ||||
|         } | ||||
|         elseif ($Runtime -eq "windowsdesktop") { | ||||
|             # The windows desktop runtime is part of the core runtime layout prior to 5.0 | ||||
|             $ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/$pvFileName" | ||||
|             if ($majorVersion -ne $null -and $majorVersion -ge 5) { | ||||
|                 $ProductVersionTxtURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/$pvFileName" | ||||
|             } | ||||
|         } | ||||
|         elseif (-not $Runtime) { | ||||
|             $ProductVersionTxtURL = "$AzureFeed/Sdk/$SpecificVersion/$pvFileName" | ||||
|         } | ||||
|         else { | ||||
|             throw "Invalid value '$Runtime' specified for `$Runtime" | ||||
|         } | ||||
|     } | ||||
|     else { | ||||
|         $ProductVersionTxtURL = $PackageDownloadLink.Substring(0, $PackageDownloadLink.LastIndexOf("/"))  + "/$pvFileName" | ||||
|     } | ||||
| 
 | ||||
|     Say-Verbose "Constructed productVersion link: $ProductVersionTxtURL" | ||||
| 
 | ||||
|     return $ProductVersionTxtURL | ||||
| } | ||||
| 
 | ||||
| function Get-ProductVersionFromDownloadLink([string]$PackageDownloadLink, [string]$SpecificVersion) | ||||
| { | ||||
|     Say-Invocation $MyInvocation | ||||
| 
 | ||||
|     #product specific version follows the product name | ||||
|     #for filename 'dotnet-sdk-3.1.404-win-x64.zip': the product version is 3.1.400 | ||||
|     $filename = $PackageDownloadLink.Substring($PackageDownloadLink.LastIndexOf("/") + 1) | ||||
|     $filenameParts = $filename.Split('-') | ||||
|     if ($filenameParts.Length -gt 2) | ||||
|     { | ||||
|         $productVersion = $filenameParts[2] | ||||
|         Say-Verbose "Extracted product version '$productVersion' from download link '$PackageDownloadLink'." | ||||
|     } | ||||
|     else { | ||||
|         Say-Verbose "Using the default value '$SpecificVersion' as the product version." | ||||
|         $productVersion = $SpecificVersion | ||||
|     } | ||||
|     return $productVersion  | ||||
| } | ||||
| 
 | ||||
| @ -702,15 +836,150 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolde | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Internal, [string]$Product, [string]$Architecture) { | ||||
|     Say-Invocation $MyInvocation  | ||||
| 
 | ||||
|     #quality is not supported for LTS or current channel | ||||
|     if (![string]::IsNullOrEmpty($Quality) -and (@("LTS", "current") -contains $Channel)) { | ||||
|         $Quality = "" | ||||
|         Say-Warning "Specifying quality for current or LTS channel is not supported, the quality will be ignored." | ||||
|     } | ||||
|     Say-Verbose "Retrieving primary payload URL from aka.ms link for channel: '$Channel', quality: '$Quality' product: '$Product', os: 'win', architecture: '$Architecture'."  | ||||
|     | ||||
|     #construct aka.ms link | ||||
|     $akaMsLink = "https://aka.ms/dotnet" | ||||
|     if ($Internal) { | ||||
|         $akaMsLink += "/internal" | ||||
|     } | ||||
|     $akaMsLink += "/$Channel" | ||||
|     if (-not [string]::IsNullOrEmpty($Quality)) { | ||||
|         $akaMsLink +="/$Quality" | ||||
|     } | ||||
|     $akaMsLink +="/$Product-win-$Architecture.zip" | ||||
|     Say-Verbose  "Constructed aka.ms link: '$akaMsLink'." | ||||
|     $akaMsDownloadLink=$null | ||||
| 
 | ||||
|     for ($maxRedirections = 9; $maxRedirections -ge 0; $maxRedirections--) | ||||
|     { | ||||
|         #get HTTP response | ||||
|         #do not pass credentials as a part of the $akaMsLink and do not apply credentials in the GetHTTPResponse function | ||||
|         #otherwise the redirect link would have credentials as well | ||||
|         #it would result in applying credentials twice to the resulting link and thus breaking it, and in echoing credentials to the output as a part of redirect link | ||||
|         $Response= GetHTTPResponse -Uri $akaMsLink -HeaderOnly $true -DisableRedirect $true -DisableFeedCredential $true | ||||
|         Say-Verbose "Received response:`n$Response" | ||||
| 
 | ||||
|         if ([string]::IsNullOrEmpty($Response)) { | ||||
|             Say-Verbose "The link '$akaMsLink' is not valid: failed to get redirect location. The resource is not available." | ||||
|             return $null | ||||
|         } | ||||
| 
 | ||||
|         #if HTTP code is 301 (Moved Permanently), the redirect link exists | ||||
|         if  ($Response.StatusCode -eq 301) | ||||
|         { | ||||
|             try { | ||||
|                 $akaMsDownloadLink = $Response.Headers.GetValues("Location")[0] | ||||
| 
 | ||||
|                 if ([string]::IsNullOrEmpty($akaMsDownloadLink)) { | ||||
|                     Say-Verbose "The link '$akaMsLink' is not valid: server returned 301 (Moved Permanently), but the headers do not contain the redirect location." | ||||
|                     return $null | ||||
|                 } | ||||
| 
 | ||||
|                 Say-Verbose "The redirect location retrieved: '$akaMsDownloadLink'." | ||||
|                 # This may yet be a link to another redirection. Attempt to retrieve the page again. | ||||
|                 $akaMsLink = $akaMsDownloadLink | ||||
|                 continue | ||||
|             } | ||||
|             catch { | ||||
|                 Say-Verbose "The link '$akaMsLink' is not valid: failed to get redirect location." | ||||
|                 return $null | ||||
|             } | ||||
|         } | ||||
|         elseif ((($Response.StatusCode -lt 300) -or ($Response.StatusCode -ge 400)) -and (-not [string]::IsNullOrEmpty($akaMsDownloadLink))) | ||||
|         { | ||||
|             # Redirections have ended. | ||||
|             return $akaMsDownloadLink | ||||
|         } | ||||
| 
 | ||||
|         Say-Verbose "The link '$akaMsLink' is not valid: failed to retrieve the redirection location." | ||||
|         return $null | ||||
|     } | ||||
| 
 | ||||
|     Say-Verbose "Aka.ms links have redirected more than the maximum allowed redirections. This may be caused by a cyclic redirection of aka.ms links." | ||||
|     return $null | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| $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 | ||||
| $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 | ||||
|     | ||||
|     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 "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." | ||||
|     } | ||||
|     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('/') | ||||
|         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'." | ||||
|         } | ||||
| 
 | ||||
|         #retrieve effective (product) version | ||||
|         $EffectiveVersion = Get-Product-Version -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -PackageDownloadLink $DownloadLink | ||||
|         Say-Verbose "Product version: '$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" | ||||
| @ -718,9 +987,9 @@ $ScriptName = $MyInvocation.MyCommand.Name | ||||
| 
 | ||||
| if ($DryRun) { | ||||
|     Say "Payload URLs:" | ||||
|     Say "Primary named payload URL: $DownloadLink" | ||||
|     Say "Primary named payload URL: ${DownloadLink}" | ||||
|     if ($LegacyDownloadLink) { | ||||
|         Say "Legacy named payload URL: $LegacyDownloadLink" | ||||
|         Say "Legacy named payload URL: ${LegacyDownloadLink}" | ||||
|     } | ||||
|     $RepeatableCommand = ".\$ScriptName -Version `"$SpecificVersion`" -InstallDir `"$InstallRoot`" -Architecture `"$CLIArchitecture`"" | ||||
|     if ($Runtime -eq "dotnet") { | ||||
| @ -729,11 +998,20 @@ if ($DryRun) { | ||||
|     elseif ($Runtime -eq "aspnetcore") { | ||||
|        $RepeatableCommand+=" -Runtime `"aspnetcore`"" | ||||
|     } | ||||
| 
 | ||||
|     if (-not [string]::IsNullOrEmpty($NormalizedQuality)) | ||||
|     { | ||||
|         $RepeatableCommand+=" -Quality `"$NormalizedQuality`"" | ||||
|     } | ||||
| 
 | ||||
|     foreach ($key in $MyInvocation.BoundParameters.Keys) { | ||||
|         if (-not (@("Architecture","Channel","DryRun","InstallDir","Runtime","SharedRuntime","Version") -contains $key)) { | ||||
|         if (-not (@("Architecture","Channel","DryRun","InstallDir","Runtime","SharedRuntime","Version","Quality","FeedCredential") -contains $key)) { | ||||
|             $RepeatableCommand+=" -$key `"$($MyInvocation.BoundParameters[$key])`"" | ||||
|         } | ||||
|     } | ||||
|     if ($MyInvocation.BoundParameters.Keys -contains "FeedCredential") { | ||||
|         $RepeatableCommand+=" -FeedCredential `"<feedCredential>`"" | ||||
|     } | ||||
|     Say "Repeatable invocation: $RepeatableCommand" | ||||
|     if ($SpecificVersion -ne $EffectiveVersion) | ||||
|     { | ||||
| @ -779,9 +1057,16 @@ if ($isAssetInstalled) { | ||||
| 
 | ||||
| New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null | ||||
| 
 | ||||
| $installDrive = $((Get-Item $InstallRoot).PSDrive.Name); | ||||
| $diskInfo = Get-PSDrive -Name $installDrive | ||||
| if ($diskInfo.Free / 1MB -le 100) { | ||||
| $installDrive = $((Get-Item $InstallRoot -Force).PSDrive.Name); | ||||
| $diskInfo = $null | ||||
| try{ | ||||
|     $diskInfo = Get-PSDrive -Name $installDrive | ||||
| } | ||||
| 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)) { | ||||
|     throw "There is not enough disk space on drive ${installDrive}:" | ||||
| } | ||||
| 
 | ||||
| @ -902,42 +1187,42 @@ 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 | ||||
| # MIIjjwYJKoZIhvcNAQcCoIIjgDCCI3wCAQExDzANBglghkgBZQMEAgEFADB5Bgor | ||||
| # MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor | ||||
| # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG | ||||
| # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCNsnhcJvx/hXmM | ||||
| # w8KjuvvIMDBFonhg9XJFc1QwfTyH4aCCDYEwggX/MIID56ADAgECAhMzAAABh3IX | ||||
| # chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD | ||||
| # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAGF/0aIv/nK8pL | ||||
| # ube4cwR/nwps7FSM0D5vjXxuQe3LXaCCDYEwggX/MIID56ADAgECAhMzAAAB32vw | ||||
| # LpKnSrTQAAAAAAHfMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD | ||||
| # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy | ||||
| # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p | ||||
| # bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw | ||||
| # bmcgUENBIDIwMTEwHhcNMjAxMjE1MjEzMTQ1WhcNMjExMjAyMjEzMTQ1WjB0MQsw | ||||
| # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u | ||||
| # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy | ||||
| # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB | ||||
| # AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB | ||||
| # znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH | ||||
| # sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d | ||||
| # weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ | ||||
| # itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV | ||||
| # Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE | ||||
| # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw | ||||
| # AQC2uxlZEACjqfHkuFyoCwfL25ofI9DZWKt4wEj3JBQ48GPt1UsDv834CcoUUPMn | ||||
| # s/6CtPoaQ4Thy/kbOOg/zJAnrJeiMQqRe2Lsdb/NSI2gXXX9lad1/yPUDOXo4GNw | ||||
| # PjXq1JZi+HZV91bUr6ZjzePj1g+bepsqd/HC1XScj0fT3aAxLRykJSzExEBmU9eS | ||||
| # yuOwUuq+CriudQtWGMdJU650v/KmzfM46Y6lo/MCnnpvz3zEL7PMdUdwqj/nYhGG | ||||
| # 3UVILxX7tAdMbz7LN+6WOIpT1A41rwaoOVnv+8Ua94HwhjZmu1S73yeV7RZZNxoh | ||||
| # EegJi9YYssXa7UZUUkCCA+KnAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE | ||||
| # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUOPbML8IdkNGtCfMmVPtvI6VZ8+Mw | ||||
| # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 | ||||
| # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu | ||||
| # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDYzMDA5MB8GA1UdIwQYMBaAFEhu | ||||
| # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu | ||||
| # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w | ||||
| # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 | ||||
| # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx | ||||
| # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy | ||||
| # S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K | ||||
| # NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV | ||||
| # BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr | ||||
| # qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx | ||||
| # zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe | ||||
| # yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g | ||||
| # yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf | ||||
| # AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI | ||||
| # 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5 | ||||
| # GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea | ||||
| # jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS | ||||
| # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAnnqH | ||||
| # tDyYUFaVAkvAK0eqq6nhoL95SZQu3RnpZ7tdQ89QR3++7A+4hrr7V4xxmkB5BObS | ||||
| # 0YK+MALE02atjwWgPdpYQ68WdLGroJZHkbZdgERG+7tETFl3aKF4KpoSaGOskZXp | ||||
| # TPnCaMo2PXoAMVMGpsQEQswimZq3IQ3nRQfBlJ0PoMMcN/+Pks8ZTL1BoPYsJpok | ||||
| # t6cql59q6CypZYIwgyJ892HpttybHKg1ZtQLUlSXccRMlugPgEcNZJagPEgPYni4 | ||||
| # b11snjRAgf0dyQ0zI9aLXqTxWUU5pCIFiPT0b2wsxzRqCtyGqpkGM8P9GazO8eao | ||||
| # mVItCYBcJSByBx/pS0cSYwBBHAZxJODUqxSXoSGDvmTfqUJXntnWkL4okok1FiCD | ||||
| # Z4jpyXOQunb6egIXvkgQ7jb2uO26Ow0m8RwleDvhOMrnHsupiOPbozKroSa6paFt | ||||
| # VSh89abUSooR8QdZciemmoFhcWkEwFg4spzvYNP4nIs193261WyTaRMZoceGun7G | ||||
| # CT2Rl653uUj+F+g94c63AhzSq4khdL4HlFIP2ePv29smfUnHtGq6yYFDLnT0q/Y+ | ||||
| # Di3jwloF8EWkkHRtSuXlFUbTmwr/lDDgbpZiKhLS7CBTDj32I0L5i532+uHczw82 | ||||
| # oZDmYmYmIUSMbZOgS65h797rj5JJ6OkeEUJoAVwwggd6MIIFYqADAgECAgphDpDS | ||||
| # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK | ||||
| # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 | ||||
| # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 | ||||
| @ -977,55 +1262,55 @@ Say "Installation finished" | ||||
| # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 | ||||
| # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 | ||||
| # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I | ||||
| # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZDCCFWACAQEwgZUwfjELMAkG | ||||
| # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG | ||||
| # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx | ||||
| # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z | ||||
| # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN | ||||
| # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAd9r8C6Sp0q00AAAAAAB3zAN | ||||
| # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor | ||||
| # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgpT/bxWwe | ||||
| # aW0EinKMWCAzDXUjwXkIHldYzR6lw4/1Pc0wQgYKKwYBBAGCNwIBDDE0MDKgFIAS | ||||
| # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgJROF4V78 | ||||
| # d/qQulLV5Z+ncgFZgk9r0UoE37o5jTCDpSowQgYKKwYBBAGCNwIBDDE0MDKgFIAS | ||||
| # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN | ||||
| # BgkqhkiG9w0BAQEFAASCAQCHd7sSQVq0YDg8QDx6/kLWn3s6jtvvIDCCgsO9spHM | ||||
| # quPd4FPbG67DCsKDClekQs52qrtRO3Zo+JMnCw4j3bS+gZHzeJr2shbftOrpsFoD | ||||
| # l7OPcUmtrqul9dkQCOp8t0MP3ls0n96/YyNy6lz4BAlTdkdDx957uAxalKaCIBzb | ||||
| # R9QyppOKIfNFvwD4EI5KI6tpmSy/uH8SrRg7ZExAYZl6J6R18WkL7KHn649lPoAQ | ||||
| # ujwrIXH10xOJops45ILGzKWQcHmCzLJGYapL4VHUuK+73nT+9ZROGHdk/PyvIcdw | ||||
| # iERa+C06v305t3DA+CuHFy1tvyw7IFF6RVbLZPwxrJjToYIS7jCCEuoGCisGAQQB | ||||
| # gjcDAwExghLaMIIS1gYJKoZIhvcNAQcCoIISxzCCEsMCAQMxDzANBglghkgBZQME | ||||
| # BgkqhkiG9w0BAQEFAASCAQB74lkh+M6W7qWNERtX5/xMFrSgaVCptxuBlBl93FN3 | ||||
| # aQJiCaToMeDXG3Nsf/GhIFCBz4fReYrMmZg5pmjs+d8s1dgXz2oOWVwx6bhnzdXS | ||||
| # ce5dMqkUCzvN4QeJxTIhpeXsHwupWVbuqeTo5DdZHouTi4UFzgM0/K+sSbRI/FEe | ||||
| # rS/vxtMbrtMz57kKjB/Z86dKJeDxQydKSapL/YIamfmYx26rjpXJqEs7W+FVRJwK | ||||
| # nNNT0OGt7tdkL6k+7XQtK3f5yUqKMdTlmPyZ73z69tAtJclkIFC3liFVTMAf4MK+ | ||||
| # nheQal7OPNth86h4Lek3E19n2hrABTUeW2cLZ2WWEspFoYIS8TCCEu0GCisGAQQB | ||||
| # gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME | ||||
| # AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB | ||||
| # MDEwDQYJYIZIAWUDBAIBBQAEIOCaTmvM1AP0WaEVqzKaaCu/R+bTlR4kCrM/ZXsb | ||||
| # /eNOAgZgGeLsMwsYEzIwMjEwMjAzMjExNzQ5LjU5MVowBIACAfSggdSkgdEwgc4x | ||||
| # MDEwDQYJYIZIAWUDBAIBBQAEIEIDAx5adVXZRJeNOj9JW7M03Sl8XvjtY9M98TvW | ||||
| # cUwSAgZgieWmNfwYEzIwMjEwNTE5MTcwMDI4LjY0OVowBIACAfSggdSkgdEwgc4x | ||||
| # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt | ||||
| # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p | ||||
| # Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg | ||||
| # VFNTIEVTTjo4OTdBLUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt | ||||
| # U3RhbXAgU2VydmljZaCCDkEwggT1MIID3aADAgECAhMzAAABLCKvRZd1+RvuAAAA | ||||
| # AAEsMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo | ||||
| # VFNTIEVTTjpEOURFLUUzOUEtNDNGRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt | ||||
| # U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABYfWiM16gKiRpAAAA | ||||
| # AAFhMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo | ||||
| # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y | ||||
| # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw | ||||
| # MB4XDTE5MTIxOTAxMTUwM1oXDTIxMDMxNzAxMTUwM1owgc4xCzAJBgNVBAYTAlVT | ||||
| # MB4XDTIxMDExNDE5MDIyMVoXDTIyMDQxMTE5MDIyMVowgc4xCzAJBgNVBAYTAlVT | ||||
| # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK | ||||
| # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy | ||||
| # YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4OTdB | ||||
| # LUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj | ||||
| # ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPK1zgSSq+MxAYo3qpCt | ||||
| # QDxSMPPJy6mm/wfEJNjNUnYtLFBwl1BUS5trEk/t41ldxITKehs+ABxYqo4Qxsg3 | ||||
| # Gy1ugKiwHAnYiiekfC+ZhptNFgtnDZIn45zC0AlVr/6UfLtsLcHCh1XElLUHfEC0 | ||||
| # nBuQcM/SpYo9e3l1qY5NdMgDGxCsmCKdiZfYXIu+U0UYIBhdzmSHnB3fxZOBVcr5 | ||||
| # htFHEBBNt/rFJlm/A4yb8oBsp+Uf0p5QwmO/bCcdqB15JpylOhZmWs0sUfJKlK9E | ||||
| # rAhBwGki2eIRFKsQBdkXS9PWpF1w2gIJRvSkDEaCf+lbGTPdSzHSbfREWOF9wY3i | ||||
| # Yj8CAwEAAaOCARswggEXMB0GA1UdDgQWBBRRahZSGfrCQhCyIyGH9DkiaW7L0zAf | ||||
| # YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpEOURF | ||||
| # LUUzOUEtNDNGRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj | ||||
| # ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJeInahBrU//GzTqhxUy | ||||
| # AC8UXct6UJCkb2xEZKV3gjggmLAheBrxJk7tH+Pw2tTcyarLRfmV2xo5oBk5pW/O | ||||
| # cDc/n/TcTeQU6JIN5PlTcn0C9RlKQ6t9OuU/WAyAxGTjKE4ENnUjXtxiNlD/K2ZG | ||||
| # MLvjpROBKh7TtkUJK6ZGWw/uTRabNBxRg13TvjkGHXEUEDJ8imacw9BCeR9L6und | ||||
| # r32tj4duOFIHD8m1es3SNN98Zq4IDBP3Ccb+HQgxpbeHIUlK0y6zmzIkvfN73Zxw | ||||
| # fGvFv0/Max79WJY0cD8poCnZFijciWrf0eD1T2/+7HgewzrdxPdSFockUQ8QovID | ||||
| # IYkCAwEAAaOCARswggEXMB0GA1UdDgQWBBRWHpqd1hv71SVj5LAdPfNE7PhLLzAf | ||||
| # BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH | ||||
| # hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU | ||||
| # aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF | ||||
| # BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0 | ||||
| # YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG | ||||
| # AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBPFxHIwi4vAH49w9Svmz6K3tM55RlW | ||||
| # 5pPeULXdut2Rqy6Ys0+VpZsbuaEoxs6Z1C3hMbkiqZFxxyltxJpuHTyGTg61zfNI | ||||
| # F5n6RsYF3s7IElDXNfZznF1/2iWc6uRPZK8rxxUJ/7emYXZCYwuUY0XjsCpP9pbR | ||||
| # RKeJi6r5arSyI+NfKxvgoM21JNt1BcdlXuAecdd/k8UjxCscffanoK2n6LFw1PcZ | ||||
| # lEO7NId7o+soM2C0QY5BYdghpn7uqopB6ixyFIIkDXFub+1E7GmAEwfU6VwEHL7y | ||||
| # 9rNE8bd+JrQs+yAtkkHy9FmXg/PsGq1daVzX1So7CJ6nyphpuHSN3VfTMIIGcTCC | ||||
| # AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQAQTA9bqVBmx5TTMhzj+Q8zWkPQXgCc | ||||
| # SQiqy2YYWF0hWr5GEiN2LtA+EWdu1y8oysZau4CP7SzM8VTSq31CLJiOy39Z4RvE | ||||
| # q2mr0EftFvmX2CxQ7ZyzrkhWMZaZQLkYbH5oabIFwndW34nh980BOY395tfnNS/Y | ||||
| # 6N0f+jXdoFn7fI2c43TFYsUqIPWjOHJloMektlD6/uS6Zn4xse/lItFm+fWOcB2A | ||||
| # xyXEB3ZREeSg9j7+GoEl1xT/iJuV/So7TlWdwyacQu4lv3MBsvxzRIbKhZwrDYog | ||||
| # moyJ+rwgQB8mKS4/M1SDRtIptamoTFJ56Tk6DuUXx1JudToelgjEZPa5MIIGcTCC | ||||
| # BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC | ||||
| # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV | ||||
| # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv | ||||
| @ -1060,36 +1345,36 @@ Say "Installation finished" | ||||
| # cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a | ||||
| # KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ | ||||
| # cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+ | ||||
| # NR4Iuto229Nfj950iEkSoYICzzCCAjgCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT | ||||
| # NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT | ||||
| # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD | ||||
| # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP | ||||
| # cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4 | ||||
| # OTdBLUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy | ||||
| # dmljZaIjCgEBMAcGBSsOAwIaAxUADE5OKSMoNx/mYxYWap1RTOohbJ2ggYMwgYCk | ||||
| # cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpE | ||||
| # OURFLUUzOUEtNDNGRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy | ||||
| # dmljZaIjCgEBMAcGBSsOAwIaAxUAFW5ShAw5ekTEXvL/4V1s0rbDz3mggYMwgYCk | ||||
| # fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH | ||||
| # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD | ||||
| # Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF | ||||
| # AOPFChkwIhgPMjAyMTAyMDMxNTQwMDlaGA8yMDIxMDIwNDE1NDAwOVowdDA6Bgor | ||||
| # BgEEAYRZCgQBMSwwKjAKAgUA48UKGQIBADAHAgEAAgIXmDAHAgEAAgIRyTAKAgUA | ||||
| # 48ZbmQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID | ||||
| # B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAHeeznL2n6HWCjHH94Fl | ||||
| # hcdW6TEXzq4XNgp1Gx1W9F8gJ4x+SwoV7elJZkwgGffcpHomLvIY/VSuzsl1NgtJ | ||||
| # TWM2UxoqSv58BBOrl4eGhH6kkg8Ucy2tdeK5T8cHa8pMkq2j9pFd2mRG/6VMk0dl | ||||
| # Xz7Uy3Z6bZqkcABMyAfuAaGbMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMx | ||||
| # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT | ||||
| # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt | ||||
| # U3RhbXAgUENBIDIwMTACEzMAAAEsIq9Fl3X5G+4AAAAAASwwDQYJYIZIAWUDBAIB | ||||
| # BQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx | ||||
| # IgQg/QYv7yp+354WTjWUIsXWndTEzXjaYjqwYjcBxCJKjdUwgfoGCyqGSIb3DQEJ | ||||
| # EAIvMYHqMIHnMIHkMIG9BCBbn/0uFFh42hTM5XOoKdXevBaiSxmYK9Ilcn9nu5ZH | ||||
| # 4TCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw | ||||
| # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x | ||||
| # JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABLCKv | ||||
| # RZd1+RvuAAAAAAEsMCIEIIfIM3YbzHswb/Kj/qq1l1cHA6QBl+gEXYanUNJomrpT | ||||
| # MA0GCSqGSIb3DQEBCwUABIIBAAwdcXssUZGO7ho5+NHLjIxLtQk543aKGo+lrRMY | ||||
| # Q9abE1h/AaaNJl0iGxX4IihNWyfovSfYL3L4eODUBAu68tWSxeceRfWNsb/ZZfUi | ||||
| # v89hpLssI/Gf1BEgNMA4zCuIGQiC8okusVumEpAhhvCEbSiTTTtBdolTnU/CAKui | ||||
| # oxaU3R9XkKh1F4oAM26+dJ1J2BLQXPs5afNvvedDsZWNQUPK1sFF3JRfzxiTrwBW | ||||
| # EJRyflev9gyDoqCHzippgb+6+eti1WTkcA9Q49GIT11S6LOAVqkSC9N7Nqf8ksh8 | ||||
| # ARdwT8jigpsm+mj7lrVU9upDkhVYhKeO8oiZq95Q53Zkteo= | ||||
| # AORPamMwIhgPMjAyMTA1MTkxNDQzNDdaGA8yMDIxMDUyMDE0NDM0N1owdzA9Bgor | ||||
| # BgEEAYRZCgQBMS8wLTAKAgUA5E9qYwIBADAKAgEAAgIYCAIB/zAHAgEAAgIRJjAK | ||||
| # AgUA5FC74wIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB | ||||
| # AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAEP3zVlXXAn4O1Ms | ||||
| # 68s11f0LWnsKutmWLnJls7YN9alFuA+jJcq/S8x2VoJAWAZTdWtdT5N7Gf/BeTAe | ||||
| # 8D0krUvAYkKN9sIFxBsV9Zum88+HNP6X3yn+CD+ZzOlhtqvgG+fuuRXPutLZfLc/ | ||||
| # BMw0pVKop8ty4t9o1C5cghIH1n8uMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC | ||||
| # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV | ||||
| # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp | ||||
| # bWUtU3RhbXAgUENBIDIwMTACEzMAAAFh9aIzXqAqJGkAAAAAAWEwDQYJYIZIAWUD | ||||
| # BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B | ||||
| # CQQxIgQgYzAzV5OthXnPmIpD3kPIVmwz+sGvwSbjTEW5rOqHhyUwgfoGCyqGSIb3 | ||||
| # DQEJEAIvMYHqMIHnMIHkMIG9BCBhz4un6mkSLd/zA+0N5YLDGp4vW/VBtNW/lpmh | ||||
| # tAk4bzCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u | ||||
| # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp | ||||
| # b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB | ||||
| # YfWiM16gKiRpAAAAAAFhMCIEIArbvJb5j55rDAQa7Rx5K7mjnxUY6RgiRY1AROOp | ||||
| # m2rLMA0GCSqGSIb3DQEBCwUABIIBAFS544uO7FOimzTwMDkFNhMT7GmZBc9L2wDF | ||||
| # EjcDlHvcdELdWpqa8Au6rCdhW6618btwdFqR7fkNMH7F0TrY1ktOae5fZUaybIRV | ||||
| # EMWAAqXLkVyePlssQamjt1+BYvxzYFh3T5JBr2R/rzaGJIck49r1cEsLBV0JaSQT | ||||
| # QKiOsR+QEbSCNWXQaq/koJrKR5Ugro0y4SmSejnOj5+1/4PlTolFoJAM4pIiT2A1 | ||||
| # uMs5f219BvkwyRmF32z9EpYQvBdoGpT65DQDuZQ5F6wV1Ph4H7yOzarcdnwPohT+ | ||||
| # BeH2jrcR3BMAxC3umgRUmTxnzPsoq9FJuRTyHCNygGn+VMImNfk= | ||||
| # SIG # End signature block | ||||
|  | ||||
							
								
								
									
										420
									
								
								externals/install-dotnet.sh
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										420
									
								
								externals/install-dotnet.sh
									
									
									
									
										vendored
									
									
								
							| @ -24,7 +24,7 @@ exec 3>&1 | ||||
| # See if stdout is a terminal | ||||
| if [ -t 1 ] && command -v tput > /dev/null; then | ||||
|     # see if it supports colors | ||||
|     ncolors=$(tput colors) | ||||
|     ncolors=$(tput colors || echo 0) | ||||
|     if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then | ||||
|         bold="$(tput bold       || echo)" | ||||
|         normal="$(tput sgr0     || echo)" | ||||
| @ -368,6 +368,75 @@ get_normalized_os() { | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| # args: | ||||
| # quality - $1 | ||||
| get_normalized_quality() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local quality="$(to_lowercase "$1")" | ||||
|     if [ ! -z "$quality" ]; then | ||||
|         case "$quality" in | ||||
|             daily | signed | validated | preview) | ||||
|                 echo "$quality" | ||||
|                 return 0 | ||||
|                 ;; | ||||
|             ga) | ||||
|                 #ga quality is available without specifying quality, so normalizing it to empty | ||||
|                 return 0 | ||||
|                 ;; | ||||
|             *) | ||||
|                 say_err "'$quality' is not a supported value for --quality option. Supported values are: daily, signed, validated, preview, ga. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues." | ||||
|                 return 1 | ||||
|                 ;; | ||||
|         esac | ||||
|     fi | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| # args: | ||||
| # channel - $1 | ||||
| get_normalized_channel() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local channel="$(to_lowercase "$1")" | ||||
| 
 | ||||
|     if [[ $channel == release/* ]]; then | ||||
|         say_warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead.'; | ||||
|     fi | ||||
| 
 | ||||
|     if [ ! -z "$channel" ]; then | ||||
|         case "$channel" in | ||||
|             lts) | ||||
|                 echo "LTS" | ||||
|                 return 0 | ||||
|                 ;; | ||||
|             *) | ||||
|                 echo "$channel" | ||||
|                 return 0 | ||||
|                 ;; | ||||
|         esac | ||||
|     fi | ||||
| 
 | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| # args: | ||||
| # runtime - $1 | ||||
| get_normalized_product() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local runtime="$(to_lowercase "$1")" | ||||
|     if [[ "$runtime" == "dotnet" ]]; then | ||||
|         product="dotnet-runtime" | ||||
|     elif [[ "$runtime" == "aspnetcore" ]]; then | ||||
|         product="aspnetcore-runtime" | ||||
|     elif [ -z "$runtime" ]; then | ||||
|         product="dotnet-sdk" | ||||
|     fi | ||||
|     echo "$product" | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| # The version text returned from the feeds is a 1-line or 2-line string: | ||||
| # For the SDK and the dotnet runtime (2 lines): | ||||
| # Line 1: # commit_hash | ||||
| @ -541,43 +610,131 @@ construct_download_link() { | ||||
| # args: | ||||
| # azure_feed - $1 | ||||
| # specific_version - $2 | ||||
| # download link - $3 (optional) | ||||
| get_specific_product_version() { | ||||
|     # If we find a 'productVersion.txt' at the root of any folder, we'll use its contents | ||||
|     # to resolve the version of what's in the folder, superseding the specified version. | ||||
|     # if 'productVersion.txt' is missing but download link is already available, product version will be taken from download link | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local azure_feed="$1" | ||||
|     local specific_version="${2//[$'\t\r\n']}" | ||||
|     local specific_product_version=$specific_version | ||||
| 
 | ||||
|     local download_link=null | ||||
|     if [[ "$runtime" == "dotnet" ]]; then | ||||
|         download_link="$azure_feed/Runtime/$specific_version/productVersion.txt${feed_credential}" | ||||
|     elif [[ "$runtime" == "aspnetcore" ]]; then | ||||
|         download_link="$azure_feed/aspnetcore/Runtime/$specific_version/productVersion.txt${feed_credential}" | ||||
|     elif [ -z "$runtime" ]; then | ||||
|         download_link="$azure_feed/Sdk/$specific_version/productVersion.txt${feed_credential}" | ||||
|     else | ||||
|         return 1 | ||||
|     local package_download_link="" | ||||
|     if [ $# -gt 2  ]; then | ||||
|         local package_download_link="$3" | ||||
|     fi | ||||
|     local specific_product_version=null | ||||
| 
 | ||||
|     # Try to get the version number, using the productVersion.txt file located next to the installer file. | ||||
|     local download_links=($(get_specific_product_version_url "$azure_feed" "$specific_version" true "$package_download_link") | ||||
|         $(get_specific_product_version_url "$azure_feed" "$specific_version" false "$package_download_link")) | ||||
| 
 | ||||
|     for download_link in "${download_links[@]}" | ||||
|     do | ||||
|         say_verbose "Checking for the existence of $download_link" | ||||
| 
 | ||||
|         if machine_has "curl" | ||||
|         then | ||||
|         specific_product_version=$(curl -s --fail "$download_link") | ||||
|         if [ $? -ne 0 ] | ||||
|         then | ||||
|             specific_product_version=$specific_version | ||||
|             specific_product_version=$(curl -s --fail "${download_link}${feed_credential}") | ||||
|             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") | ||||
|         if [ $? -ne 0 ] | ||||
|         then | ||||
|             specific_product_version=$(wget -qO- "${download_link}${feed_credential}") | ||||
|             if [ $? = 0 ]; then | ||||
|                 echo "${specific_product_version//[$'\t\r\n']}" | ||||
|                 return 0 | ||||
|             fi | ||||
|         fi | ||||
|     done | ||||
|      | ||||
|     # Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number. | ||||
|     say_verbose "Failed to get the version using productVersion.txt file. Download link will be parsed instead." | ||||
|     specific_product_version="$(get_product_specific_version_from_download_link "$package_download_link" "$specific_version")" | ||||
|     echo "${specific_product_version//[$'\t\r\n']}" | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| # args: | ||||
| # azure_feed - $1 | ||||
| # specific_version - $2 | ||||
| # is_flattened - $3 | ||||
| # download link - $4 (optional) | ||||
| get_specific_product_version_url() { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local azure_feed="$1" | ||||
|     local specific_version="$2" | ||||
|     local is_flattened="$3" | ||||
|     local package_download_link="" | ||||
|     if [ $# -gt 3  ]; then | ||||
|         local package_download_link="$4" | ||||
|     fi | ||||
| 
 | ||||
|     local pvFileName="productVersion.txt" | ||||
|     if [ "$is_flattened" = true ]; then | ||||
|         if [ -z "$runtime" ]; then | ||||
|             pvFileName="sdk-productVersion.txt" | ||||
|         elif [[ "$runtime" == "dotnet" ]]; then | ||||
|             pvFileName="runtime-productVersion.txt" | ||||
|         else | ||||
|             pvFileName="$runtime-productVersion.txt" | ||||
|         fi | ||||
|     fi | ||||
| 
 | ||||
|     local download_link=null | ||||
| 
 | ||||
|     if [ -z "$package_download_link" ]; then | ||||
|         if [[ "$runtime" == "dotnet" ]]; then | ||||
|             download_link="$azure_feed/Runtime/$specific_version/${pvFileName}" | ||||
|         elif [[ "$runtime" == "aspnetcore" ]]; then | ||||
|             download_link="$azure_feed/aspnetcore/Runtime/$specific_version/${pvFileName}" | ||||
|         elif [ -z "$runtime" ]; then | ||||
|             download_link="$azure_feed/Sdk/$specific_version/${pvFileName}" | ||||
|         else | ||||
|             return 1 | ||||
|         fi | ||||
|     else | ||||
|         download_link="${package_download_link%/*}/${pvFileName}" | ||||
|     fi | ||||
| 
 | ||||
|     say_verbose "Constructed productVersion link: $download_link" | ||||
|     echo "$download_link" | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| # args: | ||||
| # download link - $1 | ||||
| # specific version - $2 | ||||
| get_product_specific_version_from_download_link() | ||||
| { | ||||
|     eval $invocation | ||||
| 
 | ||||
|     local download_link="$1" | ||||
|     local specific_version="$2" | ||||
|     local specific_product_version=""  | ||||
| 
 | ||||
|     if [ -z "$download_link" ]; then | ||||
|         echo "$specific_version" | ||||
|         return 0 | ||||
|     fi | ||||
| 
 | ||||
|     #get filename | ||||
|     filename="${download_link##*/}" | ||||
| 
 | ||||
|     #product specific version follows the product name | ||||
|     #for filename 'dotnet-sdk-3.1.404-linux-x64.tar.gz': the product version is 3.1.404 | ||||
|     IFS='-' | ||||
|     read -ra filename_elems <<< "$filename" | ||||
|     count=${#filename_elems[@]} | ||||
|     if [[ "$count" -gt 2 ]]; then | ||||
|         specific_product_version="${filename_elems[2]}" | ||||
|     else | ||||
|         specific_product_version=$specific_version | ||||
|     fi | ||||
|     fi | ||||
|     specific_product_version="${specific_product_version//[$'\t\r\n']}" | ||||
| 
 | ||||
|     unset IFS; | ||||
|     echo "$specific_product_version" | ||||
|     return 0 | ||||
| } | ||||
| @ -711,19 +868,62 @@ extract_dotnet_package() { | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| # args: | ||||
| # remote_path - $1 | ||||
| # disable_feed_credential - $2 | ||||
| get_http_header() | ||||
| { | ||||
|     eval $invocation | ||||
|     local remote_path="$1" | ||||
|     local disable_feed_credential="$2" | ||||
| 
 | ||||
|     local failed=false | ||||
|     local response | ||||
|     if machine_has "curl"; then | ||||
|         get_http_header_curl $remote_path $disable_feed_credential || failed=true | ||||
|     elif machine_has "wget"; then | ||||
|         get_http_header_wget $remote_path $disable_feed_credential || failed=true | ||||
|     else | ||||
|         failed=true | ||||
|     fi | ||||
|     if [ "$failed" = true ]; then | ||||
|         say_verbose "Failed to get HTTP header: '$remote_path'." | ||||
|         return 1 | ||||
|     fi | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| # args: | ||||
| # remote_path - $1 | ||||
| # disable_feed_credential - $2 | ||||
| get_http_header_curl() { | ||||
|     eval $invocation | ||||
|     local remote_path="$1" | ||||
|     remote_path_with_credential="${remote_path}${feed_credential}" | ||||
|     local disable_feed_credential="$2" | ||||
| 
 | ||||
|     remote_path_with_credential="$remote_path" | ||||
|     if [ "$disable_feed_credential" = false ]; then | ||||
|         remote_path_with_credential+="$feed_credential" | ||||
|     fi | ||||
| 
 | ||||
|     curl_options="-I -sSL --retry 5 --retry-delay 2 --connect-timeout 15 " | ||||
|     curl $curl_options "$remote_path_with_credential" || return 1 | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| # args: | ||||
| # remote_path - $1 | ||||
| # disable_feed_credential - $2 | ||||
| get_http_header_wget() { | ||||
|     eval $invocation | ||||
|     local remote_path="$1" | ||||
|     remote_path_with_credential="${remote_path}${feed_credential}" | ||||
|     local disable_feed_credential="$2" | ||||
| 
 | ||||
|     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 | ||||
| @ -763,7 +963,7 @@ download() { | ||||
| 
 | ||||
|         say "Download attempt #$attempts has failed: $http_code $download_error_msg" | ||||
|         say "Attempt #$((attempts+1)) will start in $((attempts*10)) seconds." | ||||
|         sleep $((attempts*20)) | ||||
|         sleep $((attempts*10)) | ||||
|     done | ||||
| 
 | ||||
| 
 | ||||
| @ -783,6 +983,7 @@ downloadcurl() { | ||||
|     local remote_path="$1" | ||||
|     local out_path="${2:-}" | ||||
|     # Append feed_credential as late as possible before calling curl to avoid logging feed_credential | ||||
|     # Avoid passing URI with credentials to functions: note, most of them echoing parameters of invocation in verbose output. | ||||
|     local remote_path_with_credential="${remote_path}${feed_credential}" | ||||
|     local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs " | ||||
|     local failed=false | ||||
| @ -792,7 +993,8 @@ downloadcurl() { | ||||
|         curl $curl_options -o "$out_path" "$remote_path_with_credential" || failed=true | ||||
|     fi | ||||
|     if [ "$failed" = true ]; then | ||||
|         local response=$(get_http_header_curl $remote_path_with_credential) | ||||
|         local disable_feed_credential=false | ||||
|         local response=$(get_http_header_curl $remote_path $disable_feed_credential) | ||||
|         http_code=$( echo "$response" | awk '/^HTTP/{print $2}' | tail -1 ) | ||||
|         download_error_msg="Unable to download $remote_path." | ||||
|         if  [[ $http_code != 2* ]]; then | ||||
| @ -822,7 +1024,8 @@ downloadwget() { | ||||
|         wget $wget_options -O "$out_path" "$remote_path_with_credential" || failed=true | ||||
|     fi | ||||
|     if [ "$failed" = true ]; then | ||||
|         local response=$(get_http_header_wget $remote_path_with_credential) | ||||
|         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 ) | ||||
|         download_error_msg="Unable to download $remote_path." | ||||
|         if  [[ $http_code != 2* ]]; then | ||||
| @ -834,15 +1037,115 @@ downloadwget() { | ||||
|     return 0 | ||||
| } | ||||
| 
 | ||||
| get_download_link_from_aka_ms() {     | ||||
|     eval $invocation | ||||
| 
 | ||||
|     #quality is not supported for LTS or current channel | ||||
|     if [[ ! -z "$normalized_quality"  && ("$normalized_channel" == "LTS" || "$normalized_channel" == "current") ]]; then | ||||
|         normalized_quality="" | ||||
|         say_warning "Specifying quality for current or LTS channel is not supported, the quality will be ignored." | ||||
|     fi | ||||
| 
 | ||||
|     say_verbose "Retrieving primary payload URL from aka.ms for channel: '$normalized_channel', quality: '$normalized_quality', product: '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'."  | ||||
| 
 | ||||
|     #construct aka.ms link | ||||
|     aka_ms_link="https://aka.ms/dotnet" | ||||
|     if  [ "$internal" = true ]; then | ||||
|         aka_ms_link="$aka_ms_link/internal" | ||||
|     fi | ||||
|     aka_ms_link="$aka_ms_link/$normalized_channel" | ||||
|     if [[ ! -z "$normalized_quality" ]]; then | ||||
|         aka_ms_link="$aka_ms_link/$normalized_quality" | ||||
|     fi | ||||
|     aka_ms_link="$aka_ms_link/$normalized_product-$normalized_os-$normalized_architecture.tar.gz" | ||||
|     say_verbose "Constructed aka.ms link: '$aka_ms_link'." | ||||
| 
 | ||||
|     #get HTTP response | ||||
|     #do not pass credentials as a part of the $aka_ms_link and do not apply credentials in the get_http_header function | ||||
|     #otherwise the redirect link would have credentials as well | ||||
|     #it would result in applying credentials twice to the resulting link and thus breaking it, and in echoing credentials to the output as a part of redirect link | ||||
|     disable_feed_credential=true | ||||
|     response="$(get_http_header $aka_ms_link $disable_feed_credential)" | ||||
| 
 | ||||
|     say_verbose "Received response: $response" | ||||
|     # Get results of all the redirects. | ||||
|     http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' ) | ||||
|     # They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404). | ||||
|     broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' ) | ||||
| 
 | ||||
|     # All HTTP codes are 301 (Moved Permanently), the redirect link exists. | ||||
|     if [[ -z "$broken_redirects" ]]; then | ||||
|         aka_ms_download_link=$( echo "$response" | awk '$1 ~ /^Location/{print $2}' | tail -1 | tr -d '\r') | ||||
| 
 | ||||
|         if [[ -z "$aka_ms_download_link" ]]; then | ||||
|             say_verbose "The aka.ms link '$aka_ms_link' is not valid: failed to get redirect location." | ||||
|             return 1 | ||||
|         fi | ||||
| 
 | ||||
|         say_verbose "The redirect location retrieved: '$aka_ms_download_link'." | ||||
|         return 0 | ||||
|     else | ||||
|         say_verbose "The aka.ms link '$aka_ms_link' is not valid: received HTTP code: $(echo "$broken_redirects" | paste -sd "," -)." | ||||
|         return 1 | ||||
|     fi | ||||
| } | ||||
| 
 | ||||
| calculate_vars() { | ||||
|     eval $invocation | ||||
|     valid_legacy_download_link=true | ||||
| 
 | ||||
|     #normalize input variables | ||||
|     normalized_architecture="$(get_normalized_architecture_from_architecture "$architecture")" | ||||
|     say_verbose "normalized_architecture=$normalized_architecture" | ||||
| 
 | ||||
|     say_verbose "Normalized architecture: '$normalized_architecture'." | ||||
|     normalized_os="$(get_normalized_os "$user_defined_os")" | ||||
|     say_verbose "normalized_os=$normalized_os" | ||||
|     say_verbose "Normalized OS: '$normalized_os'." | ||||
|     normalized_quality="$(get_normalized_quality "$quality")" | ||||
|     say_verbose "Normalized quality: '$normalized_quality'." | ||||
|     normalized_channel="$(get_normalized_channel "$channel")" | ||||
|     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")" | ||||
| @ -1011,6 +1314,8 @@ feed_credential="" | ||||
| verbose=false | ||||
| runtime="" | ||||
| runtime_id="" | ||||
| quality="" | ||||
| internal=false | ||||
| override_non_versioned_files=true | ||||
| non_dynamic_parameters="" | ||||
| user_defined_os="" | ||||
| @ -1027,6 +1332,14 @@ do | ||||
|             shift | ||||
|             version="$1" | ||||
|             ;; | ||||
|         -q|--quality|-[Qq]uality) | ||||
|             shift | ||||
|             quality="$1" | ||||
|             ;; | ||||
|         --internal|-[Ii]nternal) | ||||
|             internal=true | ||||
|             non_dynamic_parameters+=" $name" | ||||
|             ;; | ||||
|         -i|--install-dir|-[Ii]nstall[Dd]ir) | ||||
|             shift | ||||
|             install_dir="$1" | ||||
| @ -1084,7 +1397,9 @@ do | ||||
|         --feed-credential|-[Ff]eed[Cc]redential) | ||||
|             shift | ||||
|             feed_credential="$1" | ||||
|             non_dynamic_parameters+=" $name "\""$1"\""" | ||||
|             #feed_credential should start with "?", for it to be added to the end of the link. | ||||
|             #adding "?" at the beginning of the feed_credential if needed. | ||||
|             [[ -z "$(echo $feed_credential)" ]] || [[ $feed_credential == \?* ]] || feed_credential="?$feed_credential" | ||||
|             ;; | ||||
|         --runtime-id|-[Rr]untime[Ii]d) | ||||
|             shift | ||||
| @ -1116,15 +1431,26 @@ do | ||||
|             echo "          - LTS - most current supported release" | ||||
|             echo "          - 2-part version in a format A.B - represents a specific release" | ||||
|             echo "              examples: 2.0; 1.0" | ||||
|             echo "          - Branch name" | ||||
|             echo "              examples: release/2.0.0; Master" | ||||
|             echo "          Note: The version parameter overrides the channel parameter." | ||||
|             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 "  -v,--version <VERSION>         Use specific VERSION, Defaults to \`$version\`." | ||||
|             echo "      -Version" | ||||
|             echo "          Possible values:" | ||||
|             echo "          - latest - most latest build on specific channel" | ||||
|             echo "          - 3-part version in a format A.B.C - represents specific version of build" | ||||
|             echo "              examples: 2.0.0-preview2-006120; 1.1.0" | ||||
|             echo "  -q,--quality <quality>         Download the latest build of specified quality in the channel." | ||||
|             echo "      -Quality" | ||||
|             echo "          The possible values are: daily, signed, validated, preview, GA." | ||||
|             echo "          Works only in combination with channel. Not applicable for current and LTS channels and will be ignored if those channels are used."  | ||||
|             echo "          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 "  --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." | ||||
|             echo "  -i,--install-dir <DIR>             Install under specified location (see Install Location below)" | ||||
|             echo "      -InstallDir" | ||||
|             echo "  --architecture <ARCHITECTURE>      Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`." | ||||
| @ -1145,7 +1471,6 @@ do | ||||
|             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 "  --feed-credential,-FeedCredential  Azure feed shared access token. This parameter typically is not specified." | ||||
|             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." | ||||
| @ -1186,23 +1511,44 @@ say "- The SDK needs to be installed without user interaction and without admin | ||||
| 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.\n" | ||||
| 
 | ||||
| if [ "$internal" = true ] && [ -z "$(echo $feed_credential)" ]; then | ||||
|     message="Provide credentials via --feed-credential parameter." | ||||
|     if [ "$dry_run" = true ]; then | ||||
|         say_warning "$message" | ||||
|     else | ||||
|         say_err "$message" | ||||
|         exit 1 | ||||
|     fi | ||||
| fi | ||||
| 
 | ||||
| check_min_reqs | ||||
| calculate_vars | ||||
| script_name=$(basename "$0") | ||||
| 
 | ||||
| if [ "$dry_run" = true ]; then | ||||
|     say "Payload URLs:" | ||||
|     say "Primary named payload URL: $download_link" | ||||
|     say "Primary named payload URL: ${download_link}" | ||||
|     if [ "$valid_legacy_download_link" = true ]; then | ||||
|         say "Legacy named payload URL: $legacy_download_link" | ||||
|         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" | ||||
|     exit 0 | ||||
| fi | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user