| #!/bin/echo ERROR: This script needs to be sourced. Please run as . | |
| # toaster - shell script to start Toaster | |
| # Copyright (C) 2013-2015 Intel Corp. | |
| # | |
| # SPDX-License-Identifier: GPL-2.0-or-later | |
| # | |
| HELP=" | |
| Usage 1: source toaster start|stop [webport=<address:port>] [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/../) | |
| Usage 2: source toaster manage [createsuperuser|lsupdates|migrate|makemigrations|checksettings|collectstatic|...] | |
| " | |
| 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=<ME> | |
| $MANAGE migrate --noinput || retval=1 | |
| if [ $retval -eq 1 ]; then | |
| echo "Failed migrations, halting 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; exiting\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" \ | |
| </dev/null >>${TOASTER_LOGS_DIR}/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 <target>' 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. | |
| # BBSETUP no longer supports .templateconf | |
| if [ -f $OE_ROOT/.templateconf ] ; then | |
| . $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 | |
| else | |
| # Force poky | |
| TEMPLATECONF="layers/meta-yocto/meta-poky/conf/templates/default" | |
| fi | |
| unset OE_ROOT | |
| WEBSERVER=1 | |
| export TOASTER_BUILDSERVER=1 | |
| ADDR_PORT="localhost:8000" | |
| TOASTERDIR=`dirname $BUILDDIR` | |
| # ${BUILDDIR}/toaster_logs/ became the default location for toaster logs | |
| # This is needed for implemented django-log-viewer: https://pypi.org/project/django-log-viewer/ | |
| # If the directory does not exist, create it. | |
| TOASTER_LOGS_DIR="${BUILDDIR}/toaster_logs/" | |
| if [ ! -d $TOASTER_LOGS_DIR ] | |
| then | |
| mkdir $TOASTER_LOGS_DIR | |
| fi | |
| 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#*=}" | |
| ;; | |
| manage ) | |
| CMD=$param | |
| manage_cmd="" | |
| ;; | |
| --help) | |
| echo "$HELP" | |
| return 0 | |
| ;; | |
| *) | |
| if [ "manage" == "$CMD" ] ; then | |
| manage_cmd="$manage_cmd $param" | |
| else | |
| echo "$HELP" | |
| return 1 | |
| fi | |
| ;; | |
| 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 | |
| # By default we move this all into the Toaster's parent build directory | |
| export TOASTER_DIR=$BUILDDIR | |
| export BB_ENV_PASSTHROUGH_ADDITIONS="$BB_ENV_PASSTHROUGH_ADDITIONS 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 \ | |
| </dev/null >>${TOASTER_LOGS_DIR}/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}." | |
| ;; | |
| manage ) | |
| cd $BBBASEDIR/lib/toaster | |
| $MANAGE $manage_cmd | |
| ;; | |
| esac | |
| custom_extention toaster_postpend $CMD $ADDR_PORT | |