summaryrefslogtreecommitdiff
path: root/yocto-poky/meta/classes/toaster.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'yocto-poky/meta/classes/toaster.bbclass')
-rw-r--r--yocto-poky/meta/classes/toaster.bbclass166
1 files changed, 104 insertions, 62 deletions
diff --git a/yocto-poky/meta/classes/toaster.bbclass b/yocto-poky/meta/classes/toaster.bbclass
index d63cff532..1a70f14a9 100644
--- a/yocto-poky/meta/classes/toaster.bbclass
+++ b/yocto-poky/meta/classes/toaster.bbclass
@@ -112,27 +112,25 @@ def _toaster_load_pkgdatafile(dirpath, filepath):
pass # ignore lines without valid key: value pairs
return pkgdata
-
python toaster_package_dumpdata() {
"""
- Dumps the data created by emit_pkgdata
+ Dumps the data about the packages created by a recipe
"""
- # replicate variables from the package.bbclass
- packages = d.getVar('PACKAGES', True)
- pkgdest = d.getVar('PKGDEST', True)
+ # No need to try and dumpdata if the recipe isn't generating packages
+ if not d.getVar('PACKAGES', True):
+ return
pkgdatadir = d.getVar('PKGDESTWORK', True)
-
- # scan and send data for each package
-
lpkgdata = {}
- for pkg in packages.split():
-
- lpkgdata = _toaster_load_pkgdatafile(pkgdatadir + "/runtime/", pkg)
-
- # Fire an event containing the pkg data
- bb.event.fire(bb.event.MetadataEvent("SinglePackageInfo", lpkgdata), d)
+ datadir = os.path.join(pkgdatadir, 'runtime')
+
+ # scan and send data for each generated package
+ for datafile in os.listdir(datadir):
+ if not datafile.endswith('.packaged'):
+ lpkgdata = _toaster_load_pkgdatafile(datadir, datafile)
+ # Fire an event containing the pkg data
+ bb.event.fire(bb.event.MetadataEvent("SinglePackageInfo", lpkgdata), d)
}
# 2. Dump output image files information
@@ -143,35 +141,55 @@ python toaster_image_dumpdata() {
image_types.bbclass will spell out IMAGE_CMD_xxx variables that actually
have hardcoded ways to create image file names in them.
So we look for files starting with the set name.
+
+ We also look for other files in the images/ directory which don't
+ match IMAGE_NAME, such as the kernel bzImage, modules tarball etc.
"""
- deploy_dir_image = d.getVar('DEPLOY_DIR_IMAGE', True);
+ dir_to_walk = d.getVar('DEPLOY_DIR_IMAGE', True);
image_name = d.getVar('IMAGE_NAME', True);
-
image_info_data = {}
artifact_info_data = {}
- # collect all artifacts
- for dirpath, dirnames, filenames in os.walk(deploy_dir_image):
- for fn in filenames:
+ # collect all images and artifacts in the images directory
+ for dirpath, dirnames, filenames in os.walk(dir_to_walk):
+ for filename in filenames:
+ full_path = os.path.join(dirpath, filename)
try:
- if fn.startswith(image_name):
- image_output = os.path.join(dirpath, fn)
- image_info_data[image_output] = os.stat(image_output).st_size
+ if filename.startswith(image_name):
+ # image
+ image_info_data[full_path] = os.stat(full_path).st_size
else:
- import stat
- artifact_path = os.path.join(dirpath, fn)
- filestat = os.stat(artifact_path)
- if not os.path.islink(artifact_path):
- artifact_info_data[artifact_path] = filestat.st_size
+ # other non-image artifact
+ if not os.path.islink(full_path):
+ artifact_info_data[full_path] = os.stat(full_path).st_size
except OSError as e:
bb.event.fire(bb.event.MetadataEvent("OSErrorException", e), d)
- bb.event.fire(bb.event.MetadataEvent("ImageFileSize",image_info_data), d)
- bb.event.fire(bb.event.MetadataEvent("ArtifactFileSize",artifact_info_data), d)
+ bb.event.fire(bb.event.MetadataEvent("ImageFileSize", image_info_data), d)
+ bb.event.fire(bb.event.MetadataEvent("ArtifactFileSize", artifact_info_data), d)
}
+python toaster_artifact_dumpdata() {
+ """
+ Dump data about artifacts in the SDK_DEPLOY directory
+ """
+
+ dir_to_walk = d.getVar("SDK_DEPLOY", True)
+ artifact_info_data = {}
+
+ # collect all artifacts in the sdk directory
+ for dirpath, dirnames, filenames in os.walk(dir_to_walk):
+ for filename in filenames:
+ full_path = os.path.join(dirpath, filename)
+ try:
+ if not os.path.islink(full_path):
+ artifact_info_data[full_path] = os.stat(full_path).st_size
+ except OSError as e:
+ bb.event.fire(bb.event.MetadataEvent("OSErrorException", e), d)
+ bb.event.fire(bb.event.MetadataEvent("ArtifactFileSize", artifact_info_data), d)
+}
# collect list of buildstats files based on fired events; when the build completes, collect all stats and fire an event with collected data
@@ -182,29 +200,37 @@ python toaster_collect_task_stats() {
import bb.utils
import os
+ toaster_statlist_file = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), "toasterstatlist")
+
if not e.data.getVar('BUILDSTATS_BASE', True):
return # if we don't have buildstats, we cannot collect stats
+ def stat_to_float(value):
+ return float(value.strip('% \n\r'))
+
def _append_read_list(v):
lock = bb.utils.lockfile(e.data.expand("${TOPDIR}/toaster.lock"), False, True)
- with open(os.path.join(e.data.getVar('BUILDSTATS_BASE', True), "toasterstatlist"), "a") as fout:
- bn = get_bn(e)
- bsdir = os.path.join(e.data.getVar('BUILDSTATS_BASE', True), bn)
- taskdir = os.path.join(bsdir, e.data.expand("${PF}"))
+ with open(toaster_statlist_file, "a") as fout:
+ taskdir = e.data.expand("${BUILDSTATS_BASE}/${BUILDNAME}/${PF}")
fout.write("%s::%s::%s::%s\n" % (e.taskfile, e.taskname, os.path.join(taskdir, e.task), e.data.expand("${PN}")))
bb.utils.unlockfile(lock)
def _read_stats(filename):
- cpu_usage = 0
- disk_io = 0
- startio = '0'
- endio = '0'
- started = '0'
- ended = '0'
- pn = ''
+ # seconds
+ cpu_time_user = 0
+ cpu_time_system = 0
+
+ # bytes
+ disk_io_read = 0
+ disk_io_write = 0
+
+ started = 0
+ ended = 0
+
taskname = ''
+
statinfo = {}
with open(filename, 'r') as task_bs:
@@ -212,43 +238,49 @@ python toaster_collect_task_stats() {
k,v = line.strip().split(": ", 1)
statinfo[k] = v
- if "CPU usage" in statinfo:
- cpu_usage = str(statinfo["CPU usage"]).strip('% \n\r')
-
- if "EndTimeIO" in statinfo:
- endio = str(statinfo["EndTimeIO"]).strip('% \n\r')
-
- if "StartTimeIO" in statinfo:
- startio = str(statinfo["StartTimeIO"]).strip('% \n\r')
-
if "Started" in statinfo:
- started = str(statinfo["Started"]).strip('% \n\r')
+ started = stat_to_float(statinfo["Started"])
if "Ended" in statinfo:
- ended = str(statinfo["Ended"]).strip('% \n\r')
+ ended = stat_to_float(statinfo["Ended"])
- disk_io = int(endio) - int(startio)
+ if "Child rusage ru_utime" in statinfo:
+ cpu_time_user = cpu_time_user + stat_to_float(statinfo["Child rusage ru_utime"])
- elapsed_time = float(ended) - float(started)
+ if "Child rusage ru_stime" in statinfo:
+ cpu_time_system = cpu_time_system + stat_to_float(statinfo["Child rusage ru_stime"])
- cpu_usage = float(cpu_usage)
+ if "IO write_bytes" in statinfo:
+ write_bytes = int(statinfo["IO write_bytes"].strip('% \n\r'))
+ disk_io_write = disk_io_write + write_bytes
- return {'cpu_usage': cpu_usage, 'disk_io': disk_io, 'elapsed_time': elapsed_time}
+ if "IO read_bytes" in statinfo:
+ read_bytes = int(statinfo["IO read_bytes"].strip('% \n\r'))
+ disk_io_read = disk_io_read + read_bytes
+ return {
+ 'stat_file': filename,
+ 'cpu_time_user': cpu_time_user,
+ 'cpu_time_system': cpu_time_system,
+ 'disk_io_read': disk_io_read,
+ 'disk_io_write': disk_io_write,
+ 'started': started,
+ 'ended': ended
+ }
if isinstance(e, (bb.build.TaskSucceeded, bb.build.TaskFailed)):
_append_read_list(e)
pass
-
- if isinstance(e, bb.event.BuildCompleted) and os.path.exists(os.path.join(e.data.getVar('BUILDSTATS_BASE', True), "toasterstatlist")):
+ if isinstance(e, bb.event.BuildCompleted) and os.path.exists(toaster_statlist_file):
events = []
- with open(os.path.join(e.data.getVar('BUILDSTATS_BASE', True), "toasterstatlist"), "r") as fin:
+ with open(toaster_statlist_file, "r") as fin:
for line in fin:
(taskfile, taskname, filename, recipename) = line.strip().split("::")
- events.append((taskfile, taskname, _read_stats(filename), recipename))
+ stats = _read_stats(filename)
+ events.append((taskfile, taskname, stats, recipename))
bb.event.fire(bb.event.MetadataEvent("BuildStatsList", events), e.data)
- os.unlink(os.path.join(e.data.getVar('BUILDSTATS_BASE', True), "toasterstatlist"))
+ os.unlink(toaster_statlist_file)
}
# dump relevant build history data as an event when the build is completed
@@ -265,6 +297,7 @@ python toaster_buildhistory_dump() {
allpkgs = {}
files = {}
for target in e._pkgs:
+ target = target.split(':')[0] # strip ':<task>' suffix from the target
installed_img_path = e.data.expand(os.path.join(BUILDHISTORY_DIR_IMAGE_BASE, target))
if os.path.exists(installed_img_path):
images[target] = {}
@@ -347,9 +380,18 @@ toaster_collect_task_stats[eventmask] = "bb.event.BuildCompleted bb.build.TaskSu
addhandler toaster_buildhistory_dump
toaster_buildhistory_dump[eventmask] = "bb.event.BuildCompleted"
+
+do_packagedata_setscene[postfuncs] += "toaster_package_dumpdata "
+do_packagedata_setscene[vardepsexclude] += "toaster_package_dumpdata "
+
do_package[postfuncs] += "toaster_package_dumpdata "
do_package[vardepsexclude] += "toaster_package_dumpdata "
-do_rootfs[postfuncs] += "toaster_image_dumpdata "
+do_image_complete[postfuncs] += "toaster_image_dumpdata "
+do_image_complete[vardepsexclude] += "toaster_image_dumpdata "
+
do_rootfs[postfuncs] += "toaster_licensemanifest_dump "
-do_rootfs[vardepsexclude] += "toaster_image_dumpdata toaster_licensemanifest_dump"
+do_rootfs[vardepsexclude] += "toaster_licensemanifest_dump "
+
+do_populate_sdk[postfuncs] += "toaster_artifact_dumpdata "
+do_populate_sdk[vardepsexclude] += "toaster_artifact_dumpdata "