Created
October 5, 2023 07:37
-
-
Save maunzCache/cfa1d015a738afa6b8cd23ef37d77fd0 to your computer and use it in GitHub Desktop.
OpenTofu installer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -e | |
# OPENTOFU INSTALLER based on | |
# TERRAFORM INSTALLER - Automated Terraform Installation | |
# Apache 2 License - Copyright (c) 2018 Robert Peteuil @RobertPeteuil | |
# | |
# Automatically Download, Extract and Install | |
# Latest or Specific Version of Terraform | |
# | |
# from: https://github.com/robertpeteuil/terraform-installer | |
# Uncomment line below to always use 'sudo' to install to /usr/local/bin/ | |
# sudoInstall=true | |
scriptname=$(basename "$0") | |
scriptbuildnum="2.0.0" | |
scriptbuilddate="2023-10-05" | |
# CHECK DEPENDANCIES AND SET NET RETRIEVAL TOOL | |
if ! unzip -h 2&> /dev/null; then | |
echo "aborting - unzip not installed and required" | |
exit 1 | |
fi | |
if curl -h 2&> /dev/null; then | |
nettool="curl" | |
elif wget -h 2&> /dev/null; then | |
nettool="wget" | |
else | |
echo "aborting - wget or curl not installed and required" | |
exit 1 | |
fi | |
displayVer() { | |
echo -e "${scriptname} ver ${scriptbuildnum} - ${scriptbuilddate}" | |
} | |
usage() { | |
[[ "$1" ]] && echo -e "Download and Install OpenTofu - Latest Version unless '-i' specified\n" | |
echo -e "usage: ${scriptname} [-i VERSION] [-a] [-c] [-h] [-u] [-v]" | |
echo -e " -i VERSION\t: specify version to install in format '1.6.0-alpha1' (OPTIONAL)" | |
echo -e " -a\t\t: automatically use sudo to install to /usr/local/bin (or \$TF_INSTALL_DIR)" | |
echo -e " -c\t\t: leave binary in working directory (for CI/DevOps use)" | |
echo -e " -h\t\t: help" | |
echo -e " -u\t\t: allow to auto-pick any unstable version as latest" | |
echo -e " -v\t\t: display ${scriptname} version" | |
} | |
getLatest() { | |
# USE NET RETRIEVAL TOOL TO GET LATEST VERSION | |
case "${nettool}" in | |
# parse version from github API | |
wget) | |
LATEST_ARR=($(wget -q -O- https://api.github.com/repos/opentofu/opentofu/releases 2> /dev/null | awk '/tag_name/ {print $2}' | cut -d '"' -f 2 | cut -d 'v' -f 2)) | |
;; | |
curl) | |
LATEST_ARR=($(curl -s https://api.github.com/repos/opentofu/opentofu/releases 2> /dev/null | awk '/tag_name/ {print $2}' | cut -d '"' -f 2 | cut -d 'v' -f 2)) | |
;; | |
*) | |
echo "Unable to get latest version from Github." | |
;; | |
esac | |
# make sure latest version isn't beta or rc | |
for ver in "${LATEST_ARR[@]}"; do | |
if [[ $unstable != "true" ]] && [[ ! $ver =~ beta ]] && [[ ! $ver =~ rc ]] && [[ ! $ver =~ alpha ]]; then | |
LATEST="$ver" | |
break | |
elif [[ $unstable ]]; then | |
# TODO: If can be shortened | |
LATEST="$ver" | |
break | |
fi | |
done | |
echo -n "$LATEST" | |
} | |
while getopts ":i:achuv" arg; do | |
case "${arg}" in | |
a) sudoInstall=true;; | |
c) cwdInstall=true;; | |
i) VERSION=${OPTARG};; | |
h) usage x; exit;; | |
u) unstable=true;; | |
v) displayVer; exit;; | |
\?) echo -e "Error - Invalid option: $OPTARG"; usage; exit;; | |
:) echo "Error - $OPTARG requires an argument"; usage; exit 1;; | |
esac | |
done | |
shift $((OPTIND-1)) | |
# POPULATE VARIABLES NEEDED TO CREATE DOWNLOAD URL AND FILENAME | |
if [[ -z "$VERSION" ]]; then | |
VERSION=$(getLatest) | |
fi | |
OS=$(uname -s | tr '[:upper:]' '[:lower:]') | |
if [[ "$OS" == "linux" ]]; then | |
PROC=$(lscpu 2> /dev/null | awk '/Architecture/ {if($2 == "x86_64") {print "amd64"; exit} else if($2 ~ /arm/) {print "arm"; exit} else if($2 ~ /aarch64/) {print "arm"; exit} else {print "386"; exit}}') | |
if [[ -z $PROC ]]; then | |
PROC=$(cat /proc/cpuinfo | awk '/model\ name/ {if($0 ~ /ARM/) {print "arm"; exit}}') | |
fi | |
if [[ -z $PROC ]]; then | |
PROC=$(cat /proc/cpuinfo | awk '/flags/ {if($0 ~ /lm/) {print "amd64"; exit} else {print "386"; exit}}') | |
fi | |
else | |
PROC="amd64" | |
fi | |
[[ $PROC =~ arm ]] && PROC="arm" # opentofu downloads use "arm" not full arm type | |
# CREATE FILENAME AND URL FROM GATHERED PARAMETERS | |
FILENAME="tofu_${VERSION}_${OS}_${PROC}.zip" | |
LINK="https://github.com/opentofu/opentofu/releases/download/v${VERSION}/${FILENAME}" | |
SHALINK="https://github.com/opentofu/opentofu/releases/download/v${VERSION}/tofu_${VERSION}_SHA256SUMS" | |
# TEST CALCULATED LINKS | |
case "${nettool}" in | |
wget*) | |
LINKVALID=$(wget --spider -S "$LINK" 2>&1 | grep "HTTP/" | awk 'END{print $2}') | |
SHALINKVALID=$(wget --spider -S "$SHALINK" 2>&1 | grep "HTTP/" | awk 'END{print $2}') | |
;; | |
curl*) | |
LINKVALID=$(curl -L -o /dev/null --silent --head --write-out '%{http_code}\n' "$LINK") | |
SHALINKVALID=$(curl -L -o /dev/null --silent --head --write-out '%{http_code}\n' "$SHALINK") | |
;; | |
esac | |
# VERIFY LINK VALIDITY | |
if [[ "$LINKVALID" != 200 ]]; then | |
echo -e "Cannot Install - Download URL Invalid" | |
echo -e "\nParameters:" | |
echo -e "\tVER:\t$VERSION" | |
echo -e "\tOS:\t$OS" | |
echo -e "\tPROC:\t$PROC" | |
echo -e "\tURL:\t$LINK" | |
exit 1 | |
fi | |
# VERIFY SHA LINK VALIDITY | |
if [[ "$SHALINKVALID" != 200 ]]; then | |
echo -e "Cannot Install - URL for Checksum File Invalid" | |
echo -e "\tURL:\t$SHALINK" | |
exit 1 | |
fi | |
# DETERMINE DESTINATION | |
if [[ "$cwdInstall" ]]; then | |
BINDIR=$(pwd) | |
elif [[ -n "$TF_INSTALL_DIR" ]]; then | |
BINDIR="$TF_INSTALL_DIR" | |
CMDPREFIX="${sudoInstall:+sudo }" | |
STREAMLINED=true | |
elif [[ -w "/usr/local/bin" ]]; then | |
BINDIR="/usr/local/bin" | |
CMDPREFIX="" | |
STREAMLINED=true | |
elif [[ "$sudoInstall" ]]; then | |
BINDIR="/usr/local/bin" | |
CMDPREFIX="sudo " | |
STREAMLINED=true | |
else | |
echo -e "OpenTofu Installer\n" | |
echo "Specify install directory (a,b or c):" | |
echo -en "\t(a) '~/bin' (b) '/usr/local/bin' as root (c) abort : " | |
read -r -n 1 SELECTION | |
echo | |
if [ "${SELECTION}" == "a" ] || [ "${SELECTION}" == "A" ]; then | |
BINDIR="${HOME}/bin" | |
CMDPREFIX="" | |
elif [ "${SELECTION}" == "b" ] || [ "${SELECTION}" == "B" ]; then | |
BINDIR="/usr/local/bin" | |
CMDPREFIX="sudo " | |
else | |
exit 0 | |
fi | |
fi | |
# CREATE TMPDIR FOR EXTRACTION | |
if [[ ! "$cwdInstall" ]]; then | |
TMPDIR=${TMPDIR:-/tmp} | |
UTILTMPDIR="tofu_${VERSION}" | |
cd "$TMPDIR" || exit 1 | |
mkdir -p "$UTILTMPDIR" | |
cd "$UTILTMPDIR" || exit 1 | |
fi | |
# DOWNLOAD ZIP AND CHECKSUM FILES | |
case "${nettool}" in | |
wget*) | |
wget -q "$LINK" -O "$FILENAME" | |
wget -q "$SHALINK" -O SHAFILE | |
;; | |
curl*) | |
curl -L -s -o "$FILENAME" "$LINK" | |
curl -L -s -o SHAFILE "$SHALINK" | |
;; | |
esac | |
# VERIFY ZIP CHECKSUM | |
if shasum -h 2&> /dev/null; then | |
expected_sha=$(cat SHAFILE | grep "$FILENAME" | awk '{print $1}') | |
download_sha=$(shasum -a 256 "$FILENAME" | cut -d' ' -f1) | |
if [ $expected_sha != $download_sha ]; then | |
echo "Download Checksum Incorrect" | |
echo "Expected: $expected_sha" | |
echo "Actual: $download_sha" | |
exit 1 | |
fi | |
fi | |
# EXTRACT ZIP | |
unzip -qq "$FILENAME" || exit 1 | |
# COPY TO DESTINATION | |
if [[ ! "$cwdInstall" ]]; then | |
mkdir -p "${BINDIR}" || exit 1 | |
${CMDPREFIX} mv tofu "$BINDIR" || exit 1 | |
# CLEANUP AND EXIT | |
cd "${TMPDIR}" || exit 1 | |
rm -rf "${UTILTMPDIR}" | |
[[ ! "$STREAMLINED" ]] && echo | |
echo "OpenTofu Version ${VERSION} installed to ${BINDIR}" | |
else | |
rm -f "$FILENAME" SHAFILE | |
echo "OpenTofu Version ${VERSION} downloaded" | |
fi | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment