
The new buildbot code can directly monitor the logfiles itself so we need to be able to optionally stop echoing onto the console. Add missing flush() calls and print the command being used and logfile so its clear what is happening on stdout too. Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
6.2 KiB
Executable File
#!/usr/bin/env python3
Iterate over a set of configurations from json.conf, calling setup-config for each one, then running the build.
Called with $1 - The 'nightly' target the autobuilder is running
$2 - The target build directory to configure
$3 - The poky branch name the build is running on
$4 - The name of the repository the build is running on
$5 - The directory to publish sstate into
$6 - A build-appliance SRCREV to use
$7 - Where to publish artefacts to (or None)
$8 - URL back to this build (for the error reporting system)
$9 - Disable echoing logs to stdout (if specified)
import json import os import sys import subprocess import errno
import utils
if len(sys.argv) != 9 and len(sys.argv) != 10: print("Incorrect number of parameters, please call as %s " % sys.argv[0]) sys.exit(1)
target = sys.argv[1] builddir = sys.argv[2] branchname = sys.argv[3] reponame = sys.argv[4] sstate_release = sys.argv[5] buildappsrcrev = sys.argv[6] publish = None if sys.argv[7] != "None": publish = sys.argv[7] errorurl = None if sys.argv[8] != "None": errorurl = sys.argv[8] echologs = True if len(sys.argv) == 10: echologs = False
scriptsdir = os.path.dirname(os.path.realpath(file)) ourconfig = utils.loadconfig()
testmode = False if "ABHELPERTEST" in os.environ: testmode = True
Find out the number of steps this target has
maxsteps = 1 if target in ourconfig['overrides']: for v in ourconfig['overrides'][target]: if v.startswith("step"): n = int(v[4:]) if n <= maxsteps: continue maxsteps = n
utils.printheader("Target task %s has %d steps" % (target, maxsteps))
finalret = 0
def flush(): sys.stdout.flush() sys.stderr.flush()
lognum = 0 def logname(path): global lognum lognum += 1 return path + "/command.log.%s" % lognum
revision = "unknown" report = utils.ErrorReport(ourconfig, target, builddir, branchname, revision) errordir = utils.errorreportdir(builddir) utils.mkdir(errordir)
def bitbakecmd(builddir, cmd, report, stepnum, oeenv=True): global finalret flush() log = logname(builddir) errordir = utils.errorreportdir(builddir) try: numreports = len(os.listdir(errordir)) except FileNotFoundError: numreports = 0
if oeenv:
cmd = ". ./oe-init-build-env; %s" % cmd
if testmode:
print("Would run '%s'" % cmd)
return
print("Running '%s' with output to %s" % (cmd, log))
flush()
with subprocess.Popen(cmd, shell=True, cwd=builddir + "/..", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1) as p, open(log, 'ab') as f:
for line in p.stdout:
if echologs:
sys.stdout.buffer.write(line)
sys.stdout.flush()
f.write(line)
f.flush()
ret = p.wait()
if ret:
utils.printheader("ERROR: Command %s failed with exit code %d, see errors above." % (cmd, ret))
# No error report was written but the command failed so we should write one
try:
finalnumreports = len(os.listdir(errordir))
except FileNotFoundError:
finalnumreports = 0
if finalnumreports == numreports:
report.create(cmd, stepnum, log)
finalret += 1
def runcmd(cmd, *args, **kwargs): if testmode: print("Running %s" % cmd) if "setup-config" not in cmd[0]: return subprocess.check_call(cmd, *args, **kwargs)
bh_path, remoterepo, remotebranch, baseremotebranch = utils.getbuildhistoryconfig(ourconfig, builddir, target, reponame, branchname) if bh_path: runcmd([os.path.join(scriptsdir, "buildhistory-init"), bh_path, remoterepo, remotebranch, baseremotebranch])
for stepnum in range(1, maxsteps + 1): # Add any layers specified layers = utils.getconfiglist("ADDLAYER", ourconfig, target, stepnum) for layer in layers: bitbakecmd(builddir, "bitbake-layers add-layer %s" % layer, report, stepnum)
flush()
# Generate the configuration files needed for this step
if utils.getconfigvar("WRITECONFIG", ourconfig, target, stepnum):
runcmd([scriptsdir + "/setup-config", target, str(stepnum - 1), builddir, branchname, reponame, sstate_release, buildappsrcrev])
# Execute the targets for this configuration
targets = utils.getconfigvar("BBTARGETS", ourconfig, target, stepnum)
if targets:
utils.printheader("Step %s/%s: Running bitbake %s" % (stepnum, maxsteps, targets))
bitbakecmd(builddir, "bitbake %s" % targets, report, stepnum)
# Execute the sanity targets for this configuration
sanitytargets = utils.getconfigvar("SANITYTARGETS", ourconfig, target, stepnum)
if sanitytargets:
utils.printheader("Step %s/%s: Running bitbake %s" % (stepnum, maxsteps, sanitytargets))
bitbakecmd(builddir, "%s/checkvnc; DISPLAY=:1 bitbake %s" % (scriptsdir, sanitytargets), report, stepnum)
# Run any extra commands specified
cmds = utils.getconfiglist("EXTRACMDS", ourconfig, target, stepnum)
for cmd in cmds:
utils.printheader("Step %s/%s: Running command %s" % (stepnum, maxsteps, cmd))
bitbakecmd(builddir, cmd, report, stepnum)
cmds = utils.getconfiglist("EXTRAPLAINCMDS", ourconfig, target, stepnum)
for cmd in cmds:
utils.printheader("Step %s/%s: Running 'plain' command %s" % (stepnum, maxsteps, cmd))
bitbakecmd(builddir, cmd, report, stepnum, oeenv=False)
# Remove any layers we added in a reverse order
for layer in reversed(layers):
bitbakecmd(builddir, "bitbake-layers remove-layer %s" % layer, report, stepnum)
if publish: utils.printheader("Running publish artefacts") runcmd([scriptsdir + "/publish-artefacts", builddir, publish, target])
if errorurl and utils.getconfigvar("SENDERRORS", ourconfig, target, stepnum): utils.printheader("Sending any error reports") runcmd([scriptsdir + "/upload-error-reports", builddir, errorurl])
if finalret: utils.printheader("There were %s failures" % finalret) sys.exit(1) sys.exit(0)