* [Buildroot] [PATCH v4 00/30] builder-class series cover letter
@ 2019-08-01 2:46 Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 01/30] autobuild-run: introduce Builder class Atharva Lele
` (30 more replies)
0 siblings, 31 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Since various functions in the autobuilder script use a lot of common data, we
introduce a Builder class to house these variables.
I have also included modified versions of Thomas's commits after adapting them
to work with Builder class.
I created a v4 to change the order of one patch, and to delete another patch. No
other changes have been made.
RFC: Few patches, namely patches 25, 27-30 have not been reviewed yet. I'd like
some feedback on them, if any, so that necessary modifications can be done and
it can be merged as soon as possible.
Atharva Lele (28):
autobuild-run: introduce Builder class
autobuild-run: move instance variable from kwargs to Builder class
autobuild-run: move njobs from kwargs to Builder class
autobuild-run: move sysinfo from kwargs to Builder class
autobuild-run: move http variables from kwargs to Builder class
autobuild-run: move submitter from kwargs to Builder class
autobuild-run: move make_opts from kwargs to Builder class
autobuild-run: move niceness from kwargs to Builder class
autobuild-run: move toolchains_csv from kwargs to Builder class
autobuild-run: move repo from kwargs to Builder class
autobuild-run: move upload variable from kwargs to Builder class
autobuild-run: move buildpid from kwargs to Builder class
autobuild-run: move debug from kwargs to Builder class
autobuild-run: define instance directory as a part of Builder class
autobuild-run: move log variable to Builder class
autobuild-run: remove kwargs argument from function calls and
definitions
autobuild-run: define source directory as part of Builder class
autobuild-run: define download directory as part of Builder class
autobuild-run: define output directory as part of Builder class
autobuild-run: define results directory as part of Builder class
autobuild-run: move check_version() to Builder class
autobuild-run: move get_branch() to Builder class
autobuild-run: create reason file on build failures
web/import.inc.php: support reading failure reason from reason file
autobuild-run: modify do_build() to accept outputdir as argument
autobuild-run: define different output directory for reproducible
builds
autobuild-run: use different output directories for reproducible
builds testing
autobuild-run: make prepare_build() clean the output directory used
for reproducibility testing
Thomas Petazzoni (2):
scripts/autobuild-run: make the HTTP URL really configurable
scripts/autobuild-run: support changing repo
scripts/autobuild-run | 943 +++++++++++++++++++++---------------------
web/import.inc.php | 26 +-
2 files changed, 488 insertions(+), 481 deletions(-)
--
2.22.0
^ permalink raw reply [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 01/30] autobuild-run: introduce Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 02/30] autobuild-run: move instance variable from kwargs to " Atharva Lele
` (29 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Various functions in the autobuild-run script use a lot of common data.
To make it easier to work with, create a Builder class.
For ease of review, this commit only introduces the Builder class but
does not actually use it for anything. Subsequent patches will do that.
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Reviewed-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Fix indentation issues (suggested by Arnout)
---
scripts/autobuild-run | 858 +++++++++++++++++++++---------------------
1 file changed, 430 insertions(+), 428 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 601fb31..6bd6856 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -270,473 +270,474 @@ class SystemInfo:
return not missing_requirements
-def prepare_build(**kwargs):
- """Prepare for the next build of the specified instance
+class Builder:
+ def prepare_build(self, **kwargs):
+ """Prepare for the next build of the specified instance
- This function prepares the build by making sure all the needed
- directories are created, cloning or updating the Buildroot source
- code, and cleaning up remaining stuff from previous builds.
- """
+ This function prepares the build by making sure all the needed
+ directories are created, cloning or updating the Buildroot source
+ code, and cleaning up remaining stuff from previous builds.
+ """
- idir = "instance-%d" % kwargs['instance']
- log = kwargs['log']
-
- log_write(log, "INFO: preparing a new build")
-
- # Create the download directory if it doesn't exist
- dldir = os.path.join(idir, "dl")
- if not os.path.exists(dldir):
- os.mkdir(dldir)
-
- # recursively find files under root
- def find_files(root):
- for r, d, f in os.walk(root):
- # do not remove individual files from git caches. 'git' can
- # be either dl/<package>/git or dl/git and we want to
- # eventually remove tarballs for the git package, so check
- # for '.git' instead to match only dl/<package>/git/.git .
- if '.git' in d:
- del d[:]
- continue
- for i in f:
- yield os.path.join(r, i)
-
- # Remove 5 random files from the download directory. Removing
- # random files from the download directory allows to ensure we
- # regularly re-download files to check that their upstream
- # location is still correct.
- for i in range(0, 5):
- flist = list(find_files(dldir))
- if not flist:
- break
- f = flist[randint(0, len(flist) - 1)]
- log_write(log, "INFO: removing %s from downloads" %
- os.path.relpath(f, dldir))
- os.remove(f)
-
- branch = get_branch()
- log_write(log, "INFO: testing branch '%s'" % branch)
-
- # Clone Buildroot. This only happens if the source directory
- # didn't exist already.
- srcdir = os.path.join(idir, "buildroot")
- if not os.path.exists(srcdir):
- ret = subprocess.call(["git", "clone", kwargs['repo'], srcdir],
- stdout=log, stderr=log)
+ idir = "instance-%d" % kwargs['instance']
+ log = kwargs['log']
+
+ log_write(log, "INFO: preparing a new build")
+
+ # Create the download directory if it doesn't exist
+ dldir = os.path.join(idir, "dl")
+ if not os.path.exists(dldir):
+ os.mkdir(dldir)
+
+ # recursively find files under root
+ def find_files(root):
+ for r, d, f in os.walk(root):
+ # do not remove individual files from git caches. 'git' can
+ # be either dl/<package>/git or dl/git and we want to
+ # eventually remove tarballs for the git package, so check
+ # for '.git' instead to match only dl/<package>/git/.git .
+ if '.git' in d:
+ del d[:]
+ continue
+ for i in f:
+ yield os.path.join(r, i)
+
+ # Remove 5 random files from the download directory. Removing
+ # random files from the download directory allows to ensure we
+ # regularly re-download files to check that their upstream
+ # location is still correct.
+ for i in range(0, 5):
+ flist = list(find_files(dldir))
+ if not flist:
+ break
+ f = flist[randint(0, len(flist) - 1)]
+ log_write(log, "INFO: removing %s from downloads" %
+ os.path.relpath(f, dldir))
+ os.remove(f)
+
+ branch = get_branch()
+ log_write(log, "INFO: testing branch '%s'" % branch)
+
+ # Clone Buildroot. This only happens if the source directory
+ # didn't exist already.
+ srcdir = os.path.join(idir, "buildroot")
+ if not os.path.exists(srcdir):
+ ret = subprocess.call(["git", "clone", kwargs['repo'], srcdir],
+ stdout=log, stderr=log)
+ if ret != 0:
+ log_write(log, "ERROR: could not clone Buildroot sources")
+ return -1
+
+ # Update the Buildroot sources.
+ abssrcdir = os.path.abspath(srcdir)
+ ret = subprocess.call(["git", "fetch", "origin"], cwd=abssrcdir, stdout=log, stderr=log)
if ret != 0:
- log_write(log, "ERROR: could not clone Buildroot sources")
+ log_write(log, "ERROR: could not fetch Buildroot sources")
return -1
- # Update the Buildroot sources.
- abssrcdir = os.path.abspath(srcdir)
- ret = subprocess.call(["git", "fetch", "origin"], cwd=abssrcdir, stdout=log, stderr=log)
- if ret != 0:
- log_write(log, "ERROR: could not fetch Buildroot sources")
- return -1
-
- ret = subprocess.call(["git", "checkout", "--detach", "origin/%s" % branch], cwd=abssrcdir, stdout=log, stderr=log)
- if ret != 0:
- log_write(log, "ERROR: could not check out Buildroot sources")
- return -1
-
- # Create an empty output directory. We remove it first, in case a previous build was aborted.
- outputdir = os.path.join(idir, "output")
- if os.path.exists(outputdir):
- # shutil.rmtree doesn't remove write-protected files
- subprocess.call(["rm", "-rf", outputdir])
- os.mkdir(outputdir)
- with open(os.path.join(outputdir, "branch"), "w") as branchf:
- branchf.write(branch)
-
- return 0
-
-def gen_config(**kwargs):
- """Generate a new random configuration."""
- idir = "instance-%d" % kwargs['instance']
- log = kwargs['log']
- outputdir = os.path.abspath(os.path.join(idir, "output"))
- srcdir = os.path.join(idir, "buildroot")
-
- log_write(log, "INFO: generate the configuration")
-
- if kwargs['debug']:
- devnull = log
- else:
- devnull = open(os.devnull, "w")
-
- args = [os.path.join(srcdir, "utils/genrandconfig"),
- "-o", outputdir, "-b", srcdir]
-
- toolchains_csv = kwargs['toolchains_csv']
- if toolchains_csv:
- if not os.path.isabs(toolchains_csv):
- toolchains_csv = os.path.join(srcdir, toolchains_csv)
- args.extend(["--toolchains-csv", toolchains_csv])
-
- ret = subprocess.call(args, stdout=devnull, stderr=log)
- return ret
-
-def stop_on_build_hang(monitor_thread_hung_build_flag,
- monitor_thread_stop_flag,
- sub_proc, outputdir, log):
- build_time_logfile = os.path.join(outputdir, "build/build-time.log")
- while True:
- if monitor_thread_stop_flag.is_set():
- return
- if os.path.exists(build_time_logfile):
- mtime = datetime.datetime.fromtimestamp(os.stat(build_time_logfile).st_mtime)
-
- if mtime < datetime.datetime.now() - datetime.timedelta(minutes=HUNG_BUILD_TIMEOUT):
- if sub_proc.poll() is None:
- monitor_thread_hung_build_flag.set() # Used by do_build() to determine build hang
- log_write(log, "INFO: build hung")
- sub_proc.kill()
- break
- monitor_thread_stop_flag.wait(30)
+ ret = subprocess.call(["git", "checkout", "--detach", "origin/%s" % branch], cwd=abssrcdir, stdout=log, stderr=log)
+ if ret != 0:
+ log_write(log, "ERROR: could not check out Buildroot sources")
+ return -1
-def check_reproducibility(**kwargs):
- """Check reproducibility of builds
+ # Create an empty output directory. We remove it first, in case a previous build was aborted.
+ outputdir = os.path.join(idir, "output")
+ if os.path.exists(outputdir):
+ # shutil.rmtree doesn't remove write-protected files
+ subprocess.call(["rm", "-rf", outputdir])
+ os.mkdir(outputdir)
+ with open(os.path.join(outputdir, "branch"), "w") as branchf:
+ branchf.write(branch)
+
+ return 0
+
+ def gen_config(self, **kwargs):
+ """Generate a new random configuration."""
+ idir = "instance-%d" % kwargs['instance']
+ log = kwargs['log']
+ outputdir = os.path.abspath(os.path.join(idir, "output"))
+ srcdir = os.path.join(idir, "buildroot")
- Use diffoscope on the built images, if diffoscope is not
- installed, fallback to cmp
- """
+ log_write(log, "INFO: generate the configuration")
- log = kwargs['log']
- idir = "instance-%d" % kwargs['instance']
- outputdir = os.path.join(idir, "output")
- srcdir = os.path.join(idir, "buildroot")
- reproducible_results = os.path.join(outputdir, "results", "reproducible_results")
- # Using only tar images for now
- build_1_image = os.path.join(outputdir, "images-1", "rootfs.tar")
- build_2_image = os.path.join(outputdir, "images", "rootfs.tar")
-
- with open(reproducible_results, 'w') as diff:
- if kwargs['sysinfo'].has("diffoscope"):
- # Prefix to point diffoscope towards cross-tools
- prefix = subprocess.check_output(["make", "O=%s" % outputdir, "-C", srcdir, "printvars", "VARS=TARGET_CROSS"])
- # Remove TARGET_CROSS= and \n from the string
- prefix = prefix[13:-1]
- log_write(log, "INFO: running diffoscope on images")
- subprocess.call(["diffoscope", build_1_image, build_2_image,
- "--tool-prefix-binutils", prefix], stdout=diff, stderr=log)
+ if kwargs['debug']:
+ devnull = log
else:
- log_write(log, "INFO: diffoscope not installed, falling back to cmp")
- subprocess.call(["cmp", "-b", build_1_image, build_2_image], stdout=diff, stderr=log)
-
- if os.stat(reproducible_results).st_size > 0:
- log_write(log, "INFO: Build is non-reproducible.")
- return -1
-
- # rootfs images match byte-for-byte -> reproducible image
- log_write(log, "INFO: Build is reproducible!")
- return 0
-
-def do_build(**kwargs):
- """Run the build itself"""
-
- idir = "instance-%d" % kwargs['instance']
- log = kwargs['log']
- nice = kwargs['nice']
-
- # 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
- # script.
- dldir = os.path.abspath(os.path.join(idir, "dl"))
- outputdir = os.path.abspath(os.path.join(idir, "output"))
- srcdir = os.path.join(idir, "buildroot")
- f = open(os.path.join(outputdir, "logfile"), "w+")
- log_write(log, "INFO: build started")
-
- cmd = ["nice", "-n", str(nice),
- "make", "O=%s" % outputdir,
- "-C", srcdir, "BR2_DL_DIR=%s" % dldir,
- "BR2_JLEVEL=%s" % kwargs['njobs']] \
- + kwargs['make_opts'].split()
- sub = subprocess.Popen(cmd, stdout=f, stderr=f)
-
- # Setup hung build monitoring thread
- monitor_thread_hung_build_flag = Event()
- monitor_thread_stop_flag = Event()
- build_monitor = Thread(target=stop_on_build_hang,
- args=(monitor_thread_hung_build_flag,
- monitor_thread_stop_flag,
- sub, outputdir, log))
- build_monitor.daemon = True
- build_monitor.start()
-
- kwargs['buildpid'][kwargs['instance']] = sub.pid
- ret = sub.wait()
- kwargs['buildpid'][kwargs['instance']] = 0
-
- # If build failed, monitor thread would have exited at this point
- if monitor_thread_hung_build_flag.is_set():
- log_write(log, "INFO: build timed out [%d]" % ret)
- return -2
- else:
- # Stop monitor thread as this build didn't timeout
- monitor_thread_stop_flag.set()
- # Monitor thread should be exiting around this point
-
- if ret != 0:
- log_write(log, "INFO: build failed [%d]" % ret)
- return -1
-
- cmd = ["make", "O=%s" % outputdir, "-C", srcdir,
- "BR2_DL_DIR=%s" % dldir, "legal-info"] \
- + kwargs['make_opts'].split()
- ret = subprocess.call(cmd, stdout=f, stderr=f)
- if ret != 0:
- log_write(log, "INFO: build failed during legal-info")
- return -1
- log_write(log, "INFO: build successful")
- return 0
-
-def do_reproducible_build(**kwargs):
- """Run the builds for reproducibility testing
-
- Build twice with the same configuration. Calls do_build() to
- perform the actual build.
- """
+ devnull = open(os.devnull, "w")
+
+ args = [os.path.join(srcdir, "utils/genrandconfig"),
+ "-o", outputdir, "-b", srcdir]
- idir = "instance-%d" % kwargs['instance']
- outputdir = os.path.abspath(os.path.join(idir, "output"))
- srcdir = os.path.join(idir, "buildroot")
- log = kwargs['log']
+ toolchains_csv = kwargs['toolchains_csv']
+ if toolchains_csv:
+ if not os.path.isabs(toolchains_csv):
+ toolchains_csv = os.path.join(srcdir, toolchains_csv)
+ args.extend(["--toolchains-csv", toolchains_csv])
- # Start the first build
- log_write(log, "INFO: Reproducible Build Test, starting build 1")
- ret = do_build(**kwargs)
- if ret != 0:
- log_write(log, "INFO: build 1 failed, skipping build 2")
+ ret = subprocess.call(args, stdout=devnull, stderr=log)
return ret
- # First build has been built, move files and start build 2
- os.rename(os.path.join(outputdir, "images"), os.path.join(outputdir, "images-1"))
+ def stop_on_build_hang(self, monitor_thread_hung_build_flag,
+ monitor_thread_stop_flag, sub_proc,
+ outputdir, log):
+ build_time_logfile = os.path.join(outputdir, "build/build-time.log")
+ while True:
+ if monitor_thread_stop_flag.is_set():
+ return
+ if os.path.exists(build_time_logfile):
+ mtime = datetime.datetime.fromtimestamp(os.stat(build_time_logfile).st_mtime)
+
+ if mtime < datetime.datetime.now() - datetime.timedelta(minutes=HUNG_BUILD_TIMEOUT):
+ if sub_proc.poll() is None:
+ monitor_thread_hung_build_flag.set() # Used by do_build() to determine build hang
+ log_write(log, "INFO: build hung")
+ sub_proc.kill()
+ break
+ monitor_thread_stop_flag.wait(30)
+
+ def check_reproducibility(self, **kwargs):
+ """Check reproducibility of builds
+
+ Use diffoscope on the built images, if diffoscope is not
+ installed, fallback to cmp
+ """
- # Clean up build 1
- f = open(os.path.join(outputdir, "logfile"), "w+")
- subprocess.call(["make", "O=%s" % outputdir, "-C", srcdir, "clean"], stdout=f, stderr=f)
+ log = kwargs['log']
+ idir = "instance-%d" % kwargs['instance']
+ outputdir = os.path.join(idir, "output")
+ srcdir = os.path.join(idir, "buildroot")
+ reproducible_results = os.path.join(outputdir, "results", "reproducible_results")
+ # Using only tar images for now
+ build_1_image = os.path.join(outputdir, "images-1", "rootfs.tar")
+ build_2_image = os.path.join(outputdir, "images", "rootfs.tar")
+
+ with open(reproducible_results, 'w') as diff:
+ if kwargs['sysinfo'].has("diffoscope"):
+ # Prefix to point diffoscope towards cross-tools
+ prefix = subprocess.check_output(["make", "O=%s" % outputdir, "-C", srcdir, "printvars", "VARS=TARGET_CROSS"])
+ # Remove TARGET_CROSS= and \n from the string
+ prefix = prefix[13:-1]
+ log_write(log, "INFO: running diffoscope on images")
+ subprocess.call(["diffoscope", build_1_image, build_2_image,
+ "--tool-prefix-binutils", prefix], stdout=diff, stderr=log)
+ else:
+ log_write(log, "INFO: diffoscope not installed, falling back to cmp")
+ subprocess.call(["cmp", "-b", build_1_image, build_2_image], stdout=diff, stderr=log)
- # Start the second build
- log_write(log, "INFO: Reproducible Build Test, starting build 2")
- ret = do_build(**kwargs)
- if ret != 0:
- log_write(log, "INFO: build 2 failed")
- return ret
+ if os.stat(reproducible_results).st_size > 0:
+ log_write(log, "INFO: Build is non-reproducible.")
+ return -1
- # Assuming both have built successfully
- ret = check_reproducibility(**kwargs)
- return ret
+ # rootfs images match byte-for-byte -> reproducible image
+ log_write(log, "INFO: Build is reproducible!")
+ return 0
-def send_results(result, **kwargs):
- """Prepare and store/send tarball with results
+ def do_build(self, **kwargs):
+ """Run the build itself"""
- This function prepares the tarball with the results, and either
- submits them to the official server (if the appropriate credentials
- are available) or stores them locally as tarballs.
- """
+ idir = "instance-%d" % kwargs['instance']
+ log = kwargs['log']
+ nice = kwargs['nice']
- 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")
-
- shutil.copyfile(os.path.join(outputdir, ".config"),
- os.path.join(resultdir, "config"))
- shutil.copyfile(os.path.join(outputdir, "defconfig"),
- os.path.join(resultdir, "defconfig"))
- shutil.copyfile(os.path.join(outputdir, "branch"),
- os.path.join(resultdir, "branch"))
-
- def copy_if_exists(directory, src, dst=None):
- if os.path.exists(os.path.join(outputdir, directory, src)):
- shutil.copyfile(os.path.join(outputdir, directory, src),
- os.path.join(resultdir, src if dst is None else dst))
-
- copy_if_exists("build", "build-time.log")
- copy_if_exists("build", "packages-file-list.txt")
- copy_if_exists("build", "packages-file-list-host.txt")
- copy_if_exists("build", "packages-file-list-staging.txt")
- copy_if_exists("legal-info", "manifest.csv", "licenses-manifest.csv")
-
- subprocess.call(["git log -n 1 --pretty=format:%%H > %s" % \
- os.path.join(resultdir, "gitid")],
- shell=True, cwd=srcdir)
-
- # Return True if the result should be rejected, False otherwise
- def reject_results():
- lastlines = decode_bytes(subprocess.Popen(
- ["tail", "-n", "3", os.path.join(outputdir, "logfile")],
- stdout=subprocess.PIPE).communicate()[0]).splitlines()
-
- # Reject results where qemu-user refused to build
- regexp = re.compile(r'^package/qemu/qemu.mk:.*Refusing to build qemu-user')
- for line in lastlines:
- if regexp.match(line):
- return True
-
- return False
-
- if reject_results():
- return
-
- def get_failure_reason():
- # Output is a tuple (package, version), or None.
- lastlines = decode_bytes(subprocess.Popen(
- ["tail", "-n", "3", os.path.join(outputdir, "logfile")],
- stdout=subprocess.PIPE).communicate()[0]).splitlines()
-
- regexp = re.compile(r'make: \*\*\* .*/(?:build|toolchain)/([^/]*)/')
- for line in lastlines:
- m = regexp.search(line)
- if m:
- return m.group(1).rsplit('-', 1)
-
- # not found
- return None
+ # 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
+ # script.
+ dldir = os.path.abspath(os.path.join(idir, "dl"))
+ outputdir = os.path.abspath(os.path.join(idir, "output"))
+ srcdir = os.path.join(idir, "buildroot")
+ f = open(os.path.join(outputdir, "logfile"), "w+")
+ log_write(log, "INFO: build started")
+
+ cmd = ["nice", "-n", str(nice),
+ "make", "O=%s" % outputdir,
+ "-C", srcdir, "BR2_DL_DIR=%s" % dldir,
+ "BR2_JLEVEL=%s" % kwargs['njobs']] \
+ + kwargs['make_opts'].split()
+ sub = subprocess.Popen(cmd, stdout=f, stderr=f)
+
+ # Setup hung build monitoring thread
+ monitor_thread_hung_build_flag = Event()
+ monitor_thread_stop_flag = Event()
+ build_monitor = Thread(target=self.stop_on_build_hang,
+ args=(monitor_thread_hung_build_flag,
+ monitor_thread_stop_flag,
+ sub, outputdir, log))
+ build_monitor.daemon = True
+ build_monitor.start()
+
+ kwargs['buildpid'][kwargs['instance']] = sub.pid
+ ret = sub.wait()
+ kwargs['buildpid'][kwargs['instance']] = 0
+
+ # If build failed, monitor thread would have exited at this point
+ if monitor_thread_hung_build_flag.is_set():
+ log_write(log, "INFO: build timed out [%d]" % ret)
+ return -2
+ else:
+ # Stop monitor thread as this build didn't timeout
+ monitor_thread_stop_flag.set()
+ # Monitor thread should be exiting around this point
- def extract_end_log(resultfile):
- """Save the last part of the build log, starting from the failed package"""
+ if ret != 0:
+ log_write(log, "INFO: build failed [%d]" % ret)
+ return -1
- def extract_last_500_lines():
- subprocess.call(["tail -500 %s > %s" % \
- (os.path.join(outputdir, "logfile"), resultfile)],
- shell=True)
+ cmd = ["make", "O=%s" % outputdir, "-C", srcdir,
+ "BR2_DL_DIR=%s" % dldir, "legal-info"] \
+ + kwargs['make_opts'].split()
+ ret = subprocess.call(cmd, stdout=f, stderr=f)
+ if ret != 0:
+ log_write(log, "INFO: build failed during legal-info")
+ return -1
+ log_write(log, "INFO: build successful")
+ return 0
- reason = get_failure_reason()
- if not reason:
- extract_last_500_lines()
- else:
- f = open(os.path.join(outputdir, "logfile"), 'r')
- mf = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
- mf.seek(0)
- # Search for first action on the failed package
- offset = mf.find(encode_str('>>> %s' % ' '.join(reason)))
- if offset != -1:
- with open(resultfile, "w") as endlog:
- endlog.write(decode_bytes(mf[offset:]))
- else:
- # not found, use last 500 lines as fallback
- extract_last_500_lines()
+ def do_reproducible_build(self, **kwargs):
+ """Run the builds for reproducibility testing
- mf.close()
- f.close()
+ Build twice with the same configuration. Calls do_build() to
+ perform the actual build.
+ """
- extract_end_log(os.path.join(resultdir, "build-end.log"))
+ idir = "instance-%d" % kwargs['instance']
+ outputdir = os.path.abspath(os.path.join(idir, "output"))
+ srcdir = os.path.join(idir, "buildroot")
+ log = kwargs['log']
- def copy_config_log_files():
- """Recursively copy any config.log files from the failing package"""
+ # Start the first build
+ log_write(log, "INFO: Reproducible Build Test, starting build 1")
+ ret = self.do_build(**kwargs)
+ if ret != 0:
+ log_write(log, "INFO: build 1 failed, skipping build 2")
+ return ret
- reason = get_failure_reason()
- if not reason:
- return
+ # First build has been built, move files and start build 2
+ os.rename(os.path.join(outputdir, "images"), os.path.join(outputdir, "images-1"))
- srcroot = os.path.join(outputdir, "build", '-'.join(reason))
- destroot = os.path.join(resultdir, '-'.join(reason))
- config_files = ('config.log', 'CMakeCache.txt', 'CMakeError.log',
- 'CMakeOutput.log')
-
- for root, dirs, files in os.walk(srcroot):
- dest = os.path.join(destroot, os.path.relpath(root, srcroot))
-
- for fname in files:
- if fname in config_files:
- if not os.path.exists(dest):
- os.makedirs(dest)
- shutil.copy(os.path.join(root, fname), os.path.join(dest, fname))
-
- copy_config_log_files()
-
- resultf = open(os.path.join(resultdir, "status"), "w+")
- if result == 0:
- resultf.write("OK")
- elif result == -1:
- resultf.write("NOK")
- elif result == -2:
- resultf.write("TIMEOUT")
- resultf.close()
-
- with open(os.path.join(resultdir, "submitter"), "w+") as submitterf:
- submitterf.write(kwargs['submitter'])
-
- # Yes, shutil.make_archive() would be nice, but it doesn't exist
- # in Python 2.6.
- ret = subprocess.call(["tar", "cjf", "results.tar.bz2", "results"],
- cwd=outputdir, stdout=log, stderr=log)
- if ret != 0:
- log_write(log, "ERROR: could not make results tarball")
- sys.exit(1)
+ # Clean up build 1
+ f = open(os.path.join(outputdir, "logfile"), "w+")
+ subprocess.call(["make", "O=%s" % outputdir, "-C", srcdir, "clean"], stdout=f, stderr=f)
- if kwargs['upload']:
- # 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" % (kwargs['http_login'], kwargs['http_password']),
- "-H", "Expect:",
- "-F", "uploadedfile=@%s" % os.path.join(outputdir, "results.tar.bz2"),
- "-F", "uploadsubmit=1",
- kwargs['http_url']],
- stdout=log, stderr=log)
+ # Start the second build
+ log_write(log, "INFO: Reproducible Build Test, starting build 2")
+ ret = self.do_build(**kwargs)
if ret != 0:
- log_write(log, "INFO: results could not be submitted, %d" % ret)
- else:
- log_write(log, "INFO: results were submitted successfully")
- else:
- # 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" % (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(**kwargs):
- """Main per-instance loop
-
- Prepare the build, generate a configuration, run the build, and submit the
- results.
- """
+ log_write(log, "INFO: build 2 failed")
+ return ret
- idir = "instance-%d" % kwargs['instance']
+ # Assuming both have built successfully
+ ret = self.check_reproducibility(**kwargs)
+ return ret
- # If it doesn't exist, create the instance directory
- if not os.path.exists(idir):
- os.mkdir(idir)
+ def send_results(self, result, **kwargs):
+ """Prepare and store/send tarball with results
- if kwargs['debug']:
- kwargs['log'] = sys.stdout
- else:
- kwargs['log'] = open(os.path.join(idir, "instance.log"), "a+")
- log_write(kwargs['log'], "INFO: instance started")
+ This function prepares the tarball with the results, and either
+ submits them to the official server (if the appropriate credentials
+ are available) or stores them locally as tarballs.
+ """
- while True:
- check_version()
+ idir = "instance-%d" % kwargs['instance']
+ log = kwargs['log']
- ret = prepare_build(**kwargs)
- if ret != 0:
- continue
+ outputdir = os.path.abspath(os.path.join(idir, "output"))
+ srcdir = os.path.join(idir, "buildroot")
+ resultdir = os.path.join(outputdir, "results")
+
+ shutil.copyfile(os.path.join(outputdir, ".config"),
+ os.path.join(resultdir, "config"))
+ shutil.copyfile(os.path.join(outputdir, "defconfig"),
+ os.path.join(resultdir, "defconfig"))
+ shutil.copyfile(os.path.join(outputdir, "branch"),
+ os.path.join(resultdir, "branch"))
+
+ def copy_if_exists(directory, src, dst=None):
+ if os.path.exists(os.path.join(outputdir, directory, src)):
+ shutil.copyfile(os.path.join(outputdir, directory, src),
+ os.path.join(resultdir, src if dst is None else dst))
+
+ copy_if_exists("build", "build-time.log")
+ copy_if_exists("build", "packages-file-list.txt")
+ copy_if_exists("build", "packages-file-list-host.txt")
+ copy_if_exists("build", "packages-file-list-staging.txt")
+ copy_if_exists("legal-info", "manifest.csv", "licenses-manifest.csv")
+
+ subprocess.call(["git log -n 1 --pretty=format:%%H > %s" % \
+ os.path.join(resultdir, "gitid")],
+ shell=True, cwd=srcdir)
+
+ # Return True if the result should be rejected, False otherwise
+ def reject_results():
+ lastlines = decode_bytes(subprocess.Popen(
+ ["tail", "-n", "3", os.path.join(outputdir, "logfile")],
+ stdout=subprocess.PIPE).communicate()[0]).splitlines()
+
+ # Reject results where qemu-user refused to build
+ regexp = re.compile(r'^package/qemu/qemu.mk:.*Refusing to build qemu-user')
+ for line in lastlines:
+ if regexp.match(line):
+ return True
+
+ return False
+
+ if reject_results():
+ return
+
+ def get_failure_reason():
+ # Output is a tuple (package, version), or None.
+ lastlines = decode_bytes(subprocess.Popen(
+ ["tail", "-n", "3", os.path.join(outputdir, "logfile")],
+ stdout=subprocess.PIPE).communicate()[0]).splitlines()
+
+ regexp = re.compile(r'make: \*\*\* .*/(?:build|toolchain)/([^/]*)/')
+ for line in lastlines:
+ m = regexp.search(line)
+ if m:
+ return m.group(1).rsplit('-', 1)
+
+ # not found
+ return None
+
+ def extract_end_log(resultfile):
+ """Save the last part of the build log, starting from the failed package"""
- resultdir = os.path.join(idir, "output", "results")
- os.mkdir(resultdir)
+ def extract_last_500_lines():
+ subprocess.call(["tail -500 %s > %s" % \
+ (os.path.join(outputdir, "logfile"), resultfile)],
+ shell=True)
- ret = gen_config(**kwargs)
+ reason = get_failure_reason()
+ if not reason:
+ extract_last_500_lines()
+ else:
+ f = open(os.path.join(outputdir, "logfile"), 'r')
+ mf = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
+ mf.seek(0)
+ # Search for first action on the failed package
+ offset = mf.find(encode_str('>>> %s' % ' '.join(reason)))
+ if offset != -1:
+ with open(resultfile, "w") as endlog:
+ endlog.write(decode_bytes(mf[offset:]))
+ else:
+ # not found, use last 500 lines as fallback
+ extract_last_500_lines()
+
+ mf.close()
+ f.close()
+
+ extract_end_log(os.path.join(resultdir, "build-end.log"))
+
+ def copy_config_log_files():
+ """Recursively copy any config.log files from the failing package"""
+
+ reason = get_failure_reason()
+ if not reason:
+ return
+
+ srcroot = os.path.join(outputdir, "build", '-'.join(reason))
+ destroot = os.path.join(resultdir, '-'.join(reason))
+ config_files = ('config.log', 'CMakeCache.txt', 'CMakeError.log',
+ 'CMakeOutput.log')
+
+ for root, dirs, files in os.walk(srcroot):
+ dest = os.path.join(destroot, os.path.relpath(root, srcroot))
+
+ for fname in files:
+ if fname in config_files:
+ if not os.path.exists(dest):
+ os.makedirs(dest)
+ shutil.copy(os.path.join(root, fname), os.path.join(dest, fname))
+
+ copy_config_log_files()
+
+ resultf = open(os.path.join(resultdir, "status"), "w+")
+ if result == 0:
+ resultf.write("OK")
+ elif result == -1:
+ resultf.write("NOK")
+ elif result == -2:
+ resultf.write("TIMEOUT")
+ resultf.close()
+
+ with open(os.path.join(resultdir, "submitter"), "w+") as submitterf:
+ submitterf.write(kwargs['submitter'])
+
+ # Yes, shutil.make_archive() would be nice, but it doesn't exist
+ # in Python 2.6.
+ ret = subprocess.call(["tar", "cjf", "results.tar.bz2", "results"],
+ cwd=outputdir, stdout=log, stderr=log)
if ret != 0:
- log_write(kwargs['log'], "WARN: failed to generate configuration")
- continue
+ log_write(log, "ERROR: could not make results tarball")
+ sys.exit(1)
+
+ if kwargs['upload']:
+ # 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" % (kwargs['http_login'], kwargs['http_password']),
+ "-H", "Expect:",
+ "-F", "uploadedfile=@%s" % os.path.join(outputdir, "results.tar.bz2"),
+ "-F", "uploadsubmit=1",
+ kwargs['http_url']],
+ stdout=log, stderr=log)
+ if ret != 0:
+ log_write(log, "INFO: results could not be submitted, %d" % ret)
+ else:
+ log_write(log, "INFO: results were submitted successfully")
+ else:
+ # 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" % (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(self, **kwargs):
+ """Main per-instance loop
+
+ Prepare the build, generate a configuration, run the build, and submit the
+ results.
+ """
- # Check if the build test is supposed to be a reproducible test
- outputdir = os.path.abspath(os.path.join(idir, "output"))
- with open(os.path.join(outputdir, ".config"), "r") as fconf:
- reproducible = "BR2_REPRODUCIBLE=y\n" in fconf.read()
- if reproducible:
- ret = do_reproducible_build(**kwargs)
+ idir = "instance-%d" % kwargs['instance']
+
+ # If it doesn't exist, create the instance directory
+ if not os.path.exists(idir):
+ os.mkdir(idir)
+
+ if kwargs['debug']:
+ kwargs['log'] = sys.stdout
else:
- ret = do_build(**kwargs)
+ kwargs['log'] = open(os.path.join(idir, "instance.log"), "a+")
+ log_write(kwargs['log'], "INFO: instance started")
+
+ while True:
+ check_version()
+
+ ret = self.prepare_build(**kwargs)
+ if ret != 0:
+ continue
+
+ resultdir = os.path.join(idir, "output", "results")
+ os.mkdir(resultdir)
+
+ ret = self.gen_config(**kwargs)
+ if ret != 0:
+ log_write(kwargs['log'], "WARN: failed to generate configuration")
+ continue
+
+ # Check if the build test is supposed to be a reproducible test
+ outputdir = os.path.abspath(os.path.join(idir, "output"))
+ with open(os.path.join(outputdir, ".config"), "r") as fconf:
+ reproducible = "BR2_REPRODUCIBLE=y\n" in fconf.read()
+ if reproducible:
+ ret = self.do_reproducible_build(**kwargs)
+ else:
+ ret = self.do_build(**kwargs)
- send_results(ret, **kwargs)
+ self.send_results(ret, **kwargs)
# args / config file merging inspired by:
# https://github.com/docopt/docopt/blob/master/examples/config_file_example.py
@@ -839,7 +840,8 @@ def main():
buildpid = multiprocessing.Array('i', int(args['--ninstances']))
processes = []
for i in range(0, int(args['--ninstances'])):
- p = multiprocessing.Process(target=run_instance, kwargs=dict(
+ builder = Builder()
+ p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
instance = i,
njobs = args['--njobs'],
sysinfo = sysinfo,
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 02/30] autobuild-run: move instance variable from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 01/30] autobuild-run: introduce Builder class Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 03/30] autobuild-run: move njobs " Atharva Lele
` (28 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
As discussed in the previous patch, these common variables are needed
in many functions, and it'll be better to have them as part of the class.
This will make the code cleaner and make it easier to introduce variability
for reproducibility testing. Succeeding patches will move all variables from
kwargs to the Builder constructor.
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor argument
---
scripts/autobuild-run | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 6bd6856..9946ddc 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -271,6 +271,9 @@ class SystemInfo:
return not missing_requirements
class Builder:
+ def __init__(self, instance):
+ self.instance = instance
+
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -279,7 +282,7 @@ class Builder:
code, and cleaning up remaining stuff from previous builds.
"""
- idir = "instance-%d" % kwargs['instance']
+ idir = "instance-%d" % self.instance
log = kwargs['log']
log_write(log, "INFO: preparing a new build")
@@ -353,7 +356,7 @@ class Builder:
def gen_config(self, **kwargs):
"""Generate a new random configuration."""
- idir = "instance-%d" % kwargs['instance']
+ idir = "instance-%d" % self.instance
log = kwargs['log']
outputdir = os.path.abspath(os.path.join(idir, "output"))
srcdir = os.path.join(idir, "buildroot")
@@ -403,7 +406,7 @@ class Builder:
"""
log = kwargs['log']
- idir = "instance-%d" % kwargs['instance']
+ idir = "instance-%d" % self.instance
outputdir = os.path.join(idir, "output")
srcdir = os.path.join(idir, "buildroot")
reproducible_results = os.path.join(outputdir, "results", "reproducible_results")
@@ -435,7 +438,7 @@ class Builder:
def do_build(self, **kwargs):
"""Run the build itself"""
- idir = "instance-%d" % kwargs['instance']
+ idir = "instance-%d" % self.instance
log = kwargs['log']
nice = kwargs['nice']
@@ -466,9 +469,9 @@ class Builder:
build_monitor.daemon = True
build_monitor.start()
- kwargs['buildpid'][kwargs['instance']] = sub.pid
+ kwargs['buildpid'][self.instance] = sub.pid
ret = sub.wait()
- kwargs['buildpid'][kwargs['instance']] = 0
+ kwargs['buildpid'][self.instance] = 0
# If build failed, monitor thread would have exited at this point
if monitor_thread_hung_build_flag.is_set():
@@ -500,7 +503,7 @@ class Builder:
perform the actual build.
"""
- idir = "instance-%d" % kwargs['instance']
+ idir = "instance-%d" % self.instance
outputdir = os.path.abspath(os.path.join(idir, "output"))
srcdir = os.path.join(idir, "buildroot")
log = kwargs['log']
@@ -538,7 +541,7 @@ class Builder:
are available) or stores them locally as tarballs.
"""
- idir = "instance-%d" % kwargs['instance']
+ idir = "instance-%d" % self.instance
log = kwargs['log']
outputdir = os.path.abspath(os.path.join(idir, "output"))
@@ -690,7 +693,7 @@ class Builder:
# 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" % (kwargs['instance'], sha1)
+ resultfilename = "instance-%d-%s.tar.bz2" % (self.instance, sha1)
os.rename(os.path.join(outputdir, "results.tar.bz2"), resultfilename)
log_write(log, "INFO: results saved as %s" % resultfilename)
@@ -701,7 +704,7 @@ class Builder:
results.
"""
- idir = "instance-%d" % kwargs['instance']
+ idir = "instance-%d" % self.instance
# If it doesn't exist, create the instance directory
if not os.path.exists(idir):
@@ -840,9 +843,8 @@ def main():
buildpid = multiprocessing.Array('i', int(args['--ninstances']))
processes = []
for i in range(0, int(args['--ninstances'])):
- builder = Builder()
+ builder = Builder(instance = i)
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- instance = i,
njobs = args['--njobs'],
sysinfo = sysinfo,
http_url = args['--http-url'],
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 03/30] autobuild-run: move njobs from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 01/30] autobuild-run: introduce Builder class Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 02/30] autobuild-run: move instance variable from kwargs to " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 04/30] autobuild-run: move sysinfo " Atharva Lele
` (27 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor argument
---
scripts/autobuild-run | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 9946ddc..4d730ce 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -271,8 +271,9 @@ class SystemInfo:
return not missing_requirements
class Builder:
- def __init__(self, instance):
+ def __init__(self, instance, njobs):
self.instance = instance
+ self.njobs = njobs
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -455,7 +456,7 @@ class Builder:
cmd = ["nice", "-n", str(nice),
"make", "O=%s" % outputdir,
"-C", srcdir, "BR2_DL_DIR=%s" % dldir,
- "BR2_JLEVEL=%s" % kwargs['njobs']] \
+ "BR2_JLEVEL=%s" % self.njobs] \
+ kwargs['make_opts'].split()
sub = subprocess.Popen(cmd, stdout=f, stderr=f)
@@ -843,9 +844,10 @@ def main():
buildpid = multiprocessing.Array('i', int(args['--ninstances']))
processes = []
for i in range(0, int(args['--ninstances'])):
- builder = Builder(instance = i)
+ builder = Builder(
+ instance = i,
+ njobs = args['--njobs'])
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- njobs = args['--njobs'],
sysinfo = sysinfo,
http_url = args['--http-url'],
http_login = args['--http-login'],
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 04/30] autobuild-run: move sysinfo from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (2 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 03/30] autobuild-run: move njobs " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 05/30] autobuild-run: move http variables " Atharva Lele
` (26 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor argument
---
scripts/autobuild-run | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 4d730ce..ca2dd83 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -271,9 +271,10 @@ class SystemInfo:
return not missing_requirements
class Builder:
- def __init__(self, instance, njobs):
+ def __init__(self, instance, njobs, sysinfo):
self.instance = instance
self.njobs = njobs
+ self.sysinfo = sysinfo
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -416,7 +417,7 @@ class Builder:
build_2_image = os.path.join(outputdir, "images", "rootfs.tar")
with open(reproducible_results, 'w') as diff:
- if kwargs['sysinfo'].has("diffoscope"):
+ if self.sysinfo.has("diffoscope"):
# Prefix to point diffoscope towards cross-tools
prefix = subprocess.check_output(["make", "O=%s" % outputdir, "-C", srcdir, "printvars", "VARS=TARGET_CROSS"])
# Remove TARGET_CROSS= and \n from the string
@@ -846,9 +847,9 @@ def main():
for i in range(0, int(args['--ninstances'])):
builder = Builder(
instance = i,
- njobs = args['--njobs'])
+ njobs = args['--njobs'],
+ sysinfo = sysinfo)
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- sysinfo = sysinfo,
http_url = args['--http-url'],
http_login = args['--http-login'],
http_password = args['--http-password'],
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 05/30] autobuild-run: move http variables from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (3 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 04/30] autobuild-run: move sysinfo " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 06/30] autobuild-run: move submitter " Atharva Lele
` (25 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor arguments
- Fix whitespace issues
---
scripts/autobuild-run | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index ca2dd83..9d16ce5 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -271,10 +271,14 @@ class SystemInfo:
return not missing_requirements
class Builder:
- def __init__(self, instance, njobs, sysinfo):
+ def __init__(self, instance, njobs, sysinfo,
+ http_url, http_login, http_password):
self.instance = instance
self.njobs = njobs
self.sysinfo = sysinfo
+ self.http_url = http_url
+ self.http_login = http_login
+ self.http_password = http_password
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -681,11 +685,11 @@ class Builder:
# 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" % (kwargs['http_login'], kwargs['http_password']),
+ "%s:%s" % (self.http_login, self.http_password),
"-H", "Expect:",
"-F", "uploadedfile=@%s" % os.path.join(outputdir, "results.tar.bz2"),
"-F", "uploadsubmit=1",
- kwargs['http_url']],
+ self.http_url],
stdout=log, stderr=log)
if ret != 0:
log_write(log, "INFO: results could not be submitted, %d" % ret)
@@ -848,11 +852,11 @@ def main():
builder = Builder(
instance = i,
njobs = args['--njobs'],
- sysinfo = sysinfo)
+ sysinfo = sysinfo,
+ http_url = args['--http-url'],
+ http_login = args['--http-login'],
+ http_password = args['--http-password'])
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- http_url = args['--http-url'],
- http_login = args['--http-login'],
- http_password = args['--http-password'],
submitter = args['--submitter'],
make_opts = (args['--make-opts'] or ''),
nice = (args['--nice'] or 0),
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 06/30] autobuild-run: move submitter from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (4 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 05/30] autobuild-run: move http variables " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 07/30] autobuild-run: move make_opts " Atharva Lele
` (24 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor argument
---
scripts/autobuild-run | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 9d16ce5..426078c 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -272,13 +272,15 @@ class SystemInfo:
class Builder:
def __init__(self, instance, njobs, sysinfo,
- http_url, http_login, http_password):
+ http_url, http_login, http_password,
+ submitter):
self.instance = instance
self.njobs = njobs
self.sysinfo = sysinfo
self.http_url = http_url
self.http_login = http_login
self.http_password = http_password
+ self.submitter = submitter
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -670,7 +672,7 @@ class Builder:
resultf.close()
with open(os.path.join(resultdir, "submitter"), "w+") as submitterf:
- submitterf.write(kwargs['submitter'])
+ submitterf.write(self.submitter)
# Yes, shutil.make_archive() would be nice, but it doesn't exist
# in Python 2.6.
@@ -855,9 +857,9 @@ def main():
sysinfo = sysinfo,
http_url = args['--http-url'],
http_login = args['--http-login'],
- http_password = args['--http-password'])
+ http_password = args['--http-password'],
+ submitter = args['--submitter'])
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- submitter = args['--submitter'],
make_opts = (args['--make-opts'] or ''),
nice = (args['--nice'] or 0),
toolchains_csv = args['--toolchains-csv'],
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 07/30] autobuild-run: move make_opts from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (5 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 06/30] autobuild-run: move submitter " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 08/30] autobuild-run: move niceness " Atharva Lele
` (23 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- New patch, split accidental squash of niceness move and make_opts move
---
scripts/autobuild-run | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 426078c..c2d137c 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -273,7 +273,7 @@ class SystemInfo:
class Builder:
def __init__(self, instance, njobs, sysinfo,
http_url, http_login, http_password,
- submitter):
+ submitter, make_opts):
self.instance = instance
self.njobs = njobs
self.sysinfo = sysinfo
@@ -281,6 +281,7 @@ class Builder:
self.http_login = http_login
self.http_password = http_password
self.submitter = submitter
+ self.make_opts = make_opts
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -464,7 +465,7 @@ class Builder:
"make", "O=%s" % outputdir,
"-C", srcdir, "BR2_DL_DIR=%s" % dldir,
"BR2_JLEVEL=%s" % self.njobs] \
- + kwargs['make_opts'].split()
+ + self.make_opts.split()
sub = subprocess.Popen(cmd, stdout=f, stderr=f)
# Setup hung build monitoring thread
@@ -496,7 +497,7 @@ class Builder:
cmd = ["make", "O=%s" % outputdir, "-C", srcdir,
"BR2_DL_DIR=%s" % dldir, "legal-info"] \
- + kwargs['make_opts'].split()
+ + self.make_opts.split()
ret = subprocess.call(cmd, stdout=f, stderr=f)
if ret != 0:
log_write(log, "INFO: build failed during legal-info")
@@ -858,9 +859,9 @@ def main():
http_url = args['--http-url'],
http_login = args['--http-login'],
http_password = args['--http-password'],
- submitter = args['--submitter'])
+ submitter = args['--submitter'],
+ make_opts = (args['--make-opts'] or ''))
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- make_opts = (args['--make-opts'] or ''),
nice = (args['--nice'] or 0),
toolchains_csv = args['--toolchains-csv'],
repo = args['--repo'],
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 08/30] autobuild-run: move niceness from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (6 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 07/30] autobuild-run: move make_opts " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 09/30] autobuild-run: move toolchains_csv " Atharva Lele
` (22 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor argument
- Fix accidentally moving make_opts in the same patch
---
scripts/autobuild-run | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index c2d137c..87d0bd8 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -273,7 +273,7 @@ class SystemInfo:
class Builder:
def __init__(self, instance, njobs, sysinfo,
http_url, http_login, http_password,
- submitter, make_opts):
+ submitter, make_opts, nice):
self.instance = instance
self.njobs = njobs
self.sysinfo = sysinfo
@@ -282,6 +282,7 @@ class Builder:
self.http_password = http_password
self.submitter = submitter
self.make_opts = make_opts
+ self.nice = nice
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -449,7 +450,6 @@ class Builder:
idir = "instance-%d" % self.instance
log = kwargs['log']
- nice = kwargs['nice']
# We need the absolute path to use with O=, because the relative
# path to the output directory here is not relative to the
@@ -461,7 +461,7 @@ class Builder:
f = open(os.path.join(outputdir, "logfile"), "w+")
log_write(log, "INFO: build started")
- cmd = ["nice", "-n", str(nice),
+ cmd = ["nice", "-n", str(self.nice),
"make", "O=%s" % outputdir,
"-C", srcdir, "BR2_DL_DIR=%s" % dldir,
"BR2_JLEVEL=%s" % self.njobs] \
@@ -860,9 +860,9 @@ def main():
http_login = args['--http-login'],
http_password = args['--http-password'],
submitter = args['--submitter'],
- make_opts = (args['--make-opts'] or ''))
+ make_opts = (args['--make-opts'] or ''),
+ nice = (args['--nice'] or 0))
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- nice = (args['--nice'] or 0),
toolchains_csv = args['--toolchains-csv'],
repo = args['--repo'],
upload = upload,
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 09/30] autobuild-run: move toolchains_csv from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (7 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 08/30] autobuild-run: move niceness " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 10/30] autobuild-run: move repo " Atharva Lele
` (21 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor argument
---
scripts/autobuild-run | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 87d0bd8..3bd10f7 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -273,7 +273,7 @@ class SystemInfo:
class Builder:
def __init__(self, instance, njobs, sysinfo,
http_url, http_login, http_password,
- submitter, make_opts, nice):
+ submitter, make_opts, nice, toolchains_csv):
self.instance = instance
self.njobs = njobs
self.sysinfo = sysinfo
@@ -283,6 +283,7 @@ class Builder:
self.submitter = submitter
self.make_opts = make_opts
self.nice = nice
+ self.toolchains_csv = toolchains_csv
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -381,7 +382,7 @@ class Builder:
args = [os.path.join(srcdir, "utils/genrandconfig"),
"-o", outputdir, "-b", srcdir]
- toolchains_csv = kwargs['toolchains_csv']
+ toolchains_csv = self.toolchains_csv
if toolchains_csv:
if not os.path.isabs(toolchains_csv):
toolchains_csv = os.path.join(srcdir, toolchains_csv)
@@ -861,9 +862,9 @@ def main():
http_password = args['--http-password'],
submitter = args['--submitter'],
make_opts = (args['--make-opts'] or ''),
- nice = (args['--nice'] or 0))
+ nice = (args['--nice'] or 0),
+ toolchains_csv = args['--toolchains-csv'])
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- toolchains_csv = args['--toolchains-csv'],
repo = args['--repo'],
upload = upload,
buildpid = buildpid,
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 10/30] autobuild-run: move repo from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (8 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 09/30] autobuild-run: move toolchains_csv " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 11/30] autobuild-run: move upload variable " Atharva Lele
` (20 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor argument
---
scripts/autobuild-run | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 3bd10f7..e64f6db 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -273,7 +273,8 @@ class SystemInfo:
class Builder:
def __init__(self, instance, njobs, sysinfo,
http_url, http_login, http_password,
- submitter, make_opts, nice, toolchains_csv):
+ submitter, make_opts, nice, toolchains_csv,
+ repo):
self.instance = instance
self.njobs = njobs
self.sysinfo = sysinfo
@@ -284,6 +285,7 @@ class Builder:
self.make_opts = make_opts
self.nice = nice
self.toolchains_csv = toolchains_csv
+ self.repo = repo
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -336,7 +338,7 @@ class Builder:
# didn't exist already.
srcdir = os.path.join(idir, "buildroot")
if not os.path.exists(srcdir):
- ret = subprocess.call(["git", "clone", kwargs['repo'], srcdir],
+ ret = subprocess.call(["git", "clone", self.repo, srcdir],
stdout=log, stderr=log)
if ret != 0:
log_write(log, "ERROR: could not clone Buildroot sources")
@@ -863,9 +865,9 @@ def main():
submitter = args['--submitter'],
make_opts = (args['--make-opts'] or ''),
nice = (args['--nice'] or 0),
- toolchains_csv = args['--toolchains-csv'])
+ toolchains_csv = args['--toolchains-csv'],
+ repo = args['--repo'])
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- repo = args['--repo'],
upload = upload,
buildpid = buildpid,
debug = args['--debug']
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 11/30] autobuild-run: move upload variable from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (9 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 10/30] autobuild-run: move repo " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 12/30] autobuild-run: move buildpid " Atharva Lele
` (19 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor argument
---
scripts/autobuild-run | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index e64f6db..e217117 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -274,7 +274,7 @@ class Builder:
def __init__(self, instance, njobs, sysinfo,
http_url, http_login, http_password,
submitter, make_opts, nice, toolchains_csv,
- repo):
+ repo, upload):
self.instance = instance
self.njobs = njobs
self.sysinfo = sysinfo
@@ -286,6 +286,7 @@ class Builder:
self.nice = nice
self.toolchains_csv = toolchains_csv
self.repo = repo
+ self.upload = upload
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -686,7 +687,7 @@ class Builder:
log_write(log, "ERROR: could not make results tarball")
sys.exit(1)
- if kwargs['upload']:
+ if self.upload:
# 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.
@@ -866,9 +867,9 @@ def main():
make_opts = (args['--make-opts'] or ''),
nice = (args['--nice'] or 0),
toolchains_csv = args['--toolchains-csv'],
- repo = args['--repo'])
+ repo = args['--repo'],
+ upload = upload)
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- upload = upload,
buildpid = buildpid,
debug = args['--debug']
))
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 12/30] autobuild-run: move buildpid from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (10 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 11/30] autobuild-run: move upload variable " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 13/30] autobuild-run: move debug " Atharva Lele
` (18 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor argument
---
scripts/autobuild-run | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index e217117..05de063 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -274,7 +274,7 @@ class Builder:
def __init__(self, instance, njobs, sysinfo,
http_url, http_login, http_password,
submitter, make_opts, nice, toolchains_csv,
- repo, upload):
+ repo, upload, buildpid):
self.instance = instance
self.njobs = njobs
self.sysinfo = sysinfo
@@ -287,6 +287,7 @@ class Builder:
self.toolchains_csv = toolchains_csv
self.repo = repo
self.upload = upload
+ self.buildpid = buildpid
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -482,9 +483,9 @@ class Builder:
build_monitor.daemon = True
build_monitor.start()
- kwargs['buildpid'][self.instance] = sub.pid
+ self.buildpid[self.instance] = sub.pid
ret = sub.wait()
- kwargs['buildpid'][self.instance] = 0
+ self.buildpid[self.instance] = 0
# If build failed, monitor thread would have exited at this point
if monitor_thread_hung_build_flag.is_set():
@@ -868,9 +869,9 @@ def main():
nice = (args['--nice'] or 0),
toolchains_csv = args['--toolchains-csv'],
repo = args['--repo'],
- upload = upload)
+ upload = upload,
+ buildpid = buildpid)
p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- buildpid = buildpid,
debug = args['--debug']
))
p.start()
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 13/30] autobuild-run: move debug from kwargs to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (11 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 12/30] autobuild-run: move buildpid " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 14/30] autobuild-run: define instance directory as a part of " Atharva Lele
` (17 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Explicitly state class constructor argument
---
scripts/autobuild-run | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 05de063..923652c 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -274,7 +274,7 @@ class Builder:
def __init__(self, instance, njobs, sysinfo,
http_url, http_login, http_password,
submitter, make_opts, nice, toolchains_csv,
- repo, upload, buildpid):
+ repo, upload, buildpid, debug):
self.instance = instance
self.njobs = njobs
self.sysinfo = sysinfo
@@ -288,6 +288,7 @@ class Builder:
self.repo = repo
self.upload = upload
self.buildpid = buildpid
+ self.debug = debug
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -378,7 +379,7 @@ class Builder:
log_write(log, "INFO: generate the configuration")
- if kwargs['debug']:
+ if self.debug:
devnull = log
else:
devnull = open(os.devnull, "w")
@@ -724,7 +725,7 @@ class Builder:
if not os.path.exists(idir):
os.mkdir(idir)
- if kwargs['debug']:
+ if self.debug:
kwargs['log'] = sys.stdout
else:
kwargs['log'] = open(os.path.join(idir, "instance.log"), "a+")
@@ -870,10 +871,9 @@ def main():
toolchains_csv = args['--toolchains-csv'],
repo = args['--repo'],
upload = upload,
- buildpid = buildpid)
- p = multiprocessing.Process(target=builder.run_instance, kwargs=dict(
- debug = args['--debug']
- ))
+ buildpid = buildpid,
+ debug = args['--debug'])
+ p = multiprocessing.Process(target=builder.run_instance)
p.start()
processes.append(p)
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 14/30] autobuild-run: define instance directory as a part of Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (12 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 13/30] autobuild-run: move debug " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 15/30] autobuild-run: move log variable to " Atharva Lele
` (16 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
We need idir as a class member before moving log out of kwargs.
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
scripts/autobuild-run | 49 +++++++++++++++++++------------------------
1 file changed, 22 insertions(+), 27 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 923652c..d1ecbb3 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -290,6 +290,9 @@ class Builder:
self.buildpid = buildpid
self.debug = debug
+ # frequently needed directories
+ self.idir = "instance-%d" % self.instance
+
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -298,13 +301,12 @@ class Builder:
code, and cleaning up remaining stuff from previous builds.
"""
- idir = "instance-%d" % self.instance
log = kwargs['log']
log_write(log, "INFO: preparing a new build")
# Create the download directory if it doesn't exist
- dldir = os.path.join(idir, "dl")
+ dldir = os.path.join(self.idir, "dl")
if not os.path.exists(dldir):
os.mkdir(dldir)
@@ -339,7 +341,7 @@ class Builder:
# Clone Buildroot. This only happens if the source directory
# didn't exist already.
- srcdir = os.path.join(idir, "buildroot")
+ srcdir = os.path.join(self.idir, "buildroot")
if not os.path.exists(srcdir):
ret = subprocess.call(["git", "clone", self.repo, srcdir],
stdout=log, stderr=log)
@@ -360,7 +362,7 @@ class Builder:
return -1
# Create an empty output directory. We remove it first, in case a previous build was aborted.
- outputdir = os.path.join(idir, "output")
+ outputdir = os.path.join(self.idir, "output")
if os.path.exists(outputdir):
# shutil.rmtree doesn't remove write-protected files
subprocess.call(["rm", "-rf", outputdir])
@@ -372,10 +374,9 @@ class Builder:
def gen_config(self, **kwargs):
"""Generate a new random configuration."""
- idir = "instance-%d" % self.instance
log = kwargs['log']
- outputdir = os.path.abspath(os.path.join(idir, "output"))
- srcdir = os.path.join(idir, "buildroot")
+ outputdir = os.path.abspath(os.path.join(self.idir, "output"))
+ srcdir = os.path.join(self.idir, "buildroot")
log_write(log, "INFO: generate the configuration")
@@ -422,9 +423,8 @@ class Builder:
"""
log = kwargs['log']
- idir = "instance-%d" % self.instance
- outputdir = os.path.join(idir, "output")
- srcdir = os.path.join(idir, "buildroot")
+ outputdir = os.path.join(self.idir, "output")
+ srcdir = os.path.join(self.idir, "buildroot")
reproducible_results = os.path.join(outputdir, "results", "reproducible_results")
# Using only tar images for now
build_1_image = os.path.join(outputdir, "images-1", "rootfs.tar")
@@ -454,16 +454,15 @@ class Builder:
def do_build(self, **kwargs):
"""Run the build itself"""
- idir = "instance-%d" % self.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
# script.
- dldir = os.path.abspath(os.path.join(idir, "dl"))
- outputdir = os.path.abspath(os.path.join(idir, "output"))
- srcdir = os.path.join(idir, "buildroot")
+ dldir = os.path.abspath(os.path.join(self.idir, "dl"))
+ outputdir = os.path.abspath(os.path.join(self.idir, "output"))
+ srcdir = os.path.join(self.idir, "buildroot")
f = open(os.path.join(outputdir, "logfile"), "w+")
log_write(log, "INFO: build started")
@@ -518,9 +517,8 @@ class Builder:
perform the actual build.
"""
- idir = "instance-%d" % self.instance
- outputdir = os.path.abspath(os.path.join(idir, "output"))
- srcdir = os.path.join(idir, "buildroot")
+ outputdir = os.path.abspath(os.path.join(self.idir, "output"))
+ srcdir = os.path.join(self.idir, "buildroot")
log = kwargs['log']
# Start the first build
@@ -556,11 +554,10 @@ class Builder:
are available) or stores them locally as tarballs.
"""
- idir = "instance-%d" % self.instance
log = kwargs['log']
- outputdir = os.path.abspath(os.path.join(idir, "output"))
- srcdir = os.path.join(idir, "buildroot")
+ outputdir = os.path.abspath(os.path.join(self.idir, "output"))
+ srcdir = os.path.join(self.idir, "buildroot")
resultdir = os.path.join(outputdir, "results")
shutil.copyfile(os.path.join(outputdir, ".config"),
@@ -719,16 +716,14 @@ class Builder:
results.
"""
- idir = "instance-%d" % self.instance
-
# If it doesn't exist, create the instance directory
- if not os.path.exists(idir):
- os.mkdir(idir)
+ if not os.path.exists(self.idir):
+ os.mkdir(self.idir)
if self.debug:
kwargs['log'] = sys.stdout
else:
- kwargs['log'] = open(os.path.join(idir, "instance.log"), "a+")
+ kwargs['log'] = open(os.path.join(self.idir, "instance.log"), "a+")
log_write(kwargs['log'], "INFO: instance started")
while True:
@@ -738,7 +733,7 @@ class Builder:
if ret != 0:
continue
- resultdir = os.path.join(idir, "output", "results")
+ resultdir = os.path.join(self.idir, "output", "results")
os.mkdir(resultdir)
ret = self.gen_config(**kwargs)
@@ -747,7 +742,7 @@ class Builder:
continue
# Check if the build test is supposed to be a reproducible test
- outputdir = os.path.abspath(os.path.join(idir, "output"))
+ outputdir = os.path.abspath(os.path.join(self.idir, "output"))
with open(os.path.join(outputdir, ".config"), "r") as fconf:
reproducible = "BR2_REPRODUCIBLE=y\n" in fconf.read()
if reproducible:
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 15/30] autobuild-run: move log variable to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (13 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 14/30] autobuild-run: define instance directory as a part of " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 16/30] autobuild-run: remove kwargs argument from function calls and definitions Atharva Lele
` (15 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Fix whitespace errors
---
scripts/autobuild-run | 94 ++++++++++++++++++++-----------------------
1 file changed, 43 insertions(+), 51 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index d1ecbb3..cb00745 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -293,6 +293,11 @@ class Builder:
# frequently needed directories
self.idir = "instance-%d" % self.instance
+ if self.debug:
+ self.log = sys.stdout
+ else:
+ self.log = open(os.path.join(self.idir, "instance.log"), "a+")
+
def prepare_build(self, **kwargs):
"""Prepare for the next build of the specified instance
@@ -301,9 +306,7 @@ class Builder:
code, and cleaning up remaining stuff from previous builds.
"""
- log = kwargs['log']
-
- log_write(log, "INFO: preparing a new build")
+ log_write(self.log, "INFO: preparing a new build")
# Create the download directory if it doesn't exist
dldir = os.path.join(self.idir, "dl")
@@ -332,33 +335,33 @@ class Builder:
if not flist:
break
f = flist[randint(0, len(flist) - 1)]
- log_write(log, "INFO: removing %s from downloads" %
+ log_write(self.log, "INFO: removing %s from downloads" %
os.path.relpath(f, dldir))
os.remove(f)
branch = get_branch()
- log_write(log, "INFO: testing branch '%s'" % branch)
+ log_write(self.log, "INFO: testing branch '%s'" % branch)
# Clone Buildroot. This only happens if the source directory
# didn't exist already.
srcdir = os.path.join(self.idir, "buildroot")
if not os.path.exists(srcdir):
ret = subprocess.call(["git", "clone", self.repo, srcdir],
- stdout=log, stderr=log)
+ stdout=self.log, stderr=self.log)
if ret != 0:
- log_write(log, "ERROR: could not clone Buildroot sources")
+ log_write(self.log, "ERROR: could not clone Buildroot sources")
return -1
# Update the Buildroot sources.
abssrcdir = os.path.abspath(srcdir)
- ret = subprocess.call(["git", "fetch", "origin"], cwd=abssrcdir, stdout=log, stderr=log)
+ ret = subprocess.call(["git", "fetch", "origin"], cwd=abssrcdir, stdout=self.log, stderr=self.log)
if ret != 0:
- log_write(log, "ERROR: could not fetch Buildroot sources")
+ log_write(self.log, "ERROR: could not fetch Buildroot sources")
return -1
- ret = subprocess.call(["git", "checkout", "--detach", "origin/%s" % branch], cwd=abssrcdir, stdout=log, stderr=log)
+ ret = subprocess.call(["git", "checkout", "--detach", "origin/%s" % branch], cwd=abssrcdir, stdout=self.log, stderr=self.log)
if ret != 0:
- log_write(log, "ERROR: could not check out Buildroot sources")
+ log_write(self.log, "ERROR: could not check out Buildroot sources")
return -1
# Create an empty output directory. We remove it first, in case a previous build was aborted.
@@ -374,14 +377,13 @@ class Builder:
def gen_config(self, **kwargs):
"""Generate a new random configuration."""
- log = kwargs['log']
outputdir = os.path.abspath(os.path.join(self.idir, "output"))
srcdir = os.path.join(self.idir, "buildroot")
- log_write(log, "INFO: generate the configuration")
+ log_write(self.log, "INFO: generate the configuration")
if self.debug:
- devnull = log
+ devnull = self.log
else:
devnull = open(os.devnull, "w")
@@ -394,12 +396,12 @@ class Builder:
toolchains_csv = os.path.join(srcdir, toolchains_csv)
args.extend(["--toolchains-csv", toolchains_csv])
- ret = subprocess.call(args, stdout=devnull, stderr=log)
+ ret = subprocess.call(args, stdout=devnull, stderr=self.log)
return ret
def stop_on_build_hang(self, monitor_thread_hung_build_flag,
monitor_thread_stop_flag, sub_proc,
- outputdir, log):
+ outputdir):
build_time_logfile = os.path.join(outputdir, "build/build-time.log")
while True:
if monitor_thread_stop_flag.is_set():
@@ -410,7 +412,7 @@ class Builder:
if mtime < datetime.datetime.now() - datetime.timedelta(minutes=HUNG_BUILD_TIMEOUT):
if sub_proc.poll() is None:
monitor_thread_hung_build_flag.set() # Used by do_build() to determine build hang
- log_write(log, "INFO: build hung")
+ log_write(self.log, "INFO: build hung")
sub_proc.kill()
break
monitor_thread_stop_flag.wait(30)
@@ -422,7 +424,6 @@ class Builder:
installed, fallback to cmp
"""
- log = kwargs['log']
outputdir = os.path.join(self.idir, "output")
srcdir = os.path.join(self.idir, "buildroot")
reproducible_results = os.path.join(outputdir, "results", "reproducible_results")
@@ -436,26 +437,24 @@ class Builder:
prefix = subprocess.check_output(["make", "O=%s" % outputdir, "-C", srcdir, "printvars", "VARS=TARGET_CROSS"])
# Remove TARGET_CROSS= and \n from the string
prefix = prefix[13:-1]
- log_write(log, "INFO: running diffoscope on images")
+ log_write(self.log, "INFO: running diffoscope on images")
subprocess.call(["diffoscope", build_1_image, build_2_image,
- "--tool-prefix-binutils", prefix], stdout=diff, stderr=log)
+ "--tool-prefix-binutils", prefix], stdout=diff, stderr=self.log)
else:
- log_write(log, "INFO: diffoscope not installed, falling back to cmp")
- subprocess.call(["cmp", "-b", build_1_image, build_2_image], stdout=diff, stderr=log)
+ log_write(self.log, "INFO: diffoscope not installed, falling back to cmp")
+ subprocess.call(["cmp", "-b", build_1_image, build_2_image], stdout=diff, stderr=self.log)
if os.stat(reproducible_results).st_size > 0:
- log_write(log, "INFO: Build is non-reproducible.")
+ log_write(self.log, "INFO: Build is non-reproducible.")
return -1
# rootfs images match byte-for-byte -> reproducible image
- log_write(log, "INFO: Build is reproducible!")
+ log_write(self.log, "INFO: Build is reproducible!")
return 0
def do_build(self, **kwargs):
"""Run the build itself"""
- 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
@@ -464,7 +463,7 @@ class Builder:
outputdir = os.path.abspath(os.path.join(self.idir, "output"))
srcdir = os.path.join(self.idir, "buildroot")
f = open(os.path.join(outputdir, "logfile"), "w+")
- log_write(log, "INFO: build started")
+ log_write(self.log, "INFO: build started")
cmd = ["nice", "-n", str(self.nice),
"make", "O=%s" % outputdir,
@@ -479,7 +478,7 @@ class Builder:
build_monitor = Thread(target=self.stop_on_build_hang,
args=(monitor_thread_hung_build_flag,
monitor_thread_stop_flag,
- sub, outputdir, log))
+ sub, outputdir))
build_monitor.daemon = True
build_monitor.start()
@@ -489,7 +488,7 @@ class Builder:
# If build failed, monitor thread would have exited at this point
if monitor_thread_hung_build_flag.is_set():
- log_write(log, "INFO: build timed out [%d]" % ret)
+ log_write(self.log, "INFO: build timed out [%d]" % ret)
return -2
else:
# Stop monitor thread as this build didn't timeout
@@ -497,7 +496,7 @@ class Builder:
# Monitor thread should be exiting around this point
if ret != 0:
- log_write(log, "INFO: build failed [%d]" % ret)
+ log_write(self.log, "INFO: build failed [%d]" % ret)
return -1
cmd = ["make", "O=%s" % outputdir, "-C", srcdir,
@@ -505,9 +504,9 @@ class Builder:
+ self.make_opts.split()
ret = subprocess.call(cmd, stdout=f, stderr=f)
if ret != 0:
- log_write(log, "INFO: build failed during legal-info")
+ log_write(self.log, "INFO: build failed during legal-info")
return -1
- log_write(log, "INFO: build successful")
+ log_write(self.log, "INFO: build successful")
return 0
def do_reproducible_build(self, **kwargs):
@@ -519,13 +518,12 @@ class Builder:
outputdir = os.path.abspath(os.path.join(self.idir, "output"))
srcdir = os.path.join(self.idir, "buildroot")
- log = kwargs['log']
# Start the first build
- log_write(log, "INFO: Reproducible Build Test, starting build 1")
+ log_write(self.log, "INFO: Reproducible Build Test, starting build 1")
ret = self.do_build(**kwargs)
if ret != 0:
- log_write(log, "INFO: build 1 failed, skipping build 2")
+ log_write(self.log, "INFO: build 1 failed, skipping build 2")
return ret
# First build has been built, move files and start build 2
@@ -536,10 +534,10 @@ class Builder:
subprocess.call(["make", "O=%s" % outputdir, "-C", srcdir, "clean"], stdout=f, stderr=f)
# Start the second build
- log_write(log, "INFO: Reproducible Build Test, starting build 2")
+ log_write(self.log, "INFO: Reproducible Build Test, starting build 2")
ret = self.do_build(**kwargs)
if ret != 0:
- log_write(log, "INFO: build 2 failed")
+ log_write(self.log, "INFO: build 2 failed")
return ret
# Assuming both have built successfully
@@ -554,8 +552,6 @@ class Builder:
are available) or stores them locally as tarballs.
"""
- log = kwargs['log']
-
outputdir = os.path.abspath(os.path.join(self.idir, "output"))
srcdir = os.path.join(self.idir, "buildroot")
resultdir = os.path.join(outputdir, "results")
@@ -681,9 +677,9 @@ class Builder:
# Yes, shutil.make_archive() would be nice, but it doesn't exist
# in Python 2.6.
ret = subprocess.call(["tar", "cjf", "results.tar.bz2", "results"],
- cwd=outputdir, stdout=log, stderr=log)
+ cwd=outputdir, stdout=self.log, stderr=self.log)
if ret != 0:
- log_write(log, "ERROR: could not make results tarball")
+ log_write(self.log, "ERROR: could not make results tarball")
sys.exit(1)
if self.upload:
@@ -696,18 +692,18 @@ class Builder:
"-F", "uploadedfile=@%s" % os.path.join(outputdir, "results.tar.bz2"),
"-F", "uploadsubmit=1",
self.http_url],
- stdout=log, stderr=log)
+ stdout=self.log, stderr=self.log)
if ret != 0:
- log_write(log, "INFO: results could not be submitted, %d" % ret)
+ log_write(self.log, "INFO: results could not be submitted, %d" % ret)
else:
- log_write(log, "INFO: results were submitted successfully")
+ log_write(self.log, "INFO: results were submitted successfully")
else:
# 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" % (self.instance, sha1)
os.rename(os.path.join(outputdir, "results.tar.bz2"), resultfilename)
- log_write(log, "INFO: results saved as %s" % resultfilename)
+ log_write(self.log, "INFO: results saved as %s" % resultfilename)
def run_instance(self, **kwargs):
"""Main per-instance loop
@@ -720,11 +716,7 @@ class Builder:
if not os.path.exists(self.idir):
os.mkdir(self.idir)
- if self.debug:
- kwargs['log'] = sys.stdout
- else:
- kwargs['log'] = open(os.path.join(self.idir, "instance.log"), "a+")
- log_write(kwargs['log'], "INFO: instance started")
+ log_write(self.log, "INFO: instance started")
while True:
check_version()
@@ -738,7 +730,7 @@ class Builder:
ret = self.gen_config(**kwargs)
if ret != 0:
- log_write(kwargs['log'], "WARN: failed to generate configuration")
+ log_write(self.log, "WARN: failed to generate configuration")
continue
# Check if the build test is supposed to be a reproducible test
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 16/30] autobuild-run: remove kwargs argument from function calls and definitions
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (14 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 15/30] autobuild-run: move log variable to " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 17/30] autobuild-run: define source directory as part of Builder class Atharva Lele
` (14 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
scripts/autobuild-run | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index cb00745..adc8795 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -298,7 +298,7 @@ class Builder:
else:
self.log = open(os.path.join(self.idir, "instance.log"), "a+")
- def prepare_build(self, **kwargs):
+ def prepare_build(self):
"""Prepare for the next build of the specified instance
This function prepares the build by making sure all the needed
@@ -375,7 +375,7 @@ class Builder:
return 0
- def gen_config(self, **kwargs):
+ def gen_config(self):
"""Generate a new random configuration."""
outputdir = os.path.abspath(os.path.join(self.idir, "output"))
srcdir = os.path.join(self.idir, "buildroot")
@@ -417,7 +417,7 @@ class Builder:
break
monitor_thread_stop_flag.wait(30)
- def check_reproducibility(self, **kwargs):
+ def check_reproducibility(self):
"""Check reproducibility of builds
Use diffoscope on the built images, if diffoscope is not
@@ -452,7 +452,7 @@ class Builder:
log_write(self.log, "INFO: Build is reproducible!")
return 0
- def do_build(self, **kwargs):
+ def do_build(self):
"""Run the build itself"""
# We need the absolute path to use with O=, because the relative
@@ -509,7 +509,7 @@ class Builder:
log_write(self.log, "INFO: build successful")
return 0
- def do_reproducible_build(self, **kwargs):
+ def do_reproducible_build(self):
"""Run the builds for reproducibility testing
Build twice with the same configuration. Calls do_build() to
@@ -521,7 +521,7 @@ class Builder:
# Start the first build
log_write(self.log, "INFO: Reproducible Build Test, starting build 1")
- ret = self.do_build(**kwargs)
+ ret = self.do_build()
if ret != 0:
log_write(self.log, "INFO: build 1 failed, skipping build 2")
return ret
@@ -535,16 +535,16 @@ class Builder:
# Start the second build
log_write(self.log, "INFO: Reproducible Build Test, starting build 2")
- ret = self.do_build(**kwargs)
+ ret = self.do_build()
if ret != 0:
log_write(self.log, "INFO: build 2 failed")
return ret
# Assuming both have built successfully
- ret = self.check_reproducibility(**kwargs)
+ ret = self.check_reproducibility()
return ret
- def send_results(self, result, **kwargs):
+ def send_results(self, result):
"""Prepare and store/send tarball with results
This function prepares the tarball with the results, and either
@@ -705,7 +705,7 @@ class Builder:
os.rename(os.path.join(outputdir, "results.tar.bz2"), resultfilename)
log_write(self.log, "INFO: results saved as %s" % resultfilename)
- def run_instance(self, **kwargs):
+ def run_instance(self):
"""Main per-instance loop
Prepare the build, generate a configuration, run the build, and submit the
@@ -721,14 +721,14 @@ class Builder:
while True:
check_version()
- ret = self.prepare_build(**kwargs)
+ ret = self.prepare_build()
if ret != 0:
continue
resultdir = os.path.join(self.idir, "output", "results")
os.mkdir(resultdir)
- ret = self.gen_config(**kwargs)
+ ret = self.gen_config()
if ret != 0:
log_write(self.log, "WARN: failed to generate configuration")
continue
@@ -738,11 +738,11 @@ class Builder:
with open(os.path.join(outputdir, ".config"), "r") as fconf:
reproducible = "BR2_REPRODUCIBLE=y\n" in fconf.read()
if reproducible:
- ret = self.do_reproducible_build(**kwargs)
+ ret = self.do_reproducible_build()
else:
- ret = self.do_build(**kwargs)
+ ret = self.do_build()
- self.send_results(ret, **kwargs)
+ self.send_results(ret)
# args / config file merging inspired by:
# https://github.com/docopt/docopt/blob/master/examples/config_file_example.py
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 17/30] autobuild-run: define source directory as part of Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (15 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 16/30] autobuild-run: remove kwargs argument from function calls and definitions Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 18/30] autobuild-run: define download " Atharva Lele
` (13 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Fix whitespace issue
---
scripts/autobuild-run | 29 ++++++++++++-----------------
1 file changed, 12 insertions(+), 17 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index adc8795..741d316 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -292,6 +292,7 @@ class Builder:
# frequently needed directories
self.idir = "instance-%d" % self.instance
+ self.srcdir = os.path.join(self.idir, "buildroot")
if self.debug:
self.log = sys.stdout
@@ -344,16 +345,15 @@ class Builder:
# Clone Buildroot. This only happens if the source directory
# didn't exist already.
- srcdir = os.path.join(self.idir, "buildroot")
- if not os.path.exists(srcdir):
- ret = subprocess.call(["git", "clone", self.repo, srcdir],
+ if not os.path.exists(self.srcdir):
+ ret = subprocess.call(["git", "clone", self.repo, self.srcdir],
stdout=self.log, stderr=self.log)
if ret != 0:
log_write(self.log, "ERROR: could not clone Buildroot sources")
return -1
# Update the Buildroot sources.
- abssrcdir = os.path.abspath(srcdir)
+ abssrcdir = os.path.abspath(self.srcdir)
ret = subprocess.call(["git", "fetch", "origin"], cwd=abssrcdir, stdout=self.log, stderr=self.log)
if ret != 0:
log_write(self.log, "ERROR: could not fetch Buildroot sources")
@@ -378,7 +378,6 @@ class Builder:
def gen_config(self):
"""Generate a new random configuration."""
outputdir = os.path.abspath(os.path.join(self.idir, "output"))
- srcdir = os.path.join(self.idir, "buildroot")
log_write(self.log, "INFO: generate the configuration")
@@ -387,13 +386,13 @@ class Builder:
else:
devnull = open(os.devnull, "w")
- args = [os.path.join(srcdir, "utils/genrandconfig"),
- "-o", outputdir, "-b", srcdir]
+ args = [os.path.join(self.srcdir, "utils/genrandconfig"),
+ "-o", outputdir, "-b", self.srcdir]
toolchains_csv = self.toolchains_csv
if toolchains_csv:
if not os.path.isabs(toolchains_csv):
- toolchains_csv = os.path.join(srcdir, toolchains_csv)
+ toolchains_csv = os.path.join(self.srcdir, toolchains_csv)
args.extend(["--toolchains-csv", toolchains_csv])
ret = subprocess.call(args, stdout=devnull, stderr=self.log)
@@ -425,7 +424,6 @@ class Builder:
"""
outputdir = os.path.join(self.idir, "output")
- srcdir = os.path.join(self.idir, "buildroot")
reproducible_results = os.path.join(outputdir, "results", "reproducible_results")
# Using only tar images for now
build_1_image = os.path.join(outputdir, "images-1", "rootfs.tar")
@@ -434,7 +432,7 @@ class Builder:
with open(reproducible_results, 'w') as diff:
if self.sysinfo.has("diffoscope"):
# Prefix to point diffoscope towards cross-tools
- prefix = subprocess.check_output(["make", "O=%s" % outputdir, "-C", srcdir, "printvars", "VARS=TARGET_CROSS"])
+ prefix = subprocess.check_output(["make", "O=%s" % outputdir, "-C", self.srcdir, "printvars", "VARS=TARGET_CROSS"])
# Remove TARGET_CROSS= and \n from the string
prefix = prefix[13:-1]
log_write(self.log, "INFO: running diffoscope on images")
@@ -461,13 +459,12 @@ class Builder:
# script.
dldir = os.path.abspath(os.path.join(self.idir, "dl"))
outputdir = os.path.abspath(os.path.join(self.idir, "output"))
- srcdir = os.path.join(self.idir, "buildroot")
f = open(os.path.join(outputdir, "logfile"), "w+")
log_write(self.log, "INFO: build started")
cmd = ["nice", "-n", str(self.nice),
"make", "O=%s" % outputdir,
- "-C", srcdir, "BR2_DL_DIR=%s" % dldir,
+ "-C", self.srcdir, "BR2_DL_DIR=%s" % dldir,
"BR2_JLEVEL=%s" % self.njobs] \
+ self.make_opts.split()
sub = subprocess.Popen(cmd, stdout=f, stderr=f)
@@ -499,7 +496,7 @@ class Builder:
log_write(self.log, "INFO: build failed [%d]" % ret)
return -1
- cmd = ["make", "O=%s" % outputdir, "-C", srcdir,
+ cmd = ["make", "O=%s" % outputdir, "-C", self.srcdir,
"BR2_DL_DIR=%s" % dldir, "legal-info"] \
+ self.make_opts.split()
ret = subprocess.call(cmd, stdout=f, stderr=f)
@@ -517,7 +514,6 @@ class Builder:
"""
outputdir = os.path.abspath(os.path.join(self.idir, "output"))
- srcdir = os.path.join(self.idir, "buildroot")
# Start the first build
log_write(self.log, "INFO: Reproducible Build Test, starting build 1")
@@ -531,7 +527,7 @@ class Builder:
# Clean up build 1
f = open(os.path.join(outputdir, "logfile"), "w+")
- subprocess.call(["make", "O=%s" % outputdir, "-C", srcdir, "clean"], stdout=f, stderr=f)
+ subprocess.call(["make", "O=%s" % outputdir, "-C", self.srcdir, "clean"], stdout=f, stderr=f)
# Start the second build
log_write(self.log, "INFO: Reproducible Build Test, starting build 2")
@@ -553,7 +549,6 @@ class Builder:
"""
outputdir = os.path.abspath(os.path.join(self.idir, "output"))
- srcdir = os.path.join(self.idir, "buildroot")
resultdir = os.path.join(outputdir, "results")
shutil.copyfile(os.path.join(outputdir, ".config"),
@@ -576,7 +571,7 @@ class Builder:
subprocess.call(["git log -n 1 --pretty=format:%%H > %s" % \
os.path.join(resultdir, "gitid")],
- shell=True, cwd=srcdir)
+ shell=True, cwd=self.srcdir)
# Return True if the result should be rejected, False otherwise
def reject_results():
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 18/30] autobuild-run: define download directory as part of Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (16 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 17/30] autobuild-run: define source directory as part of Builder class Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 19/30] autobuild-run: define output " Atharva Lele
` (12 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
scripts/autobuild-run | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 741d316..84b4dee 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -293,6 +293,7 @@ class Builder:
# frequently needed directories
self.idir = "instance-%d" % self.instance
self.srcdir = os.path.join(self.idir, "buildroot")
+ self.dldir = os.path.join(self.idir, "dl")
if self.debug:
self.log = sys.stdout
@@ -310,9 +311,8 @@ class Builder:
log_write(self.log, "INFO: preparing a new build")
# Create the download directory if it doesn't exist
- dldir = os.path.join(self.idir, "dl")
- if not os.path.exists(dldir):
- os.mkdir(dldir)
+ if not os.path.exists(self.dldir):
+ os.mkdir(self.dldir)
# recursively find files under root
def find_files(root):
@@ -332,12 +332,12 @@ class Builder:
# regularly re-download files to check that their upstream
# location is still correct.
for i in range(0, 5):
- flist = list(find_files(dldir))
+ flist = list(find_files(self.dldir))
if not flist:
break
f = flist[randint(0, len(flist) - 1)]
log_write(self.log, "INFO: removing %s from downloads" %
- os.path.relpath(f, dldir))
+ os.path.relpath(f, self.dldir))
os.remove(f)
branch = get_branch()
@@ -457,14 +457,13 @@ class Builder:
# path to the output directory here is not relative to the
# Buildroot sources, but to the location of the autobuilder
# script.
- dldir = os.path.abspath(os.path.join(self.idir, "dl"))
outputdir = os.path.abspath(os.path.join(self.idir, "output"))
f = open(os.path.join(outputdir, "logfile"), "w+")
log_write(self.log, "INFO: build started")
cmd = ["nice", "-n", str(self.nice),
"make", "O=%s" % outputdir,
- "-C", self.srcdir, "BR2_DL_DIR=%s" % dldir,
+ "-C", self.srcdir, "BR2_DL_DIR=%s" % self.dldir,
"BR2_JLEVEL=%s" % self.njobs] \
+ self.make_opts.split()
sub = subprocess.Popen(cmd, stdout=f, stderr=f)
@@ -497,7 +496,7 @@ class Builder:
return -1
cmd = ["make", "O=%s" % outputdir, "-C", self.srcdir,
- "BR2_DL_DIR=%s" % dldir, "legal-info"] \
+ "BR2_DL_DIR=%s" % self.dldir, "legal-info"] \
+ self.make_opts.split()
ret = subprocess.call(cmd, stdout=f, stderr=f)
if ret != 0:
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 19/30] autobuild-run: define output directory as part of Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (17 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 18/30] autobuild-run: define download " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 20/30] autobuild-run: define results " Atharva Lele
` (11 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Absolute path for output dir is required when using outputdir with
system commands like make or tail. It was necessary because the
relative path would be relative to the autobuilder script rather
than the buildroot source directory.
It is OK to use an absolute path everywhere because an absolute
path is always correct.
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
---
Changes v2 -> v3:
- Use outputdir as argument in stop_on_build_hang(), required for
later changes (different output dir for reproducibility testing)
Changes v1 -> v2:
- Fixed inaccuracies in commit message
- Fixed whitespace issue
---
scripts/autobuild-run | 81 ++++++++++++++++++++-----------------------
1 file changed, 37 insertions(+), 44 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 84b4dee..e225211 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -294,6 +294,11 @@ class Builder:
self.idir = "instance-%d" % self.instance
self.srcdir = os.path.join(self.idir, "buildroot")
self.dldir = os.path.join(self.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
+ # Buildroot sources, but to the location of the autobuilder
+ # script.
+ self.outputdir = os.path.abspath(os.path.join(self.idir, "output"))
if self.debug:
self.log = sys.stdout
@@ -365,19 +370,17 @@ class Builder:
return -1
# Create an empty output directory. We remove it first, in case a previous build was aborted.
- outputdir = os.path.join(self.idir, "output")
- if os.path.exists(outputdir):
+ if os.path.exists(self.outputdir):
# shutil.rmtree doesn't remove write-protected files
- subprocess.call(["rm", "-rf", outputdir])
- os.mkdir(outputdir)
- with open(os.path.join(outputdir, "branch"), "w") as branchf:
+ subprocess.call(["rm", "-rf", self.outputdir])
+ os.mkdir(self.outputdir)
+ with open(os.path.join(self.outputdir, "branch"), "w") as branchf:
branchf.write(branch)
return 0
def gen_config(self):
"""Generate a new random configuration."""
- outputdir = os.path.abspath(os.path.join(self.idir, "output"))
log_write(self.log, "INFO: generate the configuration")
@@ -387,7 +390,7 @@ class Builder:
devnull = open(os.devnull, "w")
args = [os.path.join(self.srcdir, "utils/genrandconfig"),
- "-o", outputdir, "-b", self.srcdir]
+ "-o", self.outputdir, "-b", self.srcdir]
toolchains_csv = self.toolchains_csv
if toolchains_csv:
@@ -423,16 +426,15 @@ class Builder:
installed, fallback to cmp
"""
- outputdir = os.path.join(self.idir, "output")
- reproducible_results = os.path.join(outputdir, "results", "reproducible_results")
+ reproducible_results = os.path.join(self.outputdir, "results", "reproducible_results")
# Using only tar images for now
- build_1_image = os.path.join(outputdir, "images-1", "rootfs.tar")
- build_2_image = os.path.join(outputdir, "images", "rootfs.tar")
+ build_1_image = os.path.join(self.outputdir, "images-1", "rootfs.tar")
+ build_2_image = os.path.join(self.outputdir, "images", "rootfs.tar")
with open(reproducible_results, 'w') as diff:
if self.sysinfo.has("diffoscope"):
# Prefix to point diffoscope towards cross-tools
- prefix = subprocess.check_output(["make", "O=%s" % outputdir, "-C", self.srcdir, "printvars", "VARS=TARGET_CROSS"])
+ prefix = subprocess.check_output(["make", "O=%s" % self.outputdir, "-C", self.srcdir, "printvars", "VARS=TARGET_CROSS"])
# Remove TARGET_CROSS= and \n from the string
prefix = prefix[13:-1]
log_write(self.log, "INFO: running diffoscope on images")
@@ -453,16 +455,11 @@ class Builder:
def do_build(self):
"""Run the build itself"""
- # 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
- # script.
- outputdir = os.path.abspath(os.path.join(self.idir, "output"))
- f = open(os.path.join(outputdir, "logfile"), "w+")
+ f = open(os.path.join(self.outputdir, "logfile"), "w+")
log_write(self.log, "INFO: build started")
cmd = ["nice", "-n", str(self.nice),
- "make", "O=%s" % outputdir,
+ "make", "O=%s" % self.outputdir,
"-C", self.srcdir, "BR2_DL_DIR=%s" % self.dldir,
"BR2_JLEVEL=%s" % self.njobs] \
+ self.make_opts.split()
@@ -474,7 +471,7 @@ class Builder:
build_monitor = Thread(target=self.stop_on_build_hang,
args=(monitor_thread_hung_build_flag,
monitor_thread_stop_flag,
- sub, outputdir))
+ sub, self.outputdir))
build_monitor.daemon = True
build_monitor.start()
@@ -495,7 +492,7 @@ class Builder:
log_write(self.log, "INFO: build failed [%d]" % ret)
return -1
- cmd = ["make", "O=%s" % outputdir, "-C", self.srcdir,
+ cmd = ["make", "O=%s" % self.outputdir, "-C", self.srcdir,
"BR2_DL_DIR=%s" % self.dldir, "legal-info"] \
+ self.make_opts.split()
ret = subprocess.call(cmd, stdout=f, stderr=f)
@@ -512,8 +509,6 @@ class Builder:
perform the actual build.
"""
- outputdir = os.path.abspath(os.path.join(self.idir, "output"))
-
# Start the first build
log_write(self.log, "INFO: Reproducible Build Test, starting build 1")
ret = self.do_build()
@@ -522,11 +517,11 @@ class Builder:
return ret
# First build has been built, move files and start build 2
- os.rename(os.path.join(outputdir, "images"), os.path.join(outputdir, "images-1"))
+ os.rename(os.path.join(self.outputdir, "images"), os.path.join(self.outputdir, "images-1"))
# Clean up build 1
- f = open(os.path.join(outputdir, "logfile"), "w+")
- subprocess.call(["make", "O=%s" % outputdir, "-C", self.srcdir, "clean"], stdout=f, stderr=f)
+ f = open(os.path.join(self.outputdir, "logfile"), "w+")
+ subprocess.call(["make", "O=%s" % self.outputdir, "-C", self.srcdir, "clean"], stdout=f, stderr=f)
# Start the second build
log_write(self.log, "INFO: Reproducible Build Test, starting build 2")
@@ -547,19 +542,18 @@ class Builder:
are available) or stores them locally as tarballs.
"""
- outputdir = os.path.abspath(os.path.join(self.idir, "output"))
- resultdir = os.path.join(outputdir, "results")
+ resultdir = os.path.join(self.outputdir, "results")
- shutil.copyfile(os.path.join(outputdir, ".config"),
+ shutil.copyfile(os.path.join(self.outputdir, ".config"),
os.path.join(resultdir, "config"))
- shutil.copyfile(os.path.join(outputdir, "defconfig"),
+ shutil.copyfile(os.path.join(self.outputdir, "defconfig"),
os.path.join(resultdir, "defconfig"))
- shutil.copyfile(os.path.join(outputdir, "branch"),
+ shutil.copyfile(os.path.join(self.outputdir, "branch"),
os.path.join(resultdir, "branch"))
def copy_if_exists(directory, src, dst=None):
- if os.path.exists(os.path.join(outputdir, directory, src)):
- shutil.copyfile(os.path.join(outputdir, directory, src),
+ if os.path.exists(os.path.join(self.outputdir, directory, src)):
+ shutil.copyfile(os.path.join(self.outputdir, directory, src),
os.path.join(resultdir, src if dst is None else dst))
copy_if_exists("build", "build-time.log")
@@ -575,7 +569,7 @@ class Builder:
# Return True if the result should be rejected, False otherwise
def reject_results():
lastlines = decode_bytes(subprocess.Popen(
- ["tail", "-n", "3", os.path.join(outputdir, "logfile")],
+ ["tail", "-n", "3", os.path.join(self.outputdir, "logfile")],
stdout=subprocess.PIPE).communicate()[0]).splitlines()
# Reject results where qemu-user refused to build
@@ -592,7 +586,7 @@ class Builder:
def get_failure_reason():
# Output is a tuple (package, version), or None.
lastlines = decode_bytes(subprocess.Popen(
- ["tail", "-n", "3", os.path.join(outputdir, "logfile")],
+ ["tail", "-n", "3", os.path.join(self.outputdir, "logfile")],
stdout=subprocess.PIPE).communicate()[0]).splitlines()
regexp = re.compile(r'make: \*\*\* .*/(?:build|toolchain)/([^/]*)/')
@@ -609,14 +603,14 @@ class Builder:
def extract_last_500_lines():
subprocess.call(["tail -500 %s > %s" % \
- (os.path.join(outputdir, "logfile"), resultfile)],
+ (os.path.join(self.outputdir, "logfile"), resultfile)],
shell=True)
reason = get_failure_reason()
if not reason:
extract_last_500_lines()
else:
- f = open(os.path.join(outputdir, "logfile"), 'r')
+ f = open(os.path.join(self.outputdir, "logfile"), 'r')
mf = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
mf.seek(0)
# Search for first action on the failed package
@@ -640,7 +634,7 @@ class Builder:
if not reason:
return
- srcroot = os.path.join(outputdir, "build", '-'.join(reason))
+ srcroot = os.path.join(self.outputdir, "build", '-'.join(reason))
destroot = os.path.join(resultdir, '-'.join(reason))
config_files = ('config.log', 'CMakeCache.txt', 'CMakeError.log',
'CMakeOutput.log')
@@ -671,7 +665,7 @@ class Builder:
# Yes, shutil.make_archive() would be nice, but it doesn't exist
# in Python 2.6.
ret = subprocess.call(["tar", "cjf", "results.tar.bz2", "results"],
- cwd=outputdir, stdout=self.log, stderr=self.log)
+ cwd=self.outputdir, stdout=self.log, stderr=self.log)
if ret != 0:
log_write(self.log, "ERROR: could not make results tarball")
sys.exit(1)
@@ -683,7 +677,7 @@ class Builder:
ret = subprocess.call(["curl", "-u",
"%s:%s" % (self.http_login, self.http_password),
"-H", "Expect:",
- "-F", "uploadedfile=@%s" % os.path.join(outputdir, "results.tar.bz2"),
+ "-F", "uploadedfile=@%s" % os.path.join(self.outputdir, "results.tar.bz2"),
"-F", "uploadsubmit=1",
self.http_url],
stdout=self.log, stderr=self.log)
@@ -693,10 +687,10 @@ class Builder:
log_write(self.log, "INFO: results were submitted successfully")
else:
# No http login/password, keep tarballs locally
- with open(os.path.join(outputdir, "results.tar.bz2"), 'rb') as f:
+ with open(os.path.join(self.outputdir, "results.tar.bz2"), 'rb') as f:
sha1 = hashlib.sha1(f.read()).hexdigest()
resultfilename = "instance-%d-%s.tar.bz2" % (self.instance, sha1)
- os.rename(os.path.join(outputdir, "results.tar.bz2"), resultfilename)
+ os.rename(os.path.join(self.outputdir, "results.tar.bz2"), resultfilename)
log_write(self.log, "INFO: results saved as %s" % resultfilename)
def run_instance(self):
@@ -728,8 +722,7 @@ class Builder:
continue
# Check if the build test is supposed to be a reproducible test
- outputdir = os.path.abspath(os.path.join(self.idir, "output"))
- with open(os.path.join(outputdir, ".config"), "r") as fconf:
+ with open(os.path.join(self.outputdir, ".config"), "r") as fconf:
reproducible = "BR2_REPRODUCIBLE=y\n" in fconf.read()
if reproducible:
ret = self.do_reproducible_build()
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 20/30] autobuild-run: define results directory as part of Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (18 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 19/30] autobuild-run: define output " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 21/30] autobuild-run: move check_version() to " Atharva Lele
` (10 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Acked-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
scripts/autobuild-run | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index e225211..8a0bec7 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -299,6 +299,7 @@ class Builder:
# Buildroot sources, but to the location of the autobuilder
# script.
self.outputdir = os.path.abspath(os.path.join(self.idir, "output"))
+ self.resultdir = os.path.join(self.outputdir, "results")
if self.debug:
self.log = sys.stdout
@@ -542,19 +543,17 @@ class Builder:
are available) or stores them locally as tarballs.
"""
- resultdir = os.path.join(self.outputdir, "results")
-
shutil.copyfile(os.path.join(self.outputdir, ".config"),
- os.path.join(resultdir, "config"))
+ os.path.join(self.resultdir, "config"))
shutil.copyfile(os.path.join(self.outputdir, "defconfig"),
- os.path.join(resultdir, "defconfig"))
+ os.path.join(self.resultdir, "defconfig"))
shutil.copyfile(os.path.join(self.outputdir, "branch"),
- os.path.join(resultdir, "branch"))
+ os.path.join(self.resultdir, "branch"))
def copy_if_exists(directory, src, dst=None):
if os.path.exists(os.path.join(self.outputdir, directory, src)):
shutil.copyfile(os.path.join(self.outputdir, directory, src),
- os.path.join(resultdir, src if dst is None else dst))
+ os.path.join(self.resultdir, src if dst is None else dst))
copy_if_exists("build", "build-time.log")
copy_if_exists("build", "packages-file-list.txt")
@@ -563,7 +562,7 @@ class Builder:
copy_if_exists("legal-info", "manifest.csv", "licenses-manifest.csv")
subprocess.call(["git log -n 1 --pretty=format:%%H > %s" % \
- os.path.join(resultdir, "gitid")],
+ os.path.join(self.resultdir, "gitid")],
shell=True, cwd=self.srcdir)
# Return True if the result should be rejected, False otherwise
@@ -625,7 +624,7 @@ class Builder:
mf.close()
f.close()
- extract_end_log(os.path.join(resultdir, "build-end.log"))
+ extract_end_log(os.path.join(self.resultdir, "build-end.log"))
def copy_config_log_files():
"""Recursively copy any config.log files from the failing package"""
@@ -635,7 +634,7 @@ class Builder:
return
srcroot = os.path.join(self.outputdir, "build", '-'.join(reason))
- destroot = os.path.join(resultdir, '-'.join(reason))
+ destroot = os.path.join(self.resultdir, '-'.join(reason))
config_files = ('config.log', 'CMakeCache.txt', 'CMakeError.log',
'CMakeOutput.log')
@@ -650,7 +649,7 @@ class Builder:
copy_config_log_files()
- resultf = open(os.path.join(resultdir, "status"), "w+")
+ resultf = open(os.path.join(self.resultdir, "status"), "w+")
if result == 0:
resultf.write("OK")
elif result == -1:
@@ -659,7 +658,7 @@ class Builder:
resultf.write("TIMEOUT")
resultf.close()
- with open(os.path.join(resultdir, "submitter"), "w+") as submitterf:
+ with open(os.path.join(self.resultdir, "submitter"), "w+") as submitterf:
submitterf.write(self.submitter)
# Yes, shutil.make_archive() would be nice, but it doesn't exist
@@ -713,8 +712,7 @@ class Builder:
if ret != 0:
continue
- resultdir = os.path.join(self.idir, "output", "results")
- os.mkdir(resultdir)
+ os.mkdir(self.resultdir)
ret = self.gen_config()
if ret != 0:
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 21/30] autobuild-run: move check_version() to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (19 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 20/30] autobuild-run: define results " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 22/30] autobuild-run: move get_branch() " Atharva Lele
` (9 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Upcoming patch from Thomas needs check_version() to
use http_url. As that is inside Builder class and check_version()
is only used inside Builder class, move it inside the class.
Also remove the redundant call to check_version() from main().
We already call check_version() in run_instance(). Also the fact
that we cannot call check_version() in main() since the builder
class object is not defined at that point.
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Reviewed-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- New patch
---
scripts/autobuild-run | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 8a0bec7..391c1dc 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -178,13 +178,6 @@ def log_write(logf, msg):
logf.write("[%s] %s\n" % (strftime("%a, %d %b %Y %H:%M:%S", localtime()), msg))
logf.flush()
-def check_version():
- with urlopen_closing('http://autobuild.buildroot.org/version') as r:
- version = int(decode_bytes(r.readline()).strip())
- if version > VERSION:
- print("ERROR: script version too old, please upgrade.")
- sys.exit(1)
-
def get_branch():
"""Returns the branch that should be built. It fetches a CSV file from
autobuild.buildroot.org that provides the list of branches to test
@@ -306,6 +299,13 @@ class Builder:
else:
self.log = open(os.path.join(self.idir, "instance.log"), "a+")
+ def check_version(self):
+ with urlopen_closing('http://autobuild.buildroot.org/version') as r:
+ version = int(decode_bytes(r.readline()).strip())
+ if version > VERSION:
+ print("ERROR: script version too old, please upgrade.")
+ sys.exit(1)
+
def prepare_build(self):
"""Prepare for the next build of the specified instance
@@ -706,7 +706,7 @@ class Builder:
log_write(self.log, "INFO: instance started")
while True:
- check_version()
+ self.check_version()
ret = self.prepare_build()
if ret != 0:
@@ -765,7 +765,6 @@ def main():
# showing error messages in another language.
os.environ['LC_ALL'] = 'C'
- check_version()
sysinfo = SystemInfo()
args = docopt.docopt(doc, version=VERSION)
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 22/30] autobuild-run: move get_branch() to Builder class
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (20 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 21/30] autobuild-run: move check_version() to " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 23/30] scripts/autobuild-run: make the HTTP URL really configurable Atharva Lele
` (8 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
get_branch() requires http_url and is only called inside
Builder class. Moving it to builder class makes http_url
available to it and makes the Builder class cohesive.
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Reviewed-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- New patch
---
scripts/autobuild-run | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 391c1dc..ccfa9c4 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -178,23 +178,6 @@ def log_write(logf, msg):
logf.write("[%s] %s\n" % (strftime("%a, %d %b %Y %H:%M:%S", localtime()), msg))
logf.flush()
-def get_branch():
- """Returns the branch that should be built. It fetches a CSV file from
- autobuild.buildroot.org that provides the list of branches to test
- (first field) and their weight (second field). We build a list of
- branches, where the branch name is repeated N times, with N being
- the weight of the branch. We then pick a random branch in this
- list. This way, branches with a higher weight are more likely to
- be selected.
- """
- with urlopen_closing('http://autobuild.buildroot.org/branches') as r:
- csv_branches = r.readlines()
- branches = []
- for branch in csv.reader(csv_branches):
- branches += [branch[0]] * int(branch[1])
-
- return branches[randint(0, len(branches) - 1)]
-
class SystemInfo:
DEFAULT_NEEDED_PROGS = ["make", "git", "gcc"]
DEFAULT_OPTIONAL_PROGS = ["bzr", "diffoscope", "java", "javac", "jar"]
@@ -306,6 +289,23 @@ class Builder:
print("ERROR: script version too old, please upgrade.")
sys.exit(1)
+ def get_branch(self):
+ """Returns the branch that should be built. It fetches a CSV file from
+ autobuild.buildroot.org that provides the list of branches to test
+ (first field) and their weight (second field). We build a list of
+ branches, where the branch name is repeated N times, with N being
+ the weight of the branch. We then pick a random branch in this
+ list. This way, branches with a higher weight are more likely to
+ be selected.
+ """
+ with urlopen_closing('http://autobuild.buildroot.org/branches') as r:
+ csv_branches = r.readlines()
+ branches = []
+ for branch in csv.reader(csv_branches):
+ branches += [branch[0]] * int(branch[1])
+
+ return branches[randint(0, len(branches) - 1)]
+
def prepare_build(self):
"""Prepare for the next build of the specified instance
@@ -346,7 +346,7 @@ class Builder:
os.path.relpath(f, self.dldir))
os.remove(f)
- branch = get_branch()
+ branch = self.get_branch()
log_write(self.log, "INFO: testing branch '%s'" % branch)
# Clone Buildroot. This only happens if the source directory
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 23/30] scripts/autobuild-run: make the HTTP URL really configurable
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (21 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 22/30] autobuild-run: move get_branch() " Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 24/30] autobuild-run: create reason file on build failures Atharva Lele
` (7 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
The --http-url option allowed to customize the URL at which build
results are submitted. However, there were two other places in the
script where autobuild.buildroot.org was hardcoded: when checking the
script version, and when getting the list of branches to build.
This commit changes the --http-url to be the base URL of the autobuild
server, and it is used everywhere instead of hardcoding
autobuild.buildroot.org.
Note: users of autobuild-run that were passing a custom --http-url
option such as http://foo.com/submit/ should change it to just
http://foo.com/
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
[Atharva: Adapted Thomas' patches to work with Builder class]
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Reviewed-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Incorporate Thomas' patch into Builder class series
- Move patch for appropriate order of patches
---
scripts/autobuild-run | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index ccfa9c4..678bac5 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -66,7 +66,7 @@ defaults = {
'--make-opts': '',
'--nice': 0,
'--pid-file': '/tmp/buildroot-autobuild.pid',
- '--http-url': 'http://autobuild.buildroot.org/submit/',
+ '--http-url': 'http://autobuild.buildroot.org/',
'--toolchains-csv': 'support/config-fragments/autobuild/toolchain-configs.csv',
'--repo': 'https://github.com/buildroot/buildroot.git',
}
@@ -145,6 +145,7 @@ from distutils.version import StrictVersion
import platform
from threading import Thread, Event
import datetime
+import urlparse
if sys.hexversion >= 0x3000000:
import configparser
@@ -283,7 +284,7 @@ class Builder:
self.log = open(os.path.join(self.idir, "instance.log"), "a+")
def check_version(self):
- with urlopen_closing('http://autobuild.buildroot.org/version') as r:
+ with urlopen_closing(urlparse.urljoin(self.http_url, 'version')) as r:
version = int(decode_bytes(r.readline()).strip())
if version > VERSION:
print("ERROR: script version too old, please upgrade.")
@@ -291,14 +292,14 @@ class Builder:
def get_branch(self):
"""Returns the branch that should be built. It fetches a CSV file from
- autobuild.buildroot.org that provides the list of branches to test
+ the autobuild server that provides the list of branches to test
(first field) and their weight (second field). We build a list of
branches, where the branch name is repeated N times, with N being
the weight of the branch. We then pick a random branch in this
list. This way, branches with a higher weight are more likely to
be selected.
"""
- with urlopen_closing('http://autobuild.buildroot.org/branches') as r:
+ with urlopen_closing(urlparse.urljoin(self.http_url, 'branches')) as r:
csv_branches = r.readlines()
branches = []
for branch in csv.reader(csv_branches):
@@ -678,7 +679,7 @@ class Builder:
"-H", "Expect:",
"-F", "uploadedfile=@%s" % os.path.join(self.outputdir, "results.tar.bz2"),
"-F", "uploadsubmit=1",
- self.http_url],
+ urlparse.urljoin(self.http_url, 'submit/')],
stdout=self.log, stderr=self.log)
if ret != 0:
log_write(self.log, "INFO: results could not be submitted, %d" % ret)
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 24/30] autobuild-run: create reason file on build failures
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (22 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 23/30] scripts/autobuild-run: make the HTTP URL really configurable Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 25/30] web/import.inc.php: support reading failure reason from reason file Atharva Lele
` (6 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
When a build fails, we calculate the reason of failure on
the server side as well as client side. To solve this redundancy
we only calculate on the client side and submit a file which
contains the reason of failure.
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Reviewed-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes from reason-file-v2 series:
- Move to builder-class series
---
scripts/autobuild-run | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 678bac5..8f60e89 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -598,6 +598,11 @@ class Builder:
# not found
return None
+ reason = get_failure_reason()
+ if reason:
+ with open(os.path.join(self.resultdir, "reason"), "w+") as reasonf:
+ reasonf.write("-".join(reason))
+
def extract_end_log(resultfile):
"""Save the last part of the build log, starting from the failed package"""
@@ -606,7 +611,6 @@ class Builder:
(os.path.join(self.outputdir, "logfile"), resultfile)],
shell=True)
- reason = get_failure_reason()
if not reason:
extract_last_500_lines()
else:
@@ -630,7 +634,6 @@ class Builder:
def copy_config_log_files():
"""Recursively copy any config.log files from the failing package"""
- reason = get_failure_reason()
if not reason:
return
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 25/30] web/import.inc.php: support reading failure reason from reason file
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (23 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 24/30] autobuild-run: create reason file on build failures Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 26/30] scripts/autobuild-run: support changing repo Atharva Lele
` (5 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
---
NOTE: This patch is untested.
Changes from reason-file-v2 series:
- Move to builder-class series
---
web/import.inc.php | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/web/import.inc.php b/web/import.inc.php
index a9b368f..6f878e0 100644
--- a/web/import.inc.php
+++ b/web/import.inc.php
@@ -230,17 +230,21 @@ function import_result($buildid, $filename)
if ($status == 0)
$reason = "none";
else {
- $tmp = Array();
- exec("tail -3 " . $thisbuildfinaldir . "build-end.log | grep -v '\[_all\]' | grep 'make.*: \*\*\*' | sed 's,.*\[\([^\]*\)\] Error.*,\\1,' | sed 's,.*/build/\([^/]*\)/.*,\\1,'", $tmp);
- if (trim($tmp[0]))
- $reason = $tmp[0];
- else {
- exec("tail -1 " . $thisbuildfinaldir . "build-time.log | grep :start: | cut -d':' -f4", $tmp);
- if (trim($tmp[0]))
- $reason = trim($tmp[0]);
- else
- $reason = "unknown";
- }
+ if (file_exists($thisbuildfinaldir . "reason"))
+ $reason = trim(file_get_contents($thisbuildfinaldir . "reason", "r"));
+ else {
+ $tmp = Array();
+ exec("tail -3 " . $thisbuildfinaldir . "build-end.log | grep -v '\[_all\]' | grep 'make.*: \*\*\*' | sed 's,.*\[\([^\]*\)\] Error.*,\\1,' | sed 's,.*/build/\([^/]*\)/.*,\\1,'", $tmp);
+ if (trim($tmp[0]))
+ $reason = $tmp[0];
+ else {
+ exec("tail -1 " . $thisbuildfinaldir . "build-time.log | grep :start: | cut -d':' -f4", $tmp);
+ if (trim($tmp[0]))
+ $reason = trim($tmp[0]);
+ else
+ $reason = "unknown";
+ }
+ }
}
/* Compress files that are typically too large and infrequently
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 26/30] scripts/autobuild-run: support changing repo
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (24 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 25/30] web/import.inc.php: support reading failure reason from reason file Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 27/30] autobuild-run: modify do_build() to accept outputdir as argument Atharva Lele
` (4 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
The current logic in prepare_build() assumes that the "origin" repo
never changes. However, if one regularly changes his autobuild-run
configuration, switching being repository, this is not
true. Currently, it requires manually wiping out the Buildroot clone
in every autobuild instance when changing the repository to pull from.
So instead, use:
git fetch <repo> <branch>
git checkout FETCH_HEAD
which will easily allow switching from one repo to the other.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
[Atharva: Adapted Thomas' patches to work with Builder class]
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
Reviewed-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
---
Changes v1 -> v2:
- Incorporate Thomas' patch into Builder class series
---
scripts/autobuild-run | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 8f60e89..09dd520 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -361,12 +361,12 @@ class Builder:
# Update the Buildroot sources.
abssrcdir = os.path.abspath(self.srcdir)
- ret = subprocess.call(["git", "fetch", "origin"], cwd=abssrcdir, stdout=self.log, stderr=self.log)
+ ret = subprocess.call(["git", "fetch", self.repo, branch], cwd=abssrcdir, stdout=self.log, stderr=self.log)
if ret != 0:
log_write(self.log, "ERROR: could not fetch Buildroot sources")
return -1
- ret = subprocess.call(["git", "checkout", "--detach", "origin/%s" % branch], cwd=abssrcdir, stdout=self.log, stderr=self.log)
+ ret = subprocess.call(["git", "checkout", "FETCH_HEAD"], cwd=abssrcdir, stdout=self.log, stderr=self.log)
if ret != 0:
log_write(self.log, "ERROR: could not check out Buildroot sources")
return -1
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 27/30] autobuild-run: modify do_build() to accept outputdir as argument
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (25 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 26/30] scripts/autobuild-run: support changing repo Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 28/30] autobuild-run: define different output directory for reproducible builds Atharva Lele
` (3 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Pass outputdir to do_build() so in future patches we can pass
different output directories to increase variance in case of
reproducibility testing.
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
---
Changes v3:
- New patch
---
scripts/autobuild-run | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 09dd520..7c05234 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -454,14 +454,14 @@ class Builder:
log_write(self.log, "INFO: Build is reproducible!")
return 0
- def do_build(self):
+ def do_build(self, outputdir):
"""Run the build itself"""
- f = open(os.path.join(self.outputdir, "logfile"), "w+")
+ f = open(os.path.join(outputdir, "logfile"), "w+")
log_write(self.log, "INFO: build started")
cmd = ["nice", "-n", str(self.nice),
- "make", "O=%s" % self.outputdir,
+ "make", "O=%s" % outputdir,
"-C", self.srcdir, "BR2_DL_DIR=%s" % self.dldir,
"BR2_JLEVEL=%s" % self.njobs] \
+ self.make_opts.split()
@@ -473,7 +473,7 @@ class Builder:
build_monitor = Thread(target=self.stop_on_build_hang,
args=(monitor_thread_hung_build_flag,
monitor_thread_stop_flag,
- sub, self.outputdir))
+ sub, outputdir))
build_monitor.daemon = True
build_monitor.start()
@@ -494,7 +494,7 @@ class Builder:
log_write(self.log, "INFO: build failed [%d]" % ret)
return -1
- cmd = ["make", "O=%s" % self.outputdir, "-C", self.srcdir,
+ cmd = ["make", "O=%s" % outputdir, "-C", self.srcdir,
"BR2_DL_DIR=%s" % self.dldir, "legal-info"] \
+ self.make_opts.split()
ret = subprocess.call(cmd, stdout=f, stderr=f)
@@ -513,7 +513,7 @@ class Builder:
# Start the first build
log_write(self.log, "INFO: Reproducible Build Test, starting build 1")
- ret = self.do_build()
+ ret = self.do_build(self.outputdir)
if ret != 0:
log_write(self.log, "INFO: build 1 failed, skipping build 2")
return ret
@@ -527,7 +527,7 @@ class Builder:
# Start the second build
log_write(self.log, "INFO: Reproducible Build Test, starting build 2")
- ret = self.do_build()
+ ret = self.do_build(self.outputdir)
if ret != 0:
log_write(self.log, "INFO: build 2 failed")
return ret
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 28/30] autobuild-run: define different output directory for reproducible builds
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (26 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 27/30] autobuild-run: modify do_build() to accept outputdir as argument Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 29/30] autobuild-run: use different output directories for reproducible builds testing Atharva Lele
` (2 subsequent siblings)
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Having different output directories will increase variance. Subsequent
patches will modify other parts of the scripts to use this directory.
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
---
Changes v3:
- New patch
---
scripts/autobuild-run | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index 7c05234..a96840f 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -278,6 +278,10 @@ class Builder:
self.outputdir = os.path.abspath(os.path.join(self.idir, "output"))
self.resultdir = os.path.join(self.outputdir, "results")
+ # We use a different output directory for more variance in reproducibility
+ # testing.
+ self.outputdir_1 = os.path.abspath(os.path.join(self.idir, "output-1"))
+
if self.debug:
self.log = sys.stdout
else:
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 29/30] autobuild-run: use different output directories for reproducible builds testing
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (27 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 28/30] autobuild-run: define different output directory for reproducible builds Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 30/30] autobuild-run: make prepare_build() clean the output directory used for reproducibility testing Atharva Lele
2019-08-01 8:39 ` [Buildroot] [PATCH v4 00/30] builder-class series cover letter Thomas Petazzoni
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
---
Changes v3:
- New patch
---
scripts/autobuild-run | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index a96840f..b32cd5b 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -434,8 +434,8 @@ class Builder:
reproducible_results = os.path.join(self.outputdir, "results", "reproducible_results")
# Using only tar images for now
- build_1_image = os.path.join(self.outputdir, "images-1", "rootfs.tar")
- build_2_image = os.path.join(self.outputdir, "images", "rootfs.tar")
+ build_1_image = os.path.join(self.outputdir, "images", "rootfs.tar")
+ build_2_image = os.path.join(self.outputdir_1, "images", "rootfs.tar")
with open(reproducible_results, 'w') as diff:
if self.sysinfo.has("diffoscope"):
@@ -522,16 +522,17 @@ class Builder:
log_write(self.log, "INFO: build 1 failed, skipping build 2")
return ret
- # First build has been built, move files and start build 2
- os.rename(os.path.join(self.outputdir, "images"), os.path.join(self.outputdir, "images-1"))
+ # Create the second output directory if it does not exist
+ if not os.path.exists(self.outputdir_1):
+ os.mkdir(self.outputdir_1)
- # Clean up build 1
- f = open(os.path.join(self.outputdir, "logfile"), "w+")
- subprocess.call(["make", "O=%s" % self.outputdir, "-C", self.srcdir, "clean"], stdout=f, stderr=f)
+ # Copy .config to the other output directory
+ shutil.copyfile(os.path.join(self.outputdir, ".config"),
+ os.path.join(self.outputdir_1, ".config"))
# Start the second build
log_write(self.log, "INFO: Reproducible Build Test, starting build 2")
- ret = self.do_build(self.outputdir)
+ ret = self.do_build(self.outputdir_1)
if ret != 0:
log_write(self.log, "INFO: build 2 failed")
return ret
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 30/30] autobuild-run: make prepare_build() clean the output directory used for reproducibility testing
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (28 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 29/30] autobuild-run: use different output directories for reproducible builds testing Atharva Lele
@ 2019-08-01 2:46 ` Atharva Lele
2019-08-01 8:39 ` [Buildroot] [PATCH v4 00/30] builder-class series cover letter Thomas Petazzoni
30 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 2:46 UTC (permalink / raw)
To: buildroot
Signed-off-by: Atharva Lele <itsatharva@gmail.com>
---
Changes v3:
- New patch
---
scripts/autobuild-run | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/scripts/autobuild-run b/scripts/autobuild-run
index b32cd5b..7fcbf2a 100755
--- a/scripts/autobuild-run
+++ b/scripts/autobuild-run
@@ -380,6 +380,10 @@ class Builder:
# shutil.rmtree doesn't remove write-protected files
subprocess.call(["rm", "-rf", self.outputdir])
os.mkdir(self.outputdir)
+
+ # If it exists, remove the other output directory used for reproducibility testing
+ if os.path.exists(self.outputdir_1):
+ subprocess.call(["rm", "-rf", self.outputdir_1])
with open(os.path.join(self.outputdir, "branch"), "w") as branchf:
branchf.write(branch)
--
2.22.0
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 00/30] builder-class series cover letter
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
` (29 preceding siblings ...)
2019-08-01 2:46 ` [Buildroot] [PATCH v4 30/30] autobuild-run: make prepare_build() clean the output directory used for reproducibility testing Atharva Lele
@ 2019-08-01 8:39 ` Thomas Petazzoni
2019-08-01 10:46 ` Atharva Lele
30 siblings, 1 reply; 33+ messages in thread
From: Thomas Petazzoni @ 2019-08-01 8:39 UTC (permalink / raw)
To: buildroot
Hello Atharva,
On Thu, 1 Aug 2019 08:16:13 +0530
Atharva Lele <itsatharva@gmail.com> wrote:
> Since various functions in the autobuilder script use a lot of common data, we
> introduce a Builder class to house these variables.
>
> I have also included modified versions of Thomas's commits after adapting them
> to work with Builder class.
>
> I created a v4 to change the order of one patch, and to delete another patch. No
> other changes have been made.
>
> RFC: Few patches, namely patches 25, 27-30 have not been reviewed yet. I'd like
> some feedback on them, if any, so that necessary modifications can be done and
> it can be merged as soon as possible.
First of all, thanks a lot for all this work! Nice refactoring of the
autobuild-run script.
I merged all patches up to patch 27, included. According to Arnout,
applying patches 28/29/30 is problematic, because builds done in
different output directories are currently not reproducible at all, so
we would simply fail *all* reproducible builds if we apply those
patches. So I believe we need to fix this before we can apply such
patches.
A small detail is that patches 28 and 29 should be squashed together:
patch 28 is only introducing a new variable pointing to the secondary
output directory, but it's not used anywhere.
Also, long term, I'd like the send_results() method to be split into
several methods. One calculating the failure reason, one deciding if
the build result should be rejected, one preparing the build results
for upload, one doing the actual upload. But please don't work on this
additional refactoring, I think it's much more important that you focus
on the reproducible build topic.
Thanks!
Thomas
--
Thomas Petazzoni, CTO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 33+ messages in thread
* [Buildroot] [PATCH v4 00/30] builder-class series cover letter
2019-08-01 8:39 ` [Buildroot] [PATCH v4 00/30] builder-class series cover letter Thomas Petazzoni
@ 2019-08-01 10:46 ` Atharva Lele
0 siblings, 0 replies; 33+ messages in thread
From: Atharva Lele @ 2019-08-01 10:46 UTC (permalink / raw)
To: buildroot
On Thursday, August 1, 2019 2:09:51 PM IST Thomas Petazzoni wrote:
> Hello Atharva,
>
> On Thu, 1 Aug 2019 08:16:13 +0530
>
> Atharva Lele <itsatharva@gmail.com> wrote:
> > Since various functions in the autobuilder script use a lot of common
> > data, we introduce a Builder class to house these variables.
> >
> > I have also included modified versions of Thomas's commits after adapting
> > them to work with Builder class.
> >
> > I created a v4 to change the order of one patch, and to delete another
> > patch. No other changes have been made.
> >
> > RFC: Few patches, namely patches 25, 27-30 have not been reviewed yet. I'd
> > like some feedback on them, if any, so that necessary modifications can
> > be done and it can be merged as soon as possible.
>
> First of all, thanks a lot for all this work! Nice refactoring of the
> autobuild-run script.
Thank you!
> I merged all patches up to patch 27, included. According to Arnout,
> applying patches 28/29/30 is problematic, because builds done in
> different output directories are currently not reproducible at all, so
> we would simply fail *all* reproducible builds if we apply those
> patches. So I believe we need to fix this before we can apply such
> patches.
Yes, correct.
> A small detail is that patches 28 and 29 should be squashed together:
> patch 28 is only introducing a new variable pointing to the secondary
> output directory, but it's not used anywhere.
OK, so once I'm done with the reproducibility fixes for different output
directories, I'll send the revised version.
> Also, long term, I'd like the send_results() method to be split into
> several methods. One calculating the failure reason, one deciding if
> the build result should be rejected, one preparing the build results
> for upload, one doing the actual upload. But please don't work on this
> additional refactoring, I think it's much more important that you focus
> on the reproducible build topic.
Of course! I'd love to work on it once majority of work on reproducible builds
is done.
> Thanks!
>
> Thomas
Thanks for merging!
Regards,
Atharva Lele
^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2019-08-01 10:46 UTC | newest]
Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-01 2:46 [Buildroot] [PATCH v4 00/30] builder-class series cover letter Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 01/30] autobuild-run: introduce Builder class Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 02/30] autobuild-run: move instance variable from kwargs to " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 03/30] autobuild-run: move njobs " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 04/30] autobuild-run: move sysinfo " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 05/30] autobuild-run: move http variables " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 06/30] autobuild-run: move submitter " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 07/30] autobuild-run: move make_opts " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 08/30] autobuild-run: move niceness " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 09/30] autobuild-run: move toolchains_csv " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 10/30] autobuild-run: move repo " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 11/30] autobuild-run: move upload variable " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 12/30] autobuild-run: move buildpid " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 13/30] autobuild-run: move debug " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 14/30] autobuild-run: define instance directory as a part of " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 15/30] autobuild-run: move log variable to " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 16/30] autobuild-run: remove kwargs argument from function calls and definitions Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 17/30] autobuild-run: define source directory as part of Builder class Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 18/30] autobuild-run: define download " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 19/30] autobuild-run: define output " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 20/30] autobuild-run: define results " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 21/30] autobuild-run: move check_version() to " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 22/30] autobuild-run: move get_branch() " Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 23/30] scripts/autobuild-run: make the HTTP URL really configurable Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 24/30] autobuild-run: create reason file on build failures Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 25/30] web/import.inc.php: support reading failure reason from reason file Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 26/30] scripts/autobuild-run: support changing repo Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 27/30] autobuild-run: modify do_build() to accept outputdir as argument Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 28/30] autobuild-run: define different output directory for reproducible builds Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 29/30] autobuild-run: use different output directories for reproducible builds testing Atharva Lele
2019-08-01 2:46 ` [Buildroot] [PATCH v4 30/30] autobuild-run: make prepare_build() clean the output directory used for reproducibility testing Atharva Lele
2019-08-01 8:39 ` [Buildroot] [PATCH v4 00/30] builder-class series cover letter Thomas Petazzoni
2019-08-01 10:46 ` Atharva Lele
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.