Skip to content
This repository has been archived by the owner on Apr 17, 2023. It is now read-only.

Commit

Permalink
(MAINT) Improve robustness of install.sh
Browse files Browse the repository at this point in the history
Prior to this commit, it was observed on Github Actions CI runs
that the `macos-latest` (and to a lesser extent, the `ubuntu-latest`)
runners would occasionally fail to install the PCT package.

This commit added the following functionality to `install.sh`:
- Fetches the releases checksums file to perform verification on
the download
- Wraps all curl commands in a retry loop, to improve reliability
and mitigate failures caused by network blips
- Inspect the HTTP Response Code from each curl command
- Output debug logging to help diagnose / investigate failures

Debug logging is enabled by setting the ENV VAR `PCT_INSTALL_DEBUG`
  • Loading branch information
petergmurphy authored and sanfrancrisko committed Oct 22, 2021
1 parent efe066f commit b730881
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 25 deletions.
53 changes: 53 additions & 0 deletions .github/workflows/installation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Installation Tests

on:
pull_request:
branches: [ main ]

jobs:
install_test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
env:
PCT_INSTALL_DEBUG: true
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Get Latest Tag (Windows)
id: latest_tag
if: runner.os == 'Windows'
run: |
$TagVersion = git tag --list |
Where-Object { $_ -match '^\d+\.\d+\.\d+$' } |
Sort-Object -Descending |
Select-Object -First 1
echo "::set-output name=tag::0.4.0 d18bd02"
- name: Install PCT (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
. .\tools\install.ps1; Install-Pct
- name: Validate install (Windows)
if: runner.os == 'Windows'
run: |
$HomeDir = Get-Item ~ | Select-Object -ExpandProperty FullName
$PctPath = "${HomeDir}\.puppetlabs\pct\pct.exe"
$verInfo = & $PctPath --version |
Select-Object -First 1 |
ForEach-Object { $_ -split " " } |
Select-Object -Skip 1 -First 2
if (& $PctPath --version | Out-String -Stream | Select-String -Pattern '${{ steps.latest_tag.outputs.tag }}') {
exit 0
} else {
exit 1
}
- name: Install PCT (Unix)
if: runner.os != 'Windows'
run: ./tools/install.sh
- name: Validate install (Unix)
if: runner.os != 'Windows'
run: $HOME/.puppetlabs/pct/pct --version | grep "pct $(git tag | tail -n 1)"
116 changes: 91 additions & 25 deletions tools/install.sh
Original file line number Diff line number Diff line change
@@ -1,41 +1,107 @@
#!/bin/sh
set -eu
set -e

org="puppetlabs"
repo="pdkgo"
ARCH="x86_64"
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
EXT=".tar.gz"

app="pct"
appPkgName="pct"
ORG="puppetlabs"
REPO="pdkgo"
APP="pct"
APP_PKG_NAME="pct"

noTel="${1:-false}"
NO_TEL=${1:-false}

if [ "$noTel" = "--no-telemetry" ]; then
appPkgName="notel_pct"
if [ ${NO_TEL} = "--no-telemetry" ]; then
APP_PKG_NAME="notel_pct"
fi

arch="x86_64"
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
ext=".tar.gz"
RELEASES=""
FILE=""
VER=""
CHECKSUM=""

releases="$(curl -s -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${org}/${repo}/releases")"
logDebug() {
if [ ! -z $PCT_INSTALL_DEBUG ]; then
echo $1
fi
}

