diff options
Diffstat (limited to 'meta')
-rw-r--r-- | meta/classes/workdir_save.bbclass | 54 |
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)) +} |