1*4882a593Smuzhiyun#!/bin/echo ERROR: This script needs to be sourced. Please run as . 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun# toaster - shell script to start Toaster 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun# Copyright (C) 2013-2015 Intel Corp. 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-or-later 8*4882a593Smuzhiyun# 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunHELP=" 11*4882a593SmuzhiyunUsage 1: source toaster start|stop [webport=<address:port>] [noweb] [nobuild] [toasterdir] 12*4882a593Smuzhiyun Optional arguments: 13*4882a593Smuzhiyun [nobuild] Setup the environment for capturing builds with toaster but disable managed builds 14*4882a593Smuzhiyun [noweb] Setup the environment for capturing builds with toaster but don't start the web server 15*4882a593Smuzhiyun [webport] Set the development server (default: localhost:8000) 16*4882a593Smuzhiyun [toasterdir] Set absolute path to be used as TOASTER_DIR (default: BUILDDIR/../) 17*4882a593SmuzhiyunUsage 2: source toaster manage [createsuperuser|lsupdates|migrate|makemigrations|checksettings|collectstatic|...] 18*4882a593Smuzhiyun" 19*4882a593Smuzhiyun 20*4882a593Smuzhiyuncustom_extention() 21*4882a593Smuzhiyun{ 22*4882a593Smuzhiyun custom_extension=$BBBASEDIR/lib/toaster/orm/fixtures/custom_toaster_append.sh 23*4882a593Smuzhiyun if [ -f $custom_extension ] ; then 24*4882a593Smuzhiyun $custom_extension $* 25*4882a593Smuzhiyun fi 26*4882a593Smuzhiyun} 27*4882a593Smuzhiyun 28*4882a593SmuzhiyundatabaseCheck() 29*4882a593Smuzhiyun{ 30*4882a593Smuzhiyun retval=0 31*4882a593Smuzhiyun # you can always add a superuser later via 32*4882a593Smuzhiyun # ../bitbake/lib/toaster/manage.py createsuperuser --username=<ME> 33*4882a593Smuzhiyun $MANAGE migrate --noinput || retval=1 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun if [ $retval -eq 1 ]; then 36*4882a593Smuzhiyun echo "Failed migrations, halting system start" 1>&2 37*4882a593Smuzhiyun return $retval 38*4882a593Smuzhiyun fi 39*4882a593Smuzhiyun # Make sure that checksettings can pick up any value for TEMPLATECONF 40*4882a593Smuzhiyun export TEMPLATECONF 41*4882a593Smuzhiyun $MANAGE checksettings --traceback || retval=1 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun if [ $retval -eq 1 ]; then 44*4882a593Smuzhiyun printf "\nError while checking settings; exiting\n" 45*4882a593Smuzhiyun return $retval 46*4882a593Smuzhiyun fi 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun return $retval 49*4882a593Smuzhiyun} 50*4882a593Smuzhiyun 51*4882a593SmuzhiyunwebserverKillAll() 52*4882a593Smuzhiyun{ 53*4882a593Smuzhiyun local pidfile 54*4882a593Smuzhiyun if [ -f ${BUILDDIR}/.toastermain.pid ] ; then 55*4882a593Smuzhiyun custom_extention web_stop_postpend 56*4882a593Smuzhiyun else 57*4882a593Smuzhiyun custom_extention noweb_stop_postpend 58*4882a593Smuzhiyun fi 59*4882a593Smuzhiyun for pidfile in ${BUILDDIR}/.toastermain.pid ${BUILDDIR}/.runbuilds.pid; do 60*4882a593Smuzhiyun if [ -f ${pidfile} ]; then 61*4882a593Smuzhiyun pid=`cat ${pidfile}` 62*4882a593Smuzhiyun while kill -0 $pid 2>/dev/null; do 63*4882a593Smuzhiyun kill -SIGTERM $pid 2>/dev/null 64*4882a593Smuzhiyun sleep 1 65*4882a593Smuzhiyun done 66*4882a593Smuzhiyun rm ${pidfile} 67*4882a593Smuzhiyun fi 68*4882a593Smuzhiyun done 69*4882a593Smuzhiyun} 70*4882a593Smuzhiyun 71*4882a593SmuzhiyunwebserverStartAll() 72*4882a593Smuzhiyun{ 73*4882a593Smuzhiyun # do not start if toastermain points to a valid process 74*4882a593Smuzhiyun if ! cat "${BUILDDIR}/.toastermain.pid" 2>/dev/null | xargs -I{} kill -0 {} ; then 75*4882a593Smuzhiyun retval=1 76*4882a593Smuzhiyun rm "${BUILDDIR}/.toastermain.pid" 77*4882a593Smuzhiyun fi 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun retval=0 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun # check the database 82*4882a593Smuzhiyun databaseCheck || return 1 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun echo "Starting webserver..." 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun $MANAGE runserver --noreload "$ADDR_PORT" \ 87*4882a593Smuzhiyun </dev/null >>${BUILDDIR}/toaster_web.log 2>&1 \ 88*4882a593Smuzhiyun & echo $! >${BUILDDIR}/.toastermain.pid 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun sleep 1 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun if ! cat "${BUILDDIR}/.toastermain.pid" | xargs -I{} kill -0 {} ; then 93*4882a593Smuzhiyun retval=1 94*4882a593Smuzhiyun rm "${BUILDDIR}/.toastermain.pid" 95*4882a593Smuzhiyun else 96*4882a593Smuzhiyun echo "Toaster development webserver started at http://$ADDR_PORT" 97*4882a593Smuzhiyun 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" 98*4882a593Smuzhiyun custom_extention web_start_postpend $ADDR_PORT 99*4882a593Smuzhiyun fi 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun return $retval 102*4882a593Smuzhiyun} 103*4882a593Smuzhiyun 104*4882a593SmuzhiyunINSTOPSYSTEM=0 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun# define the stop command 107*4882a593Smuzhiyunstop_system() 108*4882a593Smuzhiyun{ 109*4882a593Smuzhiyun # prevent reentry 110*4882a593Smuzhiyun if [ $INSTOPSYSTEM -eq 1 ]; then return; fi 111*4882a593Smuzhiyun INSTOPSYSTEM=1 112*4882a593Smuzhiyun webserverKillAll 113*4882a593Smuzhiyun # unset exported variables 114*4882a593Smuzhiyun unset TOASTER_DIR 115*4882a593Smuzhiyun unset BITBAKE_UI 116*4882a593Smuzhiyun unset BBBASEDIR 117*4882a593Smuzhiyun trap - SIGHUP 118*4882a593Smuzhiyun #trap - SIGCHLD 119*4882a593Smuzhiyun INSTOPSYSTEM=0 120*4882a593Smuzhiyun} 121*4882a593Smuzhiyun 122*4882a593Smuzhiyunverify_prereq() { 123*4882a593Smuzhiyun # Verify Django version 124*4882a593Smuzhiyun reqfile=$(python3 -c "import os; print(os.path.realpath('$BBBASEDIR/toaster-requirements.txt'))") 125*4882a593Smuzhiyun exp='s/Django\([><=]\+\)\([^,]\+\),\([><=]\+\)\(.\+\)/' 126*4882a593Smuzhiyun # expand version parts to 2 digits to support 1.10.x > 1.8 127*4882a593Smuzhiyun # (note:helper functions hard to insert in-line) 128*4882a593Smuzhiyun exp=$exp'import sys,django;' 129*4882a593Smuzhiyun exp=$exp'version=["%02d" % int(n) for n in django.get_version().split(".")];' 130*4882a593Smuzhiyun exp=$exp'vmin=["%02d" % int(n) for n in "\2".split(".")];' 131*4882a593Smuzhiyun exp=$exp'vmax=["%02d" % int(n) for n in "\4".split(".")];' 132*4882a593Smuzhiyun exp=$exp'sys.exit(not (version \1 vmin and version \3 vmax))' 133*4882a593Smuzhiyun exp=$exp'/p' 134*4882a593Smuzhiyun if ! sed -n "$exp" $reqfile | python3 - ; then 135*4882a593Smuzhiyun req=`grep ^Django $reqfile` 136*4882a593Smuzhiyun echo "This program needs $req" 137*4882a593Smuzhiyun echo "Please install with pip3 install -r $reqfile" 138*4882a593Smuzhiyun return 2 139*4882a593Smuzhiyun fi 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun return 0 142*4882a593Smuzhiyun} 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun# read command line parameters 145*4882a593Smuzhiyunif [ -n "$BASH_SOURCE" ] ; then 146*4882a593Smuzhiyun TOASTER=${BASH_SOURCE} 147*4882a593Smuzhiyunelif [ -n "$ZSH_NAME" ] ; then 148*4882a593Smuzhiyun TOASTER=${(%):-%x} 149*4882a593Smuzhiyunelse 150*4882a593Smuzhiyun TOASTER=$0 151*4882a593Smuzhiyunfi 152*4882a593Smuzhiyun 153*4882a593Smuzhiyunexport BBBASEDIR=`dirname $TOASTER`/.. 154*4882a593SmuzhiyunMANAGE="python3 $BBBASEDIR/lib/toaster/manage.py" 155*4882a593Smuzhiyunif [ -z "$OE_ROOT" ]; then 156*4882a593Smuzhiyun OE_ROOT=`dirname $TOASTER`/../.. 157*4882a593Smuzhiyunfi 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun# this is the configuraton file we are using for toaster 160*4882a593Smuzhiyun# we are using the same logic that oe-setup-builddir uses 161*4882a593Smuzhiyun# (based on TEMPLATECONF and .templateconf) to determine 162*4882a593Smuzhiyun# which toasterconf.json to use. 163*4882a593Smuzhiyun# note: There are a number of relative path assumptions 164*4882a593Smuzhiyun# in the local layers that currently make using an arbitrary 165*4882a593Smuzhiyun# toasterconf.json difficult. 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun. $OE_ROOT/.templateconf 168*4882a593Smuzhiyunif [ -n "$TEMPLATECONF" ]; then 169*4882a593Smuzhiyun if [ ! -d "$TEMPLATECONF" ]; then 170*4882a593Smuzhiyun # Allow TEMPLATECONF=meta-xyz/conf as a shortcut 171*4882a593Smuzhiyun if [ -d "$OE_ROOT/$TEMPLATECONF" ]; then 172*4882a593Smuzhiyun TEMPLATECONF="$OE_ROOT/$TEMPLATECONF" 173*4882a593Smuzhiyun fi 174*4882a593Smuzhiyun fi 175*4882a593Smuzhiyunfi 176*4882a593Smuzhiyun 177*4882a593Smuzhiyununset OE_ROOT 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun 180*4882a593SmuzhiyunWEBSERVER=1 181*4882a593Smuzhiyunexport TOASTER_BUILDSERVER=1 182*4882a593SmuzhiyunADDR_PORT="localhost:8000" 183*4882a593SmuzhiyunTOASTERDIR=`dirname $BUILDDIR` 184*4882a593Smuzhiyununset CMD 185*4882a593Smuzhiyunfor param in $*; do 186*4882a593Smuzhiyun case $param in 187*4882a593Smuzhiyun noweb ) 188*4882a593Smuzhiyun WEBSERVER=0 189*4882a593Smuzhiyun ;; 190*4882a593Smuzhiyun nobuild ) 191*4882a593Smuzhiyun TOASTER_BUILDSERVER=0 192*4882a593Smuzhiyun ;; 193*4882a593Smuzhiyun start ) 194*4882a593Smuzhiyun CMD=$param 195*4882a593Smuzhiyun ;; 196*4882a593Smuzhiyun stop ) 197*4882a593Smuzhiyun CMD=$param 198*4882a593Smuzhiyun ;; 199*4882a593Smuzhiyun webport=*) 200*4882a593Smuzhiyun ADDR_PORT="${param#*=}" 201*4882a593Smuzhiyun # Split the addr:port string 202*4882a593Smuzhiyun ADDR=`echo $ADDR_PORT | cut -f 1 -d ':'` 203*4882a593Smuzhiyun PORT=`echo $ADDR_PORT | cut -f 2 -d ':'` 204*4882a593Smuzhiyun # If only a port has been speified then set address to localhost. 205*4882a593Smuzhiyun if [ $ADDR = $PORT ] ; then 206*4882a593Smuzhiyun ADDR_PORT="localhost:$PORT" 207*4882a593Smuzhiyun fi 208*4882a593Smuzhiyun ;; 209*4882a593Smuzhiyun toasterdir=*) 210*4882a593Smuzhiyun TOASTERDIR="${param#*=}" 211*4882a593Smuzhiyun ;; 212*4882a593Smuzhiyun manage ) 213*4882a593Smuzhiyun CMD=$param 214*4882a593Smuzhiyun manage_cmd="" 215*4882a593Smuzhiyun ;; 216*4882a593Smuzhiyun --help) 217*4882a593Smuzhiyun echo "$HELP" 218*4882a593Smuzhiyun return 0 219*4882a593Smuzhiyun ;; 220*4882a593Smuzhiyun *) 221*4882a593Smuzhiyun if [ "manage" == "$CMD" ] ; then 222*4882a593Smuzhiyun manage_cmd="$manage_cmd $param" 223*4882a593Smuzhiyun else 224*4882a593Smuzhiyun echo "$HELP" 225*4882a593Smuzhiyun exit 1 226*4882a593Smuzhiyun fi 227*4882a593Smuzhiyun ;; 228*4882a593Smuzhiyun 229*4882a593Smuzhiyun esac 230*4882a593Smuzhiyundone 231*4882a593Smuzhiyun 232*4882a593Smuzhiyunif [ `basename \"$0\"` = `basename \"${TOASTER}\"` ]; then 233*4882a593Smuzhiyun echo "Error: This script needs to be sourced. Please run as . $TOASTER" 234*4882a593Smuzhiyun return 1 235*4882a593Smuzhiyunfi 236*4882a593Smuzhiyun 237*4882a593Smuzhiyunverify_prereq || return 1 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun# We make sure we're running in the current shell and in a good environment 240*4882a593Smuzhiyunif [ -z "$BUILDDIR" ] || ! which bitbake >/dev/null 2>&1 ; then 241*4882a593Smuzhiyun echo "Error: Build environment is not setup or bitbake is not in path." 1>&2 242*4882a593Smuzhiyun return 2 243*4882a593Smuzhiyunfi 244*4882a593Smuzhiyun 245*4882a593Smuzhiyun# this defines the dir toaster will use for 246*4882a593Smuzhiyun# 1) clones of layers (in _toaster_clones ) 247*4882a593Smuzhiyun# 2) the build dir (in build) 248*4882a593Smuzhiyun# 3) the sqlite db if that is being used. 249*4882a593Smuzhiyun# 4) pid's we need to clean up on exit/shutdown 250*4882a593Smuzhiyunexport TOASTER_DIR=$TOASTERDIR 251*4882a593Smuzhiyunexport BB_ENV_PASSTHROUGH_ADDITIONS="$BB_ENV_PASSTHROUGH_ADDITIONS TOASTER_DIR" 252*4882a593Smuzhiyun 253*4882a593Smuzhiyun# Determine the action. If specified by arguments, fine, if not, toggle it 254*4882a593Smuzhiyunif [ "$CMD" = "start" ] ; then 255*4882a593Smuzhiyun if [ -n "$BBSERVER" ]; then 256*4882a593Smuzhiyun echo " Toaster is already running. Exiting..." 257*4882a593Smuzhiyun return 1 258*4882a593Smuzhiyunfi 259*4882a593Smuzhiyunelif [ "$CMD" = "" ]; then 260*4882a593Smuzhiyun echo "No command specified" 261*4882a593Smuzhiyun echo "$HELP" 262*4882a593Smuzhiyun return 1 263*4882a593Smuzhiyunfi 264*4882a593Smuzhiyun 265*4882a593Smuzhiyunecho "The system will $CMD." 266*4882a593Smuzhiyun 267*4882a593Smuzhiyun# Execute the commands 268*4882a593Smuzhiyuncustom_extention toaster_prepend $CMD $ADDR_PORT 269*4882a593Smuzhiyun 270*4882a593Smuzhiyuncase $CMD in 271*4882a593Smuzhiyun start ) 272*4882a593Smuzhiyun # check if addr:port is not in use 273*4882a593Smuzhiyun if [ "$CMD" == 'start' ]; then 274*4882a593Smuzhiyun if [ $WEBSERVER -gt 0 ]; then 275*4882a593Smuzhiyun $MANAGE checksocket "$ADDR_PORT" || return 1 276*4882a593Smuzhiyun fi 277*4882a593Smuzhiyun fi 278*4882a593Smuzhiyun 279*4882a593Smuzhiyun # Create configuration file 280*4882a593Smuzhiyun conf=${BUILDDIR}/conf/local.conf 281*4882a593Smuzhiyun line='INHERIT+="toaster buildhistory"' 282*4882a593Smuzhiyun grep -q "$line" $conf || echo $line >> $conf 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun if [ $WEBSERVER -eq 0 ] ; then 285*4882a593Smuzhiyun # Do not update the database for "noweb" unless 286*4882a593Smuzhiyun # it does not yet exist 287*4882a593Smuzhiyun if [ ! -f "$TOASTER_DIR/toaster.sqlite" ] ; then 288*4882a593Smuzhiyun if ! databaseCheck; then 289*4882a593Smuzhiyun echo "Failed ${CMD}." 290*4882a593Smuzhiyun return 4 291*4882a593Smuzhiyun fi 292*4882a593Smuzhiyun fi 293*4882a593Smuzhiyun custom_extention noweb_start_postpend $ADDR_PORT 294*4882a593Smuzhiyun fi 295*4882a593Smuzhiyun if [ $WEBSERVER -gt 0 ] && ! webserverStartAll; then 296*4882a593Smuzhiyun echo "Failed ${CMD}." 297*4882a593Smuzhiyun return 4 298*4882a593Smuzhiyun fi 299*4882a593Smuzhiyun export BITBAKE_UI='toasterui' 300*4882a593Smuzhiyun if [ $TOASTER_BUILDSERVER -eq 1 ] ; then 301*4882a593Smuzhiyun $MANAGE runbuilds \ 302*4882a593Smuzhiyun </dev/null >>${BUILDDIR}/toaster_runbuilds.log 2>&1 \ 303*4882a593Smuzhiyun & echo $! >${BUILDDIR}/.runbuilds.pid 304*4882a593Smuzhiyun else 305*4882a593Smuzhiyun echo "Toaster build server not started." 306*4882a593Smuzhiyun fi 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun # set fail safe stop system on terminal exit 309*4882a593Smuzhiyun trap stop_system SIGHUP 310*4882a593Smuzhiyun echo "Successful ${CMD}." 311*4882a593Smuzhiyun custom_extention toaster_postpend $CMD $ADDR_PORT 312*4882a593Smuzhiyun return 0 313*4882a593Smuzhiyun ;; 314*4882a593Smuzhiyun stop ) 315*4882a593Smuzhiyun stop_system 316*4882a593Smuzhiyun echo "Successful ${CMD}." 317*4882a593Smuzhiyun ;; 318*4882a593Smuzhiyun manage ) 319*4882a593Smuzhiyun cd $BBBASEDIR/lib/toaster 320*4882a593Smuzhiyun $MANAGE $manage_cmd 321*4882a593Smuzhiyun ;; 322*4882a593Smuzhiyunesac 323*4882a593Smuzhiyuncustom_extention toaster_postpend $CMD $ADDR_PORT 324*4882a593Smuzhiyun 325