#!/bin/bash

# Installer for the Ksplice Uptrack client. For additional installation
# instructions, see http://www.ksplice.com/uptrack/install. Please contact
# ksplice-support_ww@oracle.com with questions or feedback.
#
# Copyright (C) 2012 Ksplice, Inc.
#
# install-uptrack is licensed under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
# License for the specific language governing permissions and limitations under
# the License.

set -e

aptget="apt-get -o APT::Install-Recommends=false"

usage() {
    (
	echo "Usage: ${0} ACCESSKEY [OPTIONS]"
	echo ""
	echo "OPTIONS"
	echo "-a, --autoinstall"
	echo "       Enable autoinstall. In this mode, Ksplice Uptrack will"
	echo "       automatically install updates as they become available"
	echo "-r, --release=RELEASE"
	echo "       One of: ol rhel centos virtuozzo openvz cloudlinux fedora scilinux"
	echo "       jessie wheezy squeeze vivid utopic trusty precise lucid"
    ) >&2
    exit 1
}

contact_info() {
    (
	echo "Oracle Linux Premier support customers, please log a MyOracle Support service request for assistance."
	echo "Ksplice legacy customers, please contact ksplice-support_ww@oracle.com."
    ) >&2
}
unsupported_info() {
    echo "You appear to be running an unsupported version of ${1}." >&2
    contact_info
    exit 1
}

have_program() {
    hash "$1" >/dev/null 2>&1
}

dep_check() {
    if ! have_program "$1"; then
        exit_message "'${1}' command not found. Please install or add it to your PATH and try again."
    fi
}

exit_message() {
    echo "[ ${1} ]" >&2
    contact_info
    exit 1
}

do_retrieval() {
    path=${1}
    installer=${2}

    if have_program wget; then
        getter="wget -N ${path}"
    else
        if have_program curl; then
            getter="curl -O ${path}"
        else
            # Give up and install curl, preferential to wget because
            # curl is used in other parts of the Uptrack service.
            echo "[ Installing curl ]"
            if [ "${installer}" = "yum" ]; then
                yum -y install curl
            elif [ "${installer}" = "apt" ]; then
                $aptget -y install curl
            else
                up2date curl
            fi
            getter="curl -O ${path}"
        fi
    fi

    if ! ${getter}; then
        exit_message "Unable to retrieve archive. Please check your Internet connection and try again."
    fi
}

do_redhat_install() {
    access_key=${1}
    release=${2}

    # Check software dependencies and directories
    dep_check rpm

    # Do installation
    if have_program yum; then
        install_cmd="yum -y install uptrack"
        installer="yum"
    elif have_program up2date; then
        install_cmd="up2date uptrack"
        installer="up2date"
    else
        exit_message "'yum' command not found. Please install or add it to your PATH and try again."
    fi

    if [ "${release}" = "ol" ]; then
	do_retrieval https://www.ksplice.com/yum/uptrack/ol/ksplice-uptrack-release.noarch.rpm ${installer}
    elif [ "${release}" = "fedora" ]; then
	do_retrieval https://www.ksplice.com/yum/uptrack/fedora/ksplice-uptrack-release.noarch.rpm ${installer}
    elif [ "${release}" = "rhel" ]; then
	do_retrieval https://www.ksplice.com/yum/uptrack/rhel/ksplice-uptrack-release.noarch.rpm ${installer}
    else
	do_retrieval https://www.ksplice.com/yum/uptrack/centos/ksplice-uptrack-release.noarch.rpm ${installer}
    fi

    echo "[ Installing Uptrack ]"
    if rpm --quiet -q ksplice-uptrack-release; then
        rpm -Fv ksplice-uptrack-release.noarch.rpm
    else
        rpm -iv ksplice-uptrack-release.noarch.rpm
    fi

    if ! ${install_cmd}; then
	exit_message "Error installing Ksplice Uptrack."
    fi

    perl -pi -e "s/^\s*accesskey\s*=.*/accesskey = $access_key/" /etc/uptrack/uptrack.conf

    if [ "$autoinstall" -eq "1" ]; then
	perl -pi -e "s/^\s*autoinstall\s*=.*/autoinstall = yes/" /etc/uptrack/uptrack.conf
    fi

    # Installing the Debian package does this automatically, but we
    # need to do it manually here.
    if [ -z "$no_run_uptrack_upgrade" ]; then
	/usr/sbin/uptrack-upgrade -n
    fi
}

