xref: /OK3568_Linux_fs/yocto/poky/bitbake/bin/toaster (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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