summaryrefslogtreecommitdiffstats
path: root/meta/classes/workdir_save.bbclass
blob: 70070419a84c6cf046b18c8ffc54e84d661c22d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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))
}