BW3-Core/boswatch/processManager.py

146 lines
4.8 KiB
Python
Raw Normal View History

2019-03-04 19:43:32 +01:00
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""!
____ ____ ______ __ __ __ _____
/ __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
/ __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
/ /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
German BOS Information Script
by Bastian Schroll
@file: processManager.py
@date: 04.03.2018
@author: Bastian Schroll
@description: Class for managing sub processes
"""
import logging
import subprocess
logging.debug("- %s loaded", __name__)
class ProcessManager:
2019-03-05 08:33:35 +01:00
"""!class to manage a extern sub process"""
2019-03-05 07:49:15 +01:00
def __init__(self, process, textMode=False):
2019-03-05 08:24:55 +01:00
logging.debug("create process instance %s - textMode: %s", process, textMode)
2019-03-04 19:43:32 +01:00
self._args = []
self._args.append(process)
self._stdin = None
self._stdout = subprocess.PIPE
2019-03-05 07:49:15 +01:00
self._stderr = subprocess.STDOUT
2019-03-04 19:43:32 +01:00
self._processHandle = None
2019-03-05 07:49:15 +01:00
self._textMode = textMode
2019-03-05 08:24:55 +01:00
2019-10-09 20:10:49 +02:00
def __del__(self):
self.stop()
2019-03-04 19:43:32 +01:00
def addArgument(self, arg):
2019-03-05 08:33:35 +01:00
"""!add a new argument
@param arg: argument to add as string"""
2019-03-05 08:24:55 +01:00
logging.debug("add argument to process: %s -> %s", self._args[0], arg)
2019-03-08 22:22:41 +01:00
for splitArg in arg.split():
self._args.append(splitArg)
2019-03-04 19:43:32 +01:00
def clearArguments(self):
2019-03-05 08:33:35 +01:00
"""!clear all arguments"""
self._args = self._args[0:1] # kept first element (process name)
2019-03-04 19:43:32 +01:00
2019-10-09 20:10:49 +02:00
def start(self):
2019-03-08 22:22:41 +01:00
"""!start the new process
@return: True or False"""
2019-09-19 10:48:27 +02:00
logging.debug("start new process: %s %s", self._args[0], self._args[1:])
try:
self._processHandle = subprocess.Popen(self._args,
stdin=self._stdin,
stdout=self._stdout,
stderr=self._stderr,
2019-09-19 10:48:27 +02:00
universal_newlines=self._textMode,
2019-10-09 20:10:49 +02:00
shell=False)
2019-03-08 22:22:41 +01:00
if not self.isRunning:
logging.error("cannot start")
return False
2019-09-19 10:48:27 +02:00
logging.debug("process started with PID %d", self._processHandle.pid)
2019-03-08 22:22:41 +01:00
return True
except FileNotFoundError:
logging.error("File not found: %s", self._args[0])
2019-03-08 22:22:41 +01:00
return False
2019-03-05 07:49:15 +01:00
def stop(self):
"""!Stop the process by sending SIGTERM and wait for ending"""
2019-03-08 22:22:41 +01:00
logging.debug("stopping process: %s", self._args[0])
if self.isRunning:
2019-03-05 07:49:15 +01:00
self._processHandle.terminate()
2019-03-05 08:24:55 +01:00
while self.isRunning:
pass
2019-09-19 10:48:27 +02:00
logging.debug("process %s returned %d", self._args[0], self._processHandle.returncode)
2019-03-04 19:43:32 +01:00
def readline(self):
2019-03-05 08:33:35 +01:00
"""!Read one line from stdout stream
@return singe line or None"""
2019-03-05 07:49:15 +01:00
if self.isRunning and self._stdout is not None:
try:
line = self._processHandle.stdout.readline().strip()
except UnicodeDecodeError:
return None
2019-09-19 10:48:27 +02:00
return line
2019-03-04 19:43:32 +01:00
return None
def skipLines(self, lineCount=1):
"""!Skip given number of lines from the output
@param lineCount: number of lines to skip
"""
logging.debug("skip %d lines from output", lineCount)
while lineCount:
2019-09-20 17:38:53 +02:00
self.readline()
lineCount -= 1
def skipLinesUntil(self, matchText):
"""!Skip lines from the output until the given string is in it
@param matchText: string to search for in output
"""
logging.debug("skip lines till %s from output", matchText)
2019-10-18 21:10:00 +02:00
if not self._textMode:
matchText = bytes(matchText, "utf-8")
2019-10-18 09:21:50 +02:00
while matchText not in self.readline():
pass
2019-09-20 17:38:53 +02:00
2019-03-04 19:43:32 +01:00
def setStdin(self, stdin):
2019-03-05 08:33:35 +01:00
"""!Set the stdin stream instance"""
2019-03-04 19:43:32 +01:00
self._stdin = stdin
def setStdout(self, stdout):
2019-03-05 08:33:35 +01:00
"""!Set the stdout stream instance"""
2019-03-04 19:43:32 +01:00
self._stdout = stdout
def setStderr(self, stderr):
2019-03-05 08:33:35 +01:00
"""!Set the stderr stream instance"""
2019-03-04 19:43:32 +01:00
self._stderr = stderr
@property
def stdout(self):
2019-03-05 08:33:35 +01:00
"""!Property to get the stdout stream"""
2019-03-04 19:43:32 +01:00
return self._processHandle.stdout
@property
def stderr(self):
2019-03-05 08:33:35 +01:00
"""!Property to get the stderr stream"""
2019-03-04 19:43:32 +01:00
return self._processHandle.stderr
2019-03-05 07:49:15 +01:00
@property
def isRunning(self):
2019-03-05 08:33:35 +01:00
"""!Property to get process running state
@return True or False"""
2019-03-05 07:49:15 +01:00
if self._processHandle:
if self._processHandle.poll() is None:
return True
return False