Skip to content

Instantly share code, notes, and snippets.

@bplasmeijer
Created December 13, 2022 10:55
Show Gist options
  • Save bplasmeijer/f81f12badc1bc8c108dbd07a06b642c4 to your computer and use it in GitHub Desktop.
Save bplasmeijer/f81f12badc1bc8c108dbd07a06b642c4 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -e
DEFAULT_BIN_DIR="/usr/local/bin"
BIN_DIR=${1:-"${DEFAULT_BIN_DIR}"}
GITHUB_REPO="fluxcd/flux2"
# Helper functions for logs
info() {
echo '[INFO] ' "$@"
}
warn() {
echo '[WARN] ' "$@" >&2
}
fatal() {
echo '[ERROR] ' "$@" >&2
exit 1
}
# Set os, fatal if operating system not supported
setup_verify_os() {
if [[ -z "${OS}" ]]; then
OS=$(uname)
fi
case ${OS} in
Darwin)
OS=darwin
;;
Linux)
OS=linux
;;
*)
fatal "Unsupported operating system ${OS}"
esac
}
# Set arch, fatal if architecture not supported
setup_verify_arch() {
if [[ -z "${ARCH}" ]]; then
ARCH=$(uname -m)
fi
case ${ARCH} in
arm|armv6l|armv7l)
ARCH=arm
;;
arm64|aarch64|armv8l)
ARCH=arm64
;;
amd64)
ARCH=amd64
;;
x86_64)
ARCH=amd64
;;
*)
fatal "Unsupported architecture ${ARCH}"
esac
}
# Verify existence of downloader executable
verify_downloader() {
# Return failure if it doesn't exist or is no executable
[[ -x "$(which "$1")" ]] || return 1
# Set verified executable as our downloader program and return success
DOWNLOADER=$1
return 0
}
# Create tempory directory and cleanup when done
setup_tmp() {
TMP_DIR=$(mktemp -d -t flux-install.XXXXXXXXXX)
TMP_METADATA="${TMP_DIR}/flux.json"
TMP_HASH="${TMP_DIR}/flux.hash"
TMP_BIN="${TMP_DIR}/flux.tar.gz"
cleanup() {
local code=$?
set +e
trap - EXIT
rm -rf "${TMP_DIR}"
exit ${code}
}
trap cleanup INT EXIT
}
# Find version from Github metadata
get_release_version() {
if [[ -n "${FLUX_VERSION}" ]]; then
SUFFIX_URL="tags/v${FLUX_VERSION}"
else
SUFFIX_URL="latest"
fi
METADATA_URL="https://api.github.com/repos/${GITHUB_REPO}/releases/${SUFFIX_URL}"
echo "-> $METADATA_URL"
info "Downloading metadata ${METADATA_URL}"
download "${TMP_METADATA}" "${METADATA_URL}"
VERSION_FLUX=$(grep '"tag_name":' "${TMP_METADATA}" | sed -E 's/.*"([^"]+)".*/\1/' | cut -c 2-)
if [[ -n "${VERSION_FLUX}" ]]; then
info "Using ${VERSION_FLUX} as release"
else
fatal "Unable to determine release version"
fi
}
# Download from file from URL
download() {
[[ $# -eq 2 ]] || fatal 'download needs exactly 2 arguments'
case $DOWNLOADER in
curl)
curl -o "$1" -sfL "$2"
;;
wget)
wget -qO "$1" "$2"
;;
*)
fatal "Incorrect executable '${DOWNLOADER}'"
;;
esac
# Abort if download command failed
[[ $? -eq 0 ]] || fatal 'Download failed'
}
# Version comparison
# Returns 0 on '=', 1 on '>', and 2 on '<'.
# Ref: https://stackoverflow.com/a/4025065
vercomp () {
if [[ $1 == $2 ]]
then
return 0
fi
local IFS=.
local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++))
do
ver1[i]=0
done
for ((i=0; i<${#ver1[@]}; i++))
do
if [[ -z ${ver2[i]} ]]
then
# fill empty fields in ver2 with zeros
ver2[i]=0
fi
if ((10#${ver1[i]} > 10#${ver2[i]}))
then
return 1
fi
if ((10#${ver1[i]} < 10#${ver2[i]}))
then
return 2
fi
done
return 0
}
# Download hash from Github URL
download_hash() {
HASH_URL="https://github.com/${GITHUB_REPO}/releases/download/v${VERSION_FLUX}/flux_${VERSION_FLUX}_checksums.txt"
# NB: support the checksum filename format prior to v0.6.0
set +e
vercomp ${VERSION_FLUX} 0.6.0
if [[ $? -eq 2 ]]; then
HASH_URL="https://github.com/${GITHUB_REPO}/releases/download/v${VERSION_FLUX}/flux2_${VERSION_FLUX}_checksums.txt"
fi
set -e
info "Downloading hash ${HASH_URL}"
download "${TMP_HASH}" "${HASH_URL}"
HASH_EXPECTED=$(grep " flux_${VERSION_FLUX}_${OS}_${ARCH}.tar.gz$" "${TMP_HASH}")
HASH_EXPECTED=${HASH_EXPECTED%%[[:blank:]]*}
}
# Download binary from Github URL
download_binary() {
BIN_URL="https://github.com/${GITHUB_REPO}/releases/download/v${VERSION_FLUX}/flux_${VERSION_FLUX}_${OS}_${ARCH}.tar.gz"
info "Downloading binary ${BIN_URL}"
download "${TMP_BIN}" "${BIN_URL}"
}
compute_sha256sum() {
cmd=$(which sha256sum shasum | head -n 1)
case $(basename "$cmd") in
sha256sum)
sha256sum "$1" | cut -f 1 -d ' '
;;
shasum)
shasum -a 256 "$1" | cut -f 1 -d ' '
;;
*)
fatal "Can not find sha256sum or shasum to compute checksum"
;;
esac
}
# Verify downloaded binary hash
verify_binary() {
info "Verifying binary download"
HASH_BIN=$(compute_sha256sum "${TMP_BIN}")
HASH_BIN=${HASH_BIN%%[[:blank:]]*}
if [[ "${HASH_EXPECTED}" != "${HASH_BIN}" ]]; then
fatal "Download sha256 does not match ${HASH_EXPECTED}, got ${HASH_BIN}"
fi
}
# Setup permissions and move binary
setup_binary() {
chmod 755 "${TMP_BIN}"
info "Installing flux to ${BIN_DIR}/flux"
tar -xzof "${TMP_BIN}" -C "${TMP_DIR}"
local CMD_MOVE="mv -f \"${TMP_DIR}/flux\" \"${BIN_DIR}\""
if [[ -w "${BIN_DIR}" ]]; then
eval "${CMD_MOVE}"
else
eval "sudo ${CMD_MOVE}"
fi
}
# Run the install process
{
echo "-> example use: export FLUX_VERSION=0.27.3 -> $FLUX_VERSION"
setup_verify_os
setup_verify_arch
verify_downloader curl || verify_downloader wget || fatal 'Can not find curl or wget for downloading files'
setup_tmp
get_release_version
download_hash
download_binary
verify_binary
setup_binary
sudo mv /usr/local/bin/flux /home/bap/.local/bin/flux
echo "flux install --version=latest --export > gotk-components.yaml"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment