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.

347 lines
9.2 KiB

  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. CALLER_DIR=$PWD
  17. RUNNER_BASE_DIR=${RUNNER_SCRIPT_DIR%/*}
  18. RUNNER_ETC_DIR=$RUNNER_BASE_DIR/etc
  19. # Note the trailing slash on $PIPE_DIR/
  20. PIPE_DIR=/tmp/$RUNNER_BASE_DIR/
  21. RUNNER_USER=
  22. WHOAMI=$(whoami)
  23. # Make sure this script is running as the appropriate user
  24. if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then
  25. type sudo > /dev/null 2>&1
  26. if [ $? -ne 0 ]; then
  27. echo "sudo doesn't appear to be installed and your EUID isn't $RUNNER_USER" 1>&2
  28. exit 1
  29. fi
  30. echo "Attempting to restart script through sudo -H -u $RUNNER_USER" >&2
  31. exec sudo -H -u $RUNNER_USER -i $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $@
  32. fi
  33. # Identify the script name
  34. SCRIPT=`basename $0`
  35. # Parse out release and erts info
  36. START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data`
  37. ERTS_VSN=${START_ERL% *}
  38. APP_VSN=${START_ERL#* }
  39. # Use $CWD/vm.args if exists, otherwise releases/APP_VSN/vm.args, or
  40. # else etc/vm.args
  41. if [ -e "$CALLER_DIR/vm.args" ]; then
  42. VMARGS_PATH=$CALLER_DIR/vm.args
  43. USE_DIR=$CALLER_DIR
  44. else
  45. USE_DIR=$RUNNER_BASE_DIR
  46. if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/vm.args" ]; then
  47. VMARGS_PATH="$RUNNER_BASE_DIR/releases/$APP_VSN/vm.args"
  48. else
  49. VMARGS_PATH="$RUNNER_ETC_DIR/vm.args"
  50. fi
  51. fi
  52. RUNNER_LOG_DIR=$USE_DIR/log
  53. # Make sure log directory exists
  54. mkdir -p $RUNNER_LOG_DIR
  55. # Use releases/VSN/sys.config if it exists otherwise use etc/app.config
  56. if [ -e "$USE_DIR/sys.config" ]; then
  57. CONFIG_PATH="$USE_DIR/sys.config"
  58. else
  59. if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/sys.config" ]; then
  60. CONFIG_PATH="$RUNNER_BASE_DIR/releases/$APP_VSN/sys.config"
  61. else
  62. CONFIG_PATH="$RUNNER_ETC_DIR/app.config"
  63. fi
  64. fi
  65. # Extract the target node name from node.args
  66. NAME_ARG=`egrep '^\-s?name' $VMARGS_PATH`
  67. if [ -z "$NAME_ARG" ]; then
  68. echo "vm.args needs to have either -name or -sname parameter."
  69. exit 1
  70. fi
  71. # Extract the name type and name from the NAME_ARG for REMSH
  72. REMSH_TYPE=`echo $NAME_ARG | awk '{print $1}'`
  73. REMSH_NAME=`echo $NAME_ARG | awk '{print $2}'`
  74. # Note the `date +%s`, used to allow multiple remsh to the same node
  75. # transparently
  76. REMSH_NAME_ARG="$REMSH_TYPE remsh`date +%s`@`echo $REMSH_NAME | awk -F@ '{print $2}'`"
  77. REMSH_REMSH_ARG="-remsh $REMSH_NAME"
  78. # Extract the target cookie
  79. COOKIE_ARG=`grep '^\-setcookie' $VMARGS_PATH`
  80. if [ -z "$COOKIE_ARG" ]; then
  81. echo "vm.args needs to have a -setcookie parameter."
  82. exit 1
  83. fi
  84. # Make sure CWD is set to the right dir
  85. cd $USE_DIR
  86. # Make sure log directory exists
  87. mkdir -p $USE_DIR/log
  88. # Add ERTS bin dir to our path
  89. ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin
  90. # Setup command to control the node
  91. NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG"
  92. # Setup remote shell command to control node
  93. REMSH="$ERTS_PATH/erl $REMSH_NAME_ARG $REMSH_REMSH_ARG $COOKIE_ARG"
  94. # Common functions
  95. # Ping node without allowing nodetool to take stdin
  96. ping_node() {
  97. $NODETOOL ping < /dev/null
  98. }
  99. # Set the PID global variable, return 1 on error
  100. get_pid() {
  101. PID=`$NODETOOL getpid < /dev/null`
  102. ES=$?
  103. if [ "$ES" -ne 0 ]; then
  104. echo "Node is not running!"
  105. return 1
  106. fi
  107. # don't allow empty or init pid's
  108. if [ -z $PID ] || [ "$PID" -le 1 ]; then
  109. return 1
  110. fi
  111. return 0
  112. }
  113. # Check the first argument for instructions
  114. case "$1" in
  115. start|start_boot)
  116. # Make sure there is not already a node running
  117. RES=`ping_node`
  118. if [ "$RES" = "pong" ]; then
  119. echo "Node is already running!"
  120. exit 1
  121. fi
  122. case "$1" in
  123. start)
  124. shift
  125. START_OPTION="console"
  126. HEART_OPTION="start"
  127. ;;
  128. start_boot)
  129. shift
  130. START_OPTION="console_boot"
  131. HEART_OPTION="start_boot"
  132. ;;
  133. esac
  134. RUN_PARAM=$(printf "\'%s\' " "$@")
  135. HEART_COMMAND="$RUNNER_BASE_DIR/bin/$SCRIPT $HEART_OPTION $RUN_PARAM"
  136. export HEART_COMMAND
  137. mkdir -p $PIPE_DIR
  138. $ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT $START_OPTION $RUN_PARAM" 2>&1
  139. ;;
  140. stop)
  141. # Wait for the node to completely stop...
  142. case `uname -s` in
  143. Darwin)
  144. # Make sure we explicitly set this because iTerm.app doesn't for
  145. # some reason.
  146. COMMAND_MODE=unix2003
  147. esac
  148. # Get the PID from nodetool
  149. get_pid
  150. GPR=$?
  151. if [ "$GPR" -ne 0 ] || [ -z $PID ]; then
  152. exit $GPR
  153. fi
  154. # Tell nodetool to initiate a stop
  155. $NODETOOL stop
  156. ES=$?
  157. if [ "$ES" -ne 0 ]; then
  158. exit $ES
  159. fi
  160. # Wait for the node to completely stop...
  161. while `kill -s 0 $PID 2>/dev/null`
  162. do
  163. sleep 1
  164. done
  165. ;;
  166. restart)
  167. ## Restart the VM without exiting the process
  168. $NODETOOL restart
  169. ES=$?
  170. if [ "$ES" -ne 0 ]; then
  171. exit $ES
  172. fi
  173. ;;
  174. reboot)
  175. ## Restart the VM completely (uses heart to restart it)
  176. $NODETOOL reboot
  177. ES=$?
  178. if [ "$ES" -ne 0 ]; then
  179. exit $ES
  180. fi
  181. ;;
  182. ping)
  183. ## See if the VM is alive
  184. ping_node
  185. ES=$?
  186. if [ "$ES" -ne 0 ]; then
  187. exit $ES
  188. fi
  189. ;;
  190. attach)
  191. # Make sure a node is running
  192. ping_node
  193. ES=$?
  194. if [ "$ES" -ne 0 ]; then
  195. echo "Node is not running!"
  196. exit $ES
  197. fi
  198. shift
  199. exec $ERTS_PATH/to_erl $PIPE_DIR
  200. ;;
  201. remote_console)
  202. # Make sure a node is running
  203. ping_node
  204. ES=$?
  205. if [ "$ES" -ne 0 ]; then
  206. echo "Node is not running!"
  207. exit $ES
  208. fi
  209. shift
  210. exec $REMSH
  211. ;;
  212. upgrade)
  213. if [ -z "$2" ]; then
  214. echo "Missing upgrade package argument"
  215. echo "Usage: $SCRIPT upgrade {package base name}"
  216. echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
  217. exit 1
  218. fi
  219. # Make sure a node IS running
  220. ping_node
  221. ES=$?
  222. if [ "$ES" -ne 0 ]; then
  223. echo "Node is not running!"
  224. exit $ES
  225. fi
  226. node_name=`echo $NAME_ARG | awk '{print $2}'`
  227. erlang_cookie=`echo $COOKIE_ARG | awk '{print $2}'`
  228. $ERTS_PATH/escript $RUNNER_BASE_DIR/bin/install_upgrade.escript $node_name $erlang_cookie $2
  229. ;;
  230. console|console_clean|console_boot)
  231. # .boot file typically just $SCRIPT (ie, the app name)
  232. # however, for debugging, sometimes start_clean.boot is useful.
  233. # For e.g. 'setup', one may even want to name another boot script.
  234. case "$1" in
  235. console) BOOTFILE=$SCRIPT ;;
  236. console_clean) BOOTFILE=start_clean ;;
  237. console_boot)
  238. shift
  239. BOOTFILE="$1"
  240. shift
  241. ;;
  242. esac
  243. # Setup beam-required vars
  244. ROOTDIR=$RUNNER_BASE_DIR
  245. BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
  246. EMU=beam
  247. PROGNAME=`echo $0 | sed 's/.*\\///'`
  248. CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$BOOTFILE -mode embedded -config $CONFIG_PATH -args_file $VMARGS_PATH"
  249. export EMU
  250. export ROOTDIR
  251. export BINDIR
  252. export PROGNAME
  253. # Dump environment info for logging purposes
  254. echo "Exec: $CMD" -- ${1+"$@"}
  255. echo "Root: $ROOTDIR"
  256. # Log the startup
  257. logger -t "$SCRIPT[$$]" "Starting up"
  258. # Start the VM
  259. exec $CMD -- ${1+"$@"}
  260. ;;
  261. foreground)
  262. # start up the release in the foreground for use by runit
  263. # or other supervision services
  264. BOOTFILE=$SCRIPT
  265. FOREGROUNDOPTIONS="-noinput +Bd"
  266. # Setup beam-required vars
  267. ROOTDIR=$RUNNER_BASE_DIR
  268. BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin
  269. EMU=beam
  270. PROGNAME=`echo $0 | sed 's/.*\///'`
  271. CMD="$BINDIR/erlexec $FOREGROUNDOPTIONS -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$BOOTFILE -config $CONFIG_PATH -args_file $VMARGS_PATH"
  272. export EMU
  273. export ROOTDIR
  274. export BINDIR
  275. export PROGNAME
  276. # Dump environment info for logging purposes
  277. echo "Exec: $CMD" -- ${1+"$@"}
  278. echo "Root: $ROOTDIR"
  279. # Start the VM
  280. exec $CMD -- ${1+"$@"}
  281. ;;
  282. getpid)
  283. # Get the PID from nodetool
  284. get_pid
  285. ES=$?
  286. if [ "$ES" -ne 0 ] || [ -z $PID ]; then
  287. exit $ES
  288. fi
  289. echo $PID
  290. ;;
  291. *)
  292. echo "Usage: $SCRIPT {start|start_boot <file>|foreground|stop|restart|reboot|ping|console|getpid|console_clean|console_boot <file>|attach|remote_console|upgrade}"
  293. exit 1
  294. ;;
  295. esac
  296. exit 0