[Mac OS] Rewrite function download_with_retry (#8914)

* [Mac OS] Rewrite function download_with_retry

* Update powershell function DownloadWithRetry
This commit is contained in:
Vasilii Polikarpov
2023-11-30 13:39:32 +01:00
committed by GitHub
parent bf202afb1e
commit 5f5ab19246
25 changed files with 202 additions and 271 deletions

View File

@@ -125,49 +125,53 @@ function Invoke-ValidateCommand {
}
}
function Start-DownloadWithRetry {
function Invoke-DownloadWithRetry {
Param
(
[Parameter(Mandatory)]
[string] $Url,
[string] $Name,
[string] $DownloadPath = "${env:Temp}",
[int] $Retries = 20,
[int] $Interval = 30
[Alias("Destination")]
[string] $Path
)
if ([String]::IsNullOrEmpty($Name)) {
$Name = [IO.Path]::GetFileName($Url)
if (-not $Path) {
$invalidChars = [IO.Path]::GetInvalidFileNameChars() -join ''
$re = "[{0}]" -f [RegEx]::Escape($invalidChars)
$fileName = [IO.Path]::GetFileName($Url) -replace $re
if ([String]::IsNullOrEmpty($fileName)) {
$fileName = [System.IO.Path]::GetRandomFileName()
}
$Path = Join-Path -Path "/tmp" -ChildPath $fileName
}
$filePath = Join-Path -Path $DownloadPath -ChildPath $Name
Write-Host "Downloading package from $Url to $Path..."
#Default retry logic for the package.
while ($Retries -gt 0)
{
try
{
Write-Host "Downloading package from: $Url to path $filePath ."
(New-Object System.Net.WebClient).DownloadFile($Url, $filePath)
$interval = 30
$downloadStartTime = Get-Date
for ($retries = 20; $retries -gt 0; $retries--) {
try {
$attemptStartTime = Get-Date
(New-Object System.Net.WebClient).DownloadFile($Url, $Path)
$attemptSeconds = [math]::Round(($(Get-Date) - $attemptStartTime).TotalSeconds, 2)
Write-Host "Package downloaded in $attemptSeconds seconds"
break
} catch {
$attemptSeconds = [math]::Round(($(Get-Date) - $attemptStartTime).TotalSeconds, 2)
Write-Warning "Package download failed in $attemptSeconds seconds"
Write-Warning $_.Exception.Message
}
catch
{
Write-Host "There is an error during package downloading:`n $_"
$Retries--
if ($Retries -eq 0)
{
Write-Host "File can't be downloaded. Please try later or check that file exists by url: $Url"
exit 1
}
Write-Host "Waiting $Interval seconds before retrying. Retries left: $Retries"
Start-Sleep -Seconds $Interval
if ($retries -eq 0) {
$totalSeconds = [math]::Round(($(Get-Date) - $downloadStartTime).TotalSeconds, 2)
throw "Package download failed after $totalSeconds seconds"
}
Write-Warning "Waiting $interval seconds before retrying (retries left: $retries)..."
Start-Sleep -Seconds $interval
}
return $filePath
return $Path
}
function Add-EnvironmentVariable {

View File

@@ -32,9 +32,8 @@ function Invoke-DownloadXcodeArchive {
$xcodeFileName = 'Xcode-{0}.xip' -f $Version
$xcodeUri = '{0}{1}?{2}'-f ${env:XCODE_INSTALL_STORAGE_URL}, $xcodeFileName, ${env:XCODE_INSTALL_SAS}
Start-DownloadWithRetry -Url $xcodeUri -DownloadPath $tempXipDirectory.FullName -Name $xcodeFileName
Invoke-DownloadWithRetry -Url $xcodeUri -Path (Join-Path $tempXipDirectory.FullName $xcodeFileName) | Out-Null
return $tempXipDirectory
}
function Resolve-ExactXcodeVersion {

View File

@@ -1,49 +1,44 @@
#!/bin/bash -e -o pipefail
download_with_retries() {
# Due to restrictions of bash functions, positional arguments are used here.
# In case if you using latest argument NAME, you should also set value to all previous parameters.
# Example: download_with_retries $ANDROID_SDK_URL "." "android_sdk.zip"
local URL="$1"
local DEST="${2:-.}"
local NAME="${3:-${URL##*/}}"
local COMPRESSED="$4"
download_with_retry() {
url=$1
download_path=$2
if [[ $COMPRESSED == "compressed" ]]; then
local COMMAND="curl $URL -4 -sL --compressed -o '$DEST/$NAME' -w '%{http_code}'"
else
local COMMAND="curl $URL -4 -sL -o '$DEST/$NAME' -w '%{http_code}'"
if [ -z "$download_path" ]; then
download_path="/tmp/$(basename "$url")"
fi
# Save current errexit state and disable it to prevent unexpected exit on error
if echo $SHELLOPTS | grep '\(^\|:\)errexit\(:\|$\)' > /dev/null;
then
local ERR_EXIT_ENABLED=true
else
local ERR_EXIT_ENABLED=false
fi
set +e
echo "Downloading package from $url to $download_path..." >&2
echo "Downloading '$URL' to '${DEST}/${NAME}'..."
retries=20
interval=30
while [ $retries -gt 0 ]; do
((retries--))
test "$ERR_EXIT_ENABLED" = true && set +e
http_code=$(eval $COMMAND)
exit_code=$?
test "$ERR_EXIT_ENABLED" = true && set -e
if [ $http_code -eq 200 ] && [ $exit_code -eq 0 ]; then
echo "Download completed"
return 0
download_start_time=$(date +%s)
for ((retries=20; retries>0; retries--)); do
attempt_start_time=$(date +%s)
if http_code=$(curl -4sSLo "$download_path" "$url" -w '%{http_code}'); then
attempt_seconds=$(($(date +%s) - attempt_start_time))
if [ "$http_code" -eq 200 ]; then
echo "Package downloaded in $attempt_seconds seconds" >&2
break
else
echo "Received HTTP status code $http_code after $attempt_seconds seconds" >&2
fi
else
echo "Error — Either HTTP response code for '$URL' is wrong - '$http_code' or exit code is not 0 - '$exit_code'. Waiting $interval seconds before the next attempt, $retries attempts left"
sleep 30
attempt_seconds=$(($(date +%s) - attempt_start_time))
echo "Package download failed in $attempt_seconds seconds" >&2
fi
if [ $retries -eq 0 ]; then
total_seconds=$(($(date +%s) - download_start_time))
echo "Package download failed after $total_seconds seconds" >&2
exit 1
fi
echo "Waiting $interval seconds before retrying (retries left: $retries)..." >&2
sleep $interval
done
echo "Could not download $URL"
return 1
echo "$download_path"
}
is_Arm64() {

View File

@@ -4,15 +4,6 @@ source ~/utils/utils.sh
# Xamarin can clean their SDKs while updating to newer versions,
# so we should be able to detect it during image generation
downloadAndInstallPKG() {
local PKG_URL=$1
local PKG_NAME=${PKG_URL##*/}
download_with_retries $PKG_URL
echo "Installing $PKG_NAME..."
sudo installer -pkg "$TMPMOUNT/$PKG_NAME" -target /
}
buildVSMacDownloadUrl() {
echo "https://dl.xamarin.com/VsMac/VisualStudioForMac-${1}.dmg"
@@ -41,7 +32,8 @@ installMono() {
local MONO_FOLDER_NAME=$(echo $VERSION | cut -d. -f 1,2,3)
local SHORT_VERSION=$(echo $VERSION | cut -d. -f 1,2)
local PKG_URL=$(buildMonoDownloadUrl $VERSION)
downloadAndInstallPKG $PKG_URL
sudo installer -pkg "$(download_with_retry "$PKG_URL")" -target /
echo "Installing nunit3-console for Mono "$VERSION
installNunitConsole $MONO_FOLDER_NAME
@@ -59,7 +51,8 @@ installXamarinIOS() {
echo "Installing Xamarin.iOS ${VERSION}..."
local SHORT_VERSION=$(echo $VERSION | cut -d. -f 1,2)
local PKG_URL=$(buildXamariniIOSDownloadUrl $VERSION)
downloadAndInstallPKG $PKG_URL
sudo installer -pkg "$(download_with_retry "$PKG_URL")" -target /
echo "Creating short symlink '${SHORT_VERSION}'"
sudo ln -s ${IOS_VERSIONS_PATH}/${VERSION} ${IOS_VERSIONS_PATH}/${SHORT_VERSION}
@@ -74,7 +67,8 @@ installXamarinMac() {
echo "Installing Xamarin.Mac ${VERSION}..."
local SHORT_VERSION=$(echo $VERSION | cut -d. -f 1,2)
local PKG_URL=$(buildXamarinMacDownloadUrl $VERSION)
downloadAndInstallPKG $PKG_URL
sudo installer -pkg "$(download_with_retry "$PKG_URL")" -target /
echo "Creating short symlink '${SHORT_VERSION}'"
sudo ln -s ${MAC_VERSIONS_PATH}/${VERSION} ${MAC_VERSIONS_PATH}/${SHORT_VERSION}
@@ -89,7 +83,8 @@ installXamarinAndroid() {
echo "Installing Xamarin.Android ${VERSION}..."
local SHORT_VERSION=$(echo $VERSION | cut -d. -f 1,2)
local PKG_URL=$(buildXamarinAndroidDownloadUrl $VERSION)
downloadAndInstallPKG $PKG_URL
sudo installer -pkg "$(download_with_retry "$PKG_URL")" -target /
if [ "$VERSION" == "9.4.1.0" ]; then
# Fix symlinks for broken Xamarin.Android
@@ -159,46 +154,27 @@ fixXamarinAndroidSymlinksInLibDir() {
installNunitConsole() {
local MONO_VERSION=$1
local TMP_WRAPPER_PATH=$(mktemp)
cat <<EOF > ${TMPMOUNT}/${NUNIT3_CONSOLE_BIN}
cat <<EOF > "$TMP_WRAPPER_PATH"
#!/bin/bash -e -o pipefail
exec /Library/Frameworks/Mono.framework/Versions/${MONO_VERSION}/bin/mono --debug \$MONO_OPTIONS $NUNIT3_PATH/nunit3-console.exe "\$@"
EOF
sudo chmod +x ${TMPMOUNT}/${NUNIT3_CONSOLE_BIN}
sudo mv ${TMPMOUNT}/${NUNIT3_CONSOLE_BIN} ${MONO_VERSIONS_PATH}/${MONO_VERSION}/Commands/${NUNIT3_CONSOLE_BIN}
sudo chmod +x "$TMP_WRAPPER_PATH"
sudo mv "$TMP_WRAPPER_PATH" "${MONO_VERSIONS_PATH}/${MONO_VERSION}/Commands/nunit3-console"
}
downloadNUnitConsole() {
echo "Downloading NUnit 3..."
local NUNIT3_LOCATION='https://github.com/nunit/nunit-console/releases/download/3.6.1/NUnit.Console-3.6.1.zip'
local NUNIT_PATH="/Library/Developer/nunit"
NUNIT3_PATH="$NUNIT_PATH/3.6.1"
echo "Downloading NUnit 3..."
local NUNIT3_VERSION='3.6.1'
local NUNIT3_LOCATION="https://github.com/nunit/nunit-console/releases/download/${NUNIT3_VERSION}/NUnit.Console-${NUNIT3_VERSION}.zip"
local NUNIT3_PATH="/Library/Developer/nunit/${NUNIT3_VERSION}"
pushd $TMPMOUNT
NUNIT3_ARCHIVE=$(download_with_retry $NUNIT3_LOCATION)
sudo mkdir -p $NUNIT3_PATH
download_with_retries $NUNIT3_LOCATION "." "nunit3.zip"
echo "Installing NUnit 3..."
sudo unzip nunit3.zip -d $NUNIT3_PATH
NUNIT3_CONSOLE_BIN=nunit3-console
popd
}
installNuget() {
local MONO_VERSION=$1
local NUGET_VERSION=$2
local NUGET_URL="https://dist.nuget.org/win-x86-commandline/v${NUGET_VERSION}/nuget.exe"
echo "Installing nuget $NUGET_VERSION for Mono $MONO_VERSION"
cd ${MONO_VERSIONS_PATH}/${MONO_VERSION}/lib/mono/nuget
sudo mv nuget.exe nuget_old.exe
pushd $TMPMOUNT
download_with_retries $NUGET_URL "." "nuget.exe"
sudo chmod a+x nuget.exe
sudo mv nuget.exe ${MONO_VERSIONS_PATH}/${MONO_VERSION}/lib/mono/nuget
popd
echo "Installing NUnit 3..."
sudo mkdir -p $NUNIT3_PATH
sudo unzip "$NUNIT3_ARCHIVE" -d $NUNIT3_PATH
}
createUWPShim() {
@@ -236,4 +212,4 @@ deleteSymlink() {
sudo rm -f ${IOS_VERSIONS_PATH}/${1}
sudo rm -f ${MAC_VERSIONS_PATH}/${1}
sudo rm -f ${ANDROID_VERSIONS_PATH}/${1}
}
}