summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.microsoft.com>2020-07-08 10:57:39 -0700
committerPaul Eggleton <paul.eggleton@linux.microsoft.com>2020-07-08 10:57:59 -0700
commit8a17db382b6b7fde9d5dddebb0fc410dc35b5088 (patch)
treed568b3695b9ecee076d8e517ac95f4f15ad7ef03
parentb3c96103a5063eeefb0c537227eab3f77616b9c0 (diff)
downloadopenembedded-core-contrib-paule/workdir_save.tar.gz
classes: add workdir_save classpaule/workdir_save
If you are running your builds inside an environment where you don't have access to the build tree (e.g. an autobuilder where you can only download final artifacts such as images), then debugging build failures can be difficult - you can't examine log files, the source tree or output files. When enabled, this class triggers on task failure and saves a tarball of the work directory for the task's recipe and puts it in a configurable location, where it can be picked up by a separate process and made available as a downloadable artifact. Signed-off-by: Paul Eggleton <paul.eggleton@linux.microsoft.com>
-rw-r--r--meta/classes/workdir_save.bbclass54
1 files changed, 54 insertions, 0 deletions
diff --git a/meta/classes/workdir_save.bbclass b/meta/classes/workdir_save.bbclass
new file mode 100644
index 0000000000..70070419a8
--- /dev/null
+++ b/meta/classes/workdir_save.bbclass
@@ -0,0 +1,54 @@
+# Save the work directory for a recipe when one of its tasks fails.
+# Useful in cases where the environment in which builds are run is
+# ephemeral or otherwise inaccessible for examination during
+# debugging.
+#
+# To enable, simply add the following to your configuration:
+#
+# INHERIT += "workdir_save"
+#
+# Notes:
+# * For this to work you also need corresponding logic in your build
+# orchestration tool to pick up any files written out to WORKDIR_SAVE_DIR
+# (with the other assumption being that no files are present there at
+# the start of the build).
+# * Work directories can be quite large, so saving them can take some time
+# and of course space.
+#
+# Copyright (c) 2020 Microsoft Corporation
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+
+WORKDIR_SAVE_DIR ?= "${TMPDIR}/workdir_save"
+WORKDIR_SAVE_ENABLED ?= "1"
+
+addhandler workdir_save_handler
+workdir_save_handler[eventmask] = "bb.build.TaskFailed"
+
+python workdir_save_handler() {
+ import datetime
+ if d.getVar('WORKDIR_SAVE_ENABLED') != '1':
+ return
+
+ base_workdir = d.getVar('BASE_WORKDIR')
+ workdir = d.getVar('WORKDIR')
+ outdir = d.getVar('WORKDIR_SAVE_DIR')
+ bb.utils.mkdirhier(outdir)
+ pn = d.getVar('PN')
+ tstamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
+ tarfn = 'workdir_%s_%s.tar.gz' % (pn, tstamp)
+ tarfp = os.path.join(outdir, tarfn)
+ taskname = d.getVar('BB_CURRENTTASK')
+ bb.plain('NOTE: Saving workdir for failed task %s.do_%s to %s' % (pn, taskname, tarfp))
+ try:
+ bb.process.run(['tar', 'czf', tarfp,
+ os.path.relpath(workdir, base_workdir)], cwd=base_workdir)
+ except bb.process.ExecutionError as e:
+ # It is possible for other tasks to be writing to the workdir
+ # while we are tarring it up, in which case tar will return 1,
+ # but we don't care in this situation (tar returns 2 for other
+ # errors so we we will see those)
+ if e.exitcode != 1:
+ bb.warn('workdir save error: %s' % str(e))
+}