Merge pull request #270 from snickler/main

Updated dotnet-install scripts to latest version
This commit is contained in:
Vladimir Safonkin 2022-02-22 16:38:32 +03:00 committed by GitHub
commit 608ee757cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 767 additions and 616 deletions

File diff suppressed because it is too large Load Diff

View File

@ -135,6 +135,31 @@ get_legacy_os_name_from_platform() {
return 1 return 1
} }
get_legacy_os_name() {
eval $invocation
local uname=$(uname)
if [ "$uname" = "Darwin" ]; then
echo "osx"
return 0
elif [ -n "$runtime_id" ]; then
echo $(get_legacy_os_name_from_platform "${runtime_id%-*}" || echo "${runtime_id%-*}")
return 0
else
if [ -e /etc/os-release ]; then
. /etc/os-release
os=$(get_legacy_os_name_from_platform "$ID${VERSION_ID:+.${VERSION_ID}}" || echo "")
if [ -n "$os" ]; then
echo "$os"
return 0
fi
fi
fi
say_verbose "Distribution specific OS name and version could not be detected: UName = $uname"
return 1
}
get_linux_platform_name() { get_linux_platform_name() {
eval $invocation eval $invocation
@ -174,8 +199,8 @@ get_current_os_name() {
echo "freebsd" echo "freebsd"
return 0 return 0
elif [ "$uname" = "Linux" ]; then elif [ "$uname" = "Linux" ]; then
local linux_platform_name local linux_platform_name=""
linux_platform_name="$(get_linux_platform_name)" || { echo "linux" && return 0 ; } linux_platform_name="$(get_linux_platform_name)" || true
if [ "$linux_platform_name" = "rhel.6" ]; then if [ "$linux_platform_name" = "rhel.6" ]; then
echo $linux_platform_name echo $linux_platform_name
@ -196,31 +221,6 @@ get_current_os_name() {
return 1 return 1
} }
get_legacy_os_name() {
eval $invocation
local uname=$(uname)
if [ "$uname" = "Darwin" ]; then
echo "osx"
return 0
elif [ -n "$runtime_id" ]; then
echo $(get_legacy_os_name_from_platform "${runtime_id%-*}" || echo "${runtime_id%-*}")
return 0
else
if [ -e /etc/os-release ]; then
. /etc/os-release
os=$(get_legacy_os_name_from_platform "$ID${VERSION_ID:+.${VERSION_ID}}" || echo "")
if [ -n "$os" ]; then
echo "$os"
return 0
fi
fi
fi
say_verbose "Distribution specific OS name and version could not be detected: UName = $uname"
return 1
}
machine_has() { machine_has() {
eval $invocation eval $invocation
@ -228,7 +228,6 @@ machine_has() {
return $? return $?
} }
check_min_reqs() { check_min_reqs() {
local hasMinimum=false local hasMinimum=false
if machine_has "curl"; then if machine_has "curl"; then
@ -321,11 +320,13 @@ get_normalized_architecture_from_architecture() {
eval $invocation eval $invocation
local architecture="$(to_lowercase "$1")" local architecture="$(to_lowercase "$1")"
case "$architecture" in
\<auto\>) if [[ $architecture == \<auto\> ]]; then
echo "$(get_normalized_architecture_from_architecture "$(get_machine_architecture)")" echo "$(get_machine_architecture)"
return 0 return 0
;; fi
case "$architecture" in
amd64|x64) amd64|x64)
echo "x64" echo "x64"
return 0 return 0
@ -425,6 +426,7 @@ get_normalized_channel() {
get_normalized_product() { get_normalized_product() {
eval $invocation eval $invocation
local product=""
local runtime="$(to_lowercase "$1")" local runtime="$(to_lowercase "$1")"
if [[ "$runtime" == "dotnet" ]]; then if [[ "$runtime" == "dotnet" ]]; then
product="dotnet-runtime" product="dotnet-runtime"
@ -446,7 +448,7 @@ get_normalized_product() {
# args: # args:
# version_text - stdin # version_text - stdin
get_version_from_version_info() { get_version_from_latestversion_file_content() {
eval $invocation eval $invocation
cat | tail -n 1 | sed 's/\r$//' cat | tail -n 1 | sed 's/\r$//'
@ -478,7 +480,7 @@ is_dotnet_package_installed() {
# azure_feed - $1 # azure_feed - $1
# channel - $2 # channel - $2
# normalized_architecture - $3 # normalized_architecture - $3
get_latest_version_info() { get_version_from_latestversion_file() {
eval $invocation eval $invocation
local azure_feed="$1" local azure_feed="$1"
@ -487,24 +489,24 @@ get_latest_version_info() {
local version_file_url=null local version_file_url=null
if [[ "$runtime" == "dotnet" ]]; then if [[ "$runtime" == "dotnet" ]]; then
version_file_url="$uncached_feed/Runtime/$channel/latest.version" version_file_url="$azure_feed/Runtime/$channel/latest.version"
elif [[ "$runtime" == "aspnetcore" ]]; then elif [[ "$runtime" == "aspnetcore" ]]; then
version_file_url="$uncached_feed/aspnetcore/Runtime/$channel/latest.version" version_file_url="$azure_feed/aspnetcore/Runtime/$channel/latest.version"
elif [ -z "$runtime" ]; then elif [ -z "$runtime" ]; then
version_file_url="$uncached_feed/Sdk/$channel/latest.version" version_file_url="$azure_feed/Sdk/$channel/latest.version"
else else
say_err "Invalid value for \$runtime" say_err "Invalid value for \$runtime"
return 1 return 1
fi fi
say_verbose "get_latest_version_info: latest url: $version_file_url" say_verbose "get_version_from_latestversion_file: latest url: $version_file_url"
download "$version_file_url" download "$version_file_url" || return $?
return $? return 0
} }
# args: # args:
# json_file - $1 # json_file - $1
parse_jsonfile_for_version() { parse_globaljson_file_for_version() {
eval $invocation eval $invocation
local json_file="$1" local json_file="$1"
@ -560,9 +562,9 @@ get_specific_version_from_version() {
if [ -z "$json_file" ]; then if [ -z "$json_file" ]; then
if [[ "$version" == "latest" ]]; then if [[ "$version" == "latest" ]]; then
local version_info local version_info
version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1 version_info="$(get_version_from_latestversion_file "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1
say_verbose "get_specific_version_from_version: version_info=$version_info" say_verbose "get_specific_version_from_version: version_info=$version_info"
echo "$version_info" | get_version_from_version_info echo "$version_info" | get_version_from_latestversion_file_content
return 0 return 0
else else
echo "$version" echo "$version"
@ -570,7 +572,7 @@ get_specific_version_from_version() {
fi fi
else else
local version_info local version_info
version_info="$(parse_jsonfile_for_version "$json_file")" || return 1 version_info="$(parse_globaljson_file_for_version "$json_file")" || return 1
echo "$version_info" echo "$version_info"
return 0 return 0
fi fi
@ -635,14 +637,14 @@ get_specific_product_version() {
if machine_has "curl" if machine_has "curl"
then then
specific_product_version=$(curl -s --fail "${download_link}${feed_credential}") specific_product_version=$(curl -s --fail "${download_link}${feed_credential}" 2>&1)
if [ $? = 0 ]; then if [ $? = 0 ]; then
echo "${specific_product_version//[$'\t\r\n']}" echo "${specific_product_version//[$'\t\r\n']}"
return 0 return 0
fi fi
elif machine_has "wget" elif machine_has "wget"
then then
specific_product_version=$(wget -qO- "${download_link}${feed_credential}") specific_product_version=$(wget -qO- "${download_link}${feed_credential}" 2>&1)
if [ $? = 0 ]; then if [ $? = 0 ]; then
echo "${specific_product_version//[$'\t\r\n']}" echo "${specific_product_version//[$'\t\r\n']}"
return 0 return 0
@ -907,7 +909,7 @@ get_http_header_curl() {
fi 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" 2>&1 || return 1
return 0 return 0
} }
@ -918,15 +920,26 @@ get_http_header_wget() {
eval $invocation eval $invocation
local remote_path="$1" local remote_path="$1"
local disable_feed_credential="$2" local disable_feed_credential="$2"
local wget_options="-q -S --spider --tries 5 "
# Store options that aren't supported on all wget implementations separately.
local wget_options_extra="--waitretry 2 --connect-timeout 15 "
local wget_result=''
remote_path_with_credential="$remote_path" remote_path_with_credential="$remote_path"
if [ "$disable_feed_credential" = false ]; then if [ "$disable_feed_credential" = false ]; then
remote_path_with_credential+="$feed_credential" remote_path_with_credential+="$feed_credential"
fi fi
wget_options="-q -S --spider --tries 5 --waitretry 2 --connect-timeout 15 " wget $wget_options $wget_options_extra "$remote_path_with_credential" 2>&1
wget $wget_options "$remote_path_with_credential" 2>&1 || return 1 wget_result=$?
return 0
if [[ $wget_result == 2 ]]; then
# Parsing of the command has failed. Exclude potentially unrecognized options and retry.
wget $wget_options "$remote_path_with_credential" 2>&1
return $?
fi
return $wget_result
} }
# args: # args:
@ -988,9 +1001,9 @@ downloadcurl() {
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
if [ -z "$out_path" ]; then if [ -z "$out_path" ]; then
curl $curl_options "$remote_path_with_credential" || failed=true curl $curl_options "$remote_path_with_credential" 2>&1 || failed=true
else else
curl $curl_options -o "$out_path" "$remote_path_with_credential" || failed=true curl $curl_options -o "$out_path" "$remote_path_with_credential" 2>&1 || failed=true
fi fi
if [ "$failed" = true ]; then if [ "$failed" = true ]; then
local disable_feed_credential=false local disable_feed_credential=false
@ -1016,14 +1029,31 @@ downloadwget() {
local out_path="${2:-}" local out_path="${2:-}"
# Append feed_credential as late as possible before calling wget to avoid logging feed_credential # Append feed_credential as late as possible before calling wget to avoid logging feed_credential
local remote_path_with_credential="${remote_path}${feed_credential}" local remote_path_with_credential="${remote_path}${feed_credential}"
local wget_options="--tries 20 --waitretry 2 --connect-timeout 15 " local wget_options="--tries 20 "
local failed=false # Store options that aren't supported on all wget implementations separately.
local wget_options_extra="--waitretry 2 --connect-timeout 15 "
local wget_result=''
if [ -z "$out_path" ]; then if [ -z "$out_path" ]; then
wget -q $wget_options -O - "$remote_path_with_credential" || failed=true wget -q $wget_options $wget_options_extra -O - "$remote_path_with_credential" 2>&1
wget_result=$?
else else
wget $wget_options -O "$out_path" "$remote_path_with_credential" || failed=true wget $wget_options $wget_options_extra -O "$out_path" "$remote_path_with_credential" 2>&1
wget_result=$?
fi fi
if [ "$failed" = true ]; then
if [[ $wget_result == 2 ]]; then
# Parsing of the command has failed. Exclude potentially unrecognized options and retry.
if [ -z "$out_path" ]; then
wget -q $wget_options -O - "$remote_path_with_credential" 2>&1
wget_result=$?
else
wget $wget_options -O "$out_path" "$remote_path_with_credential" 2>&1
wget_result=$?
fi
fi
if [[ $wget_result != 0 ]]; then
local disable_feed_credential=false local disable_feed_credential=false
local response=$(get_http_header_wget $remote_path $disable_feed_credential) local response=$(get_http_header_wget $remote_path $disable_feed_credential)
http_code=$( echo "$response" | awk '/^ HTTP/{print $2}' | tail -1 ) http_code=$( echo "$response" | awk '/^ HTTP/{print $2}' | tail -1 )
@ -1034,6 +1064,7 @@ downloadwget() {
say_verbose "$download_error_msg" say_verbose "$download_error_msg"
return 1 return 1
fi fi
return 0 return 0
} }
@ -1090,11 +1121,197 @@ get_download_link_from_aka_ms() {
fi fi
} }
get_feeds_to_use()
{
feeds=(
"https://dotnetcli.azureedge.net/dotnet"
"https://dotnetbuilds.azureedge.net/public"
)
if [[ -n "$azure_feed" ]]; then
feeds=("$azure_feed")
fi
if [[ "$no_cdn" == "true" ]]; then
feeds=(
"https://dotnetcli.blob.core.windows.net/dotnet"
"https://dotnetbuilds.blob.core.windows.net/public"
)
if [[ -n "$uncached_feed" ]]; then
feeds=("$uncached_feed")
fi
fi
}
# THIS FUNCTION MAY EXIT (if the determined version is already installed).
generate_download_links() {
download_links=()
specific_versions=()
effective_versions=()
link_types=()
# If generate_akams_links returns false, no fallback to old links. Just terminate.
# This function may also 'exit' (if the determined version is already installed).
generate_akams_links || return
# Check other feeds only if we haven't been able to find an aka.ms link.
if [[ "${#download_links[@]}" -lt 1 ]]; then
for feed in ${feeds[@]}
do
# generate_regular_links may also 'exit' (if the determined version is already installed).
generate_regular_links $feed || return
done
fi
if [[ "${#download_links[@]}" -eq 0 ]]; then
say_err "Failed to resolve the exact version number."
return 1
fi
say_verbose "Generated ${#download_links[@]} links."
for link_index in ${!download_links[@]}
do
say_verbose "Link $link_index: ${link_types[$link_index]}, ${effective_versions[$link_index]}, ${download_links[$link_index]}"
done
}
# THIS FUNCTION MAY EXIT (if the determined version is already installed).
generate_akams_links() {
local valid_aka_ms_link=true;
normalized_version="$(to_lowercase "$version")"
if [[ -n "$json_file" || "$normalized_version" != "latest" ]]; then
# aka.ms links are not needed when exact version is specified via command or json file
return
fi
get_download_link_from_aka_ms || valid_aka_ms_link=false
if [[ "$valid_aka_ms_link" == true ]]; then
say_verbose "Retrieved primary payload URL from aka.ms link: '$aka_ms_download_link'."
say_verbose "Downloading using legacy url will not be attempted."
download_link=$aka_ms_download_link
#get version from the path
IFS='/'
read -ra pathElems <<< "$download_link"
count=${#pathElems[@]}
specific_version="${pathElems[count-2]}"
unset IFS;
say_verbose "Version: '$specific_version'."
#Retrieve effective version
effective_version="$(get_specific_product_version "$azure_feed" "$specific_version" "$download_link")"
# Add link info to arrays
download_links+=($download_link)
specific_versions+=($specific_version)
effective_versions+=($effective_version)
link_types+=("aka.ms")
# Check if the SDK version is already installed.
if [[ "$dry_run" != true ]] && is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then
say "$asset_name with version '$effective_version' is already installed."
exit 0
fi
return 0
fi
# if quality is specified - exit with error - there is no fallback approach
if [ ! -z "$normalized_quality" ]; then
say_err "Failed to locate the latest version in the channel '$normalized_channel' with '$normalized_quality' quality for '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'."
say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support."
return 1
fi
say_verbose "Falling back to latest.version file approach."
}
# THIS FUNCTION MAY EXIT (if the determined version is already installed)
# args:
# feed - $1
generate_regular_links() {
local feed="$1"
local valid_legacy_download_link=true
specific_version=$(get_specific_version_from_version "$feed" "$channel" "$normalized_architecture" "$version" "$json_file") || specific_version='0'
if [[ "$specific_version" == '0' ]]; then
say_verbose "Failed to resolve the specific version number using feed '$feed'"
return
fi
effective_version="$(get_specific_product_version "$feed" "$specific_version")"
say_verbose "specific_version=$specific_version"
download_link="$(construct_download_link "$feed" "$channel" "$normalized_architecture" "$specific_version" "$normalized_os")"
say_verbose "Constructed primary named payload URL: $download_link"
# Add link info to arrays
download_links+=($download_link)
specific_versions+=($specific_version)
effective_versions+=($effective_version)
link_types+=("primary")
legacy_download_link="$(construct_legacy_download_link "$feed" "$channel" "$normalized_architecture" "$specific_version")" || valid_legacy_download_link=false
if [ "$valid_legacy_download_link" = true ]; then
say_verbose "Constructed legacy named payload URL: $legacy_download_link"
download_links+=($legacy_download_link)
specific_versions+=($specific_version)
effective_versions+=($effective_version)
link_types+=("legacy")
else
legacy_download_link=""
say_verbose "Cound not construct a legacy_download_link; omitting..."
fi
# Check if the SDK version is already installed.
if [[ "$dry_run" != true ]] && is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then
say "$asset_name with version '$effective_version' is already installed."
exit 0
fi
}
print_dry_run() {
say "Payload URLs:"
for link_index in "${!download_links[@]}"
do
say "URL #$link_index - ${link_types[$link_index]}: ${download_links[$link_index]}"
done
resolved_version=${specific_versions[0]}
repeatable_command="./$script_name --version "\""$resolved_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"" --os "\""$normalized_os"\"""
if [ ! -z "$normalized_quality" ]; then
repeatable_command+=" --quality "\""$normalized_quality"\"""
fi
if [[ "$runtime" == "dotnet" ]]; then
repeatable_command+=" --runtime "\""dotnet"\"""
elif [[ "$runtime" == "aspnetcore" ]]; then
repeatable_command+=" --runtime "\""aspnetcore"\"""
fi
repeatable_command+="$non_dynamic_parameters"
if [ -n "$feed_credential" ]; then
repeatable_command+=" --feed-credential "\""<feed_credential>"\"""
fi
say "Repeatable invocation: $repeatable_command"
}
calculate_vars() { calculate_vars() {
eval $invocation eval $invocation
valid_legacy_download_link=true
#normalize input variables script_name=$(basename "$0")
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")"
@ -1105,76 +1322,8 @@ calculate_vars() {
say_verbose "Normalized channel: '$normalized_channel'." say_verbose "Normalized channel: '$normalized_channel'."
normalized_product="$(get_normalized_product "$runtime")" normalized_product="$(get_normalized_product "$runtime")"
say_verbose "Normalized product: '$normalized_product'." 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")" install_root="$(resolve_installation_path "$install_dir")"
say_verbose "InstallRoot: '$install_root'." say_verbose "InstallRoot: '$install_root'."
return
fi
fi
specific_version="$(get_specific_version_from_version "$azure_feed" "$channel" "$normalized_architecture" "$version" "$json_file")"
specific_product_version="$(get_specific_product_version "$azure_feed" "$specific_version")"
say_verbose "specific_version=$specific_version"
if [ -z "$specific_version" ]; then
say_err "Could not resolve version information."
return 1
fi
download_link="$(construct_download_link "$azure_feed" "$channel" "$normalized_architecture" "$specific_version" "$normalized_os")"
say_verbose "Constructed primary named payload URL: $download_link"
legacy_download_link="$(construct_legacy_download_link "$azure_feed" "$channel" "$normalized_architecture" "$specific_version")" || valid_legacy_download_link=false
if [ "$valid_legacy_download_link" = true ]; then
say_verbose "Constructed legacy named payload URL: $legacy_download_link"
else
say_verbose "Cound not construct a legacy_download_link; omitting..."
fi
install_root="$(resolve_installation_path "$install_dir")"
say_verbose "InstallRoot: $install_root"
}
install_dotnet() {
eval $invocation
local download_failed=false
local asset_name=''
local asset_relative_path=''
if [[ "$runtime" == "dotnet" ]]; then if [[ "$runtime" == "dotnet" ]]; then
asset_relative_path="shared/Microsoft.NETCore.App" asset_relative_path="shared/Microsoft.NETCore.App"
@ -1185,84 +1334,52 @@ install_dotnet() {
elif [ -z "$runtime" ]; then elif [ -z "$runtime" ]; then
asset_relative_path="sdk" asset_relative_path="sdk"
asset_name=".NET Core SDK" asset_name=".NET Core SDK"
else
say_err "Invalid value for \$runtime"
return 1
fi fi
# Check if the SDK version is already installed. get_feeds_to_use
if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$specific_version"; then }
say "$asset_name version $specific_version is already installed."
return 0 install_dotnet() {
fi eval $invocation
local download_failed=false
local download_completed=false
mkdir -p "$install_root" mkdir -p "$install_root"
zip_path="$(mktemp "$temporary_file_template")" zip_path="$(mktemp "$temporary_file_template")"
say_verbose "Zip path: $zip_path" say_verbose "Zip path: $zip_path"
for link_index in "${!download_links[@]}"
do
download_link="${download_links[$link_index]}"
specific_version="${specific_versions[$link_index]}"
effective_version="${effective_versions[$link_index]}"
link_type="${link_types[$link_index]}"
# Failures are normal in the non-legacy case for ultimately legacy downloads. say "Attempting to download using $link_type link $download_link"
# Do not output to stderr, since output to stderr is considered an error.
say "Downloading primary link $download_link"
# The download function will set variables $http_code and $download_error_msg in case of failure. # The download function will set variables $http_code and $download_error_msg in case of failure.
download "$download_link" "$zip_path" 2>&1 || download_failed=true
# if the download fails, download the legacy_download_link
if [ "$download_failed" = true ]; then
primary_path_http_code="$http_code"; primary_path_download_error_msg="$download_error_msg"
case $primary_path_http_code in
404)
say "The resource at $download_link is not available."
;;
*)
say "$primary_path_download_error_msg"
;;
esac
rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed"
if [ "$valid_legacy_download_link" = true ]; then
download_failed=false download_failed=false
download_link="$legacy_download_link"
zip_path="$(mktemp "$temporary_file_template")"
say_verbose "Legacy zip path: $zip_path"
say "Downloading legacy link $download_link"
# The download function will set variables $http_code and $download_error_msg in case of failure.
download "$download_link" "$zip_path" 2>&1 || download_failed=true download "$download_link" "$zip_path" 2>&1 || download_failed=true
if [ "$download_failed" = true ]; then if [ "$download_failed" = true ]; then
legacy_path_http_code="$http_code"; legacy_path_download_error_msg="$download_error_msg" case $http_code in
case $legacy_path_http_code in
404) 404)
say "The resource at $download_link is not available." say "The resource at $link_type link '$download_link' is not available."
;; ;;
*) *)
say "$legacy_path_download_error_msg" say "Failed to download $link_type link '$download_link': $download_error_msg"
;; ;;
esac esac
rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed" rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed"
else
download_completed=true
break
fi fi
fi done
fi
if [ "$download_failed" = true ]; then if [[ "$download_completed" == false ]]; then
if [[ "$primary_path_http_code" = "404" && ( "$valid_legacy_download_link" = false || "$legacy_path_http_code" = "404") ]]; then
say_err "Could not find \`$asset_name\` with version = $specific_version" say_err "Could not find \`$asset_name\` with version = $specific_version"
say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support" say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support"
else
say_err "Could not download: \`$asset_name\` with version = $specific_version"
# 404-NotFound is an expected response if it goes from only one of the links, do not show that error.
# If primary path is available (not 404-NotFound) then show the primary error else show the legacy error.
if [ "$primary_path_http_code" != "404" ]; then
say_err "$primary_path_download_error_msg"
return 1
fi
if [[ "$valid_legacy_download_link" = true && "$legacy_path_http_code" != "404" ]]; then
say_err "$legacy_path_download_error_msg"
return 1
fi
fi
return 1 return 1
fi fi
@ -1283,14 +1400,14 @@ install_dotnet() {
fi fi
# Check if the standard SDK version is installed. # Check if the standard SDK version is installed.
say_verbose "Checking installation: version = $specific_product_version" say_verbose "Checking installation: version = $effective_version"
if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$specific_product_version"; then if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then
return 0 return 0
fi fi
# Version verification failed. More likely something is wrong either with the downloaded content or with the verification algorithm. # Version verification failed. More likely something is wrong either with the downloaded content or with the verification algorithm.
say_err "Failed to verify the version of installed \`$asset_name\`.\nInstallation source: $download_link.\nInstallation location: $install_root.\nReport the bug at https://github.com/dotnet/install-scripts/issues." say_err "Failed to verify the version of installed \`$asset_name\`.\nInstallation source: $download_link.\nInstallation location: $install_root.\nReport the bug at https://github.com/dotnet/install-scripts/issues."
say_err "\`$asset_name\` with version = $specific_product_version failed to install with an unknown error." say_err "\`$asset_name\` with version = $effective_version failed to install with an error."
return 1 return 1
} }
@ -1308,8 +1425,8 @@ architecture="<auto>"
dry_run=false dry_run=false
no_path=false no_path=false
no_cdn=false no_cdn=false
azure_feed="https://dotnetcli.azureedge.net/dotnet" azure_feed=""
uncached_feed="https://dotnetcli.blob.core.windows.net/dotnet" uncached_feed=""
feed_credential="" feed_credential=""
verbose=false verbose=false
runtime="" runtime=""
@ -1434,7 +1551,7 @@ do
echo " - 3-part version in a format A.B.Cxx - represents a specific SDK release" echo " - 3-part version in a format A.B.Cxx - represents a specific SDK release"
echo " examples: 5.0.1xx, 5.0.2xx." echo " examples: 5.0.1xx, 5.0.2xx."
echo " Supported since 5.0 release" echo " Supported since 5.0 release"
echo " Note: The version parameter overrides the channel parameter when any version other than `latest` is used." echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used."
echo " -v,--version <VERSION> Use specific VERSION, Defaults to \`$version\`." echo " -v,--version <VERSION> Use specific VERSION, Defaults to \`$version\`."
echo " -Version" echo " -Version"
echo " Possible values:" echo " Possible values:"
@ -1447,7 +1564,7 @@ do
echo " Works only in combination with channel. Not applicable for current and LTS channels and will be ignored if those channels are used." echo " 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 " For SDK use channel in A.B.Cxx format. Using quality for SDK together with channel in A.B format is not supported."
echo " Supported since 5.0 release." echo " Supported since 5.0 release."
echo " Note: The version parameter overrides the channel parameter when any version other than `latest` is used, and therefore overrides the quality." echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used, and therefore overrides the quality."
echo " --internal,-Internal Download internal builds. Requires providing credentials via --feed-credential parameter." 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 " --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 " -FeedCredential This parameter typically is not specified."
@ -1469,8 +1586,12 @@ do
echo " --dry-run,-DryRun Do not perform installation. Display download link." echo " --dry-run,-DryRun Do not perform installation. Display download link."
echo " --no-path, -NoPath Do not set PATH for the current process." echo " --no-path, -NoPath Do not set PATH for the current process."
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 For internal use only."
echo " --uncached-feed,-UncachedFeed Uncached feed location. This parameter typically is not changed by the user." echo " Allows using a different storage to download SDK archives from."
echo " This parameter is only used if --no-cdn is false."
echo " --uncached-feed,-UncachedFeed For internal use only."
echo " Allows using a different storage to download SDK archives from."
echo " This parameter is only used if --no-cdn is true."
echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable." echo " --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."
@ -1478,14 +1599,6 @@ do
echo " Note: global.json must have a value for 'SDK:Version'" echo " Note: global.json must have a value for 'SDK:Version'"
echo " -?,--?,-h,--help,-Help Shows this help message" echo " -?,--?,-h,--help,-Help Shows this help message"
echo "" echo ""
echo "Obsolete parameters:"
echo " --shared-runtime The recommended alternative is '--runtime dotnet'."
echo " This parameter is obsolete and may be removed in a future version of this script."
echo " Installs just the shared runtime bits, not the entire SDK."
echo " --runtime-id Installs the .NET Tools for the given platform (use linux-x64 for portable linux)."
echo " -RuntimeId" The parameter is obsolete and may be removed in a future version of this script. Should be used only for versions below 2.1.
echo " For primary links to override OS or/and architecture, use --os and --architecture option instead."
echo ""
echo "Install Location:" echo "Install Location:"
echo " Location is chosen in following order:" echo " Location is chosen in following order:"
echo " - --install-dir option" echo " - --install-dir option"
@ -1502,10 +1615,6 @@ do
shift shift
done done
if [ "$no_cdn" = true ]; then
azure_feed="$uncached_feed"
fi
say "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:" say "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."
@ -1523,33 +1632,11 @@ fi
check_min_reqs check_min_reqs
calculate_vars calculate_vars
script_name=$(basename "$0") # generate_regular_links call below will 'exit' if the determined version is already installed.
generate_download_links
if [ "$dry_run" = true ]; then if [[ "$dry_run" = true ]]; then
say "Payload URLs:" print_dry_run
say "Primary named payload URL: ${download_link}"
if [ "$valid_legacy_download_link" = true ]; then
say "Legacy named payload URL: ${legacy_download_link}"
fi
repeatable_command="./$script_name --version "\""$specific_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"" --os "\""$normalized_os"\"""
if [ ! -z "$normalized_quality" ]; then
repeatable_command+=" --quality "\""$normalized_quality"\"""
fi
if [[ "$runtime" == "dotnet" ]]; then
repeatable_command+=" --runtime "\""dotnet"\"""
elif [[ "$runtime" == "aspnetcore" ]]; then
repeatable_command+=" --runtime "\""aspnetcore"\"""
fi
repeatable_command+="$non_dynamic_parameters"
if [ -n "$feed_credential" ]; then
repeatable_command+=" --feed-credential "\""<feed_credential>"\"""
fi
say "Repeatable invocation: $repeatable_command"
exit 0 exit 0
fi fi