toaster 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. #!/bin/sh
  2. # (c) 2013 Intel Corp.
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program; if not, write to the Free Software
  15. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. # This script can be run in two modes.
  17. # When used with "source", from a build directory,
  18. # it enables toaster event logging and starts the bitbake resident server.
  19. # use as: source toaster [start|stop] [noweb] [noui]
  20. # When it is called as a stand-alone script, it starts just the
  21. # web server, and the building shall be done through the web interface.
  22. # As script, it will not return to the command prompt. Stop with Ctrl-C.
  23. # Helper function to kill a background toaster development server
  24. webserverKillAll()
  25. {
  26. local pidfile
  27. for pidfile in ${BUILDDIR}/.toastermain.pid; do
  28. if [ -f ${pidfile} ]; then
  29. pid=`cat ${pidfile}`
  30. while kill -0 $pid 2>/dev/null; do
  31. kill -SIGTERM -$pid 2>/dev/null
  32. sleep 1
  33. # Kill processes if they are still running - may happen in interactive shells
  34. ps fux | grep "python.*manage.py runserver" | awk '{print $2}' | xargs kill
  35. done
  36. rm ${pidfile}
  37. fi
  38. done
  39. }
  40. webserverStartAll()
  41. {
  42. # do not start if toastermain points to a valid process
  43. if ! cat "${BUILDDIR}/.toastermain.pid" 2>/dev/null | xargs -I{} kill -0 {} ; then
  44. retval=1
  45. rm "${BUILDDIR}/.toastermain.pid"
  46. fi
  47. retval=0
  48. if [ "$TOASTER_MANAGED" '=' '1' ]; then
  49. python $BBBASEDIR/lib/toaster/manage.py syncdb || retval=1
  50. else
  51. python $BBBASEDIR/lib/toaster/manage.py syncdb --noinput || retval=1
  52. fi
  53. python $BBBASEDIR/lib/toaster/manage.py migrate orm || retval=2
  54. if [ $retval -eq 1 ]; then
  55. echo "Failed db sync, stopping system start" 1>&2
  56. elif [ $retval -eq 2 ]; then
  57. printf "\nError on migration, trying to recover... \n"
  58. python $BBBASEDIR/lib/toaster/manage.py migrate orm 0001_initial --fake
  59. retval=0
  60. python $BBBASEDIR/lib/toaster/manage.py migrate orm || retval=1
  61. fi
  62. if [ "$TOASTER_MANAGED" = '1' ]; then
  63. python $BBBASEDIR/lib/toaster/manage.py migrate bldcontrol || retval=1
  64. python $BBBASEDIR/lib/toaster/manage.py checksettings --traceback || retval=1
  65. fi
  66. if [ $retval -eq 0 ]; then
  67. echo "Starting webserver..."
  68. python $BBBASEDIR/lib/toaster/manage.py runserver "0.0.0.0:$WEB_PORT" </dev/null >>${BUILDDIR}/toaster_web.log 2>&1 & echo $! >${BUILDDIR}/.toastermain.pid
  69. sleep 1
  70. if ! cat "${BUILDDIR}/.toastermain.pid" | xargs -I{} kill -0 {} ; then
  71. retval=1
  72. rm "${BUILDDIR}/.toastermain.pid"
  73. else
  74. echo "Webserver address: http://0.0.0.0:$WEB_PORT/"
  75. fi
  76. fi
  77. return $retval
  78. }
  79. # Helper functions to add a special configuration file
  80. addtoConfiguration()
  81. {
  82. file=$1
  83. shift
  84. echo "#Created by toaster start script" > ${BUILDDIR}/conf/$file
  85. for var in "$@"; do echo $var >> ${BUILDDIR}/conf/$file; done
  86. }
  87. INSTOPSYSTEM=0
  88. # define the stop command
  89. stop_system()
  90. {
  91. # prevent reentry
  92. if [ $INSTOPSYSTEM -eq 1 ]; then return; fi
  93. INSTOPSYSTEM=1
  94. if [ -f ${BUILDDIR}/.toasterui.pid ]; then
  95. kill `cat ${BUILDDIR}/.toasterui.pid` 2>/dev/null
  96. rm ${BUILDDIR}/.toasterui.pid
  97. fi
  98. BBSERVER=0.0.0.0:-1 bitbake -m
  99. unset BBSERVER
  100. webserverKillAll
  101. # force stop any misbehaving bitbake server
  102. lsof bitbake.lock | awk '{print $2}' | grep "[0-9]\+" | xargs -n1 -r kill
  103. trap - SIGHUP
  104. #trap - SIGCHLD
  105. INSTOPSYSTEM=0
  106. }
  107. check_pidbyfile() {
  108. [ -e $1 ] && kill -0 `cat $1` 2>/dev/null
  109. }
  110. notify_chldexit() {
  111. if [ $NOTOASTERUI -eq 0 ]; then
  112. check_pidbyfile ${BUILDDIR}/.toasterui.pid && return
  113. stop_system
  114. fi
  115. }
  116. verify_prereq() {
  117. # Verify prerequisites
  118. if ! echo "import django; print (1,) == django.VERSION[0:1] and django.VERSION[1:2][0] in (6,)" | python 2>/dev/null | grep True >/dev/null; then
  119. printf "This program needs Django 1.6. Please install with\n\npip install django==1.6\n"
  120. return 2
  121. fi
  122. if ! echo "import south; print reduce(lambda x, y: 2 if x==2 else 0 if x == 0 else y, map(lambda x: 1+cmp(x[1]-x[0],0), zip([0,8,4], map(int,south.__version__.split(\".\"))))) > 0" | python 2>/dev/null | grep True >/dev/null; then
  123. printf "This program needs South 0.8.4. Please install with\n\npip install south==0.8.4\n"
  124. return 2
  125. fi
  126. return 0
  127. }
  128. # read command line parameters
  129. if [ -n "$BASH_SOURCE" ] ; then
  130. TOASTER=${BASH_SOURCE}
  131. elif [ -n "$ZSH_NAME" ] ; then
  132. TOASTER=${(%):-%x}
  133. else
  134. TOASTER=$0
  135. fi
  136. BBBASEDIR=`dirname $TOASTER`/..
  137. RUNNING=0
  138. NOTOASTERUI=0
  139. WEBSERVER=1
  140. TOASTER_BRBE=""
  141. WEB_PORT="8000"
  142. NOBROWSER=0
  143. for param in $*; do
  144. case $param in
  145. noui )
  146. NOTOASTERUI=1
  147. ;;
  148. noweb )
  149. WEBSERVER=0
  150. ;;
  151. nobrowser )
  152. NOBROWSER=1
  153. ;;
  154. brbe=* )
  155. TOASTER_BRBE=$'\n'"TOASTER_BRBE=\""${param#*=}"\""
  156. ;;
  157. webport=*)
  158. WEB_PORT="${param#*=}"
  159. esac
  160. done
  161. [ -n "${BASH_SOURCE}" ] && SRCFILE=${BASH_SOURCE} || SRCFILE=$_
  162. if [ `basename \"$0\"` = `basename \"${SRCFILE}\"` ]; then
  163. # We are called as standalone. We refuse to run in a build environment - we need the interactive mode for that.
  164. # Start just the web server, point the web browser to the interface, and start any Django services.
  165. if ! verify_prereq; then
  166. echo "Error: Could not verify that the needed dependencies are installed. Please use virtualenv and pip to install dependencies listed in toaster-requirements.txt" 1>&2
  167. exit 1
  168. fi
  169. if [ -n "$BUILDDIR" ]; then
  170. printf "Error: It looks like you sourced oe-init-build-env. Toaster cannot start in build mode from an oe-core build environment.\n You should be starting Toaster from a new terminal window." 1>&2
  171. exit 1
  172. fi
  173. # Define a fake builddir where only the pid files are actually created. No real builds will take place here.
  174. BUILDDIR=/tmp/toaster_$$
  175. if [ -d "$BUILDDIR" ]; then
  176. echo "Previous toaster run directory $BUILDDIR found, cowardly refusing to start. Please remove the directory when that toaster instance is over" 2>&1
  177. exit 1
  178. fi
  179. mkdir -p "$BUILDDIR"
  180. RUNNING=1
  181. trap_ctrlc() {
  182. echo "** Stopping system"
  183. webserverKillAll
  184. RUNNING=0
  185. }
  186. do_cleanup() {
  187. find "$BUILDDIR" -type f | xargs rm
  188. rmdir "$BUILDDIR"
  189. }
  190. cleanup() {
  191. if grep -ir error "$BUILDDIR" >/dev/null; then
  192. if grep -irn "That port is already in use" "$BUILDDIR"; then
  193. echo "You can use the \"webport=PORTNUMBER\" parameter to start Toaster on a different port (port $WEB_PORT is already in use)"
  194. do_cleanup
  195. else
  196. printf "\nErrors found in the Toaster log files present in '$BUILDDIR'. Directory will not be cleaned.\n Please review the errors and notify toaster@yoctoproject.org or submit a bug https://bugzilla.yoctoproject.org/enter_bug.cgi?product=Toaster"
  197. fi
  198. else
  199. echo "No errors found, removing the run directory '$BUILDDIR'"
  200. do_cleanup
  201. fi
  202. }
  203. TOASTER_MANAGED=1
  204. export TOASTER_MANAGED=1
  205. if [ $WEBSERVER -gt 0 ] && ! webserverStartAll; then
  206. echo "Failed to start the web server, stopping" 1>&2
  207. cleanup
  208. exit 1
  209. fi
  210. if [ $WEBSERVER -gt 0 ] && [ $NOBROWSER -eq 0 ] ; then
  211. echo "Starting browser..."
  212. xdg-open http://127.0.0.1:$WEB_PORT/ >/dev/null 2>&1 &
  213. fi
  214. trap trap_ctrlc 2
  215. echo "Toaster is now running. You can stop it with Ctrl-C"
  216. while [ $RUNNING -gt 0 ]; do
  217. python $BBBASEDIR/lib/toaster/manage.py runbuilds 2>&1 | tee -a "$BUILDDIR/toaster.log"
  218. sleep 1
  219. done
  220. cleanup
  221. echo "**** Exit"
  222. exit 0
  223. fi
  224. if ! verify_prereq; then
  225. echo "Error: Could not verify that the needed dependencies are installed. Please use virtualenv and pip to install dependencies listed in toaster-requirements.txt" 1>&2
  226. return 1
  227. fi
  228. # We make sure we're running in the current shell and in a good environment
  229. if [ -z "$BUILDDIR" ] || ! which bitbake >/dev/null 2>&1 ; then
  230. echo "Error: Build environment is not setup or bitbake is not in path." 1>&2
  231. return 2
  232. fi
  233. # Determine the action. If specified by arguments, fine, if not, toggle it
  234. if [ "$1" = 'start' ] || [ "$1" = 'stop' ]; then
  235. CMD="$1"
  236. else
  237. if [ -z "$BBSERVER" ]; then
  238. CMD="start"
  239. else
  240. CMD="stop"
  241. fi
  242. fi
  243. echo "The system will $CMD."
  244. # Make sure it's safe to run by checking bitbake lock
  245. lock=1
  246. if [ -e $BUILDDIR/bitbake.lock ]; then
  247. python -c "import fcntl; fcntl.flock(open(\"$BUILDDIR/bitbake.lock\"), fcntl.LOCK_EX|fcntl.LOCK_NB)" 2>/dev/null || lock=0
  248. fi
  249. if [ ${CMD} = 'start' ] && [ $lock -eq 0 ]; then
  250. echo "Error: bitbake lock state error. File locks show that the system is on." 1>&2
  251. echo "Please wait for the current build to finish, stop and then start the system again." 1>&2
  252. return 3
  253. fi
  254. if [ ${CMD} = 'start' ] && [ -e $BUILDDIR/.toastermain.pid ] && kill -0 `cat $BUILDDIR/.toastermain.pid`; then
  255. echo "Warning: bitbake appears to be dead, but the Toaster web server is running. Something fishy is going on." 1>&2
  256. echo "Cleaning up the web server to start from a clean slate."
  257. webserverKillAll
  258. fi
  259. # Execute the commands
  260. case $CMD in
  261. start )
  262. start_success=1
  263. addtoConfiguration toaster.conf "INHERIT+=\"toaster buildhistory\"" $TOASTER_BRBE
  264. if [ $WEBSERVER -gt 0 ] && ! webserverStartAll; then
  265. echo "Failed ${CMD}."
  266. return 4
  267. fi
  268. unset BBSERVER
  269. PREREAD=""
  270. if [ -e ${BUILDDIR}/conf/toaster-pre.conf ]; then
  271. rm ${BUILDDIR}/conf/toaster-pre.conf
  272. fi
  273. bitbake $PREREAD --postread conf/toaster.conf --server-only -t xmlrpc -B 0.0.0.0:0
  274. if [ $? -ne 0 ]; then
  275. start_success=0
  276. echo "Bitbake server start failed"
  277. else
  278. export BBSERVER=0.0.0.0:-1
  279. if [ $NOTOASTERUI -eq 0 ]; then # we start the TOASTERUI only if not inhibited
  280. bitbake --observe-only -u toasterui >>${BUILDDIR}/toaster_ui.log 2>&1 & echo $! >${BUILDDIR}/.toasterui.pid
  281. fi
  282. fi
  283. if [ $start_success -eq 1 ]; then
  284. # set fail safe stop system on terminal exit
  285. trap stop_system SIGHUP
  286. echo "Successful ${CMD}."
  287. return 0
  288. else
  289. # failed start, do stop
  290. stop_system
  291. echo "Failed ${CMD}."
  292. return 1
  293. fi
  294. # stop system on terminal exit
  295. set -o monitor
  296. trap stop_system SIGHUP
  297. #trap notify_chldexit SIGCHLD
  298. ;;
  299. stop )
  300. stop_system
  301. echo "Successful ${CMD}."
  302. ;;
  303. esac