Make arbitrary processes capable of being EventHandlers (PipeIO+stdin/stdout)

This commit is contained in:
Kristóf Tóth 2019-05-09 18:56:30 +02:00
parent c4d3319ed9
commit fc5124afb0
2 changed files with 36 additions and 2 deletions

View File

@ -11,4 +11,4 @@ from .log_monitoring_event_handler import LogMonitoringEventHandler
from .fsm_managing_event_handler import FSMManagingEventHandler from .fsm_managing_event_handler import FSMManagingEventHandler
from .snapshot_provider import SnapshotProvider from .snapshot_provider import SnapshotProvider
from .pipe_io_event_handler import PipeIOEventHandlerBase, PipeIOEventHandler, PipeIOServer from .pipe_io_event_handler import PipeIOEventHandlerBase, PipeIOEventHandler, PipeIOServer
from .pipe_io_event_handler import TransformerPipeIOEventHandler from .pipe_io_event_handler import TransformerPipeIOEventHandler, CommandEventHandler

View File

@ -1,7 +1,11 @@
from abc import abstractmethod from abc import abstractmethod
from json import loads, dumps from json import loads, dumps
from subprocess import run, PIPE from subprocess import run, PIPE, Popen
from functools import partial from functools import partial
from os import getpgid, killpg
from os.path import join
from signal import SIGTERM
from secrets import token_urlsafe
from tfw import EventHandlerBase from tfw import EventHandlerBase
from tfw.config.logs import logging from tfw.config.logs import logging
@ -85,3 +89,33 @@ class TransformerPipeIOEventHandler(PipeIOEventHandlerBase):
if transformed_bytes: if transformed_bytes:
json_message = loads(transformed_bytes) json_message = loads(transformed_bytes)
self.server_connector.send(json_message) self.server_connector.send(json_message)
class CommandEventHandler(PipeIOEventHandler):
def __init__(self, key, command, permissions=DEFAULT_PERMISSIONS):
super().__init__(
key,
self._generate_tempfilename(),
self._generate_tempfilename(),
permissions
)
self._proc_stdin = open(self.pipe_io.out_pipe, 'rb')
self._proc_stdout = open(self.pipe_io.in_pipe, 'wb')
self._proc = Popen(
command, shell=True, executable='/bin/bash',
stdin=self._proc_stdin, stdout=self._proc_stdout,
start_new_session=True
)
def _generate_tempfilename(self):
# pylint: disable=no-self-use
random_filename = partial(token_urlsafe, 10)
return join('/tmp', f'{type(self).__name__}.{random_filename()}')
def cleanup(self):
process_group_id = getpgid(self._proc.pid)
killpg(process_group_id, SIGTERM)
self._proc_stdin.close()
self._proc_stdout.close()
super().cleanup()