summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2015-07-10 14:51:40 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-07-12 22:50:40 +0100
commit3b5031230717d7430951dfa4a148b7f83bad514b (patch)
tree8e5a487c2498ed49e1a28d7acc94e964e7d7a3ba
parent8f8d3362b8631aa6d09f1ef9df5111ba7ce10f85 (diff)
downloadpoky-3b5031230717d7430951dfa4a148b7f83bad514b.tar.gz
bitbake: lib/bb: set up infrastructure for shell message functions
Create a fifo under ${T} for each running task that can be used by the task to send events back to BitBake. The purpose of this is to allow OpenEmbedded's logging.bbclass (which provides shell function equivalents for bb.warn(), bb.note() etc.) to have those functions trigger the appropriate events within BitBake so that messages are shown through the BitBake UI rather than just in the task log; to do that we just call the python functions. Part of the fix for [YOCTO #5275]. (Bitbake rev: bae330a1f8a59a912eca71177b3c6ba7c92a2f38) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/bb/build.py50
-rw-r--r--bitbake/lib/bb/process.py25
2 files changed, 65 insertions, 10 deletions
diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py
index 14dc5e0619..cce01feba2 100644
--- a/bitbake/lib/bb/build.py
+++ b/bitbake/lib/bb/build.py
@@ -329,14 +329,50 @@ exit $?
329 else: 329 else:
330 logfile = sys.stdout 330 logfile = sys.stdout
331 331
332 bb.debug(2, "Executing shell function %s" % func) 332 def readfifo(data):
333 lines = data.split('\0')
334 for line in lines:
335 splitval = line.split(' ', 1)
336 cmd = splitval[0]
337 if len(splitval) > 1:
338 value = splitval[1]
339 else:
340 value = ''
341 if cmd == 'bbplain':
342 bb.plain(value)
343 elif cmd == 'bbnote':
344 bb.note(value)
345 elif cmd == 'bbwarn':
346 bb.warn(value)
347 elif cmd == 'bberror':
348 bb.error(value)
349 elif cmd == 'bbfatal':
350 # The caller will call exit themselves, so bb.error() is
351 # what we want here rather than bb.fatal()
352 bb.error(value)
353 elif cmd == 'bbdebug':
354 splitval = value.split(' ', 1)
355 level = int(splitval[0])
356 value = splitval[1]
357 bb.debug(level, value)
333 358
334 try: 359 tempdir = d.getVar('T', True)
335 with open(os.devnull, 'r+') as stdin: 360 fifopath = os.path.join(tempdir, 'fifo.%s' % os.getpid())
336 bb.process.run(cmd, shell=False, stdin=stdin, log=logfile) 361 if os.path.exists(fifopath):
337 except bb.process.CmdError: 362 os.unlink(fifopath)
338 logfn = d.getVar('BB_LOGFILE', True) 363 os.mkfifo(fifopath)
339 raise FuncFailed(func, logfn) 364 with open(fifopath, 'r+') as fifo:
365 try:
366 bb.debug(2, "Executing shell function %s" % func)
367
368 try:
369 with open(os.devnull, 'r+') as stdin:
370 bb.process.run(cmd, shell=False, stdin=stdin, log=logfile, extrafiles=[(fifo,readfifo)])
371 except bb.process.CmdError:
372 logfn = d.getVar('BB_LOGFILE', True)
373 raise FuncFailed(func, logfn)
374 finally:
375 os.unlink(fifopath)
340 376
341 bb.debug(2, "Shell function %s finished" % func) 377 bb.debug(2, "Shell function %s finished" % func)
342 378
diff --git a/bitbake/lib/bb/process.py b/bitbake/lib/bb/process.py
index 8b1aea9a10..d95a03d176 100644
--- a/bitbake/lib/bb/process.py
+++ b/bitbake/lib/bb/process.py
@@ -64,7 +64,7 @@ class Popen(subprocess.Popen):
64 options.update(kwargs) 64 options.update(kwargs)
65 subprocess.Popen.__init__(self, *args, **options) 65 subprocess.Popen.__init__(self, *args, **options)
66 66
67def _logged_communicate(pipe, log, input): 67def _logged_communicate(pipe, log, input, extrafiles):
68 if pipe.stdin: 68 if pipe.stdin:
69 if input is not None: 69 if input is not None:
70 pipe.stdin.write(input) 70 pipe.stdin.write(input)
@@ -79,6 +79,19 @@ def _logged_communicate(pipe, log, input):
79 if pipe.stderr is not None: 79 if pipe.stderr is not None:
80 bb.utils.nonblockingfd(pipe.stderr.fileno()) 80 bb.utils.nonblockingfd(pipe.stderr.fileno())
81 rin.append(pipe.stderr) 81 rin.append(pipe.stderr)
82 for fobj, _ in extrafiles:
83 bb.utils.nonblockingfd(fobj.fileno())
84 rin.append(fobj)
85
86 def readextras():
87 for fobj, func in extrafiles:
88 try:
89 data = fobj.read()
90 except IOError as err:
91 if err.errno == errno.EAGAIN or err.errno == errno.EWOULDBLOCK:
92 data = None
93 if data is not None:
94 func(data)
82 95
83 try: 96 try:
84 while pipe.poll() is None: 97 while pipe.poll() is None:
@@ -100,15 +113,21 @@ def _logged_communicate(pipe, log, input):
100 if data is not None: 113 if data is not None:
101 errdata.append(data) 114 errdata.append(data)
102 log.write(data) 115 log.write(data)
116
117 readextras()
118
103 finally: 119 finally:
104 log.flush() 120 log.flush()
121
122 readextras()
123
105 if pipe.stdout is not None: 124 if pipe.stdout is not None:
106 pipe.stdout.close() 125 pipe.stdout.close()
107 if pipe.stderr is not None: 126 if pipe.stderr is not None:
108 pipe.stderr.close() 127 pipe.stderr.close()
109 return ''.join(outdata), ''.join(errdata) 128 return ''.join(outdata), ''.join(errdata)
110 129
111def run(cmd, input=None, log=None, **options): 130def run(cmd, input=None, log=None, extrafiles=[], **options):
112 """Convenience function to run a command and return its output, raising an 131 """Convenience function to run a command and return its output, raising an
113 exception when the command fails""" 132 exception when the command fails"""
114 133
@@ -124,7 +143,7 @@ def run(cmd, input=None, log=None, **options):
124 raise CmdError(cmd, exc) 143 raise CmdError(cmd, exc)
125 144
126 if log: 145 if log:
127 stdout, stderr = _logged_communicate(pipe, log, input) 146 stdout, stderr = _logged_communicate(pipe, log, input, extrafiles)
128 else: 147 else:
129 stdout, stderr = pipe.communicate(input) 148 stdout, stderr = pipe.communicate(input)
130 149