cisd/scripts/tms.sh

202 lines
4.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# TMS runtime script for jar deployment.
# Commands:
# ./scripts/tms.sh start
# ./scripts/tms.sh stop
# ./scripts/tms.sh restart
# ./scripts/tms.sh status
#
# External config:
# ${APP_HOME}/config/application.yml
# ${APP_HOME}/config/application-${SPRING_PROFILES_ACTIVE}.yml
DEFAULT_APP_HOME="/home/tms"
APP_HOME="${APP_HOME:-${DEFAULT_APP_HOME}}"
APP_NAME="${APP_NAME:-tms-framework}"
RUN_DIR="${RUN_DIR:-${APP_HOME}/run}"
LOG_DIR="${LOG_DIR:-${APP_HOME}/logs}"
CONF_DIR="${CONF_DIR:-${APP_HOME}/config}"
PID_FILE="${PID_FILE:-${RUN_DIR}/${APP_NAME}.pid}"
OUT_LOG="${OUT_LOG:-${LOG_DIR}/${APP_NAME}.out.log}"
ERR_LOG="${ERR_LOG:-${LOG_DIR}/${APP_NAME}.err.log}"
SPRING_PROFILES_ACTIVE="${SPRING_PROFILES_ACTIVE:-}"
JAVA_BIN="${JAVA_BIN:-java}"
JAVA_OPTS="${JAVA_OPTS:- -Xms512m -Xmx1024m}"
ALLOW_MISSING_EXTERNAL_CONFIG="${ALLOW_MISSING_EXTERNAL_CONFIG:-false}"
JAR_PATH="${JAR_PATH:-${APP_HOME}/${APP_NAME}.jar}"
ensure_dirs() {
mkdir -p "${RUN_DIR}" "${LOG_DIR}" "${CONF_DIR}"
}
resolve_jar_path() {
if [[ -f "${JAR_PATH}" ]]; then
return 0
fi
local found
found="$(ls -1 "${APP_HOME}/target/${APP_NAME}"-*.jar 2>/dev/null | grep -vE '(sources|javadoc|original)' | head -n1 || true)"
if [[ -n "${found}" ]]; then
JAR_PATH="${found}"
return 0
fi
echo "[FATAL] jar not found. set JAR_PATH or place jar at ${APP_HOME}/${APP_NAME}.jar"
exit 1
}
check_external_config() {
local base_cfg="${CONF_DIR}/application.yml"
if [[ "${ALLOW_MISSING_EXTERNAL_CONFIG}" != "true" && ! -f "${base_cfg}" ]]; then
echo "[FATAL] external config missing: ${base_cfg}"
echo "Copy template: cp ${APP_HOME}/config/application.yml.example ${base_cfg}"
exit 1
fi
}
is_running() {
if [[ ! -f "${PID_FILE}" ]]; then
return 1
fi
local pid
pid="$(cat "${PID_FILE}")"
if [[ -z "${pid}" ]]; then
return 1
fi
if kill -0 "${pid}" >/dev/null 2>&1; then
return 0
fi
return 1
}
start_app() {
ensure_dirs
resolve_jar_path
check_external_config
if is_running; then
echo "[INFO] ${APP_NAME} already running, pid=$(cat "${PID_FILE}")"
return 0
fi
local cfg_location
cfg_location="optional:file:${CONF_DIR}/"
echo "[INFO] starting ${APP_NAME}"
echo "[INFO] app home: ${APP_HOME}"
echo "[INFO] jar path: ${JAR_PATH}"
if [[ -n "${SPRING_PROFILES_ACTIVE}" ]]; then
echo "[INFO] profile override: ${SPRING_PROFILES_ACTIVE}"
else
echo "[INFO] profile override: <none>"
fi
echo "[INFO] external config dir: ${CONF_DIR}"
if [[ -n "${SPRING_PROFILES_ACTIVE}" ]]; then
# shellcheck disable=SC2086
nohup "${JAVA_BIN}" ${JAVA_OPTS} \
-jar "${JAR_PATH}" \
--spring.profiles.active="${SPRING_PROFILES_ACTIVE}" \
--spring.config.additional-location="${cfg_location}" \
>"${OUT_LOG}" 2>"${ERR_LOG}" &
else
# shellcheck disable=SC2086
nohup "${JAVA_BIN}" ${JAVA_OPTS} \
-jar "${JAR_PATH}" \
--spring.config.additional-location="${cfg_location}" \
>"${OUT_LOG}" 2>"${ERR_LOG}" &
fi
local pid="$!"
echo "${pid}" > "${PID_FILE}"
sleep 1
if kill -0 "${pid}" >/dev/null 2>&1; then
echo "[INFO] started, pid=${pid}"
echo "[INFO] out log: ${OUT_LOG}"
echo "[INFO] err log: ${ERR_LOG}"
else
echo "[ERROR] start failed, check logs"
rm -f "${PID_FILE}"
exit 1
fi
}
stop_app() {
if ! is_running; then
echo "[INFO] ${APP_NAME} not running"
rm -f "${PID_FILE}" || true
return 0
fi
local pid
pid="$(cat "${PID_FILE}")"
echo "[INFO] stopping ${APP_NAME}, pid=${pid}"
kill "${pid}" >/dev/null 2>&1 || true
local i
for i in $(seq 1 20); do
if ! kill -0 "${pid}" >/dev/null 2>&1; then
rm -f "${PID_FILE}" || true
echo "[INFO] stopped"
return 0
fi
sleep 1
done
echo "[WARN] graceful stop timeout, force kill pid=${pid}"
kill -9 "${pid}" >/dev/null 2>&1 || true
rm -f "${PID_FILE}" || true
echo "[INFO] stopped(force)"
}
status_app() {
if is_running; then
echo "[INFO] ${APP_NAME} is running, pid=$(cat "${PID_FILE}")"
return 0
fi
echo "[INFO] ${APP_NAME} is not running"
return 1
}
usage() {
cat <<EOF
Usage: $0 {start|stop|restart|status}
Environment variables:
APP_HOME default: /home/tms
APP_NAME default: tms-framework
JAR_PATH default: <app_home>/tms-framework.jar
CONF_DIR default: <app_home>/config
RUN_DIR default: <app_home>/run
LOG_DIR default: <app_home>/logs
SPRING_PROFILES_ACTIVE optional: override Spring profile
JAVA_BIN default: java
JAVA_OPTS default: -Xms512m -Xmx1024m
ALLOW_MISSING_EXTERNAL_CONFIG default: false
EOF
}
cmd="${1:-}"
case "${cmd}" in
start)
start_app
;;
stop)
stop_app
;;
restart)
stop_app
start_app
;;
status)
status_app
;;
*)
usage
exit 1
;;
esac