#!/bin/bash #------------------------------------------------------------------------------ # Script: idt-installer #------------------------------------------------------------------------------ # IBM Cloud Developer Tools - CLI installer script for MacOS and Linux systems #------------------------------------------------------------------------------ # Copyright (c) 2018, International Business Machines. All Rights Reserved. #------------------------------------------------------------------------------ VERSION="1.2.3" PROG="IBM Cloud Developer Tools for Linux/MacOS - Installer" INSTALLER_URL="https://ibm.biz/idt-installer" GIT_URL="https://github.com/IBM-Cloud/ibm-cloud-developer-tools" SLACK_URL="https://slack-invite-ibm-cloud-tech.mybluemix.net/" IDT_INSTALL_BMX_URL="https://clis.cloud.ibm.com/install" IDT_INSTALL_BMX_REPO_NAME="Bluemix" IDT_INSTALL_BMX_REPO_URL="https://plugins.cloud.ibm.com" #------------------------------------------------------------------------------ function help { cat <<-!!EOF ${PROG} Usage: idt-installer [] Where is: install [Default] Perform full install (or update) of all needed CLIs and Plugins help | -h | -? Show this help --force Force updates of dependencies and other settings during update --trace Eanble verbose tracing of all activity If "install" (or no action provided), a full CLI installation (or update) will occur: 1. Pre-req check for 'git', 'docker', and 'kubectl' 2. Install latest IBM Cloud 'ibmcloud' CLI 3. Install all required plugins Chat with us on Slack: ${SLACK_URL}, channel #developer-tools Submit any issues to : ${GIT_URL}/issues !!EOF } #------------------------------------------------------------------------------ #-- ${FUNCNAME[1]} == Calling function's name #-- Colors escape seqs YEL='\033[1;33m' CYN='\033[0;36m' GRN='\033[1;32m' RED='\033[1;31m' NRM='\033[0m' function log { echo -e "${CYN}[${FUNCNAME[1]}]${NRM} $*" } function warn { echo -e "${CYN}[${FUNCNAME[1]}]${NRM} ${YEL}WARN${NRM}: $*" } function error { echo -e "${CYN}[${FUNCNAME[1]}]${NRM} ${RED}ERROR${NRM}: $*" exit -1 } function prompt { label=${1} default=${2} if [[ -z $default ]]; then echo -en "${label}: ${CYN}" > /dev/tty else echo -en "${label} [$default]: ${CYN}" > /dev/tty fi read -r echo -e "${NRM}" > /dev/tty #-- Use $REPLY to get user's input } #------------------------------------------------------------------------------ function install { if [[ -n "$(which ibmcloud)" ]]; then log "Starting Installation..." else log "Starting Update..." fi #-- Check if internal IBM setup if [[ -n "$(which ibmcloud)" ]]; then read -r repo url <<< $(ibmcloud plugin repos | grep stage1) if [[ -n "$repo" ]]; then echo prompt "Use IBM internal '$repo' repos for install/updates (Y/n)?" echo if [[ "$REPLY" != [Nn]* ]]; then IDT_INSTALL_BMX_URL="https://clis.stage1.ng.bluemix.net/install" IDT_INSTALL_BMX_REPO_NAME="${repo}" IDT_INSTALL_BMX_REPO_URL="${url}" fi fi fi [ "$SUDO" ] && log "Note: You may be prompted for your 'sudo' password during install." install_deps install_ibmcloud install_plugins env_setup add log "Install finished." } #------------------------------------------------------------------------------ function install_deps { #-- check for/install brew for macos case "$PLATFORM" in "Darwin") install_darwin_deps ;; "Linux") if [[ "${DISTRO}" == *Ubuntu* || "${DISTRO}" == *Debian* ]]; then install_deps_with_apt_get elif [[ "${DISTRO}" == *Red*Hat* || "${DISTRO}" == *CentOS* || "${DISTRO}" == *RHEL* || "${DISTRO}" == *Fedora* ]]; then install_deps_with_yum else error "This script has not been updated for use with your linux distribution (${DISTRO})" fi ;; esac } #------------------------------------------------------------------------------ function install_darwin_deps { log "Checking for external dependency: brew" if [[ -z "$(which brew)" && -n "$(which ruby)" ]]; then log "'brew' installer not found, attempting to install..." ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" log "'brew' installation completed." fi if [[ "$FORCE" == true ]]; then log "Updating 'brew'..." brew update fi #-- GIT: log "Installing/updating external dependency: git" if [[ -z "$(which git)" ]]; then brew install git log "Please review any setup requirements for 'git' from: https://git-scm.com/downloads" elif [[ "$FORCE" == true ]]; then brew upgrade git fi #-- Docker: log "Installing/updating external dependency: docker" if [[ -z "$(which docker)" ]]; then brew install --cask docker log "Please review any setup requirements for 'docker' from: https://docs.docker.com/engine/installation/" elif [[ "$FORCE" == true ]]; then brew reinstall --cask docker fi #-- kubectl: log "Installing/updating external dependency: kubectl" if [[ -z "$(which kubectl)" || "$FORCE" == true ]]; then local kube_version=$(get_kubectl_version) curl --progress-bar -LO https://storage.googleapis.com/kubernetes-release/release/v$kube_version/bin/darwin/amd64/kubectl $SUDO mv ./kubectl /usr/local/bin/kubectl $SUDO chmod +x /usr/local/bin/kubectl log "Please review any setup requirements for 'kubectl' from: https://kubernetes.io/docs/tasks/tools/install-kubectl/" fi # #-- helm: # log "Installing/updating external dependency: helm" # if [[ -z "$(which helm)" ]]; then # brew install kubernetes-helm # log "Please review any setup requirements for 'helm' from: https://github.com/kubernetes/helm/blob/master/docs/install.md" # elif [[ "$FORCE" == true ]]; then # brew upgrade kubernetes-helm # fi } #------------------------------------------------------------------------------ function install_deps_with_apt_get { log "Checking for and updating 'apt-get' support on Linux" if [[ -z "$(which apt-get)" ]]; then error "'apt-get' is not found. That's the only Debian/Ubuntu linux installer I know, sorry." fi $SUDO apt-get -y -qq update > /dev/null if [[ -z "$(which add-apt-repository)" ]]; then if [ "$(apt-cache search software-properties-common | wc -l)" != "0" ]; then log "Installing package: software-properties-common" $SUDO apt-get install -yqq software-properties-common > /dev/null 2>&1 fi if [ "$(apt-cache search python-software-properties | wc -l)" != "0" ]; then log "Installing package: python-software-properties" $SUDO apt-get install -yqq python-software-properties > /dev/null 2>&1 fi fi $SUDO add-apt-repository -y ppa:git-core/ppa $SUDO apt-get -y update #-- CURL: log "Installing/updating external dependency: curl" if [[ -z "$(which curl)" || "$FORCE" == true ]]; then $SUDO apt-get -y install curl fi #-- GIT: log "Installing/updating external dependency: git" if [[ -z "$(which git)" || "$FORCE" == true ]]; then $SUDO apt-get -y install git log "Please review any setup requirements for 'git' from: https://git-scm.com/downloads" fi #-- Docker: install_docker #-- kubectl: log "Installing/updating external dependency: kubectl" if [[ -z "$(which kubectl)" || "$FORCE" == true ]]; then local kube_version=$(get_kubectl_version) curl --progress-bar -LO https://storage.googleapis.com/kubernetes-release/release/v$kube_version/bin/linux/amd64/kubectl $SUDO mv ./kubectl /usr/local/bin/kubectl $SUDO chmod +x /usr/local/bin/kubectl log "Please review any setup requirements for 'kubectl' from: https://kubernetes.io/docs/tasks/tools/install-kubectl/" fi # #-- helm: # log "Installing/updating external dependency: helm" # if [[ -z "$(which helm)" || "$FORCE" == true ]]; then # curl -fsSL https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash # log "Please review any setup requirements for 'helm' from: https://github.com/kubernetes/helm/blob/master/docs/install.md" # fi } #------------------------------------------------------------------------------ function install_deps_with_yum { log "Checking for and updating 'yum' support on Linux" if [[ -z "$(which yum)" ]]; then error "'yum' is not found. That's the only RedHat/Centos linux installer I know, sorry." fi #-- CURL: log "Installing/updating external dependency: curl" if [[ -z "$(which curl)" || "$FORCE" == true ]]; then $SUDO yum -y install curl fi #-- GIT: log "Installing/updating external dependency: git" if [[ -z "$(which git)" || "$FORCE" == true ]]; then $SUDO yum install -y git log "Please review any setup requirements for 'git' from: https://git-scm.com/downloads" fi #-- Docker: install_docker #-- kubectl: log "Installing/updating external dependency: kubectl" if [[ -z "$(which kubectl)" || "$FORCE" == true ]]; then $SUDO sh -c 'printf "[kubernetes]\nname=Kubernetes\nbaseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg\n" > /etc/yum.repos.d/kubernetes.repo' local kube_version=$(get_kubectl_version) local kube_yum_version=$(yum --showduplicates list kubectl -y | grep -Eo "($kube_version\-[0-9*])") $SUDO yum install -y kubectl-$kube_yum_version log "Please review any setup requirements for 'kubectl' from: https://kubernetes.io/docs/tasks/tools/install-kubectl/" fi # #-- helm: # log "Installing/updating external dependency: helm" # if [[ -z "$(which helm)" || "$FORCE" == true ]]; then # curl -fsSL https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash # log "Please review any setup requirements for 'helm' from: https://github.com/kubernetes/helm/blob/master/docs/install.md" # fi } #------------------------------------------------------------------------------ function install_docker { #-- Docker: log "Installing/updating external dependency: docker" if [[ -z "$(which docker)" || "$FORCE" == true ]]; then curl -fsSL get.docker.com | $SUDO sh - if [ "$SUDO" ]; then # Allow docker to run as a non-root user (if not running as root). sudo groupadd docker 2>/dev/null sudo usermod -aG docker $USER 2>/dev/null else log 'If you want to run docker without sudo run: "sudo groupadd docker && sudo usermod -aG docker $USER"' fi log "Please review any setup requirements for 'docker' from: https://docs.docker.com/engine/installation/" fi docker version } #------------------------------------------------------------------------------ function install_ibmcloud { if [[ -z "$(which ibmcloud)" ]]; then log "Installing IBM Cloud 'ibmcloud' CLI for platform '${PLATFORM}'..." case "$PLATFORM" in "Darwin") log "Downloading and installing IBM Cloud 'ibmcloud' CLI from: ${IDT_INSTALL_BMX_URL}/osx" sh <(curl -fsSL ${IDT_INSTALL_BMX_URL}/osx) ;; "Linux") log "Downloading and installing IBM Cloud 'ibmcloud' CLI from: ${IDT_INSTALL_BMX_URL}/linux" sh <(curl -fsSL ${IDT_INSTALL_BMX_URL}/linux) ;; esac log "IBM Cloud 'ibmcloud' CLI install finished." else #-- Upgrade log "Updating existing IBM Cloud 'ibmcloud' CLI..." if [[ "$FORCE" == true ]]; then ibmcloud update -f else ibmcloud update fi fi log "Running 'ibmcloud --version'..." ibmcloud --version } #------------------------------------------------------------------------------ function install_plugins { #-- ibmcloud plugins to process PLUGINS=( "cloud-functions" "cloud-object-storage" "container-registry" "container-service" ) log "Installing/updating IBM Cloud CLI plugins..." for plugin in "${PLUGINS[@]}"; do log "Checking status of plugin: ${plugin}" read -r p ver <<< "$(ibmcloud plugin list | grep "^${plugin} ")" if [[ -z "$p" ]]; then log "Installing plugin '$plugin'" ibmcloud plugin install -f -r "${IDT_INSTALL_BMX_REPO_NAME}" "$plugin" else log "Updating plugin '$plugin' from version '$ver'" ibmcloud plugin update -r "${IDT_INSTALL_BMX_REPO_NAME}" "$plugin" fi done log "Running 'ibmcloud plugin list'..." ibmcloud plugin list log "Finished installing/updating plugins" } #------------------------------------------------------------------------------ function env_setup { env_file="" if [[ -f ~/.bashrc ]] ; then env_file=~/.bashrc elif [[ -f ~/.bash_profile ]]; then env_file=~/.bash_profile elif [[ -f ~/.profile ]] ; then env_file=~/.profile elif [[ -f ~/.zshrc ]] ; then env_file=~/.zshrc fi #-- Clear up any old aliases if [[ -n "$(grep 'alias idt="ibmcloud dev"' "$env_file")" ]]; then log "Removing old 'idt' aliases from: ${env_file}" sed -E -i ".idt_uninstall_bak" \ -e '/^#-- Added by the IDT Installer$/d' \ -e '/^alias idt=\"ibmcloud dev\"$/d' \ -e '/^alias idt-update=/d' \ -e '/^alias idt-uninstall=/d' \ ${env_file} warn "Please restart your shell so old 'idt' alias does not get picked up!" warn "Symptom is: running 'idt update' results in 'update is not a defined command'." fi if [[ "$1" == "add" && $(grep "alias ic=" $env_file) == "" ]]; then #-- Add alias "ic" echo 'alias ic="ibmcloud"' >> ${env_file} warn "Please restart your shell to enable 'ic' alias for ibmcloud!" fi } function get_kubectl_version { # get supported kubectl versions for IBM Cloud kubernetes clusters local result=$(curl -X GET --header 'Accept: application/json' 'https://containers.cloud.ibm.com/v1/kube-versions' | grep -Eo "\{[^}]*\"default\"\:\s*true[^{]*\}") local major=$( echo $result | grep -Eo \"major\"\:\s*[0-9]* | grep -Eo [0-9]+ ) local minor=$( echo $result | grep -Eo \"minor\"\:\s*[0-9]* | grep -Eo [0-9]+ ) local patch=$( echo $result | grep -Eo \"patch\"\:\s*[0-9]* | grep -Eo [0-9]+ ) echo "$major.$minor.$patch" } #------------------------------------------------------------------------------ # MAIN #------------------------------------------------------------------------------ function main { log "--==[ ${GRN}${PROG}, v${VERSION}${NRM} ]==--" (( SECS = SECONDS )) TMPDIR=${TMPDIR:-"/tmp"} PLATFORM=$(uname) ACTION="" # Only use sudo if not running as root: [ "$(id -u)" -ne 0 ] && SUDO=sudo || SUDO="" #-- Parse args while [[ $# -gt 0 ]]; do case "$1" in "--trace") warn "Enabling verbose tracing of all activity" set -x ;; "--force") FORCE=true warn "Forcing updates for all dependencies and other settings" ;; "update") ACTION="install";; "install") ACTION="install";; "help") ACTION="help";; esac shift done case "$PLATFORM" in "Darwin") ;; "Linux") # Linux distro, e.g "Ubuntu", "RedHatEnterpriseWorkstation", "RedHatEnterpriseServer", "CentOS", "Debian" DISTRO=$(lsb_release -ds 2>/dev/null || cat /etc/*release 2>/dev/null | head -n1 || uname -om || echo "") if [[ "$DISTRO" != *Ubuntu* && "$DISTRO" != *Red*Hat* && "$DISTRO" != *CentOS* && "$DISTRO" != *Debian* && "$DISTRO" != *RHEL* && "$DISTRO" != *Fedora* ]]; then warn "Linux has only been tested on Ubuntu, RedHat, Centos, Debian and Fedora distrubutions please let us know if you use this utility on other Distros" fi ;; *) warn "Only MacOS and Linux systems are supported by this installer." warn "For Windows, please follow manual installation instructions at:" warn "${GIT_URL}" error "Unsupported platform: ${PLATFORM}" ;; esac case "$ACTION" in "") install;; "install") install;; *) help;; esac (( SECS = SECONDS - SECS )) log "--==[ ${GRN}Total time: ${SECS} seconds${NRM} ]==--" } #------------------------------------------------------------------------------ #-- Kick things off #------------------------------------------------------------------------------ main "$@"