diff options
| -rw-r--r-- | meta/classes/base.bbclass | 1 | ||||
| -rw-r--r-- | meta/classes/buildstats.bbclass | 194 | ||||
| -rw-r--r-- | meta/recipes-connectivity/gypsy/gypsy_git.bb | 15 | ||||
| -rw-r--r-- | meta/recipes-connectivity/gypsy/gypsy_svn.bb | 9 |
4 files changed, 210 insertions, 9 deletions
diff --git a/meta/classes/base.bbclass b/meta/classes/base.bbclass index e4ea69d481..a674f52fb2 100644 --- a/meta/classes/base.bbclass +++ b/meta/classes/base.bbclass | |||
| @@ -7,6 +7,7 @@ inherit mirrors | |||
| 7 | inherit utils | 7 | inherit utils |
| 8 | inherit utility-tasks | 8 | inherit utility-tasks |
| 9 | inherit metadata_scm | 9 | inherit metadata_scm |
| 10 | inherit buildstats | ||
| 10 | 11 | ||
| 11 | python sys_path_eh () { | 12 | python sys_path_eh () { |
| 12 | if isinstance(e, bb.event.ConfigParsed): | 13 | if isinstance(e, bb.event.ConfigParsed): |
diff --git a/meta/classes/buildstats.bbclass b/meta/classes/buildstats.bbclass new file mode 100644 index 0000000000..f57d018060 --- /dev/null +++ b/meta/classes/buildstats.bbclass | |||
| @@ -0,0 +1,194 @@ | |||
| 1 | BUILDSTATS_BASE = ${TMPDIR}/buildstats/ | ||
| 2 | BNFILE = ${BUILDSTATS_BASE}/.buildname | ||
| 3 | |||
| 4 | ################################################################################ | ||
| 5 | # Build statistics gathering. | ||
| 6 | # | ||
| 7 | # The CPU and Time gathering/tracking functions and bbevent inspiration | ||
| 8 | # were written by Christopher Larson and can be seen here: | ||
| 9 | # http://kergoth.pastey.net/142813 | ||
| 10 | # | ||
| 11 | ################################################################################ | ||
| 12 | |||
| 13 | def get_process_cputime(pid): | ||
| 14 | fields = open("/proc/%d/stat" % pid, "r").readline().rstrip().split() | ||
| 15 | # 13: utime, 14: stime, 15: cutime, 16: cstime | ||
| 16 | return sum(int(field) for field in fields[13:16]) | ||
| 17 | |||
| 18 | def get_cputime(): | ||
| 19 | fields = open("/proc/stat", "r").readline().rstrip().split()[1:] | ||
| 20 | return sum(int(field) for field in fields) | ||
| 21 | |||
| 22 | def set_timedata(var, data): | ||
| 23 | import time | ||
| 24 | |||
| 25 | time = time.time() | ||
| 26 | cputime = get_cputime() | ||
| 27 | proctime = get_process_cputime(os.getpid()) | ||
| 28 | data.setVar(var, (time, cputime, proctime)) | ||
| 29 | |||
| 30 | def get_timedata(var, data): | ||
| 31 | import time | ||
| 32 | timedata = data.getVar(var, False) | ||
| 33 | if timedata is None: | ||
| 34 | return | ||
| 35 | oldtime, oldcpu, oldproc = timedata | ||
| 36 | procdiff = get_process_cputime(os.getpid()) - oldproc | ||
| 37 | cpudiff = get_cputime() - oldcpu | ||
| 38 | timediff = time.time() - oldtime | ||
| 39 | if cpudiff > 0: | ||
| 40 | cpuperc = float(procdiff) * 100 / cpudiff | ||
| 41 | else: | ||
| 42 | cpuperc = None | ||
| 43 | return timediff, cpuperc | ||
| 44 | |||
| 45 | ############################################## | ||
| 46 | # We need to set the buildname to a file since | ||
| 47 | # BUILDNAME changes throughout a build | ||
| 48 | ############################################## | ||
| 49 | |||
| 50 | def set_bn(e): | ||
| 51 | bn = e.getPkgs()[0] + "-" + bb.data.getVar('MACHINE',e.data, True) | ||
| 52 | try: | ||
| 53 | os.remove(bb.data.getVar('BNFILE',e.data, True)) | ||
| 54 | except: | ||
| 55 | pass | ||
| 56 | file = open(bb.data.getVar('BNFILE',e.data, True), "w") | ||
| 57 | file.write(os.path.join(bn, bb.data.getVar('BUILDNAME', e.data, True))) | ||
| 58 | file.close() | ||
| 59 | |||
| 60 | def get_bn(e): | ||
| 61 | file = open(bb.data.getVar('BNFILE',e.data, True)) | ||
| 62 | bn = file.readline() | ||
| 63 | file.close() | ||
| 64 | return bn | ||
| 65 | |||
| 66 | python run_buildstats () { | ||
| 67 | import bb.build | ||
| 68 | import bb.event | ||
| 69 | import bb.data | ||
| 70 | import time, subprocess | ||
| 71 | |||
| 72 | if isinstance(e, bb.event.BuildStarted): | ||
| 73 | ############################################## | ||
| 74 | # at first pass make the buildstats heriarchy and then | ||
| 75 | # set the buildname | ||
| 76 | ############################################## | ||
| 77 | try: | ||
| 78 | bb.mkdirhier(bb.data.getVar('BUILDSTATS_BASE', e.data, True)) | ||
| 79 | except: | ||
| 80 | pass | ||
| 81 | set_bn(e) | ||
| 82 | bn = get_bn(e) | ||
| 83 | bb.warn(bn) | ||
| 84 | bsdir = os.path.join(bb.data.getVar('BUILDSTATS_BASE', e.data, True), bn) | ||
| 85 | try: | ||
| 86 | bb.mkdirhier(bsdir) | ||
| 87 | except: | ||
| 88 | pass | ||
| 89 | set_timedata("__timedata_build", e.data) | ||
| 90 | build_time = os.path.join(bsdir, "build_stats") | ||
| 91 | # write start of build into build_time | ||
| 92 | file = open(build_time,"a") | ||
| 93 | # We do this here because subprocess within BuildStarted is messy | ||
| 94 | host_info = subprocess.Popen(["uname", "-a"], stdout=subprocess.PIPE).stdout.read() | ||
| 95 | file.write("Host Info: %s" % host_info) | ||
| 96 | file.write("Build Started: %0.2f \n" % time.time()) | ||
| 97 | file.close() | ||
| 98 | |||
| 99 | elif isinstance(e, bb.event.BuildCompleted): | ||
| 100 | bn=get_bn(e) | ||
| 101 | timedata = get_timedata("__timedata_build", e.data) | ||
| 102 | if not timedata: | ||
| 103 | return | ||
| 104 | time, cpu = timedata | ||
| 105 | bsdir = os.path.join(bb.data.getVar('BUILDSTATS_BASE', e.data, True), bn) | ||
| 106 | build_time = os.path.join(bsdir, "build_stats") | ||
| 107 | # write end of build and cpu used into build_time | ||
| 108 | file = open(build_time, "a") | ||
| 109 | file.write("Elapsed time: %0.2f seconds \n" % (time)) | ||
| 110 | if cpu: | ||
| 111 | file.write("CPU usage: %0.1f%% \n" % cpu) | ||
| 112 | file.close() | ||
| 113 | |||
| 114 | |||
| 115 | if isinstance(e, bb.build.TaskStarted): | ||
| 116 | bn=get_bn(e) | ||
| 117 | set_timedata("__timedata_task", e.data) | ||
| 118 | |||
| 119 | bsdir = os.path.join(bb.data.getVar('BUILDSTATS_BASE', e.data, True), bn) | ||
| 120 | taskdir = os.path.join(bsdir, bb.data.expand("${PF}", e.data)) | ||
| 121 | try: | ||
| 122 | bb.mkdirhier(taskdir) | ||
| 123 | except: | ||
| 124 | pass | ||
| 125 | # write into the task event file the name and start time | ||
| 126 | file = open(os.path.join(taskdir, e.task), "a") | ||
| 127 | file.write("Event: %s \n" % bb.event.getName(e)) | ||
| 128 | file.write("Started: %0.2f \n" % time.time()) | ||
| 129 | file.close() | ||
| 130 | |||
| 131 | elif isinstance(e, bb.build.TaskSucceeded): | ||
| 132 | bn=get_bn(e) | ||
| 133 | timedata = get_timedata("__timedata_task", e.data) | ||
| 134 | if not timedata: | ||
| 135 | return | ||
| 136 | time, cpu = timedata | ||
| 137 | bsdir = os.path.join(bb.data.getVar('BUILDSTATS_BASE', e.data, True), bn) | ||
| 138 | taskdir = os.path.join(bsdir, bb.data.expand("${PF}", e.data)) | ||
| 139 | file = open(os.path.join(taskdir, e.task), "a") | ||
| 140 | file.write(bb.data.expand("${PF}: %s: Elapsed time: %0.2f seconds \n" % | ||
| 141 | (e.task, time), e.data)) | ||
| 142 | if cpu: | ||
| 143 | file.write("CPU usage: %0.1f%% \n" % cpu) | ||
| 144 | |||
| 145 | file.write("Status: PASSED") | ||
| 146 | file.close() | ||
| 147 | |||
| 148 | ############################################## | ||
| 149 | # Alot of metric gathering occurs here. | ||
| 150 | # Reminder: I stripped out some in process stuff here | ||
| 151 | ############################################## | ||
| 152 | |||
| 153 | if e.task == "do_rootfs": | ||
| 154 | bs=os.path.join(bsdir, "build_stats") | ||
| 155 | file = open(bs,"a") | ||
| 156 | rootfs = bb.data.getVar('IMAGE_ROOTFS', e.data, True) | ||
| 157 | rootfs_size = subprocess.Popen(["du", "-sh", rootfs], stdout=subprocess.PIPE).stdout.read() | ||
| 158 | file.write("Uncompressed Rootfs size: %s" % rootfs_size) | ||
| 159 | file.close() | ||
| 160 | |||
| 161 | elif isinstance(e, bb.build.TaskFailed): | ||
| 162 | bn=get_bn(e) | ||
| 163 | timedata = get_timedata("__timedata_task", e.data) | ||
| 164 | if not timedata: | ||
| 165 | return | ||
| 166 | time, cpu = timedata | ||
| 167 | bsdir = os.path.join(bb.data.getVar('BUILDSTATS_BASE', e.data, True), bn) | ||
| 168 | taskdir = os.path.join(bsdir, bb.data.expand("${PF}", e.data)) | ||
| 169 | ############################################## | ||
| 170 | # If the task fails dump the regular data. | ||
| 171 | # fgrep -R "FAILED" <bsdir> | ||
| 172 | # will grep all the events that failed. | ||
| 173 | ############################################## | ||
| 174 | file = open(os.path.join(taskdir, e.task), "a") | ||
| 175 | file.write(bb.data.expand("${PF}: %s: Elapsed time: %0.2f seconds \n" % | ||
| 176 | (e.task, time), e.data)) | ||
| 177 | if cpu: | ||
| 178 | file.write("CPU usage: %0.1f%% \n" % cpu) | ||
| 179 | file.write("Status: FAILED") | ||
| 180 | file.close() | ||
| 181 | ############################################## | ||
| 182 | # Lets make things easier and tell people where the build failed in build_status | ||
| 183 | # We do this here because BuildCompleted triggers no matter what the status of the | ||
| 184 | # build actually is | ||
| 185 | ############################################## | ||
| 186 | build_status = os.path.join(bsdir, "build_stats") | ||
| 187 | file = open(build_status,"a") | ||
| 188 | file.write(bb.data.expand("Failed at: ${PF} at task: %s \n", e.task)) | ||
| 189 | file.close() | ||
| 190 | |||
| 191 | } | ||
| 192 | |||
| 193 | addhandler run_buildstats | ||
| 194 | |||
diff --git a/meta/recipes-connectivity/gypsy/gypsy_git.bb b/meta/recipes-connectivity/gypsy/gypsy_git.bb new file mode 100644 index 0000000000..13572404e6 --- /dev/null +++ b/meta/recipes-connectivity/gypsy/gypsy_git.bb | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | require gypsy.inc | ||
| 2 | |||
| 3 | DEFAULT_PREFERENCE = "-1" | ||
| 4 | |||
| 5 | PV = "0.8+git${SRCPV}" | ||
| 6 | S = "${WORKDIR}/git" | ||
| 7 | |||
| 8 | LICENSE = "GPLv2+ & LGPLv2+" | ||
| 9 | LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe \ | ||
| 10 | file://COPYING.lib;md5=7fbc338309ac38fefcd64b04bb903e34 \ | ||
| 11 | file://src/main.c;beginline=1;endline=25;md5=3fe64e27e61b289b77383a54a982cbdd \ | ||
| 12 | file://gypsy/gypsy-time.h;beginline=1;endline=24;md5=06432ea19a7b6607428d04d9dadc37fd" | ||
| 13 | |||
| 14 | SRC_URI = "git://anongit.freedesktop.org/gypsy;protocol=git \ | ||
| 15 | file://fixups.patch;patch=1" | ||
diff --git a/meta/recipes-connectivity/gypsy/gypsy_svn.bb b/meta/recipes-connectivity/gypsy/gypsy_svn.bb deleted file mode 100644 index 2e9840afd3..0000000000 --- a/meta/recipes-connectivity/gypsy/gypsy_svn.bb +++ /dev/null | |||
| @@ -1,9 +0,0 @@ | |||
| 1 | require gypsy.inc | ||
| 2 | |||
| 3 | DEFAULT_PREFERENCE = "-1" | ||
| 4 | |||
| 5 | PV = "0.0+svnr${SRCPV}" | ||
| 6 | S = "${WORKDIR}/${PN}" | ||
| 7 | |||
| 8 | SRC_URI = "svn://svn.o-hand.com/repos/${PN}/trunk;module=${PN};proto=http \ | ||
| 9 | file://fixups.patch;patch=1" | ||