do_debian_install() {
    access_key=${1}
    release=${2}

    # Check software dependencies and directories
    dep_check apt-get
    dep_check apt-key

    if [ ! -d /etc/apt/sources.list.d/ ]; then
        exit_message "Expected directory /etc/apt/sources.list.d not found."
    fi

    echo "[ Installing ca-certificates ]"
    $aptget -y install ca-certificates
    installer="apt"
    do_retrieval https://www.ksplice.com/apt/ksplice-archive.asc ${installer}

    # Do installation
    rm -f /etc/apt/sources.list.d/ksplice.list

    echo "deb http://www.ksplice.com/apt ${release} ksplice" > /etc/apt/sources.list.d/ksplice.list
    echo "deb-src http://www.ksplice.com/apt ${release} ksplice" >> /etc/apt/sources.list.d/ksplice.list

    apt-key add ksplice-archive.asc
    echo "uptrack uptrack/accesskey string ${access_key}" | debconf-set-selections

    $aptget update
    echo "[ Installing Uptrack ]"
    # The installation automatically runs update-uptrack -n
    if ! $aptget -y install uptrack; then
	exit_message "Error installing Ksplice Uptrack."
    fi

    perl -pi -e "s/^\s*accesskey\s*=.*/accesskey = $access_key/" /etc/uptrack/uptrack.conf

    if [ "$autoinstall" -eq "1" ]; then
	perl -pi -e "s/^\s*autoinstall\s*=.*/autoinstall = yes/" /etc/uptrack/uptrack.conf
    fi
}


if [ `id -u` != "0" ]; then
    echo "You must run the Uptrack installer as root." >&2
    if [ -x /usr/bin/sudo ]; then
        echo "Try running 'sudo ${0}'." >&2
    fi
    exit 1
fi

unset release
SHORTOPTS="ar:h"
LONGOPTS="no-check-access-key,no-run-uptrack-upgrade,autoinstall,release:,help"
OPTS="$(getopt -o $SHORTOPTS --long $LONGOPTS -- "$@")" || usage

access_key=${1};
autoinstall=0

eval set -- "${OPTS}"

for opt
do
    case "${opt}" in
        -a|--autoinstall)
            autoinstall=1; shift 1;;
        -r|--release)
            release=${2}; shift 2;;
	--no-check-access-key)
	    no_check_access_key=1; shift 1;;
	--no-run-uptrack-upgrade)
	    no_run_uptrack_upgrade=1; shift 1;;
        -h|--help)
            usage ;;
        --)
            shift; break;;
    esac
done

# Checks on command line arguments, environment
if [ ! "${access_key}" ]; then
    usage
fi

if [ -z "$no_check_access_key" ] && [ ${#access_key} -ne 64 ]; then
    exit_message "Invalid access key. Please check your access key and try again."
fi

if [ "${release}" ]; then
    case "${release}" in
        ol|rhel|centos|virtuozzo|openvz|squeeze|wheezy|jessie|lenny|vivid|utopic|trusty|saucy|raring|quantal|precise|oneiric|maverick|lucid|karmic|jaunty|hardy|fedora|cloudlinux|scilinux) ;;
        *)
            usage
    esac
fi

# Detect release
if [ ! "${release}" ]; then
    if [ -f /etc/oracle-release ]; then
	release="ol"
    elif [ -f /etc/debian_version ]; then
        if ! have_program lsb_release; then
            echo "[ Installing lsb-release ]"
            $aptget -y install lsb-release
        fi
        release="$(lsb_release --short --codename)"
        case "${release}" in
            # Don't punt on Etch right away even though it's unsupported, so we
            # get the Uptrack notification that a user tried to install on Etch.
            # Similarly, Jaunty and Karmic are EOL'd, but let people install and
            # get a nice error message.
            squeeze|wheezy|jessie|lenny|etch|vivid|utopic|trusty|saucy|raring|quantal|precise|oneiric|maverick|lucid|karmic|jaunty|hardy) ;;
            *)
                unsupported_info "$(lsb_release --short --id)"
        esac
    elif [ -f /etc/redhat-release ]; then
	redhat_release=$(cat /etc/redhat-release)
	if echo ${redhat_release} | egrep -q "Red Hat"; then
	    release="rhel"
	elif echo ${redhat_release} | egrep -q "CentOS"; then
	    release="centos"
	elif echo ${redhat_release} | egrep -q "Parallels"; then
	    # Actually Parallels Server Bare Metal
	    release="rhel"
        elif echo ${redhat_release} | egrep -q "Fedora"; then
		release="fedora"
	elif echo ${redhat_release} | egrep -q "CloudLinux"; then
	    release="cloudlinux"
	elif echo ${redhat_release} | egrep -q "Scientific"; then
	    release="scilinux"
	fi
    fi

    if [ ! "${release}" ]; then
	(
            echo "Unable to detect your release."
            echo "Please supply a release option as an argument instead."
	) >&2
        usage
    fi
    echo "[ Release detected: ${release} ]"
fi

case "${release}" in
    ol|rhel|centos|virtuozzo|openvz|fedora|cloudlinux|scilinux)
        do_redhat_install ${access_key} ${release} ;;
    squeeze|wheezy|jessie|vivid|lenny|etch|vivid|utopic|trusty|saucy|raring|quantal|precise|oneiric|maverick|lucid|karmic|jaunty|hardy)
        do_debian_install ${access_key} ${release} ;;
esac

echo "[ Installation Complete! ]"
echo "[ Please run '/usr/sbin/uptrack-upgrade -y' to bring your system up to date ]"

exit 0
