yocto-autobuilder-helper/scripts/run-config
Richard Purdie b27ef9a53d run-config: Renumber the log files to match step numbers
Also print a summary of the logfiles which contain failures.

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2018-09-05 14:11:33 +01:00

6.9 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.

import json import os import sys import subprocess import errno

import utils

parser = utils.ArgParser(description='Runs configurations in json.conf.')

parser.add_argument('target', help="The 'nightly' target the autobuilder is running") parser.add_argument('builddir', help="The target build directory to configure") parser.add_argument('branchname', help="The poky branch name the build is running on") parser.add_argument('reponame', help="The name of the repository the build is running on") parser.add_argument('-s', '--sstateprefix', default='', help="The directory prefix to publish sstate into") parser.add_argument('-b', '--buildappsrcrev', default='', help="A build appliance SRCREV to use") parser.add_argument('-p', '--publish-dir', action='store', help="Where to publish artefacts to (optional)") parser.add_argument('-u', '--build-url', action='store', help="URL back to this build (for the error reporting system)") parser.add_argument('-t', '--test', action='store_true', default=False, help="Test mode - perform setup and dry-run of commands only") parser.add_argument('-q', '--quietlogging', action='store_true', default=False, help="Quiet mode - don't echo bitbake logs to stdout")

args = parser.parse_args()

scriptsdir = os.path.dirname(os.path.realpath(file)) ourconfig = utils.loadconfig()

testmode = args.test

Find out the number of steps this target has

maxsteps = 1 if args.target in ourconfig['overrides']: for v in ourconfig['overrides'][args.target]: if v.startswith("step"): n = int(v[4:]) if n <= maxsteps: continue maxsteps = n

utils.printheader("Target task %s has %d steps" % (args.target, maxsteps))

finalret = 0

def flush(): sys.stdout.flush() sys.stderr.flush()

lognum = 0 def logname(path, stepnum, logsuffix): global lognum lognum += 1 return path + "/command.log.%s%s" % (stepnum, logsuffix)

revision = "unknown" report = utils.ErrorReport(ourconfig, args.target, args.builddir, args.branchname, revision) errordir = utils.errorreportdir(args.builddir) utils.mkdir(errordir)

errorlogs = set()

def bitbakecmd(builddir, cmd, report, stepnum, logsuffix, oeenv=True): global finalret flush() log = logname(builddir, stepnum, logsuffix) 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 not args.quietlogging:
            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
    errorlogs.add(log)

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, args.builddir, args.target, args.reponame, args.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, args.target, stepnum) for layer in layers: bitbakecmd(args.builddir, "bitbake-layers add-layer %s" % layer, report, stepnum, 'a')

flush()
# Generate the configuration files needed for this step
if utils.getconfigvar("WRITECONFIG", ourconfig, args.target, stepnum):
    runcmd([scriptsdir + "/setup-config", args.target, str(stepnum - 1), args.builddir, args.branchname, args.reponame, "-s", args.sstateprefix, "-b", args.buildappsrcrev])

# Execute the targets for this configuration
targets = utils.getconfigvar("BBTARGETS", ourconfig, args.target, stepnum)
if targets:
    utils.printheader("Step %s/%s: Running bitbake %s" % (stepnum, maxsteps, targets))
    bitbakecmd(args.builddir, "bitbake %s" % targets, report, stepnum, 'b')

# Execute the sanity targets for this configuration
sanitytargets = utils.getconfigvar("SANITYTARGETS", ourconfig, args.target, stepnum)
if sanitytargets:
    utils.printheader("Step %s/%s: Running bitbake %s" % (stepnum, maxsteps, sanitytargets))
    bitbakecmd(args.builddir, "%s/checkvnc; DISPLAY=:1 bitbake %s" % (scriptsdir, sanitytargets), report, stepnum, 'c')

# Run any extra commands specified
cmds = utils.getconfiglist("EXTRACMDS", ourconfig, args.target, stepnum)
for cmd in cmds:
    utils.printheader("Step %s/%s: Running command %s" % (stepnum, maxsteps, cmd))
    bitbakecmd(args.builddir, cmd, report, stepnum, 'd')
cmds = utils.getconfiglist("EXTRAPLAINCMDS", ourconfig, args.target, stepnum)
for cmd in cmds:
    utils.printheader("Step %s/%s: Running 'plain' command %s" % (stepnum, maxsteps, cmd))
    bitbakecmd(args.builddir, cmd, report, stepnum, 'd', oeenv=False)

# Remove any layers we added in a reverse order
for layer in reversed(layers):
    bitbakecmd(args.builddir, "bitbake-layers remove-layer %s" % layer, report, stepnum, 'a')

if args.publish_dir: utils.printheader("Running publish artefacts") runcmd([scriptsdir + "/publish-artefacts", args.builddir, args.publish_dir, args.target])

if args.build_url and utils.getconfigvar("SENDERRORS", ourconfig, args.target, stepnum): utils.printheader("Sending any error reports") runcmd([scriptsdir + "/upload-error-reports", args.builddir, args.build_url])

if finalret: utils.printheader("There were %s failures" % finalret) utils.printheader("Failures in logfiles: %s" % " ".join(errorlogs)) sys.exit(1) sys.exit(0)