#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
#
# Starts a Hive Server2
#
# chkconfig: 345 85 15
# description: Hive Server2
# pidfile: /var/run/hive/hive-server2.pid
### BEGIN INIT INFO
# Provides:          hive-server2
# Short-Description: Hive Server2
# Default-Start:     3 4 5
# Default-Stop:      0 1 2 6
# Required-Start:    $syslog $remote_fs
# Required-Stop:     $syslog $remote_fs
# Should-Start:
# Should-Stop:
### END INIT INFO

if [ -r /lib/lsb/init-functions ]; then
  . /lib/lsb/init-functions
elif [ -r /etc/init.d/functions ]; then
  . /etc/init.d/functions
elif [ -r /etc/rc.d/init.d/functions ]; then
  . /etc/rc.d/init.d/functions
fi

# Minimal LSB init-functions compatibility layer for systems that ship none
# of the files sourced above (e.g. SberLinux 9.7). Adapted from the reference
# implementation of /lib/lsb/init-functions (Linux From Scratch), stripped of
# terminal colors and boot logging which are not needed here.
if ! type pidofproc >/dev/null 2>&1; then
pidofproc()
{
    local pidfile
    local program
    local prefix
    local progname
    local pidlist
    local pid
    local lpids
    local exitstatus="0"

    while true; do
        case "$1" in
            -p)
                pidfile="$2"
                shift 2
                ;;
            *)
                program="$1"
                break
                ;;
        esac
    done

    if [ -z "$pidfile" ]; then
        prefix=$(echo "$program" | sed 's/[^/]*$//')
        if [ -z "$prefix" ]; then
            progname="$program"
        else
            progname=$(echo "$program" | sed "s@$prefix@@")
        fi
        [ -e "/var/run/$progname.pid" ] && pidfile="/var/run/$progname.pid"
    fi

    if [ -n "$pidfile" ] && [ -e "$pidfile" ]; then
        pidlist=$(head -n1 "$pidfile" 2>/dev/null)
    else
        pidlist=$(pidof "$program" 2>/dev/null)
    fi

    for pid in $pidlist; do
        if kill -0 "$pid" 2>/dev/null; then
            lpids="$lpids$pid "
        else
            exitstatus="1"
        fi
    done

    if [ -z "$lpids" ] && { [ -z "$pidfile" ] || [ ! -f "$pidfile" ]; }; then
        return 3
    fi
    echo "$lpids"
    return "$exitstatus"
}
fi

if ! type start_daemon >/dev/null 2>&1; then
start_daemon()
{
    local force=""
    local nice="0"
    local pidfile=""
    local pidlist
    local retval

    while true; do
        case "$1" in
            -f) force="1"; shift 1 ;;
            -n) nice="$2"; shift 2 ;;
            -p) pidfile="$2"; shift 2 ;;
            -*) return 2 ;;
            *) break ;;
        esac
    done

    [ -e "$1" ] || return 5

    if [ -z "$force" ]; then
        if [ -z "$pidfile" ]; then
            pidlist=$(pidofproc "$1")
        else
            pidlist=$(pidofproc -p "$pidfile" "$1")
        fi
        retval="$?"
        case "$retval" in
            0) return 0 ;;
            1) [ -n "$pidfile" ] && rm -f "$pidfile" ;;
            3) : ;;
            *) return 1 ;;
        esac
    fi

    nice -n "$nice" "$@"
}
fi

if ! type killproc >/dev/null 2>&1; then
killproc()
{
    local pidfile
    local program
    local signal="-TERM"
    local fallback="-KILL"
    local nosig=""
    local pidlist
    local retval
    local pid
    local delay
    local piddead

    while true; do
        case "$1" in
            -p)
                pidfile="$2"
                shift 2
                ;;
            *)
                program="$1"
                if [ -n "$2" ]; then
                    signal="$2"
                    fallback=""
                else
                    nosig=1
                fi
                break
                ;;
        esac
    done

    if [ -z "$pidfile" ]; then
        pidlist=$(pidofproc "$program")
    else
        pidlist=$(pidofproc -p "$pidfile" "$program")
    fi
    retval="$?"

    case "$retval" in
        0) : ;;
        1)
            [ -n "$pidfile" ] && rm -f "$pidfile"
            [ -n "$nosig" ] && return 0 || return 7
            ;;
        3)
            [ -n "$nosig" ] && return 0 || return 7
            ;;
        *) return 1 ;;
    esac

    piddead=""
    for pid in $pidlist; do
        kill -0 "$pid" 2>/dev/null || continue
        kill "$signal" "$pid" 2>/dev/null
        delay=30
        while [ "$delay" -ne 0 ]; do
            kill -0 "$pid" 2>/dev/null || { piddead=1; break; }
            sleep 0.1
            delay=$((delay - 1))
        done
        if [ -n "$fallback" ] && [ "$piddead" != "1" ]; then
            kill "$fallback" "$pid" 2>/dev/null
            sleep 1
            kill -0 "$pid" 2>/dev/null && return 1
        fi
    done

    [ -n "$pidfile" ] && rm -f "$pidfile" 2>/dev/null
    return 0
}
fi

