def create_progress_handler(func, progress, logfile, d): if progress == 'percent': # Use default regex return bb.progress.BasicProgressHandler(d, outfile=logfile) elif progress.startswith('percent:'): # Use specified regex return bb.progress.BasicProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile) elif progress.startswith('outof:'): # Use specified regex return bb.progress.OutOfProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile) elif progress.startswith("custom:"): # Use a custom progress handler that was injected via OE_EXTRA_IMPORTS or __builtins__ import functools from types import ModuleType parts = progress.split(":", 2) _, cls, otherargs = parts[0], parts[1], (parts[2] or None) if parts[2:] else None if cls: def resolve(x, y): if not x: return None if isinstance(x, ModuleType): return getattr(x, y, None) return x.get(y) cls_obj = functools.reduce(resolve, cls.split("."), bb.utils._context) if not cls_obj: # Fall-back on __builtins__ cls_obj = functools.reduce(resolve, cls.split("."), __builtins__) if cls_obj: return cls_obj(d, outfile=logfile, otherargs=otherargs) bb.warn('%s: unknown custom progress handler in task progress varflag value "%s", ignoring' % (func, cls)) else: bb.warn('%s: invalid task progress varflag value "%s", ignoring' % (func, progress)) return logfile
def exec_func_shell(func, d, runfile, cwd=None): """Execute a shell function from the metadata Note on directory behavior. The 'dirs' varflag should contain a list of the directories you need created prior to execution. The last item in the list is where we will chdir/cd to. """ # Don't let the emitted shell script override PWD d.delVarFlag('PWD', 'export') with open(runfile, 'w') as script: script.write(shell_trap_code()) bb.data.emit_func(func, script, d) if bb.msg.loggerVerboseLogs: script.write("set -x\n") if cwd: script.write("cd '%s'\n" % cwd) script.write("%s\n" % func) script.write(''' # cleanup ret=$? trap '' 0 exit $ret ''') os.chmod(runfile, 0o775) cmd = runfile if d.getVarFlag(func, 'fakeroot', False): fakerootcmd = d.getVar('FAKEROOT') if fakerootcmd: cmd = [fakerootcmd, runfile] if bb.msg.loggerDefaultVerbose: logfile = LogTee(logger, sys.stdout) else: logfile = sys.stdout progress = d.getVarFlag(func, 'progress') if progress: if progress == 'percent': # Use default regex logfile = bb.progress.BasicProgressHandler(d, outfile=logfile) elif progress.startswith('percent:'): # Use specified regex logfile = bb.progress.BasicProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile) elif progress.startswith('outof:'): # Use specified regex logfile = bb.progress.OutOfProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile) else: bb.warn('%s: invalid task progress varflag value "%s", ignoring' % (func, progress)) fifobuffer = bytearray() def readfifo(data): nonlocal fifobuffer fifobuffer.extend(data) while fifobuffer: message, token, nextmsg = fifobuffer.partition(b"\00") if token: splitval = message.split(b' ', 1) cmd = splitval[0].decode("utf-8") if len(splitval) > 1: value = splitval[1].decode("utf-8") else: value = '' if cmd == 'bbplain': bb.plain(value) elif cmd == 'bbnote': bb.note(value) elif cmd == 'bbwarn': bb.warn(value) elif cmd == 'bberror': bb.error(value) elif cmd == 'bbfatal': # The caller will call exit themselves, so bb.error() is # what we want here rather than bb.fatal() bb.error(value) elif cmd == 'bbfatal_log': bb.error(value, forcelog=True) elif cmd == 'bbdebug': splitval = value.split(' ', 1) level = int(splitval[0]) value = splitval[1] bb.debug(level, value) else: bb.warn("Unrecognised command '%s' on FIFO" % cmd) fifobuffer = nextmsg else: break tempdir = d.getVar('T') fifopath = os.path.join(tempdir, 'fifo.%s' % os.getpid()) if os.path.exists(fifopath): os.unlink(fifopath) os.mkfifo(fifopath) with open(fifopath, 'r+b', buffering=0) as fifo: try: bb.debug(2, "Executing shell function %s" % func) try: with open(os.devnull, 'r+') as stdin: bb.process.run(cmd, shell=False, stdin=stdin, log=logfile, extrafiles=[(fifo,readfifo)]) except bb.process.CmdError: logfn = d.getVar('BB_LOGFILE') raise FuncFailed(func, logfn) finally: os.unlink(fifopath) bb.debug(2, "Shell function %s finished" % func)
def exec_func_shell(func, d, runfile, cwd=None): """Execute a shell function from the metadata Note on directory behavior. The 'dirs' varflag should contain a list of the directories you need created prior to execution. The last item in the list is where we will chdir/cd to. """ # Don't let the emitted shell script override PWD d.delVarFlag('PWD', 'export') with open(runfile, 'w') as script: script.write(shell_trap_code()) bb.data.emit_func(func, script, d) if bb.msg.loggerVerboseLogs: script.write("set -x\n") if cwd: script.write("cd '%s'\n" % cwd) script.write("%s\n" % func) script.write(''' # cleanup ret=$? trap '' 0 exit $ret ''') os.chmod(runfile, 0o775) cmd = runfile if d.getVarFlag(func, 'fakeroot', False): fakerootcmd = d.getVar('FAKEROOT', True) if fakerootcmd: cmd = [fakerootcmd, runfile] if bb.msg.loggerDefaultVerbose: logfile = LogTee(logger, sys.stdout) else: logfile = sys.stdout progress = d.getVarFlag(func, 'progress', True) if progress: if progress == 'percent': # Use default regex logfile = bb.progress.BasicProgressHandler(d, outfile=logfile) elif progress.startswith('percent:'): # Use specified regex logfile = bb.progress.BasicProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile) elif progress.startswith('outof:'): # Use specified regex logfile = bb.progress.OutOfProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile) else: bb.warn('%s: invalid task progress varflag value "%s", ignoring' % (func, progress)) fifobuffer = bytearray() def readfifo(data): nonlocal fifobuffer fifobuffer.extend(data) while fifobuffer: message, token, nextmsg = fifobuffer.partition(b"\00") if token: splitval = message.split(b' ', 1) cmd = splitval[0].decode("utf-8") if len(splitval) > 1: value = splitval[1].decode("utf-8") else: value = '' if cmd == 'bbplain': bb.plain(value) elif cmd == 'bbnote': bb.note(value) elif cmd == 'bbwarn': bb.warn(value) elif cmd == 'bberror': bb.error(value) elif cmd == 'bbfatal': # The caller will call exit themselves, so bb.error() is # what we want here rather than bb.fatal() bb.error(value) elif cmd == 'bbfatal_log': bb.error(value, forcelog=True) elif cmd == 'bbdebug': splitval = value.split(' ', 1) level = int(splitval[0]) value = splitval[1] bb.debug(level, value) else: bb.warn("Unrecognised command '%s' on FIFO" % cmd) fifobuffer = nextmsg else: break tempdir = d.getVar('T', True) fifopath = os.path.join(tempdir, 'fifo.%s' % os.getpid()) if os.path.exists(fifopath): os.unlink(fifopath) os.mkfifo(fifopath) with open(fifopath, 'r+b', buffering=0) as fifo: try: bb.debug(2, "Executing shell function %s" % func) try: with open(os.devnull, 'r+') as stdin: bb.process.run(cmd, shell=False, stdin=stdin, log=logfile, extrafiles=[(fifo,readfifo)]) except bb.process.CmdError: logfn = d.getVar('BB_LOGFILE', True) raise FuncFailed(func, logfn) finally: os.unlink(fifopath) bb.debug(2, "Shell function %s finished" % func)