import subprocess import threading import logging as log from .Common import * from .Device import * def PrintLog(executable_path, log_output): for _line in log_output.split('\n'): LogTokenCharCount = 4 logLevel = log.getLevelName(_line[0:LogTokenCharCount]) logText = _line[LogTokenCharCount+1:] if len(logText.strip()) > 0: if logLevel == log.FATAL: log.fatal("[{executable_path}] {logText}".format(executable_path = executable_path, logText = logText)) elif logLevel == log.ERROR: log.error("[{executable_path}] {logText}".format(executable_path = executable_path, logText = logText)) elif logLevel == log.WARNING: log.warning("[{executable_path}] {logText}".format(executable_path = executable_path, logText = logText)) elif logLevel == log.INFO: if log.getLogger().getEffectiveLevel() < logLevel: log.info("[{executable_path}] {logText}".format(executable_path = executable_path, logText = logText)) elif logLevel == log.DEBUG: if log.getLogger().getEffectiveLevel() < logLevel: log.debug("[{executable_path}] {logText}".format(executable_path = executable_path, logText = logText)) def ExecuteCommand( command, checkForError = True, success_code = 0 ): __process = None log.debug("Running " + command) if platform.system() == 'Windows': # Cannot redirect stdout, stderr AND set close_fds=True on Windows __process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False) else: __process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, executable="/bin/bash") __stdout, __stderr = __process.communicate() __stdout = __stdout.decode('UTF-8') __stderr = __stderr.decode('UTF-8') if checkForError: if __process.returncode != success_code: print(__stdout) print(__stderr) log.fatal( f"Command '{command}' failed with return code {__process.returncode}, expected {success_code}\n" f"STDOUT:\n{__stdout}\nSTDERR:\n{__stderr}" ) executable_path = "none" tokens = command.split(" ") if len(tokens) > 0: executable_path = tokens[0] PrintLog(executable_path, __stderr) return __stdout, __stderr, __process.returncode def ExecuteFunction(functionptr, functionargs): log.info( 'FUNC: ' + str(functionptr) + "(" + ",".join( str(w) for w in functionargs ) + ")" ) return functionptr( *functionargs ) def JoinThreads(threads): join_count = 0 for t in threads: if t.is_alive() == False: retcode = t.join() join_count = join_count + 1 threads.remove(t) return join_count def ExecuteCommandList(commandlist, parallelism="auto"): threads = [] running = 0 if parallelism == "auto": parallelism = str(GetNumberOfVirtualCores()) else: parallelism = str(parallelism) if len(commandlist) > 0: log.info("Running "+ str(len(commandlist)) + " commands" + " (" + parallelism + " in parallel)" ) for cmd in commandlist: # TODO(ADEEL) - Will Fix Later # stdout = None # if 'stdout' in cmd.keys(): # stdout = cmd['stdout'] # stderr = None # if 'stderr' in cmd.keys(): # stderr = cmd['stderr'] success_code = 0 if 'success_code' in cmd.keys(): success_code = cmd['success_code'] if "command" in cmd.keys(): command = cmd['command'] if parallelism == "1" or len(commandlist) == 1: ExecuteCommand(command, True, success_code) else: thread = threading.Thread(target = ExecuteCommand, args=[command, True, success_code]) thread.start() thread.setName(command) threads.append( thread ) running = running + 1 while str(running) == parallelism: running = running - JoinThreads(threads) while len(threads): JoinThreads(threads) def ExecuteFunctionList(functionlist, parallelism="auto"): threads = [] running = 0 if parallelism == "auto": parallelism = str(GetNumberOfVirtualCores()) else: parallelism = str(parallelism) log.info("Running "+ str(len(functionlist)) + " functions" + " (" + parallelism + " in parallel)" ) for function in functionlist: functionptr = function['function'] functionargs = function['arguments'] functionname = str(functionptr) + "(" + str(functionargs[0]) + "...)" if parallelism == "1" or len(functionlist) == 1: ExecuteFunction(functionptr, functionargs) else: log.info( 'LAUNCH: ' + functionname ) thread = threading.Thread( target = ExecuteFunction, args =[functionptr, functionargs] ) thread.start() thread.setName(functionname) threads.append( thread ) running = running + 1 while str(running) == parallelism: running = running - JoinThreads(threads) while len(threads): JoinThreads(threads) def ExecuteCommandInstantOutput( command, checkForError = True ): log.info(command) returncode = os.system(command) if checkForError: if returncode != 0: log.fatal('Failed command ' + command + ' | returned: ' + str(returncode)) return returncode;