From: Thomas De Schampheleire <patrickdepinguin@gmail.com>
To: buildroot@busybox.net
Subject: [Buildroot] [PATCH v4 4/9] autobuild-run: use **kwargs to avoid explicit parameter passthroughs
Date: Wed, 12 Nov 2014 20:58:32 +0100 [thread overview]
Message-ID: <1415822317-22500-5-git-send-email-patrickdepinguin@gmail.com> (raw)
In-Reply-To: <1415822317-22500-1-git-send-email-patrickdepinguin@gmail.com>
From: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
The current version of autobuild-run has some extensive explicit
parameter passing, for example:
- fixup_config needs sysinfo, passed via gen_config, in turn via
run_instance, in turn via main.
- send_results needs username/password settings, passed via
run_instance, in turn via main.
Everytime a leaf function needs an extra parameter (for example coming
from the arguments or config file), the entire call chain needs to be
adapted to pass along that parameter.
This patch introduces the **kwargs dictionary principle, that allows
implicit parameter passing. A function can accept this dictionary and
extract parameters from it by name. The dictionary can be passed as a
whole to a child function, without explicitly enumerating which entries
in the dictionary are needed in the child.
Signed-off-by: Thomas De Schampheleire <thomas.de.schampheleire@gmail.com>
---
scripts/autobuild-run | 73 ++++++++++++++++++++++++++++++---------------------
1 file changed, 43 insertions(+), 30 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index e0a87fa..8312bfb 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -189,7 +189,7 @@ def get_toolchain_configs():
configs.append(config)
return configs
-def prepare_build(instance, log):
+def prepare_build(**kwargs):
"""Prepare for the next build of the specified instance
This function prepares the build by making sure all the needed
@@ -197,7 +197,8 @@ def prepare_build(instance, log):
code, and cleaning up remaining stuff from previous builds.
"""
- idir = "instance-%d" % instance
+ idir = "instance-%d" % kwargs['instance']
+ log = kwargs['log']
log_write(log, "INFO: preparing a new build")
@@ -246,7 +247,7 @@ def prepare_build(instance, log):
return 0
-def fixup_config(instance, sysinfo):
+def fixup_config(**kwargs):
"""Finalize the configuration and reject any problematic combinations
This function returns 'True' when the configuration has been
@@ -255,9 +256,10 @@ def fixup_config(instance, sysinfo):
generated).
"""
- idir = "instance-%d" % instance
- outputdir = os.path.join(idir, "output")
+ idir = "instance-%d" % kwargs['instance']
+ sysinfo = kwargs['sysinfo']
+ outputdir = os.path.join(idir, "output")
with open(os.path.join(outputdir, ".config")) as configf:
configlines = configf.readlines()
@@ -347,7 +349,7 @@ def fixup_config(instance, sysinfo):
return True
-def gen_config(instance, log, sysinfo):
+def gen_config(**kwargs):
"""Generate a new random configuration
This function generates the configuration, by choosing a random
@@ -355,7 +357,9 @@ def gen_config(instance, log, sysinfo):
packages.
"""
- idir = "instance-%d" % instance
+ idir = "instance-%d" % kwargs['instance']
+ log = kwargs['log']
+
dldir = os.path.join(idir, "dl")
# We need the absolute path to use with O=, because the relative
# path to the output directory here is not relative to the
@@ -406,7 +410,7 @@ def gen_config(instance, log, sysinfo):
if ret != 0:
log_write(log, "ERROR: cannot generate random configuration")
return -1
- if fixup_config(instance, sysinfo):
+ if fixup_config(**kwargs):
break
ret = subprocess.call(["yes '' 2>/dev/null| make O=%s -C %s oldconfig" % \
@@ -423,10 +427,12 @@ def gen_config(instance, log, sysinfo):
return 0
-def do_build(instance, njobs, log, make_opts):
+def do_build(**kwargs):
"""Run the build itself"""
- idir = "instance-%d" % instance
+ idir = "instance-%d" % kwargs['instance']
+ log = kwargs['log']
+
# We need the absolute path to use with O=, because the relative
# path to the output directory here is not relative to the
# Buildroot sources, but to the location of the autobuilder
@@ -437,8 +443,9 @@ def do_build(instance, njobs, log, make_opts):
f = open(os.path.join(outputdir, "logfile"), "w+")
log_write(log, "INFO: build started")
cmd = ["timeout", str(MAX_DURATION), "make", "O=%s" % outputdir,
- "-C", srcdir, "BR2_DL_DIR=%s" % dldir, "BR2_JLEVEL=%s" % njobs] \
- + make_opts.split()
+ "-C", srcdir, "BR2_DL_DIR=%s" % dldir,
+ "BR2_JLEVEL=%s" % kwargs['njobs']] \
+ + kwargs['make_opts'].split()
ret = subprocess.call(cmd, stdout=f, stderr=f)
# 124 is a special error code that indicates we have reached the
# timeout
@@ -455,7 +462,7 @@ def do_build(instance, njobs, log, make_opts):
log_write(log, "INFO: build successful")
return 0
-def send_results(instance, http_login, http_password, submitter, log, result):
+def send_results(result, **kwargs):
"""Prepare and store/send tarball with results
This function prepares the tarball with the results, and either
@@ -463,7 +470,9 @@ def send_results(instance, http_login, http_password, submitter, log, result):
are available) or stores them locally as tarballs.
"""
- idir = "instance-%d" % instance
+ idir = "instance-%d" % kwargs['instance']
+ log = kwargs['log']
+
outputdir = os.path.abspath(os.path.join(idir, "output"))
srcdir = os.path.join(idir, "buildroot")
resultdir = os.path.join(outputdir, "results")
@@ -498,7 +507,7 @@ def send_results(instance, http_login, http_password, submitter, log, result):
resultf.close()
with open(os.path.join(resultdir, "submitter"), "w+") as submitterf:
- submitterf.write(submitter)
+ submitterf.write(kwargs['submitter'])
# Yes, shutil.make_archive() would be nice, but it doesn't exist
# in Python 2.6.
@@ -508,11 +517,12 @@ def send_results(instance, http_login, http_password, submitter, log, result):
log_write(log, "ERROR: could not make results tarball")
sys.exit(1)
- if http_login and http_password:
+ if kwargs['http_login'] and kwargs['http_password']:
# Submit results. Yes, Python has some HTTP libraries, but
# none of the ones that are part of the standard library can
# upload a file without writing dozens of lines of code.
- ret = subprocess.call(["curl", "-u", "%s:%s" % (http_login, http_password),
+ ret = subprocess.call(["curl", "-u",
+ "%s:%s" % (kwargs['http_login'], kwargs['http_password']),
"-H", "Expect:",
"-F", "uploadedfile=@%s" % os.path.join(outputdir, "results.tar.bz2"),
"-F", "uploadsubmit=1",
@@ -526,39 +536,40 @@ def send_results(instance, http_login, http_password, submitter, log, result):
# No http login/password, keep tarballs locally
with open(os.path.join(outputdir, "results.tar.bz2"), 'rb') as f:
sha1 = hashlib.sha1(f.read()).hexdigest()
- resultfilename = "instance-%d-%s.tar.bz2" % (instance, sha1)
+ resultfilename = "instance-%d-%s.tar.bz2" % (kwargs['instance'], sha1)
os.rename(os.path.join(outputdir, "results.tar.bz2"), resultfilename)
log_write(log, "INFO: results saved as %s" % resultfilename)
-def run_instance(instance, njobs, http_login, http_password, submitter,
- make_opts, sysinfo):
+def run_instance(**kwargs):
"""Main per-instance loop
Prepare the build, generate a configuration, run the build, and submit the
results.
"""
- idir = "instance-%d" % instance
+ idir = "instance-%d" % kwargs['instance']
# If it doesn't exist, create the instance directory
if not os.path.exists(idir):
os.mkdir(idir)
- instance_log = open(os.path.join(idir, "instance.log"), "a+")
- log_write(instance_log, "INFO: instance started")
+ kwargs['log'] = open(os.path.join(idir, "instance.log"), "a+")
+ log_write(kwargs['log'], "INFO: instance started")
+
while True:
check_version()
- ret = prepare_build(instance, instance_log)
+ ret = prepare_build(**kwargs)
if ret != 0:
continue
- ret = gen_config(instance, instance_log, sysinfo)
+ ret = gen_config(**kwargs)
if ret != 0:
continue
- ret = do_build(instance, njobs, instance_log, make_opts)
- send_results(instance, http_login, http_password, submitter, instance_log, ret)
+ ret = do_build(**kwargs)
+
+ send_results(ret, **kwargs)
# args / config file merging inspired by:
# https://github.com/docopt/docopt/blob/master/examples/config_file_example.py
@@ -610,9 +621,11 @@ def main():
sys.exit(1)
processes = []
for i in range(0, int(args['--ninstances'])):
- p = Process(target=run_instance, args=(i, int(args['--njobs']),
- args['--http-login'], args['--http-password'],
- args['--submitter'], args['--make-opts'], sysinfo))
+ p = Process(target=run_instance, kwargs={
+ 'instance': i, 'njobs': args['--njobs'], 'sysinfo': sysinfo,
+ 'http_login': args['--http-login'],
+ 'http_password': args['--http-password'],
+ 'submitter': args['--submitter'], 'make_opts': args['--make-opts']})
p.start()
processes.append(p)
signal.signal(signal.SIGTERM, sigterm_handler)
--
1.8.5.1
next prev parent reply other threads:[~2014-11-12 19:58 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-12 19:58 [Buildroot] [PATCH v4 0/9] autobuild-run improvements Thomas De Schampheleire
2014-11-12 19:58 ` [Buildroot] [PATCH v4 1/9] scripts: add python module docopt Thomas De Schampheleire
2014-11-12 19:58 ` [Buildroot] [PATCH v4 2/9] autobuild-run: use docopt for argument parsing Thomas De Schampheleire
2014-11-12 19:58 ` [Buildroot] [PATCH v4 3/9] autobuild-run: add option --make-opts for custom Buildroot options Thomas De Schampheleire
2014-11-12 19:58 ` Thomas De Schampheleire [this message]
2014-11-12 19:58 ` [Buildroot] [PATCH v4 5/9] autobuild-run: check-requirements does not need to know the login details Thomas De Schampheleire
2014-11-12 19:58 ` [Buildroot] [PATCH v4 6/9] autobuild-run: set LC_ALL=C to not use locale settings of host machine Thomas De Schampheleire
2014-11-12 19:58 ` [Buildroot] [PATCH v4 7/9] autobuild-run: improve the logic to generate build-end.log Thomas De Schampheleire
2014-11-12 19:58 ` [Buildroot] [PATCH v4 8/9] autobuild-run: save config.log files for failed package Thomas De Schampheleire
2014-11-12 19:58 ` [Buildroot] [PATCH v4 9/9] autobuild-run: extend TODO list Thomas De Schampheleire
2014-11-25 21:09 ` Thomas De Schampheleire
2014-11-25 21:20 ` Thomas Petazzoni
2014-12-04 20:41 ` Thomas De Schampheleire
2014-12-05 8:15 ` Thomas Petazzoni
2014-12-05 12:42 ` Thomas De Schampheleire
2014-11-25 20:36 ` [Buildroot] [PATCH v4 0/9] autobuild-run improvements Thomas De Schampheleire
2014-11-25 20:42 ` Thomas Petazzoni
2014-11-25 21:10 ` Thomas De Schampheleire
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1415822317-22500-5-git-send-email-patrickdepinguin@gmail.com \
--to=patrickdepinguin@gmail.com \
--cc=buildroot@busybox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox