#!/bin/sh die() { [ -n "$1" ] && echo ERROR "$1" >&2 exit ${2:-1} } usage() { die "\ Usage: $0 [-s download_url] [-p packages_url_prefix] [-d destdir] [-u jet_user] [-S] -s - source download URL, env DOWNLOAD_URL (default: $DOWNLOAD_URL) -p - packages download URL prefix, env PACKAGER_URL_PREFIX (default: $PACKAGER_URL_PREFIX) -d - destination directory, env DESTDIR (default: $DESTDIR) -u - jet user, env JET_USER (default: $JET_USER) -S - don't start jet after downloading and installing " } # # Default values and check if running as root # : ${JET_ROOT:=/jet} : ${DOWNLOAD_URL:='http://jetware.io/appliances/jetware/memcached14-170503/download/installer:nub_tgz'} : ${PACKAGER_URL_PREFIX:='http://download.jetware.org/packager/'} : ${DESTDIR:=$JET_ROOT} if [ `id -u` = 0 ]; then running_root=yes : ${JET_USER:=jet} else running_root= : ${JET_USER:=$USER} fi # # Parse options # while getopts s:p:d:u:Slh? opt; do case $opt in s) DOWNLOAD_URL="$OPTARG" ;; p) PACKAGER_URL_PREFIX="$OPTARG" ;; d) DESTDIR="$OPTARG" ;; u) JET_USER="$OPTARG" ;; S) DONT_START=yes ;; *) usage ;; esac done shift $((OPTIND-1)) [ $# = 0 ] || usage # # Check permissions and setup privileged and user execution modes # if [ -n "$running_root" ]; then run_priv() { "$@"; } user_sh() { su "$JET_USER" -s /bin/sh -- "$@" } else command -v sudo >/dev/null || die "'sudo' command required or run install from root" sudo -l >/dev/null || die "Insufficient sudo permissions" run_priv() { sudo "$@"; } if [ "$USER" = "$JET_USER" ]; then user_sh() { sh "$@" } else user_sh() { sudo su "$JET_USER" -s /bin/sh -- "$@" } fi fi # # Install required binaries using distribution's package manager # required_binaries="sudo su useradd curl tar gunzip setcap" missing= for cmd in $required_binaries; do command -v $cmd >/dev/null || missing="$missing $cmd" done if [ -n "$missing" ]; then if command -v apt-get >/dev/null; then # debian 7, 8; ubuntu 14.04, 16.04 run_priv apt-get update || die "apt-get update" run_priv apt-get install -y login passwd sudo curl gzip libcap2-bin || die "apt-get install" elif command -v yum >/dev/null; then # redhat, centos, fedora run_priv yum install -y util-linux shadow-utils sudo curl tar gzip libcap || die "yum" else die "Missing binaries: $missing" fi fi # # Set exit and cleanup handler # destdir_tmp= new_user= tmp_sudoers= CLEANUP() { trap '' EXIT [ -n "$tmp_sudoers" -a -e "$tmp_sudoers" ] && run_priv rm -f "$tmp_sudoers" # delete temporary directory new user if [ -d "$destdir_tmp" ]; then run_priv rm -rf "$destdir_tmp" [ -n "$new_user" ] && userdel $JET_USER fi } TERMINATE() { local err=$? trap '' INT TERM exit $err } trap CLEANUP EXIT trap TERMINATE INT TERM # # Check and prepare directories # [ -e "$DESTDIR" ] && die "Destination directory $DESTDIR already exists" destdir_tmp=${DESTDIR}.jet.$$ [ -e "$destdir_tmp" ] && die "Temporary directory $destdir_tmp already exists" run_priv mkdir -p "$destdir_tmp" || die # # Create user if running as root, and grant him temporary sudo to allow admin privileges during fasten process # if [ -n "$running_root" ]; then id $JET_USER >/dev/null 2>&1 && die "User $JET_USER already exists" new_user=yes run_priv useradd --system --home "$DESTDIR" --shell "$DESTDIR/login" $JET_USER || die tmp_sudoers=/etc/sudoers.d/99-tmp-$$ run_priv sh <<_EOF_ echo "\ $JET_USER ALL=NOPASSWD: ALL Defaults:$JET_USER !requiretty " > "$tmp_sudoers" _EOF_ fi run_priv chown $JET_USER "$destdir_tmp" || die # # Download # user_sh <<_EOF_ || exit if command -v curl >/dev/null; then download() { : \${COLUMNS:=80} [ -t 2 ] && printf "\\033[\$((COLUMNS/2+1))C" >&2 printf "\${1##*/}" >&2 COLUMNS=\$((COLUMNS/2)) curl --progress-bar -L "\$1" } elif command -v wget >/dev/null; then download() { wget --quiet --show-progress --progress=bar -O - "\$1" } fi echo Downloading and extracting "$DOWNLOAD_URL" ... >&2 download "$DOWNLOAD_URL" | tar xpzf - -C "$destdir_tmp" || exit while read PACKAGE ROLE NAME VERSION; do [ -e "$destdir_tmp/use/\$ROLE" ] && continue [ -h "$destdir_tmp/use/\$ROLE" ] && rm -f "$destdir_tmp/use/\$ROLE" mkdir "$destdir_tmp/use/\$ROLE" download "$PACKAGER_URL_PREFIX/\$PACKAGE.tgz" | tar xpzf - -C "$destdir_tmp/use/\$ROLE" || exit done < "$destdir_tmp/own/packages" _EOF_ # # Setup and start jet running with user credentials # sudo mv "$destdir_tmp" "$DESTDIR" || exit user_sh <<_EOF_ || exit "$DESTDIR"/own/bin/run "$JET_ROOT"/own/bin/config \ appliance.author="jetware" \ appliance.name="memcached14" \ appliance.title="Memcached 1.4" \ appliance.version="170503" \ appliance.url="http://jetware.io/appliances/jetware/memcached14-170503" \ appliance.support_url="http://jetware.io/contacts/submit?contacts_form%5Bsubject%5D=Appliance%3A+jetware%2Fmemcached14-170503" echo Setting up ... >&2 "$DESTDIR"/own/bin/run "$JET_ROOT"/own/bin/fasten || exit if [ -z "$DONT_START" ]; then echo Starting ... >&2 "$DESTDIR"/enter start fi echo Done >&2 exit 0 _EOF_ # # Show quick start manual # if [ -n "$new_user" ]; then echo -n "\ ----------------------------------------------------------------------------- To enter the runtime environment, log in as the user '$JET_USER'. " >&2 else echo -n "\ ----------------------------------------------------------------------------- To enter the runtime environment, run: $DESTDIR/enter " >&2 fi quick_start= for file in usage config_show; do if [ -e "$DESTDIR/bin/$file" ]; then quick_start="$file" break fi done if [ -n "$quick_start" ]; then if [ -n "$new_user" ]; then echo -n "\ To execute a command, i.e. show quick start configuration via '$quick_start' command, log in as the user '$JET_USER': su -l $JET_USER and run: $quick_start or run from root: su -l $JET_USER -c $quick_start " >&2 else echo -n "\ To execute a command, i.e. show quick start configuration via '$quick_start' command, run: $DESTDIR/enter $quick_start " >&2 fi fi