ver="$(echo "$releases" | grep -oE -m 1 '"tag_name": "(([0-9]+\.)+[0-9]+(-pre+)?)"' | cut -d '"' -f 4 | head -1)"
getLatestReleaseVer() {
logDebug "Fetching latest releases from https://api.github.com/repos/${ORG}/${REPO}/releases"
resp=$(curl -Ls -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${ORG}/${REPO}/releases" --write-out "%{http_code}")
VER="$(echo ${resp} | grep -oE -m 1 '"tag_name": "(([0-9]+\.)+[0-9]+(-pre+)?)"' | cut -d '"' -f 4 | head -1)"
logDebug "Latest version: ${VER}"
}

file="${appPkgName}_${ver}_${os}_${arch}${ext}"
getChecksums() {
for i in {1..5}; do
FILE="${APP_PKG_NAME}_${VER}_${OS}_${ARCH}${EXT}"
checksumURL="https://github.com/${ORG}/${REPO}/releases/download/${VER}/checksums.txt"
resp=$(curl -Ls "${checksumURL}" -o /tmp/pct_checksums.txt --write-out "%{http_code}")
respCode=$(echo ${resp} | tail -n 1)
logDebug "GET ${checksumURL} | Resp: ${resp}"
if [ ${respCode} -ne 200 ]; then
echo "Fetching checksums.txt failed on attempt ${i}, retrying..."
sleep 5
else
CHECKSUM=$(grep ${FILE} /tmp/pct_checksums.txt | cut -d ' ' -f 1)
return 0
fi
done
echo "Fetching checksums.txt failed after max retry attempts"
exit 1
}

downloadURL="https://github.com/${org}/${repo}/releases/download/${ver}/${file}"
downloadLatestRelease() {
destination="${HOME}/.puppetlabs/pct"

destination="${HOME}/.puppetlabs/pct"
[ -d ${destination} ] || mkdir -p ${destination} ]

[ -d "${destination}" ] || mkdir -p "${destination}"
if [ "${noTel}" = "--no-telemetry" ]; then
echo "Downloading and extracting ${APP_PKG_NAME} ${VER} (TELEMETRY DISABLED VERSION) to ${destination}"
else
echo "Downloading and extracting ${APP_PKG_NAME} ${VER} to ${destination}"
fi

if [ "$noTel" = "--no-telemetry" ]; then
echo "Downloading and extracting ${app} ${ver} (TELEMETRY DISABLED VERSION) to ${destination}"
else
echo "Downloading and extracting ${app} ${ver} to ${destination}"
fi
downloadURL="https://github.com/${ORG}/${REPO}/releases/download/${VER}/${FILE}"

curl -L -s "${downloadURL}" -o - | tar xz -C "${destination}"
for i in {1..5}; do
resp=$(curl -Ls ${downloadURL} -o /tmp/${FILE} --write-out "%{http_code}")
respCode=$(echo ${resp} | tail -n 1)
logDebug "GET ${downloadURL} | Resp: ${resp}"
if [ ${respCode} -ne 200 ]; then
echo "Fetching PCT package failed on attempt ${i}, retrying..."
sleep 5
else
downloadChecksumRaw=$(shasum -a 256 /tmp/${FILE} || sha256sum /tmp/${FILE})
downloadChecksum=$(echo ${downloadChecksumRaw} | cut -d ' ' -f 1)
logDebug "Checksum calc for ${FILE}:"
logDebug " - Expect checksum: ${CHECKSUM}"
logDebug " - Actual checksum: ${downloadChecksum}"
if [ ${downloadChecksum} = ${CHECKSUM} ]; then
logDebug "Extracting /tmp/${FILE} to ${destination}"
tar -zxf "/tmp/${FILE}" -C ${destination}
tarStatus=$(echo $?)
logDebug "Removing /tmp/${FILE}"
rm "/tmp/${FILE}"
if [ ${tarStatus} -eq 0 ]; then
echo "Remember to add the pct app to your path:"
echo 'export PATH=$PATH:'${destination}
exit 0
else
echo "Untar unsuccessful (status code: $?)"
exit 1
fi
else
echo "Checksum verification failed for ${FILE}"
exit 1
fi
return 0
fi
done
}

echo 'Remember to add the pct app to your path:'
echo 'export PATH=$PATH:'${destination}
getLatestReleaseVer
getChecksums
downloadLatestRelease

0 comments on commit b730881

Please sign in to comment.