#!/bin/sh
#
# Copyright 2019-2022 VMware, Inc. All rights reserved.
#
# nsx-netopa:
#   Start/Stop the NSX Netopa
#
# Tell chkconfig to start us with starting rank 98 and shutdown rank 2.
# chkconfig: 2345 98 2
# description: NSX Netopa
#

# Load the LSB shell functions
[ -f /lib/lsb/init-functions ] && . /lib/lsb/init-functions

# variables
PATH=/bin:/sbin:/usr/bin:/usr/local/bin:$PATH
NETOPA=/opt/vmware/nsx-netopa/bin/netopa
NETOPA_TAG=netopa
NETOPA_SOCK_DIR=/var/run/vmware/nsx-netopa
NETOPA_LOG_DIR=/var/log/vmware
NETOPA_MAX_QUICK_RESTARTS="100"
NETOPA_MAX_RESTARTS="1000"
NETOPA_CFG_FILE=/etc/vmware/nsx/netopa.xml
NETOPA_ARGS="-c /etc/vmware/nsx/netopa.xml"
WATCHDOG_ARGS="-d -s ${NETOPA_TAG} -q ${NETOPA_MAX_QUICK_RESTARTS} -t ${NETOPA_MAX_RESTARTS}"
WATCHDOG=/opt/vmware/nsx-netopa/bin/watchdog.sh
nsx_netopa_user="nsx-netopa"
nsx_netopa_group="nsx-netopa"
nsx_group="nsx"
nsx_nestdb_group="nestdb"

nsx_sha_user="nsx-sha"
nsx_sha_group="nsx-sha"
NSX_SHA=/opt/vmware/nsx-netopa/bin/nsx-sha
NSX_SHA_TAG=nsx-sha
NSX_SHA_LOG_DIR=/var/log/vmware
NSX_ODS_FILE_DIR=/var/log/vmware/nsx-ods
NSX_ODS_LOG_DIR=/var/log/vmware/nsx-ods/log
NSX_SHA_SOCK_DIR=/var/run/vmware/nsx-sha
NSX_SHA_PID_FILE=/var/run/vmware/nsx-sha/watchdog-nsx-sha.BG.PID
NSX_SHA_MAX_QUICK_RESTARTS="100"
NSX_SHA_WATCHDOG_ARGS="-d -s ${NSX_SHA_TAG} -q ${NSX_SHA_MAX_QUICK_RESTARTS} -b ${NSX_SHA_PID_FILE}"
nsx_sha_user="nsx-sha"
nsx_proxy_group="nsx-proxy"
adm_group="adm"
nsx_agent_group="nsx-agent"
nsx_opsagent_group="nsx-opsagent"
nsxcli_group="nsxcli"

NSX_ISSUE_FILE=/etc/nsx_issue
nsx_edge="nsx-edge"
nsx_pcg="nsx-public-cloud-gateway"
nsx_bms="nsx-bms"
nsx_bmc="nsx-bmc"

netopa_log() {
   echo "${1}"
   logger -p daemon.info -t NSX "${1}"
}

is_edge() {
   if [ -f $NSX_ISSUE_FILE ] && grep -q $nsx_edge $NSX_ISSUE_FILE; then
      return 0
   fi
   return 1
}

is_pcg() {
   if [ -f $NSX_ISSUE_FILE ] && grep -q $nsx_pcg $NSX_ISSUE_FILE; then
      return 0
   fi
   return 1
}

is_bms() {
   if [ -f $NSX_ISSUE_FILE ] && grep -q $nsx_bms $NSX_ISSUE_FILE; then
      return 0
   fi
   return 1
}

is_bmc() {
   if [ -f $NSX_ISSUE_FILE ] && grep -q $nsx_bmc $NSX_ISSUE_FILE; then
      return 0
   fi
   return 1
}