type log_success_msg >/dev/null 2>&1 || log_success_msg() { echo "$*"; }
type log_failure_msg >/dev/null 2>&1 || log_failure_msg() { echo "$*" >&2; }
type log_warning_msg >/dev/null 2>&1 || log_warning_msg() { echo "$*"; }
BIGTOP_DEFAULTS_DIR=${BIGTOP_DEFAULTS_DIR-/etc/default}
[ -n "${BIGTOP_DEFAULTS_DIR}" -a -r ${BIGTOP_DEFAULTS_DIR}/hadoop ] && . ${BIGTOP_DEFAULTS_DIR}/hadoop
[ -n "${BIGTOP_DEFAULTS_DIR}" -a -r ${BIGTOP_DEFAULTS_DIR}/hive-server2 ] && . ${BIGTOP_DEFAULTS_DIR}/hive-server2
[ -r /etc/hive/conf/hive-server-secrets-env.sh ] && . /etc/hive/conf/hive-server-secrets-env.sh
[ -r /etc/hive/conf/hive-server2-env.sh ] && . /etc/hive/conf/hive-server2-env.sh

# Configure log directory from hive-env if present, with fallback
LOG_DIR=${LOG_DIR:-${HIVE_LOG_DIR}}
LOG_DIR=${LOG_DIR:-/var/log/hive}
export LOG_DIR
export HIVE_LOG_DIR=${HIVE_LOG_DIR:-$LOG_DIR}
install -d -m 0755 -o hive -g hive "$LOG_DIR" 1>/dev/null 2>&1 || :

# Autodetect JAVA_HOME if not defined
. /usr/lib/bigtop-utils/bigtop-detect-javahome

RETVAL_SUCCESS=0

STATUS_RUNNING=0
STATUS_DEAD=1
STATUS_DEAD_AND_LOCK=2
STATUS_NOT_RUNNING=3
STATUS_OTHER_ERROR=102


ERROR_PROGRAM_NOT_INSTALLED=5
ERROR_PROGRAM_NOT_CONFIGURED=6


RETVAL=0
SLEEP_TIME=5
PROC_NAME="java"

DAEMON="hive-server2"
DESC="Hive Server2"
EXEC_PATH="/usr/lib/hive/bin/hive"
DAEMON_FLAGS=""
CONF_DIR="/etc/hive/conf"
CONF_FILE=""
LOGFILE=""
PIDFILE="/var/run/hive/hive-server2.pid"
LOCKDIR="/var/lock"
LOCKFILE="$LOCKDIR/hive-server2"
WORKING_DIR="/var/lib/hive"

install -d -m 0755 -o hive -g hive /var/run/hive 1>/dev/null 2>&1 || :
[ -d "$LOCKDIR" ] || install -d -m 0755 $LOCKDIR 1>/dev/null 2>&1 || :
start() {
    [ -x $EXE_FILE ] || exit $ERROR_PROGRAM_NOT_INSTALLED

    checkstatusofproc
    status=$?
    if [ "$status" -eq "$STATUS_RUNNING" ]; then
        log_success_msg "${DESC} is running"
        exit 0
    fi

    LOG_FILE="$LOG_DIR/${DAEMON}.out"

    exec_env="HIVE_OPTS=\"-hiveconf hive.log4j.file=/etc/hive/conf/hive-log4j.properties\""

    /bin/bash -c "$exec_env nohup nice -n 0 \
        $EXEC_PATH --service hiveserver2 $PORT \
            >> \"$LOG_FILE\" 2>&1 < /dev/null & "'echo $! '"> $PIDFILE"
    sleep 3

    checkstatusofproc
    RETVAL=$?

    if [ $RETVAL -eq $STATUS_RUNNING ]; then
      touch $LOCKFILE
      log_success_msg "Started ${DESC} (${DAEMON}): "
    else
      log_failure_msg "Failed to start ${DESC}. Return value: $RETVAL"
    fi

    return $RETVAL
}
stop() {
    killproc -p $PIDFILE java
    RETVAL=$?

    if [ $RETVAL -eq $RETVAL_SUCCESS ]; then
      log_success_msg "Stopped ${DESC}: "
      rm -f $LOCKFILE $PIDFILE
    else
      log_failure_msg "Failure to stop ${DESC}. Return value: $RETVAL"
    fi

    return $RETVAL
}
restart() {
  stop
  start
}

checkstatusofproc(){
  pidofproc -p $PIDFILE $PROC_NAME > /dev/null
}

checkstatus(){
  checkstatusofproc
  status=$?

  case "$status" in
    $STATUS_RUNNING)
      log_success_msg "${DESC} is running"
      ;;
    $STATUS_DEAD)
      log_failure_msg "${DESC} is dead and pid file exists"
      ;;
    $STATUS_DEAD_AND_LOCK)
      log_failure_msg "${DESC} is dead and lock file exists"
      ;;
    $STATUS_NOT_RUNNING)
      log_failure_msg "${DESC} is not running"
      ;;
    *)
      log_failure_msg "${DESC} status is unknown"
      ;;
  esac
  return $status
}

condrestart(){
  [ -e $LOCKFILE ] && restart || :
}

service() {
  case "$1" in
    start)
      start
      ;;
    stop)
      stop
      ;;
    status)
      checkstatus
      RETVAL=$?
      ;;
    restart|force-reload)
      restart
      ;;
    condrestart|try-restart)
      condrestart
      ;;
    *)
      echo $"Usage: $0 {start|stop|status|restart|try-restart|condrestart|force-reload}"
      exit 1
  esac
}

service "$1"

exit $RETVAL
