You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

404 lines
11 KiB

преди 14 години
преди 14 години
преди 14 години
преди 14 години
преди 14 години
преди 12 години
  1. #!/bin/sh
  2. # -*- tab-width:4;indent-tabs-mode:nil -*-
  3. # ex: ts=4 sw=4 et
  4. # /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is.
  5. if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then
  6. POSIX_SHELL="true"
  7. export POSIX_SHELL
  8. # To support 'whoami' add /usr/ucb to path
  9. PATH=/usr/ucb:$PATH
  10. export PATH
  11. exec /usr/bin/ksh $0 "$@"
  12. fi
  13. # clear it so if we invoke other scripts, they run as ksh
  14. unset POSIX_SHELL
  15. RUNNER_SCRIPT_DIR=$(cd ${0%/*} && pwd -P)
  16. RUNNER_SCRIPT=${0##*/}
  17. CALLER_DIR=$PWD
  18. RUNNER_BASE_DIR=${RUNNER_SCRIPT_DIR%/*}
  19. RUNNER_ETC_DIR=$RUNNER_BASE_DIR/etc
  20. # Note the trailing slash on $PIPE_DIR/
  21. PIPE_DIR=/tmp/$RUNNER_BASE_DIR/
  22. RUNNER_USER=
  23. WHOAMI=$(whoami)
  24. # Make sure this script is running as the appropriate user
  25. if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then
  26. type sudo > /dev/null 2>&1
  27. if [ $? -ne 0 ]; then
  28. echo "sudo doesn't appear to be installed and your EUID isn't $RUNNER_USER" 1>&2
  29. exit 1
  30. fi
  31. echo "Attempting to restart script through sudo -H -u $RUNNER_USER" >&2
  32. exec sudo -H -u $RUNNER_USER -i $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $@
  33. fi
  34. # Identify the script name
  35. SCRIPT=`basename $0`
  36. # Parse out release and erts info
  37. START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
  38. ERTS_VSN=${START_ERL% *}
  39. APP_VSN=${START_ERL#* }
  40. # Use $CWD/vm.args if exists, otherwise releases/APP_VSN/vm.args, or
  41. # else etc/vm.args
  42. if [ -e "$CALLER_DIR/vm.args" ]; then
  43. VMARGS_PATH=$CALLER_DIR/vm.args
  44. USE_DIR=$CALLER_DIR
  45. else
  46. USE_DIR=$RUNNER_BASE_DIR
  47. if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/vm.args" ]; then
  48. VMARGS_PATH="$RUNNER_BASE_DIR/releases/$APP_VSN/vm.args"
  49. else
  50. VMARGS_PATH="$RUNNER_ETC_DIR/vm.args"
  51. fi
  52. fi
  53. RUNNER_LOG_DIR=$USE_DIR/log
  54. # Make sure log directory exists
  55. mkdir -p $RUNNER_LOG_DIR
  56. # Use releases/VSN/sys.config if it exists otherwise use etc/app.config
  57. if [ -e "$USE_DIR/sys.config" ]; then
  58. CONFIG_PATH="$USE_DIR/sys.config"
  59. else
  60. if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/sys.config" ]; then
  61. CONFIG_PATH="$RUNNER_BASE_DIR/releases/$APP_VSN/sys.config"
  62. else
  63. CONFIG_PATH="$RUNNER_ETC_DIR/app.config"
  64. fi
  65. fi
  66. # Extract the target node name from node.args
  67. NAME_ARG=`egrep '^\-s?name' $VMARGS_PATH`
  68. if [ -z "$NAME_ARG" ]; then
  69. echo "vm.args needs to have either -name or -sname parameter."
  70. exit 1
  71. fi
  72. # Extract the name type and name from the NAME_ARG for REMSH
  73. REMSH_TYPE=`echo $NAME_ARG | awk '{print $1}'`
  74. REMSH_NAME=`echo $NAME_ARG | awk '{print $2}'`
  75. # Test if REMSH_NAME contains a @ and set REMSH_HOSTNAME_PART
  76. # and REMSH_NAME_PART according REMSH_TYPE
  77. MAYBE_FQDN_HOSTNAME=`hostname`
  78. HOSTNAME=`echo $MAYBE_FQDN_HOSTNAME | awk -F. '{print $1}'`
  79. REMSH_HOSTNAME_PART="$MAYBE_FQDN_HOSTNAME"
  80. case "$REMSH_NAME" in
  81. *@*)
  82. REMSH_HOSTNAME_PART=`echo $REMSH_NAME | awk -F@ '{print $2}'`
  83. REMSH_NAME_PART=`echo $REMSH_NAME | awk -F@ '{print $1}'`
  84. ;;
  85. *)
  86. REMSH_NAME_PART="$REMSH_NAME"
  87. if [ "$REMSH_TYPE" = "-sname" ]; then
  88. REMSH_HOSTNAME_PART="$HOSTNAME"
  89. else
  90. # -name type, check if `hostname` is fqdn
  91. if [ "$MAYBE_FQDN_HOSTNAME" = "$HOSTNAME" ]; then
  92. echo "Hostname must be a fqdn domain name when node is configured with long names"
  93. echo "and the full node name isn't configured in vm.args"
  94. exit 1
  95. fi
  96. fi
  97. ;;
  98. esac
  99. # Note the `date +%s`, used to allow multiple remsh to the same node
  100. # transparently
  101. REMSH_NAME_ARG="$REMSH_TYPE remsh`date +%s`@$REMSH_HOSTNAME_PART"
  102. REMSH_REMSH_ARG="-remsh $REMSH_NAME_PART@$REMSH_HOSTNAME_PART"
  103. # Extract the target cookie
  104. COOKIE_ARG=`grep '^\-setcookie' $VMARGS_PATH`
  105. if [ -z "$COOKIE_ARG" ]; then
  106. echo "vm.args needs to have a -setcookie parameter."
  107. exit 1
  108. fi
  109. # Make sure CWD is set to the right dir
  110. cd $USE_DIR
  111. # Make sure log directory exists
  112. mkdir -p $USE_DIR/log
  113. RUNNER_SCRIPT_DATA=
  114. if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/runner_script.data" ]; then
  115. RUNNER_SCRIPT_DATA=`cat $RUNNER_BASE_DIR/releases/$APP_VSN/runner_script.data`
  116. fi
  117. if [ -z "$RUNNER_SCRIPT_DATA" ]; then
  118. ROOTDIR=$RUNNER_BASE_DIR
  119. ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
  120. if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/nodetool" ]; then
  121. NODETOOL="$ERTS_PATH/escript $RUNNER_BASE_DIR/releases/$APP_VSN/nodetool $NAME_ARG $COOKIE_ARG"
  122. else
  123. NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG"
  124. fi
  125. SLIM_ARGS=
  126. elif [ "$RUNNER_SCRIPT_DATA" = "slim" ]; then
  127. # Setup system paths
  128. SYSTEM_ERL_PATH=`which erl`
  129. if [ ! -x "$SYSTEM_ERL_PATH" ]; then
  130. echo "Failed to find erl. Is Erlang/OTP available in PATH?"
  131. exit 1
  132. fi
  133. SYSTEM_HOME_BIN=${SYSTEM_ERL_PATH%/*}
  134. ROOTDIR=$SYSTEM_HOME_BIN/../lib/erlang
  135. ERTS_PATH=$ROOTDIR/erts-$ERTS_VSN/bin
  136. unset SYSTEM_ERL_PATH
  137. unset SYSTEM_HOME_BIN
  138. LOCAL_ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
  139. NODETOOL="$ERTS_PATH/escript $RUNNER_BASE_DIR/releases/$APP_VSN/nodetool $NAME_ARG $COOKIE_ARG"
  140. unset LOCAL_ERL_PATH
  141. # Setup additional arguments for slim release
  142. SLIM_ARGS="-boot_var RELTOOL_EXT_LIB $RUNNER_BASE_DIR/lib -sasl releases_dir \"$RUNNER_BASE_DIR/releases\""
  143. else
  144. echo "Unknown runner_script.data"
  145. exit 1
  146. fi
  147. # Setup remote shell command to control node
  148. REMSH="$ERTS_PATH/erl -hidden $REMSH_NAME_ARG $REMSH_REMSH_ARG $COOKIE_ARG"
  149. # Common functions
  150. # Ping node without allowing nodetool to take stdin
  151. ping_node() {
  152. $NODETOOL ping < /dev/null
  153. }
  154. # Set the PID global variable, return 1 on error
  155. get_pid() {
  156. PID=`$NODETOOL getpid < /dev/null`
  157. ES=$?
  158. if [ "$ES" -ne 0 ]; then
  159. echo "Node is not running!"
  160. return 1
  161. fi
  162. # don't allow empty or init pid's
  163. if [ -z $PID ] || [ "$PID" -le 1 ]; then
  164. return 1
  165. fi
  166. return 0
  167. }
  168. # Check the first argument for instructions
  169. case "$1" in
  170. start|start_boot)
  171. # Make sure there is not already a node running
  172. RES=`ping_node`
  173. if [ "$RES" = "pong" ]; then
  174. echo "Node is already running!"
  175. exit 1
  176. fi
  177. case "$1" in
  178. start)
  179. shift
  180. START_OPTION="console"
  181. HEART_OPTION="start"
  182. ;;
  183. start_boot)
  184. shift
  185. START_OPTION="console_boot"
  186. HEART_OPTION="start_boot"
  187. ;;
  188. esac
  189. RUN_PARAM=$(printf "\'%s\' " "$@")
  190. HEART_COMMAND="$RUNNER_BASE_DIR/bin/$SCRIPT $HEART_OPTION $RUN_PARAM"
  191. export HEART_COMMAND
  192. mkdir -p $PIPE_DIR
  193. $ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT $START_OPTION $RUN_PARAM" 2>&1
  194. ;;
  195. stop)
  196. # Wait for the node to completely stop...
  197. case `uname -s` in
  198. Darwin)
  199. # Make sure we explicitly set this because iTerm.app doesn't for
  200. # some reason.
  201. COMMAND_MODE=unix2003
  202. esac
  203. # Get the PID from nodetool
  204. get_pid
  205. GPR=$?
  206. if [ "$GPR" -ne 0 ] || [ -z $PID ]; then
  207. exit $GPR
  208. fi
  209. # Tell nodetool to initiate a stop
  210. $NODETOOL stop
  211. ES=$?
  212. if [ "$ES" -ne 0 ]; then
  213. exit $ES
  214. fi
  215. # Wait for the node to completely stop...
  216. while `kill -s 0 $PID 2>/dev/null`
  217. do
  218. sleep 1
  219. done
  220. ;;
  221. restart)
  222. ## Restart the VM without exiting the process
  223. $NODETOOL restart
  224. ES=$?
  225. if [ "$ES" -ne 0 ]; then
  226. exit $ES
  227. fi
  228. ;;
  229. reboot)
  230. ## Restart the VM completely (uses heart to restart it)
  231. $NODETOOL reboot
  232. ES=$?
  233. if [ "$ES" -ne 0 ]; then
  234. exit $ES
  235. fi
  236. ;;
  237. ping)
  238. ## See if the VM is alive
  239. ping_node
  240. ES=$?
  241. if [ "$ES" -ne 0 ]; then
  242. exit $ES
  243. fi
  244. ;;
  245. attach)
  246. # Make sure a node is running
  247. ping_node
  248. ES=$?
  249. if [ "$ES" -ne 0 ]; then
  250. echo "Node is not running!"
  251. exit $ES
  252. fi
  253. shift
  254. exec $ERTS_PATH/to_erl $PIPE_DIR
  255. ;;
  256. remote_console)
  257. # Make sure a node is running
  258. ping_node
  259. ES=$?
  260. if [ "$ES" -ne 0 ]; then
  261. echo "Node is not running!"
  262. exit $ES
  263. fi
  264. shift
  265. exec $REMSH
  266. ;;
  267. upgrade)
  268. if [ -z "$2" ]; then
  269. echo "Missing upgrade package argument"
  270. echo "Usage: $SCRIPT upgrade {package base name}"
  271. echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
  272. exit 1
  273. fi
  274. # Make sure a node IS running
  275. ping_node
  276. ES=$?
  277. if [ "$ES" -ne 0 ]; then
  278. echo "Node is not running!"
  279. exit $ES
  280. fi
  281. node_name=`echo $NAME_ARG | awk '{print $2}'`
  282. erlang_cookie=`echo $COOKIE_ARG | awk '{print $2}'`
  283. $ERTS_PATH/escript $RUNNER_BASE_DIR/bin/install_upgrade.escript $node_name $erlang_cookie $2
  284. ;;
  285. console|console_clean|console_boot)
  286. # .boot file typically just $SCRIPT (ie, the app name)
  287. # however, for debugging, sometimes start_clean.boot is useful.
  288. # For e.g. 'setup', one may even want to name another boot script.
  289. case "$1" in
  290. console) BOOTFILE=$SCRIPT ;;
  291. console_clean) BOOTFILE=start_clean ;;
  292. console_boot)
  293. shift
  294. BOOTFILE="$1"
  295. shift
  296. ;;
  297. esac
  298. # Setup beam-required vars
  299. BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
  300. EMU=beam
  301. PROGNAME=`echo $0 | sed 's/.*\\///'`
  302. CMD="$BINDIR/erlexec $SLIM_ARGS -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$BOOTFILE -mode embedded -config $CONFIG_PATH -args_file $VMARGS_PATH"
  303. export EMU
  304. export ROOTDIR
  305. export BINDIR
  306. export PROGNAME
  307. # Dump environment info for logging purposes
  308. echo "Exec: $CMD" -- ${1+"$@"}
  309. echo "Root: $ROOTDIR"
  310. # Log the startup
  311. logger -t "$SCRIPT[$$]" "Starting up"
  312. # Start the VM
  313. exec $CMD -- ${1+"$@"}
  314. ;;
  315. foreground)
  316. # start up the release in the foreground for use by runit
  317. # or other supervision services
  318. BOOTFILE=$SCRIPT
  319. FOREGROUNDOPTIONS="-noinput +Bd"
  320. # Setup beam-required vars
  321. BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
  322. EMU=beam
  323. PROGNAME=`echo $0 | sed 's/.*\///'`
  324. CMD="$BINDIR/erlexec $SLIM_ARGS $FOREGROUNDOPTIONS -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$BOOTFILE -config $CONFIG_PATH -args_file $VMARGS_PATH"
  325. export EMU
  326. export ROOTDIR
  327. export BINDIR
  328. export PROGNAME
  329. # Dump environment info for logging purposes
  330. echo "Exec: $CMD" -- ${1+"$@"}
  331. echo "Root: $ROOTDIR"
  332. # Start the VM
  333. exec $CMD -- ${1+"$@"}
  334. ;;
  335. getpid)
  336. # Get the PID from nodetool
  337. get_pid
  338. ES=$?
  339. if [ "$ES" -ne 0 ] || [ -z $PID ]; then
  340. exit $ES
  341. fi
  342. echo $PID
  343. ;;
  344. *)
  345. echo "Usage: $SCRIPT {start|start_boot <file>|foreground|stop|restart|reboot|ping|console|getpid|console_clean|console_boot <file>|attach|remote_console|upgrade}"
  346. exit 1
  347. ;;
  348. esac
  349. exit 0