start_sha() {
   groupadd -f $nsx_sha_user
   if ! getent passwd $nsx_sha_user > /dev/null; then
      useradd --system -N -g $nsx_sha_user --shell /usr/sbin/nologin -M \
      --comment "NSX SHA" $nsx_sha_user
   fi
   groupadd -f $nsx_group
   groupadd -f $nsx_netopa_group
   groupadd -f $nsx_nestdb_group
   groupadd -f $nsx_proxy_group
   groupadd -f $adm_group
   groupadd -f $nsxcli_group
   usermod -a -G $nsx_group $nsx_sha_user
   usermod -a -G $nsx_netopa_group $nsx_sha_user
   usermod -a -G $nsx_nestdb_group $nsx_sha_user
   usermod -a -G $nsx_proxy_group $nsx_sha_user
   usermod -a -G $adm_group $nsx_sha_user
   usermod -a -G $nsxcli_group $nsx_sha_user

   if is_bms; then
       groupadd -f $nsx_agent_group
       groupadd -f $nsx_opsagent_group
       usermod -a -G $nsx_agent_group $nsx_sha_user
       usermod -a -G $nsx_opsagent_group $nsx_sha_user
       # ovsdb socket
       usermod -a -G root $nsx_sha_user
       chmod 770 "/var/run/openvswitch/db.sock"
   fi

   # Check if it is already running
   if [ ! -z "$(ps auxww|grep "/opt/vmware/nsx-netopa/bin/agent.py"|grep -v 'grep' | awk '{print $2}')" ] ; then
      netopa_log "nsx-sha is already running"
      return
   fi

   if [ ! -f "${NSX_SHA}" ]; then
      netopa_log "nsx-sha binary is missing"
      exit 1
   fi

   chown $nsx_sha_user:$nsx_sha_user $NSX_SHA

   # SHA socket dir
   mkdir -p $NSX_SHA_SOCK_DIR
   chown -R $nsx_sha_user:$nsx_sha_user $NSX_SHA_SOCK_DIR
   chmod -R 770 $NSX_SHA_SOCK_DIR

   # ODS file dir
   mkdir -p $NSX_ODS_FILE_DIR
   chown $nsx_sha_user:$nsx_sha_user $NSX_ODS_FILE_DIR
   chmod 744 $NSX_ODS_FILE_DIR

   # ODS log dir
   mkdir -p $NSX_ODS_LOG_DIR
   chown $nsx_sha_user:$nsx_sha_user $NSX_ODS_LOG_DIR
   chmod 744 $NSX_ODS_LOG_DIR

   /sbin/restorecon -v ${NSX_SHA_SOCK_DIR} &> /dev/null || :

   ulimit -c unlimited
   runuser -m $nsx_sha_user -s /bin/bash \
      -c "${WATCHDOG} ${NSX_SHA_WATCHDOG_ARGS} '${NSX_SHA} ${NSX_SHA_PID_FILE}' >/dev/null 2>&1"
   netopa_log "nsx-sha starts"
}

start() {
   groupadd -f $nsx_group
   groupadd -f $nsx_nestdb_group
   groupadd -f $nsx_netopa_group

   if ! getent passwd $nsx_netopa_user > /dev/null; then
      useradd --system -N \
      -g $nsx_netopa_group \
      --shell /usr/sbin/nologin -M \
      --comment "NSX Netopa" $nsx_netopa_user
   fi
   usermod -a -G $nsx_group,$nsx_nestdb_group $nsx_netopa_user

   if [ ! -z "$(pidof -s "${NETOPA}")" ] ; then
      netopa_log "nsx-netopa is already running"
      return
   fi

   if [ ! -f "${NETOPA}" ]; then
      netopa_log "nsx-netopa binary is missing"
      exit 1
   fi
   mkdir -p "${NETOPA_SOCK_DIR}"
   chmod 0770 "${NETOPA_SOCK_DIR}"
   chown -R $nsx_netopa_user:$nsx_netopa_group "${NETOPA_SOCK_DIR}"
   mkdir -p "${NETOPA_LOG_DIR}"
   chmod 777 "${NETOPA_LOG_DIR}"
   chmod 640 "${NETOPA_CFG_FILE}"
   chown $nsx_netopa_user:$nsx_netopa_group "${NETOPA_CFG_FILE}"

   /sbin/restorecon -v ${NETOPA_SOCK_DIR} &> /dev/null || :

   chown $nsx_netopa_user:$nsx_group "${NETOPA}"
   chown $nsx_netopa_user:$nsx_group "${WATCHDOG}"

   ulimit -c unlimited
   # gperftools memory profiling needs this environment
   export TCMALLOC_SAMPLE_PARAMETER="524288"
   su -m $nsx_netopa_user -s /bin/bash \
      -c "${WATCHDOG} ${WATCHDOG_ARGS} '${NETOPA} ${NETOPA_ARGS}' >/dev/null 2>&1"
   netopa_log "nsx-netopa starts"
}

