Merge pull request #204 from vsafonkin/v-vlsafo/update-installers
Update installers scripts
This commit is contained in:
commit
c65a26fe6d
|
@ -16,15 +16,27 @@
|
||||||
- LTS - most current supported release
|
- LTS - most current supported release
|
||||||
- 2-part version in a format A.B - represents a specific release
|
- 2-part version in a format A.B - represents a specific release
|
||||||
examples: 2.0, 1.0
|
examples: 2.0, 1.0
|
||||||
- Branch name
|
- 3-part version in a format A.B.Cxx - represents a specific SDK release
|
||||||
examples: release/2.0.0, Master
|
examples: 5.0.1xx, 5.0.2xx
|
||||||
Note: The version parameter overrides the channel parameter.
|
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
|
.PARAMETER Version
|
||||||
Default: latest
|
Default: latest
|
||||||
Represents a build version on specific channel. Possible values:
|
Represents a build version on specific channel. Possible values:
|
||||||
- latest - most latest build on specific channel
|
- latest - most latest build on specific channel
|
||||||
- 3-part version in a format A.B.C - represents specific version of build
|
- 3-part version in a format A.B.C - represents specific version of build
|
||||||
examples: 2.0.0-preview2-006120, 1.1.0
|
examples: 2.0.0-preview2-006120, 1.1.0
|
||||||
|
.PARAMETER Internal
|
||||||
|
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
|
.PARAMETER InstallDir
|
||||||
Default: %LocalAppData%\Microsoft\dotnet
|
Default: %LocalAppData%\Microsoft\dotnet
|
||||||
Path to where to install dotnet. Note that binaries will be placed directly in a given directory.
|
Path to where to install dotnet. Note that binaries will be placed directly in a given directory.
|
||||||
|
@ -59,9 +71,6 @@
|
||||||
.PARAMETER UncachedFeed
|
.PARAMETER UncachedFeed
|
||||||
This parameter typically is not changed by the user.
|
This parameter typically is not changed by the user.
|
||||||
It allows changing the URL for the Uncached feed used by this installer.
|
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
|
.PARAMETER ProxyAddress
|
||||||
If set, the installer will use the proxy when making web requests
|
If set, the installer will use the proxy when making web requests
|
||||||
.PARAMETER ProxyUseDefaultCredentials
|
.PARAMETER ProxyUseDefaultCredentials
|
||||||
|
@ -81,11 +90,12 @@
|
||||||
[cmdletbinding()]
|
[cmdletbinding()]
|
||||||
param(
|
param(
|
||||||
[string]$Channel="LTS",
|
[string]$Channel="LTS",
|
||||||
|
[string]$Quality,
|
||||||
[string]$Version="Latest",
|
[string]$Version="Latest",
|
||||||
|
[switch]$Internal,
|
||||||
[string]$JSonFile,
|
[string]$JSonFile,
|
||||||
[string]$InstallDir="<auto>",
|
[string]$InstallDir="<auto>",
|
||||||
[string]$Architecture="<auto>",
|
[string]$Architecture="<auto>",
|
||||||
[ValidateSet("dotnet", "aspnetcore", "windowsdesktop", IgnoreCase = $false)]
|
|
||||||
[string]$Runtime,
|
[string]$Runtime,
|
||||||
[Obsolete("This parameter may be removed in a future version of this script. The recommended alternative is '-Runtime dotnet'.")]
|
[Obsolete("This parameter may be removed in a future version of this script. The recommended alternative is '-Runtime dotnet'.")]
|
||||||
[switch]$SharedRuntime,
|
[switch]$SharedRuntime,
|
||||||
|
@ -205,7 +215,7 @@ function Get-Machine-Architecture() {
|
||||||
function Get-CLIArchitecture-From-Architecture([string]$Architecture) {
|
function Get-CLIArchitecture-From-Architecture([string]$Architecture) {
|
||||||
Say-Invocation $MyInvocation
|
Say-Invocation $MyInvocation
|
||||||
|
|
||||||
switch ($Architecture.ToLower()) {
|
switch ($Architecture.ToLowerInvariant()) {
|
||||||
{ $_ -eq "<auto>" } { return Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture) }
|
{ $_ -eq "<auto>" } { return Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture) }
|
||||||
{ ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" }
|
{ ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" }
|
||||||
{ $_ -eq "x86" } { return "x86" }
|
{ $_ -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:
|
# The version text returned from the feeds is a 1-line or 2-line string:
|
||||||
# For the SDK and the dotnet runtime (2 lines):
|
# For the SDK and the dotnet runtime (2 lines):
|
||||||
# Line 1: # commit_hash
|
# 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(
|
Invoke-With-Retry(
|
||||||
{
|
{
|
||||||
|
@ -270,26 +327,42 @@ function GetHTTPResponse([Uri] $Uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$HttpClientHandler = New-Object System.Net.Http.HttpClientHandler
|
||||||
if($ProxyAddress) {
|
if($ProxyAddress) {
|
||||||
$HttpClientHandler = New-Object System.Net.Http.HttpClientHandler
|
|
||||||
$HttpClientHandler.Proxy = New-Object System.Net.WebProxy -Property @{
|
$HttpClientHandler.Proxy = New-Object System.Net.WebProxy -Property @{
|
||||||
Address=$ProxyAddress;
|
Address=$ProxyAddress;
|
||||||
UseDefaultCredentials=$ProxyUseDefaultCredentials;
|
UseDefaultCredentials=$ProxyUseDefaultCredentials;
|
||||||
BypassList = $ProxyBypassList;
|
BypassList = $ProxyBypassList;
|
||||||
}
|
}
|
||||||
$HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler
|
}
|
||||||
|
if ($DisableRedirect)
|
||||||
|
{
|
||||||
|
$HttpClientHandler.AllowAutoRedirect = $false
|
||||||
}
|
}
|
||||||
else {
|
$HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler
|
||||||
|
|
||||||
$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
|
# 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.
|
# 20 minutes allows it to work over much slower connections.
|
||||||
$HttpClient.Timeout = New-TimeSpan -Minutes 20
|
$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();
|
$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.
|
# The feed credential is potentially sensitive info. Do not log FeedCredential to console output.
|
||||||
$DownloadException = [System.Exception] "Unable to download $Uri."
|
$DownloadException = [System.Exception] "Unable to download $Uri."
|
||||||
|
|
||||||
|
@ -349,6 +422,9 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel) {
|
||||||
else {
|
else {
|
||||||
throw "Invalid value for `$Runtime"
|
throw "Invalid value for `$Runtime"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Say-Verbose "Constructed latest.version URL: $VersionFileUrl"
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$Response = GetHTTPResponse -Uri $VersionFileUrl
|
$Response = GetHTTPResponse -Uri $VersionFileUrl
|
||||||
}
|
}
|
||||||
|
@ -411,7 +487,7 @@ function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel,
|
||||||
Say-Invocation $MyInvocation
|
Say-Invocation $MyInvocation
|
||||||
|
|
||||||
if (-not $JSonFile) {
|
if (-not $JSonFile) {
|
||||||
if ($Version.ToLower() -eq "latest") {
|
if ($Version.ToLowerInvariant() -eq "latest") {
|
||||||
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel
|
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel
|
||||||
return $LatestVersionInfo.Version
|
return $LatestVersionInfo.Version
|
||||||
}
|
}
|
||||||
|
@ -478,58 +554,116 @@ function Get-LegacyDownload-Link([string]$AzureFeed, [string]$SpecificVersion, [
|
||||||
return $PayloadURL
|
return $PayloadURL
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion) {
|
function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion, [string]$PackageDownloadLink) {
|
||||||
Say-Invocation $MyInvocation
|
Say-Invocation $MyInvocation
|
||||||
|
|
||||||
if ($Runtime -eq "dotnet") {
|
# Try to get the version number, using the productVersion.txt file located next to the installer file.
|
||||||
$ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/productVersion.txt"
|
$ProductVersionTxtURLs = (Get-Product-Version-Url $AzureFeed $SpecificVersion $PackageDownloadLink -Flattened $true),
|
||||||
}
|
(Get-Product-Version-Url $AzureFeed $SpecificVersion $PackageDownloadLink -Flattened $false)
|
||||||
elseif ($Runtime -eq "aspnetcore") {
|
|
||||||
$ProductVersionTxtURL = "$AzureFeed/aspnetcore/Runtime/$SpecificVersion/productVersion.txt"
|
Foreach ($ProductVersionTxtURL in $ProductVersionTxtURLs) {
|
||||||
}
|
Say-Verbose "Checking for the existence of $ProductVersionTxtURL"
|
||||||
elseif ($Runtime -eq "windowsdesktop") {
|
|
||||||
# The windows desktop runtime is part of the core runtime layout prior to 5.0
|
try {
|
||||||
$ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/productVersion.txt"
|
$productVersionResponse = GetHTTPResponse($productVersionTxtUrl)
|
||||||
if ($SpecificVersion -match '^(\d+)\.(.*)')
|
|
||||||
{
|
if ($productVersionResponse.StatusCode -eq 200) {
|
||||||
$majorVersion = [int]$Matches[1]
|
$productVersion = $productVersionResponse.Content.ReadAsStringAsync().Result.Trim()
|
||||||
if ($majorVersion -ge 5)
|
if ($productVersion -ne $SpecificVersion)
|
||||||
{
|
{
|
||||||
$ProductVersionTxtURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/productVersion.txt"
|
Say "Using alternate version $productVersion found in $ProductVersionTxtURL"
|
||||||
|
}
|
||||||
|
return $productVersion
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
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)'. )"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif (-not $Runtime) {
|
|
||||||
$ProductVersionTxtURL = "$AzureFeed/Sdk/$SpecificVersion/productVersion.txt"
|
# Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number.
|
||||||
}
|
if ([string]::IsNullOrEmpty($PackageDownloadLink))
|
||||||
else {
|
{
|
||||||
throw "Invalid value '$Runtime' specified for `$Runtime"
|
Say-Verbose "Using the default value '$SpecificVersion' as the product version."
|
||||||
|
return $SpecificVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
Say-Verbose "Checking for existence of $ProductVersionTxtURL"
|
$productVersion = Get-ProductVersionFromDownloadLink $PackageDownloadLink $SpecificVersion
|
||||||
|
return $productVersion
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
function Get-Product-Version-Url([string]$AzureFeed, [string]$SpecificVersion, [string]$PackageDownloadLink, [bool]$Flattened) {
|
||||||
$productVersionResponse = GetHTTPResponse($productVersionTxtUrl)
|
Say-Invocation $MyInvocation
|
||||||
|
|
||||||
if ($productVersionResponse.StatusCode -eq 200) {
|
$majorVersion=$null
|
||||||
$productVersion = $productVersionResponse.Content.ReadAsStringAsync().Result.Trim()
|
if ($SpecificVersion -match '^(\d+)\.(.*)') {
|
||||||
if ($productVersion -ne $SpecificVersion)
|
$majorVersion = $Matches[1] -as[int]
|
||||||
{
|
}
|
||||||
Say "Using alternate version $productVersion found in $ProductVersionTxtURL"
|
|
||||||
}
|
|
||||||
|
|
||||||
return $productVersion
|
$pvFileName='productVersion.txt'
|
||||||
|
if($Flattened) {
|
||||||
|
if(-not $Runtime) {
|
||||||
|
$pvFileName='sdk-productVersion.txt'
|
||||||
|
}
|
||||||
|
elseif($Runtime -eq "dotnet") {
|
||||||
|
$pvFileName='runtime-productVersion.txt'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Say-Verbose "Got StatusCode $($productVersionResponse.StatusCode) trying to get productVersion.txt at $productVersionTxtUrl, so using default value of $SpecificVersion"
|
$pvFileName="$Runtime-productVersion.txt"
|
||||||
$productVersion = $SpecificVersion
|
|
||||||
}
|
}
|
||||||
} catch {
|
|
||||||
Say-Verbose "Could not read productVersion.txt at $productVersionTxtUrl, so using default value of $SpecificVersion (Exception: '$($_.Exception.Message)' )"
|
|
||||||
$productVersion = $SpecificVersion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $productVersion
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-User-Share-Path() {
|
function Get-User-Share-Path() {
|
||||||
|
@ -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 "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 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 "- 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"
|
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
|
$CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture
|
||||||
$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version -JSonFile $JSonFile
|
$NormalizedQuality = Get-NormalizedQuality $Quality
|
||||||
$DownloadLink, $EffectiveVersion = Get-Download-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
|
Say-Verbose "Normalized quality: '$NormalizedQuality'"
|
||||||
$LegacyDownloadLink = Get-LegacyDownload-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
|
$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
|
$InstallRoot = Resolve-Installation-Path $InstallDir
|
||||||
Say-Verbose "InstallRoot: $InstallRoot"
|
Say-Verbose "InstallRoot: $InstallRoot"
|
||||||
|
@ -718,9 +987,9 @@ $ScriptName = $MyInvocation.MyCommand.Name
|
||||||
|
|
||||||
if ($DryRun) {
|
if ($DryRun) {
|
||||||
Say "Payload URLs:"
|
Say "Payload URLs:"
|
||||||
Say "Primary named payload URL: $DownloadLink"
|
Say "Primary named payload URL: ${DownloadLink}"
|
||||||
if ($LegacyDownloadLink) {
|
if ($LegacyDownloadLink) {
|
||||||
Say "Legacy named payload URL: $LegacyDownloadLink"
|
Say "Legacy named payload URL: ${LegacyDownloadLink}"
|
||||||
}
|
}
|
||||||
$RepeatableCommand = ".\$ScriptName -Version `"$SpecificVersion`" -InstallDir `"$InstallRoot`" -Architecture `"$CLIArchitecture`""
|
$RepeatableCommand = ".\$ScriptName -Version `"$SpecificVersion`" -InstallDir `"$InstallRoot`" -Architecture `"$CLIArchitecture`""
|
||||||
if ($Runtime -eq "dotnet") {
|
if ($Runtime -eq "dotnet") {
|
||||||
|
@ -729,11 +998,20 @@ if ($DryRun) {
|
||||||
elseif ($Runtime -eq "aspnetcore") {
|
elseif ($Runtime -eq "aspnetcore") {
|
||||||
$RepeatableCommand+=" -Runtime `"aspnetcore`""
|
$RepeatableCommand+=" -Runtime `"aspnetcore`""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (-not [string]::IsNullOrEmpty($NormalizedQuality))
|
||||||
|
{
|
||||||
|
$RepeatableCommand+=" -Quality `"$NormalizedQuality`""
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($key in $MyInvocation.BoundParameters.Keys) {
|
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])`""
|
$RepeatableCommand+=" -$key `"$($MyInvocation.BoundParameters[$key])`""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ($MyInvocation.BoundParameters.Keys -contains "FeedCredential") {
|
||||||
|
$RepeatableCommand+=" -FeedCredential `"<feedCredential>`""
|
||||||
|
}
|
||||||
Say "Repeatable invocation: $RepeatableCommand"
|
Say "Repeatable invocation: $RepeatableCommand"
|
||||||
if ($SpecificVersion -ne $EffectiveVersion)
|
if ($SpecificVersion -ne $EffectiveVersion)
|
||||||
{
|
{
|
||||||
|
@ -779,9 +1057,16 @@ if ($isAssetInstalled) {
|
||||||
|
|
||||||
New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
|
New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
|
||||||
|
|
||||||
$installDrive = $((Get-Item $InstallRoot).PSDrive.Name);
|
$installDrive = $((Get-Item $InstallRoot -Force).PSDrive.Name);
|
||||||
$diskInfo = Get-PSDrive -Name $installDrive
|
$diskInfo = $null
|
||||||
if ($diskInfo.Free / 1MB -le 100) {
|
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}:"
|
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 "To check the list of dependencies, go to https://docs.microsoft.com/dotnet/core/install/windows#dependencies"
|
||||||
Say "Installation finished"
|
Say "Installation finished"
|
||||||
# SIG # Begin signature block
|
# SIG # Begin signature block
|
||||||
# MIIjjwYJKoZIhvcNAQcCoIIjgDCCI3wCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
# MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||||
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
||||||
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCNsnhcJvx/hXmM
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAGF/0aIv/nK8pL
|
||||||
# w8KjuvvIMDBFonhg9XJFc1QwfTyH4aCCDYEwggX/MIID56ADAgECAhMzAAABh3IX
|
# ube4cwR/nwps7FSM0D5vjXxuQe3LXaCCDYEwggX/MIID56ADAgECAhMzAAAB32vw
|
||||||
# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
# LpKnSrTQAAAAAAHfMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
||||||
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||||
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
||||||
# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw
|
# bmcgUENBIDIwMTEwHhcNMjAxMjE1MjEzMTQ1WhcNMjExMjAyMjEzMTQ1WjB0MQsw
|
||||||
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
||||||
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
||||||
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||||
# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB
|
# AQC2uxlZEACjqfHkuFyoCwfL25ofI9DZWKt4wEj3JBQ48GPt1UsDv834CcoUUPMn
|
||||||
# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH
|
# s/6CtPoaQ4Thy/kbOOg/zJAnrJeiMQqRe2Lsdb/NSI2gXXX9lad1/yPUDOXo4GNw
|
||||||
# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d
|
# PjXq1JZi+HZV91bUr6ZjzePj1g+bepsqd/HC1XScj0fT3aAxLRykJSzExEBmU9eS
|
||||||
# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ
|
# yuOwUuq+CriudQtWGMdJU650v/KmzfM46Y6lo/MCnnpvz3zEL7PMdUdwqj/nYhGG
|
||||||
# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV
|
# 3UVILxX7tAdMbz7LN+6WOIpT1A41rwaoOVnv+8Ua94HwhjZmu1S73yeV7RZZNxoh
|
||||||
# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
|
# EegJi9YYssXa7UZUUkCCA+KnAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
|
||||||
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw
|
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUOPbML8IdkNGtCfMmVPtvI6VZ8+Mw
|
||||||
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
|
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
|
||||||
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu
|
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDYzMDA5MB8GA1UdIwQYMBaAFEhu
|
||||||
# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
|
# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
|
||||||
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
|
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
|
||||||
# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
|
# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
|
||||||
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
|
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
|
||||||
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy
|
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAnnqH
|
||||||
# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K
|
# tDyYUFaVAkvAK0eqq6nhoL95SZQu3RnpZ7tdQ89QR3++7A+4hrr7V4xxmkB5BObS
|
||||||
# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV
|
# 0YK+MALE02atjwWgPdpYQ68WdLGroJZHkbZdgERG+7tETFl3aKF4KpoSaGOskZXp
|
||||||
# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr
|
# TPnCaMo2PXoAMVMGpsQEQswimZq3IQ3nRQfBlJ0PoMMcN/+Pks8ZTL1BoPYsJpok
|
||||||
# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx
|
# t6cql59q6CypZYIwgyJ892HpttybHKg1ZtQLUlSXccRMlugPgEcNZJagPEgPYni4
|
||||||
# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe
|
# b11snjRAgf0dyQ0zI9aLXqTxWUU5pCIFiPT0b2wsxzRqCtyGqpkGM8P9GazO8eao
|
||||||
# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g
|
# mVItCYBcJSByBx/pS0cSYwBBHAZxJODUqxSXoSGDvmTfqUJXntnWkL4okok1FiCD
|
||||||
# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf
|
# Z4jpyXOQunb6egIXvkgQ7jb2uO26Ow0m8RwleDvhOMrnHsupiOPbozKroSa6paFt
|
||||||
# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI
|
# VSh89abUSooR8QdZciemmoFhcWkEwFg4spzvYNP4nIs193261WyTaRMZoceGun7G
|
||||||
# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5
|
# CT2Rl653uUj+F+g94c63AhzSq4khdL4HlFIP2ePv29smfUnHtGq6yYFDLnT0q/Y+
|
||||||
# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea
|
# Di3jwloF8EWkkHRtSuXlFUbTmwr/lDDgbpZiKhLS7CBTDj32I0L5i532+uHczw82
|
||||||
# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS
|
# oZDmYmYmIUSMbZOgS65h797rj5JJ6OkeEUJoAVwwggd6MIIFYqADAgECAgphDpDS
|
||||||
# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
|
# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
|
||||||
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
|
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
|
||||||
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
|
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
|
||||||
|
@ -977,55 +1262,55 @@ Say "Installation finished"
|
||||||
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
|
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
|
||||||
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
|
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
|
||||||
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
|
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
|
||||||
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZDCCFWACAQEwgZUwfjELMAkG
|
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG
|
||||||
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
|
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
|
||||||
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
|
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
|
||||||
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN
|
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAd9r8C6Sp0q00AAAAAAB3zAN
|
||||||
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
|
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
|
||||||
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgpT/bxWwe
|
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgJROF4V78
|
||||||
# aW0EinKMWCAzDXUjwXkIHldYzR6lw4/1Pc0wQgYKKwYBBAGCNwIBDDE0MDKgFIAS
|
# d/qQulLV5Z+ncgFZgk9r0UoE37o5jTCDpSowQgYKKwYBBAGCNwIBDDE0MDKgFIAS
|
||||||
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
|
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
|
||||||
# BgkqhkiG9w0BAQEFAASCAQCHd7sSQVq0YDg8QDx6/kLWn3s6jtvvIDCCgsO9spHM
|
# BgkqhkiG9w0BAQEFAASCAQB74lkh+M6W7qWNERtX5/xMFrSgaVCptxuBlBl93FN3
|
||||||
# quPd4FPbG67DCsKDClekQs52qrtRO3Zo+JMnCw4j3bS+gZHzeJr2shbftOrpsFoD
|
# aQJiCaToMeDXG3Nsf/GhIFCBz4fReYrMmZg5pmjs+d8s1dgXz2oOWVwx6bhnzdXS
|
||||||
# l7OPcUmtrqul9dkQCOp8t0MP3ls0n96/YyNy6lz4BAlTdkdDx957uAxalKaCIBzb
|
# ce5dMqkUCzvN4QeJxTIhpeXsHwupWVbuqeTo5DdZHouTi4UFzgM0/K+sSbRI/FEe
|
||||||
# R9QyppOKIfNFvwD4EI5KI6tpmSy/uH8SrRg7ZExAYZl6J6R18WkL7KHn649lPoAQ
|
# rS/vxtMbrtMz57kKjB/Z86dKJeDxQydKSapL/YIamfmYx26rjpXJqEs7W+FVRJwK
|
||||||
# ujwrIXH10xOJops45ILGzKWQcHmCzLJGYapL4VHUuK+73nT+9ZROGHdk/PyvIcdw
|
# nNNT0OGt7tdkL6k+7XQtK3f5yUqKMdTlmPyZ73z69tAtJclkIFC3liFVTMAf4MK+
|
||||||
# iERa+C06v305t3DA+CuHFy1tvyw7IFF6RVbLZPwxrJjToYIS7jCCEuoGCisGAQQB
|
# nheQal7OPNth86h4Lek3E19n2hrABTUeW2cLZ2WWEspFoYIS8TCCEu0GCisGAQQB
|
||||||
# gjcDAwExghLaMIIS1gYJKoZIhvcNAQcCoIISxzCCEsMCAQMxDzANBglghkgBZQME
|
# gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME
|
||||||
# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB
|
# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB
|
||||||
# MDEwDQYJYIZIAWUDBAIBBQAEIOCaTmvM1AP0WaEVqzKaaCu/R+bTlR4kCrM/ZXsb
|
# MDEwDQYJYIZIAWUDBAIBBQAEIEIDAx5adVXZRJeNOj9JW7M03Sl8XvjtY9M98TvW
|
||||||
# /eNOAgZgGeLsMwsYEzIwMjEwMjAzMjExNzQ5LjU5MVowBIACAfSggdSkgdEwgc4x
|
# cUwSAgZgieWmNfwYEzIwMjEwNTE5MTcwMDI4LjY0OVowBIACAfSggdSkgdEwgc4x
|
||||||
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
|
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
|
||||||
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p
|
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p
|
||||||
# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg
|
# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg
|
||||||
# VFNTIEVTTjo4OTdBLUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
|
# VFNTIEVTTjpEOURFLUUzOUEtNDNGRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
|
||||||
# U3RhbXAgU2VydmljZaCCDkEwggT1MIID3aADAgECAhMzAAABLCKvRZd1+RvuAAAA
|
# U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABYfWiM16gKiRpAAAA
|
||||||
# AAEsMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
|
# AAFhMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
|
||||||
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
|
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
|
||||||
# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
|
# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
|
||||||
# MB4XDTE5MTIxOTAxMTUwM1oXDTIxMDMxNzAxMTUwM1owgc4xCzAJBgNVBAYTAlVT
|
# MB4XDTIxMDExNDE5MDIyMVoXDTIyMDQxMTE5MDIyMVowgc4xCzAJBgNVBAYTAlVT
|
||||||
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
|
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
|
||||||
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy
|
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy
|
||||||
# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4OTdB
|
# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpEOURF
|
||||||
# LUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj
|
# LUUzOUEtNDNGRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj
|
||||||
# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPK1zgSSq+MxAYo3qpCt
|
# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJeInahBrU//GzTqhxUy
|
||||||
# QDxSMPPJy6mm/wfEJNjNUnYtLFBwl1BUS5trEk/t41ldxITKehs+ABxYqo4Qxsg3
|
# AC8UXct6UJCkb2xEZKV3gjggmLAheBrxJk7tH+Pw2tTcyarLRfmV2xo5oBk5pW/O
|
||||||
# Gy1ugKiwHAnYiiekfC+ZhptNFgtnDZIn45zC0AlVr/6UfLtsLcHCh1XElLUHfEC0
|
# cDc/n/TcTeQU6JIN5PlTcn0C9RlKQ6t9OuU/WAyAxGTjKE4ENnUjXtxiNlD/K2ZG
|
||||||
# nBuQcM/SpYo9e3l1qY5NdMgDGxCsmCKdiZfYXIu+U0UYIBhdzmSHnB3fxZOBVcr5
|
# MLvjpROBKh7TtkUJK6ZGWw/uTRabNBxRg13TvjkGHXEUEDJ8imacw9BCeR9L6und
|
||||||
# htFHEBBNt/rFJlm/A4yb8oBsp+Uf0p5QwmO/bCcdqB15JpylOhZmWs0sUfJKlK9E
|
# r32tj4duOFIHD8m1es3SNN98Zq4IDBP3Ccb+HQgxpbeHIUlK0y6zmzIkvfN73Zxw
|
||||||
# rAhBwGki2eIRFKsQBdkXS9PWpF1w2gIJRvSkDEaCf+lbGTPdSzHSbfREWOF9wY3i
|
# fGvFv0/Max79WJY0cD8poCnZFijciWrf0eD1T2/+7HgewzrdxPdSFockUQ8QovID
|
||||||
# Yj8CAwEAAaOCARswggEXMB0GA1UdDgQWBBRRahZSGfrCQhCyIyGH9DkiaW7L0zAf
|
# IYkCAwEAAaOCARswggEXMB0GA1UdDgQWBBRWHpqd1hv71SVj5LAdPfNE7PhLLzAf
|
||||||
# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH
|
# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH
|
||||||
# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU
|
# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU
|
||||||
# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF
|
# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF
|
||||||
# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0
|
# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0
|
||||||
# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG
|
# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG
|
||||||
# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBPFxHIwi4vAH49w9Svmz6K3tM55RlW
|
# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQAQTA9bqVBmx5TTMhzj+Q8zWkPQXgCc
|
||||||
# 5pPeULXdut2Rqy6Ys0+VpZsbuaEoxs6Z1C3hMbkiqZFxxyltxJpuHTyGTg61zfNI
|
# SQiqy2YYWF0hWr5GEiN2LtA+EWdu1y8oysZau4CP7SzM8VTSq31CLJiOy39Z4RvE
|
||||||
# F5n6RsYF3s7IElDXNfZznF1/2iWc6uRPZK8rxxUJ/7emYXZCYwuUY0XjsCpP9pbR
|
# q2mr0EftFvmX2CxQ7ZyzrkhWMZaZQLkYbH5oabIFwndW34nh980BOY395tfnNS/Y
|
||||||
# RKeJi6r5arSyI+NfKxvgoM21JNt1BcdlXuAecdd/k8UjxCscffanoK2n6LFw1PcZ
|
# 6N0f+jXdoFn7fI2c43TFYsUqIPWjOHJloMektlD6/uS6Zn4xse/lItFm+fWOcB2A
|
||||||
# lEO7NId7o+soM2C0QY5BYdghpn7uqopB6ixyFIIkDXFub+1E7GmAEwfU6VwEHL7y
|
# xyXEB3ZREeSg9j7+GoEl1xT/iJuV/So7TlWdwyacQu4lv3MBsvxzRIbKhZwrDYog
|
||||||
# 9rNE8bd+JrQs+yAtkkHy9FmXg/PsGq1daVzX1So7CJ6nyphpuHSN3VfTMIIGcTCC
|
# moyJ+rwgQB8mKS4/M1SDRtIptamoTFJ56Tk6DuUXx1JudToelgjEZPa5MIIGcTCC
|
||||||
# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC
|
# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC
|
||||||
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
|
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
|
||||||
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv
|
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv
|
||||||
|
@ -1060,36 +1345,36 @@ Say "Installation finished"
|
||||||
# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a
|
# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a
|
||||||
# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ
|
# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ
|
||||||
# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+
|
# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+
|
||||||
# NR4Iuto229Nfj950iEkSoYICzzCCAjgCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT
|
# NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT
|
||||||
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
|
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
|
||||||
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP
|
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP
|
||||||
# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4
|
# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpE
|
||||||
# OTdBLUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
|
# OURFLUUzOUEtNDNGRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
|
||||||
# dmljZaIjCgEBMAcGBSsOAwIaAxUADE5OKSMoNx/mYxYWap1RTOohbJ2ggYMwgYCk
|
# dmljZaIjCgEBMAcGBSsOAwIaAxUAFW5ShAw5ekTEXvL/4V1s0rbDz3mggYMwgYCk
|
||||||
# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
|
# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
|
||||||
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
|
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
|
||||||
# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF
|
# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF
|
||||||
# AOPFChkwIhgPMjAyMTAyMDMxNTQwMDlaGA8yMDIxMDIwNDE1NDAwOVowdDA6Bgor
|
# AORPamMwIhgPMjAyMTA1MTkxNDQzNDdaGA8yMDIxMDUyMDE0NDM0N1owdzA9Bgor
|
||||||
# BgEEAYRZCgQBMSwwKjAKAgUA48UKGQIBADAHAgEAAgIXmDAHAgEAAgIRyTAKAgUA
|
# BgEEAYRZCgQBMS8wLTAKAgUA5E9qYwIBADAKAgEAAgIYCAIB/zAHAgEAAgIRJjAK
|
||||||
# 48ZbmQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID
|
# AgUA5FC74wIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB
|
||||||
# B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAHeeznL2n6HWCjHH94Fl
|
# AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAEP3zVlXXAn4O1Ms
|
||||||
# hcdW6TEXzq4XNgp1Gx1W9F8gJ4x+SwoV7elJZkwgGffcpHomLvIY/VSuzsl1NgtJ
|
# 68s11f0LWnsKutmWLnJls7YN9alFuA+jJcq/S8x2VoJAWAZTdWtdT5N7Gf/BeTAe
|
||||||
# TWM2UxoqSv58BBOrl4eGhH6kkg8Ucy2tdeK5T8cHa8pMkq2j9pFd2mRG/6VMk0dl
|
# 8D0krUvAYkKN9sIFxBsV9Zum88+HNP6X3yn+CD+ZzOlhtqvgG+fuuRXPutLZfLc/
|
||||||
# Xz7Uy3Z6bZqkcABMyAfuAaGbMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMx
|
# BMw0pVKop8ty4t9o1C5cghIH1n8uMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC
|
||||||
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
|
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
|
||||||
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt
|
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp
|
||||||
# U3RhbXAgUENBIDIwMTACEzMAAAEsIq9Fl3X5G+4AAAAAASwwDQYJYIZIAWUDBAIB
|
# bWUtU3RhbXAgUENBIDIwMTACEzMAAAFh9aIzXqAqJGkAAAAAAWEwDQYJYIZIAWUD
|
||||||
# BQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx
|
# BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B
|
||||||
# IgQg/QYv7yp+354WTjWUIsXWndTEzXjaYjqwYjcBxCJKjdUwgfoGCyqGSIb3DQEJ
|
# CQQxIgQgYzAzV5OthXnPmIpD3kPIVmwz+sGvwSbjTEW5rOqHhyUwgfoGCyqGSIb3
|
||||||
# EAIvMYHqMIHnMIHkMIG9BCBbn/0uFFh42hTM5XOoKdXevBaiSxmYK9Ilcn9nu5ZH
|
# DQEJEAIvMYHqMIHnMIHkMIG9BCBhz4un6mkSLd/zA+0N5YLDGp4vW/VBtNW/lpmh
|
||||||
# 4TCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
|
# tAk4bzCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
|
||||||
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
|
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
|
||||||
# JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABLCKv
|
# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB
|
||||||
# RZd1+RvuAAAAAAEsMCIEIIfIM3YbzHswb/Kj/qq1l1cHA6QBl+gEXYanUNJomrpT
|
# YfWiM16gKiRpAAAAAAFhMCIEIArbvJb5j55rDAQa7Rx5K7mjnxUY6RgiRY1AROOp
|
||||||
# MA0GCSqGSIb3DQEBCwUABIIBAAwdcXssUZGO7ho5+NHLjIxLtQk543aKGo+lrRMY
|
# m2rLMA0GCSqGSIb3DQEBCwUABIIBAFS544uO7FOimzTwMDkFNhMT7GmZBc9L2wDF
|
||||||
# Q9abE1h/AaaNJl0iGxX4IihNWyfovSfYL3L4eODUBAu68tWSxeceRfWNsb/ZZfUi
|
# EjcDlHvcdELdWpqa8Au6rCdhW6618btwdFqR7fkNMH7F0TrY1ktOae5fZUaybIRV
|
||||||
# v89hpLssI/Gf1BEgNMA4zCuIGQiC8okusVumEpAhhvCEbSiTTTtBdolTnU/CAKui
|
# EMWAAqXLkVyePlssQamjt1+BYvxzYFh3T5JBr2R/rzaGJIck49r1cEsLBV0JaSQT
|
||||||
# oxaU3R9XkKh1F4oAM26+dJ1J2BLQXPs5afNvvedDsZWNQUPK1sFF3JRfzxiTrwBW
|
# QKiOsR+QEbSCNWXQaq/koJrKR5Ugro0y4SmSejnOj5+1/4PlTolFoJAM4pIiT2A1
|
||||||
# EJRyflev9gyDoqCHzippgb+6+eti1WTkcA9Q49GIT11S6LOAVqkSC9N7Nqf8ksh8
|
# uMs5f219BvkwyRmF32z9EpYQvBdoGpT65DQDuZQ5F6wV1Ph4H7yOzarcdnwPohT+
|
||||||
# ARdwT8jigpsm+mj7lrVU9upDkhVYhKeO8oiZq95Q53Zkteo=
|
# BeH2jrcR3BMAxC3umgRUmTxnzPsoq9FJuRTyHCNygGn+VMImNfk=
|
||||||
# SIG # End signature block
|
# SIG # End signature block
|
||||||
|
|
|
@ -24,7 +24,7 @@ exec 3>&1
|
||||||
# See if stdout is a terminal
|
# See if stdout is a terminal
|
||||||
if [ -t 1 ] && command -v tput > /dev/null; then
|
if [ -t 1 ] && command -v tput > /dev/null; then
|
||||||
# see if it supports colors
|
# see if it supports colors
|
||||||
ncolors=$(tput colors)
|
ncolors=$(tput colors || echo 0)
|
||||||
if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
|
if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
|
||||||
bold="$(tput bold || echo)"
|
bold="$(tput bold || echo)"
|
||||||
normal="$(tput sgr0 || echo)"
|
normal="$(tput sgr0 || echo)"
|
||||||
|
@ -368,6 +368,75 @@ get_normalized_os() {
|
||||||
return 0
|
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:
|
# The version text returned from the feeds is a 1-line or 2-line string:
|
||||||
# For the SDK and the dotnet runtime (2 lines):
|
# For the SDK and the dotnet runtime (2 lines):
|
||||||
# Line 1: # commit_hash
|
# Line 1: # commit_hash
|
||||||
|
@ -541,43 +610,131 @@ construct_download_link() {
|
||||||
# args:
|
# args:
|
||||||
# azure_feed - $1
|
# azure_feed - $1
|
||||||
# specific_version - $2
|
# specific_version - $2
|
||||||
|
# download link - $3 (optional)
|
||||||
get_specific_product_version() {
|
get_specific_product_version() {
|
||||||
# If we find a 'productVersion.txt' at the root of any folder, we'll use its contents
|
# 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.
|
# 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
|
eval $invocation
|
||||||
|
|
||||||
local azure_feed="$1"
|
local azure_feed="$1"
|
||||||
local specific_version="${2//[$'\t\r\n']}"
|
local specific_version="${2//[$'\t\r\n']}"
|
||||||
local specific_product_version=$specific_version
|
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}${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}${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
|
local download_link=null
|
||||||
if [[ "$runtime" == "dotnet" ]]; then
|
|
||||||
download_link="$azure_feed/Runtime/$specific_version/productVersion.txt${feed_credential}"
|
if [ -z "$package_download_link" ]; then
|
||||||
elif [[ "$runtime" == "aspnetcore" ]]; then
|
if [[ "$runtime" == "dotnet" ]]; then
|
||||||
download_link="$azure_feed/aspnetcore/Runtime/$specific_version/productVersion.txt${feed_credential}"
|
download_link="$azure_feed/Runtime/$specific_version/${pvFileName}"
|
||||||
elif [ -z "$runtime" ]; then
|
elif [[ "$runtime" == "aspnetcore" ]]; then
|
||||||
download_link="$azure_feed/Sdk/$specific_version/productVersion.txt${feed_credential}"
|
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
|
else
|
||||||
return 1
|
download_link="${package_download_link%/*}/${pvFileName}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if machine_has "curl"
|
say_verbose "Constructed productVersion link: $download_link"
|
||||||
then
|
echo "$download_link"
|
||||||
specific_product_version=$(curl -s --fail "$download_link")
|
return 0
|
||||||
if [ $? -ne 0 ]
|
}
|
||||||
then
|
|
||||||
specific_product_version=$specific_version
|
|
||||||
fi
|
|
||||||
elif machine_has "wget"
|
|
||||||
then
|
|
||||||
specific_product_version=$(wget -qO- "$download_link")
|
|
||||||
if [ $? -ne 0 ]
|
|
||||||
then
|
|
||||||
specific_product_version=$specific_version
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
specific_product_version="${specific_product_version//[$'\t\r\n']}"
|
|
||||||
|
|
||||||
|
# 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
|
||||||
|
unset IFS;
|
||||||
echo "$specific_product_version"
|
echo "$specific_product_version"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -711,19 +868,62 @@ extract_dotnet_package() {
|
||||||
return 0
|
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() {
|
get_http_header_curl() {
|
||||||
eval $invocation
|
eval $invocation
|
||||||
local remote_path="$1"
|
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_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" || return 1
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# args:
|
||||||
|
# remote_path - $1
|
||||||
|
# disable_feed_credential - $2
|
||||||
get_http_header_wget() {
|
get_http_header_wget() {
|
||||||
eval $invocation
|
eval $invocation
|
||||||
local remote_path="$1"
|
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_options="-q -S --spider --tries 5 --waitretry 2 --connect-timeout 15 "
|
||||||
wget $wget_options "$remote_path_with_credential" 2>&1 || return 1
|
wget $wget_options "$remote_path_with_credential" 2>&1 || return 1
|
||||||
return 0
|
return 0
|
||||||
|
@ -763,7 +963,7 @@ download() {
|
||||||
|
|
||||||
say "Download attempt #$attempts has failed: $http_code $download_error_msg"
|
say "Download attempt #$attempts has failed: $http_code $download_error_msg"
|
||||||
say "Attempt #$((attempts+1)) will start in $((attempts*10)) seconds."
|
say "Attempt #$((attempts+1)) will start in $((attempts*10)) seconds."
|
||||||
sleep $((attempts*20))
|
sleep $((attempts*10))
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
|
@ -783,6 +983,7 @@ downloadcurl() {
|
||||||
local remote_path="$1"
|
local remote_path="$1"
|
||||||
local out_path="${2:-}"
|
local out_path="${2:-}"
|
||||||
# Append feed_credential as late as possible before calling curl to avoid logging feed_credential
|
# 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 remote_path_with_credential="${remote_path}${feed_credential}"
|
||||||
local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs "
|
local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs "
|
||||||
local failed=false
|
local failed=false
|
||||||
|
@ -792,7 +993,8 @@ downloadcurl() {
|
||||||
curl $curl_options -o "$out_path" "$remote_path_with_credential" || failed=true
|
curl $curl_options -o "$out_path" "$remote_path_with_credential" || failed=true
|
||||||
fi
|
fi
|
||||||
if [ "$failed" = true ]; then
|
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 )
|
http_code=$( echo "$response" | awk '/^HTTP/{print $2}' | tail -1 )
|
||||||
download_error_msg="Unable to download $remote_path."
|
download_error_msg="Unable to download $remote_path."
|
||||||
if [[ $http_code != 2* ]]; then
|
if [[ $http_code != 2* ]]; then
|
||||||
|
@ -822,7 +1024,8 @@ downloadwget() {
|
||||||
wget $wget_options -O "$out_path" "$remote_path_with_credential" || failed=true
|
wget $wget_options -O "$out_path" "$remote_path_with_credential" || failed=true
|
||||||
fi
|
fi
|
||||||
if [ "$failed" = true ]; then
|
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 )
|
http_code=$( echo "$response" | awk '/^ HTTP/{print $2}' | tail -1 )
|
||||||
download_error_msg="Unable to download $remote_path."
|
download_error_msg="Unable to download $remote_path."
|
||||||
if [[ $http_code != 2* ]]; then
|
if [[ $http_code != 2* ]]; then
|
||||||
|
@ -834,15 +1037,115 @@ downloadwget() {
|
||||||
return 0
|
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() {
|
calculate_vars() {
|
||||||
eval $invocation
|
eval $invocation
|
||||||
valid_legacy_download_link=true
|
valid_legacy_download_link=true
|
||||||
|
|
||||||
|
#normalize input variables
|
||||||
normalized_architecture="$(get_normalized_architecture_from_architecture "$architecture")"
|
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")"
|
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_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")"
|
specific_product_version="$(get_specific_product_version "$azure_feed" "$specific_version")"
|
||||||
|
@ -1011,6 +1314,8 @@ feed_credential=""
|
||||||
verbose=false
|
verbose=false
|
||||||
runtime=""
|
runtime=""
|
||||||
runtime_id=""
|
runtime_id=""
|
||||||
|
quality=""
|
||||||
|
internal=false
|
||||||
override_non_versioned_files=true
|
override_non_versioned_files=true
|
||||||
non_dynamic_parameters=""
|
non_dynamic_parameters=""
|
||||||
user_defined_os=""
|
user_defined_os=""
|
||||||
|
@ -1027,6 +1332,14 @@ do
|
||||||
shift
|
shift
|
||||||
version="$1"
|
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)
|
-i|--install-dir|-[Ii]nstall[Dd]ir)
|
||||||
shift
|
shift
|
||||||
install_dir="$1"
|
install_dir="$1"
|
||||||
|
@ -1084,7 +1397,9 @@ do
|
||||||
--feed-credential|-[Ff]eed[Cc]redential)
|
--feed-credential|-[Ff]eed[Cc]redential)
|
||||||
shift
|
shift
|
||||||
feed_credential="$1"
|
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)
|
--runtime-id|-[Rr]untime[Ii]d)
|
||||||
shift
|
shift
|
||||||
|
@ -1116,15 +1431,26 @@ do
|
||||||
echo " - LTS - most current supported release"
|
echo " - LTS - most current supported release"
|
||||||
echo " - 2-part version in a format A.B - represents a specific release"
|
echo " - 2-part version in a format A.B - represents a specific release"
|
||||||
echo " examples: 2.0; 1.0"
|
echo " examples: 2.0; 1.0"
|
||||||
echo " - Branch name"
|
echo " - 3-part version in a format A.B.Cxx - represents a specific SDK release"
|
||||||
echo " examples: release/2.0.0; Master"
|
echo " examples: 5.0.1xx, 5.0.2xx."
|
||||||
echo " Note: The version parameter overrides the channel parameter."
|
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 " -v,--version <VERSION> Use specific VERSION, Defaults to \`$version\`."
|
||||||
echo " -Version"
|
echo " -Version"
|
||||||
echo " Possible values:"
|
echo " Possible values:"
|
||||||
echo " - latest - most latest build on specific channel"
|
echo " - latest - most latest build on specific channel"
|
||||||
echo " - 3-part version in a format A.B.C - represents specific version of build"
|
echo " - 3-part version in a format A.B.C - represents specific version of build"
|
||||||
echo " examples: 2.0.0-preview2-006120; 1.1.0"
|
echo " examples: 2.0.0-preview2-006120; 1.1.0"
|
||||||
|
echo " -q,--quality <quality> Download the latest build of specified quality in the channel."
|
||||||
|
echo " -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 " -i,--install-dir <DIR> Install under specified location (see Install Location below)"
|
||||||
echo " -InstallDir"
|
echo " -InstallDir"
|
||||||
echo " --architecture <ARCHITECTURE> Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
|
echo " --architecture <ARCHITECTURE> Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
|
||||||
|
@ -1145,7 +1471,6 @@ do
|
||||||
echo " --verbose,-Verbose Display diagnostics information."
|
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 " --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 " --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 " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable."
|
||||||
echo " -SkipNonVersionedFiles"
|
echo " -SkipNonVersionedFiles"
|
||||||
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
|
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
|
||||||
|
@ -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 "- The SDK installation doesn't need to persist across multiple CI runs."
|
||||||
say "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.\n"
|
say "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
|
check_min_reqs
|
||||||
calculate_vars
|
calculate_vars
|
||||||
script_name=$(basename "$0")
|
script_name=$(basename "$0")
|
||||||
|
|
||||||
if [ "$dry_run" = true ]; then
|
if [ "$dry_run" = true ]; then
|
||||||
say "Payload URLs:"
|
say "Payload URLs:"
|
||||||
say "Primary named payload URL: $download_link"
|
say "Primary named payload URL: ${download_link}"
|
||||||
if [ "$valid_legacy_download_link" = true ]; then
|
if [ "$valid_legacy_download_link" = true ]; then
|
||||||
say "Legacy named payload URL: $legacy_download_link"
|
say "Legacy named payload URL: ${legacy_download_link}"
|
||||||
fi
|
fi
|
||||||
repeatable_command="./$script_name --version "\""$specific_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"" --os "\""$normalized_os"\"""
|
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
|
if [[ "$runtime" == "dotnet" ]]; then
|
||||||
repeatable_command+=" --runtime "\""dotnet"\"""
|
repeatable_command+=" --runtime "\""dotnet"\"""
|
||||||
elif [[ "$runtime" == "aspnetcore" ]]; then
|
elif [[ "$runtime" == "aspnetcore" ]]; then
|
||||||
repeatable_command+=" --runtime "\""aspnetcore"\"""
|
repeatable_command+=" --runtime "\""aspnetcore"\"""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
repeatable_command+="$non_dynamic_parameters"
|
repeatable_command+="$non_dynamic_parameters"
|
||||||
|
|
||||||
|
if [ -n "$feed_credential" ]; then
|
||||||
|
repeatable_command+=" --feed-credential "\""<feed_credential>"\"""
|
||||||
|
fi
|
||||||
|
|
||||||
say "Repeatable invocation: $repeatable_command"
|
say "Repeatable invocation: $repeatable_command"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
@ -1219,4 +1565,4 @@ fi
|
||||||
|
|
||||||
say "Note that the script does not resolve dependencies during installation."
|
say "Note that the script does not resolve dependencies during installation."
|
||||||
say "To check the list of dependencies, go to https://docs.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section."
|
say "To check the list of dependencies, go to https://docs.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section."
|
||||||
say "Installation finished successfully."
|
say "Installation finished successfully."
|
Loading…
Reference in New Issue