1#!/usr/bin/env bash 2 3# Copyright The Helm Authors. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17# The install script is based off of the MIT-licensed script from glide, 18# the package manager for Go: https://github.com/Masterminds/glide.sh/blob/master/get 19 20PROJECT_NAME="helm" 21TILLER_NAME="tiller" 22 23: ${USE_SUDO:="true"} 24: ${HELM_INSTALL_DIR:="/usr/local/bin"} 25 26# initArch discovers the architecture for this system. 27initArch() { 28 ARCH=$(uname -m) 29 case $ARCH in 30 armv5*) ARCH="armv5";; 31 armv6*) ARCH="armv6";; 32 armv7*) ARCH="arm";; 33 aarch64) ARCH="arm64";; 34 x86) ARCH="386";; 35 x86_64) ARCH="amd64";; 36 i686) ARCH="386";; 37 i386) ARCH="386";; 38 esac 39} 40 41# initOS discovers the operating system for this system. 42initOS() { 43 OS=$(echo `uname`|tr '[:upper:]' '[:lower:]') 44 45 case "$OS" in 46 # Minimalist GNU for Windows 47 mingw*) OS='windows';; 48 esac 49} 50 51# runs the given command as root (detects if we are root already) 52runAsRoot() { 53 local CMD="$*" 54 55 if [ $EUID -ne 0 -a $USE_SUDO = "true" ]; then 56 CMD="sudo $CMD" 57 fi 58 59 $CMD 60} 61 62# verifySupported checks that the os/arch combination is supported for 63# binary builds. 64verifySupported() { 65 local supported="darwin-386\ndarwin-amd64\nlinux-386\nlinux-amd64\nlinux-arm\nlinux-arm64\nlinux-ppc64le\nwindows-386\nwindows-amd64" 66 if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then 67 echo "No prebuilt binary for ${OS}-${ARCH}." 68 echo "To build from source, go to https://github.com/helm/helm" 69 exit 1 70 fi 71 72 if ! type "curl" > /dev/null && ! type "wget" > /dev/null; then 73 echo "Either curl or wget is required" 74 exit 1 75 fi 76} 77 78# checkDesiredVersion checks if the desired version is available. 79checkDesiredVersion() { 80 if [ "x$DESIRED_VERSION" == "x" ]; then 81 # Get tag from release URL 82 local release_url="https://github.com/helm/helm/releases" 83 if type "curl" > /dev/null; then 84 85 TAG=$(curl -Ls $release_url | grep 'href="/helm/helm/releases/tag/v2.' | grep -v no-underline | head -n 1 | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}' | awk 'a !~ $0{print}; {a=$0}') 86 elif type "wget" > /dev/null; then 87 TAG=$(wget $release_url -O - 2>&1 | grep 'href="/helm/helm/releases/tag/v2.' | grep -v no-underline | head -n 1 | cut -d '"' -f 2 | awk '{n=split($NF,a,"/");print a[n]}' | awk 'a !~ $0{print}; {a=$0}') 88 fi 89 else 90 TAG=$DESIRED_VERSION 91 fi 92} 93 94# checkHelmInstalledVersion checks which version of helm is installed and 95# if it needs to be changed. 96checkHelmInstalledVersion() { 97 if [[ -f "${HELM_INSTALL_DIR}/${PROJECT_NAME}" ]]; then 98 local version=$("${HELM_INSTALL_DIR}/${PROJECT_NAME}" version -c | grep '^Client' | cut -d'"' -f2) 99 if [[ "$version" == "$TAG" ]]; then 100 echo "Helm ${version} is already ${DESIRED_VERSION:-latest}" 101 return 0 102 else 103 echo "Helm ${TAG} is available. Changing from version ${version}." 104 return 1 105 fi 106 else 107 return 1 108 fi 109} 110 111# downloadFile downloads the latest binary package and also the checksum 112# for that binary. 113downloadFile() { 114 HELM_DIST="helm-$TAG-$OS-$ARCH.tar.gz" 115 DOWNLOAD_URL="https://get.helm.sh/$HELM_DIST" 116 CHECKSUM_URL="$DOWNLOAD_URL.sha256" 117 HELM_TMP_ROOT="$(mktemp -dt helm-installer-XXXXXX)" 118 HELM_TMP_FILE="$HELM_TMP_ROOT/$HELM_DIST" 119 HELM_SUM_FILE="$HELM_TMP_ROOT/$HELM_DIST.sha256" 120 echo "Downloading $DOWNLOAD_URL" 121 if type "curl" > /dev/null; then 122 curl -SsL "$CHECKSUM_URL" -o "$HELM_SUM_FILE" 123 elif type "wget" > /dev/null; then 124 wget -q -O "$HELM_SUM_FILE" "$CHECKSUM_URL" 125 fi 126 if type "curl" > /dev/null; then 127 curl -SsL "$DOWNLOAD_URL" -o "$HELM_TMP_FILE" 128 elif type "wget" > /dev/null; then 129 wget -q -O "$HELM_TMP_FILE" "$DOWNLOAD_URL" 130 fi 131} 132 133# installFile verifies the SHA256 for the file, then unpacks and 134# installs it. 135installFile() { 136 HELM_TMP="$HELM_TMP_ROOT/$PROJECT_NAME" 137 local sum=$(openssl sha1 -sha256 ${HELM_TMP_FILE} | awk '{print $2}') 138 local expected_sum=$(cat ${HELM_SUM_FILE}) 139 if [ "$sum" != "$expected_sum" ]; then 140 echo "SHA sum of ${HELM_TMP_FILE} does not match. Aborting." 141 exit 1 142 fi 143 144 mkdir -p "$HELM_TMP" 145 tar xf "$HELM_TMP_FILE" -C "$HELM_TMP" 146 HELM_TMP_BIN="$HELM_TMP/$OS-$ARCH/$PROJECT_NAME" 147 TILLER_TMP_BIN="$HELM_TMP/$OS-$ARCH/$TILLER_NAME" 148 echo "Preparing to install $PROJECT_NAME and $TILLER_NAME into ${HELM_INSTALL_DIR}" 149 runAsRoot cp "$HELM_TMP_BIN" "$HELM_INSTALL_DIR" 150 echo "$PROJECT_NAME installed into $HELM_INSTALL_DIR/$PROJECT_NAME" 151 if [ -x "$TILLER_TMP_BIN" ]; then 152 runAsRoot cp "$TILLER_TMP_BIN" "$HELM_INSTALL_DIR" 153 echo "$TILLER_NAME installed into $HELM_INSTALL_DIR/$TILLER_NAME" 154 else 155 echo "info: $TILLER_NAME binary was not found in this release; skipping $TILLER_NAME installation" 156 fi 157} 158 159# fail_trap is executed if an error occurs. 160fail_trap() { 161 result=$? 162 if [ "$result" != "0" ]; then 163 if [[ -n "$INPUT_ARGUMENTS" ]]; then 164 echo "Failed to install $PROJECT_NAME with the arguments provided: $INPUT_ARGUMENTS" 165 help 166 else 167 echo "Failed to install $PROJECT_NAME" 168 fi 169 echo -e "\tFor support, go to https://github.com/helm/helm." 170 fi 171 cleanup 172 exit $result 173} 174 175# testVersion tests the installed client to make sure it is working. 176testVersion() { 177 set +e 178 HELM="$(which $PROJECT_NAME)" 179 if [ "$?" = "1" ]; then 180 echo "$PROJECT_NAME not found. Is $HELM_INSTALL_DIR on your "'$PATH?' 181 exit 1 182 fi 183 set -e 184 echo "Run '$PROJECT_NAME init' to configure $PROJECT_NAME." 185} 186 187# help provides possible cli installation arguments 188help () { 189 echo "Accepted cli arguments are:" 190 echo -e "\t[--help|-h ] ->> prints this help" 191 echo -e "\t[--version|-v <desired_version>]" 192 echo -e "\te.g. --version v2.4.0 or -v latest" 193 echo -e "\t[--no-sudo] ->> install without sudo" 194} 195 196# cleanup temporary files to avoid https://github.com/helm/helm/issues/2977 197cleanup() { 198 if [[ -d "${HELM_TMP_ROOT:-}" ]]; then 199 rm -rf "$HELM_TMP_ROOT" 200 fi 201} 202 203# Execution 204 205#Stop execution on any error 206trap "fail_trap" EXIT 207set -e 208 209# Parsing input arguments (if any) 210export INPUT_ARGUMENTS="${@}" 211set -u 212while [[ $# -gt 0 ]]; do 213 case $1 in 214 '--version'|-v) 215 shift 216 if [[ $# -ne 0 ]]; then 217 export DESIRED_VERSION="${1}" 218 else 219 echo -e "Please provide the desired version. e.g. --version v2.4.0 or -v latest" 220 exit 0 221 fi 222 ;; 223 '--no-sudo') 224 USE_SUDO="false" 225 ;; 226 '--help'|-h) 227 help 228 exit 0 229 ;; 230 *) exit 1 231 ;; 232 esac 233 shift 234done 235set +u 236 237initArch 238initOS 239verifySupported 240checkDesiredVersion 241if ! checkHelmInstalledVersion; then 242 downloadFile 243 installFile 244fi 245testVersion 246cleanup 247