stop_sha() {
   if [ ! -z "$(${WATCHDOG} -r ${NSX_SHA_TAG})" ]; then
       # This only stops the watchdog process.
       ${WATCHDOG} -k "${NSX_SHA_TAG}"
   fi

   if [ ! -z "$(ps auxww|grep "/opt/vmware/nsx-netopa/bin/agent.py"|grep -v 'grep' | awk '{print $2}')" ]; then
      kill -TERM $(ps auxww|grep "/opt/vmware/nsx-netopa/bin/agent.py"|grep -v 'grep' | awk '{print $2}') >/dev/null 2>&1
      local TIMEOUT=10
      while [ ! -z "$(ps auxww|grep "/opt/vmware/nsx-netopa/bin/agent.py"|grep -v 'grep' | awk '{print $2}')" ] ; do
         if [ ${TIMEOUT} -gt 0 ]; then
            sleep 1
            TIMEOUT=$(expr ${TIMEOUT} - 1)
         else
            kill -KILL $(ps auxww|grep "/opt/vmware/nsx-netopa/bin/agent.py"|grep -v 'grep' | awk '{print $2}')
            break
         fi
      done
      netopa_log "nsx-sha stopped"
   else
      netopa_log "nsx-sha is not running"
   fi
}

stop() {
   if [ ! -z "$(${WATCHDOG} -r ${NETOPA_TAG})" ]; then
       # This only stops the watchdog process.
       ${WATCHDOG} -k "${NETOPA_TAG}"
   fi

   if [ ! -z "$(pidof -s "${NETOPA}")" ]; then
      kill "$(pidof -s "${NETOPA}")" >/dev/null 2>&1
      local TIMEOUT=5
      while [ ! -z "$(pidof -s "${NETOPA}")" ] ; do
         if [ ${TIMEOUT} -gt 0 ]; then
            sleep 1
            TIMEOUT=$(expr ${TIMEOUT} - 1)
         else
            kill -KILL "$(pidof -s "${NETOPA}")"
            break
         fi
      done
      netopa_log "nsx-netopa stopped"
   else
      netopa_log "nsx-netopa is not running"
   fi
}


case "${1}" in
   "start")
      start
      start_sha
   ;;
   "stop")
      stop
      stop_sha
   ;;
   "status")
      if [ -n "$(pidof -xs "${NETOPA}")" ] ; then
         netopa_log "nsx-netopa is running"
         if [ ! -z "$(ps auxww|grep "/opt/vmware/nsx-netopa/bin/agent.py"|grep -v 'grep' | awk '{print $2}')" ] ; then
            netopa_log "nsx-sha is running"
         else
            netopa_log "nsx-sha is not running"
         fi
         exit 0
      else
         netopa_log "nsx-netopa is not running"
         if [ ! -z "$(ps auxww|grep "/opt/vmware/nsx-netopa/bin/agent.py"|grep -v 'grep' | awk '{print $2}')" ] ; then
            netopa_log "nsx-sha is running"
         else
            netopa_log "nsx-sha is not running"
         fi
         exit 3
      fi
   ;;
   "restart")
      stop
      start
      stop_sha
      start_sha
   ;;
   *)
      netopa_log "Usage: $(basename ${0}) {start|stop|status|restart}"
      exit 1
   ;;
esac
