diff options
Diffstat (limited to 'yocto-poky/meta/classes/toaster.bbclass')
-rw-r--r-- | yocto-poky/meta/classes/toaster.bbclass | 166 |
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 " |