#!/bin/echo ERROR: This script needs to be sourced. Please run as . # toaster - shell script to start Toaster # Copyright (C) 2013-2015 Intel Corp. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/. HELP=" Usage: source toaster start|stop [webport=] [noweb] [nobuild] [toasterdir] Optional arguments: [nobuild] Setup the environment for capturing builds with toaster but disable managed builds [noweb] Setup the environment for capturing builds with toaster but don't start the web server [webport] Set the development server (default: localhost:8000) [toasterdir] Set absolute path to be used as TOASTER_DIR (default: BUILDDIR/../) " custom_extention() { custom_extension=$BBBASEDIR/lib/toaster/orm/fixtures/custom_toaster_append.sh if [ -f $custom_extension ] ; then $custom_extension $* fi } databaseCheck() { retval=0 # you can always add a superuser later via # ../bitbake/lib/toaster/manage.py createsuperuser --username= $MANAGE migrate --noinput || retval=1 if [ $retval -eq 1 ]; then echo "Failed migrations, aborting system start" 1>&2 return $retval fi # Make sure that checksettings can pick up any value for TEMPLATECONF export TEMPLATECONF $MANAGE checksettings --traceback || retval=1 if [ $retval -eq 1 ]; then printf "\nError while checking settings; aborting\n" return $retval fi return $retval } webserverKillAll() { local pidfile if [ -f ${BUILDDIR}/.toastermain.pid ] ; then custom_extention web_stop_postpend else custom_extention noweb_stop_postpend fi for pidfile in ${BUILDDIR}/.toastermain.pid ${BUILDDIR}/.runbuilds.pid; do if [ -f ${pidfile} ]; then pid=`cat ${pidfile}` while kill -0 $pid 2>/dev/null; do kill -SIGTERM $pid 2>/dev/null sleep 1 done rm ${pidfile} fi done } webserverStartAll() { # do not start if toastermain points to a valid process if ! cat "${BUILDDIR}/.toastermain.pid" 2>/dev/null | xargs -I{} kill -0 {} ; then retval=1 rm "${BUILDDIR}/.toastermain.pid" fi retval=0 # check the database databaseCheck || return 1 echo "Starting webserver..." $MANAGE runserver --noreload "$ADDR_PORT" \ >${BUILDDIR}/toaster_web.log 2>&1 \ & echo $! >${BUILDDIR}/.toastermain.pid sleep 1 if ! cat "${BUILDDIR}/.toastermain.pid" | xargs -I{} kill -0 {} ; then retval=1 rm "${BUILDDIR}/.toastermain.pid" else echo "Toaster development webserver started at http://$ADDR_PORT" echo -e "\nYou can now run 'bitbake ' on the command line and monitor your build in Toaster.\nYou can also use a Toaster project to configure and run a build.\n" custom_extention web_start_postpend $ADDR_PORT fi return $retval } INSTOPSYSTEM=0 # define the stop command stop_system() { # prevent reentry if [ $INSTOPSYSTEM -eq 1 ]; then return; fi INSTOPSYSTEM=1 webserverKillAll # unset exported variables unset TOASTER_DIR unset BITBAKE_UI unset BBBASEDIR trap - SIGHUP #trap - SIGCHLD INSTOPSYSTEM=0 } verify_prereq() { # Verify Django version reqfile=$(python3 -c "import os; print(os.path.realpath('$BBBASEDIR/toaster-requirements.txt'))") exp='s/Django\([><=]\+\)\([^,]\+\),\([><=]\+\)\(.\+\)/' # expand version parts to 2 digits to support 1.10.x > 1.8 # (note:helper functions hard to insert in-line) exp=$exp'import sys,django;' exp=$exp'version=["%02d" % int(n) for n in django.get_version().split(".")];' exp=$exp'vmin=["%02d" % int(n) for n in "\2".split(".")];' exp=$exp'vmax=["%02d" % int(n) for n in "\4".split(".")];' exp=$exp'sys.exit(not (version \1 vmin and version \3 vmax))' exp=$exp'/p' if ! sed -n "$exp" $reqfile | python3 - ; then req=`grep ^Django $reqfile` echo "This program needs $req" echo "Please install with pip3 install -r $reqfile" return 2 fi return 0 } # read command line parameters if [ -n "$BASH_SOURCE" ] ; then TOASTER=${BASH_SOURCE} elif [ -n "$ZSH_NAME" ] ; then TOASTER=${(%):-%x} else TOASTER=$0 fi export BBBASEDIR=`dirname $TOASTER`/.. MANAGE="python3 $BBBASEDIR/lib/toaster/manage.py" if [ -z "$OE_ROOT" ]; then OE_ROOT=`dirname $TOASTER`/../.. fi # this is the configuraton file we are using for toaster # we are using the same logic that oe-setup-builddir uses # (based on TEMPLATECONF and .templateconf) to determine # which toasterconf.json to use. # note: There are a number of relative path assumptions # in the local layers that currently make using an arbitrary # toasterconf.json difficult. . $OE_ROOT/.templateconf if [ -n "$TEMPLATECONF" ]; then if [ ! -d "$TEMPLATECONF" ]; then # Allow TEMPLATECONF=meta-xyz/conf as a shortcut if [ -d "$OE_ROOT/$TEMPLATECONF" ]; then TEMPLATECONF="$OE_ROOT/$TEMPLATECONF" fi fi fi unset OE_ROOT WEBSERVER=1 export TOASTER_BUILDSERVER=1 ADDR_PORT="localhost:8000" TOASTERDIR=`dirname $BUILDDIR` unset CMD for param in $*; do case $param in noweb ) WEBSERVER=0 ;; nobuild ) TOASTER_BUILDSERVER=0 ;; start ) CMD=$param ;; stop ) CMD=$param ;; webport=*) ADDR_PORT="${param#*=}" # Split the addr:port string ADDR=`echo $ADDR_PORT | cut -f 1 -d ':'` PORT=`echo $ADDR_PORT | cut -f 2 -d ':'` # If only a port has been speified then set address to localhost. if [ $ADDR = $PORT ] ; then ADDR_PORT="localhost:$PORT" fi ;; toasterdir=*) TOASTERDIR="${param#*=}" ;; --help) echo "$HELP" return 0 ;; *) echo "$HELP" return 1 ;; esac done if [ `basename \"$0\"` = `basename \"${TOASTER}\"` ]; then echo "Error: This script needs to be sourced. Please run as . $TOASTER" return 1 fi verify_prereq || return 1 # We make sure we're running in the current shell and in a good environment if [ -z "$BUILDDIR" ] || ! which bitbake >/dev/null 2>&1 ; then echo "Error: Build environment is not setup or bitbake is not in path." 1>&2 return 2 fi # this defines the dir toaster will use for # 1) clones of layers (in _toaster_clones ) # 2) the build dir (in build) # 3) the sqlite db if that is being used. # 4) pid's we need to clean up on exit/shutdown export TOASTER_DIR=$TOASTERDIR export BB_ENV_EXTRAWHITE="$BB_ENV_EXTRAWHITE TOASTER_DIR" # Determine the action. If specified by arguments, fine, if not, toggle it if [ "$CMD" = "start" ] ; then if [ -n "$BBSERVER" ]; then echo " Toaster is already running. Exiting..." return 1 fi elif [ "$CMD" = "" ]; then echo "No command specified" echo "$HELP" return 1 fi echo "The system will $CMD." # Execute the commands custom_extention toaster_prepend $CMD $ADDR_PORT case $CMD in start ) # check if addr:port is not in use if [ "$CMD" == 'start' ]; then if [ $WEBSERVER -gt 0 ]; then $MANAGE checksocket "$ADDR_PORT" || return 1 fi fi # Create configuration file conf=${BUILDDIR}/conf/local.conf line='INHERIT+="toaster buildhistory"' grep -q "$line" $conf || echo $line >> $conf if [ $WEBSERVER -eq 0 ] ; then # Do not update the database for "noweb" unless # it does not yet exist if [ ! -f "$TOASTER_DIR/toaster.sqlite" ] ; then if ! databaseCheck; then echo "Failed ${CMD}." return 4 fi fi custom_extention noweb_start_postpend $ADDR_PORT fi if [ $WEBSERVER -gt 0 ] && ! webserverStartAll; then echo "Failed ${CMD}." return 4 fi export BITBAKE_UI='toasterui' if [ $TOASTER_BUILDSERVER -eq 1 ] ; then $MANAGE runbuilds \ >${BUILDDIR}/toaster_runbuilds.log 2>&1 \ & echo $! >${BUILDDIR}/.runbuilds.pid else echo "Toaster build server not started." fi # set fail safe stop system on terminal exit trap stop_system SIGHUP echo "Successful ${CMD}." custom_extention toaster_postpend $CMD $ADDR_PORT return 0 ;; stop ) stop_system echo "Successful ${CMD}." ;; esac custom_extention toaster_postpend $CMD $ADDR_PORT