diff options
Diffstat (limited to 'worker')
-rw-r--r-- | worker/specs | 100 | ||||
-rw-r--r-- | worker/worker.py | 150 |
2 files changed, 0 insertions, 250 deletions
diff --git a/worker/specs b/worker/specs deleted file mode 100644 index 0d1b7dd1..00000000 --- a/worker/specs +++ /dev/null @@ -1,100 +0,0 @@ -============== -gatherer specs -============== - -WORK IN PROGRESS - -/When a command is expected, the line "#X#" is printed, where X is the number of -/the request, starting a 0 and incremented after each processed request. -[test_incrementing_counter] - -/Requests are spanned on multiple lines. The first line is the command, the -/following lines are parameters (one parameter per line unless stated otherwise). -[statement] - -/Requests are all blocking. As they are read from stdin using readline(), -/they can be buffered in stdin. -[test_queuecommands] - -/When the number of parameters or returns is variable, it should be indicated -/first. -/When a parameter or returned value is not one line of printable characters, -/its length as returned by len() should be indicated first. -[statement] - -/When gatherer is expected to write in a file, its parent directory should exist -/and it will be opened with the "w" flag (unless stated otherwise). -[statement] - -/No timeout handling should be implemented in gatherer. -[statement] - -SIGINT should stop the current request parsing or execution, -write '#X# INTERRUPTED' to stderr where X is the number of the request, -then continue the normal flow of execution including incrementing the request -number. - -/stderr is only used: -/- by Python to display exceptions; -/- to print "ALIVE" when SIGUSR1 is received or after a "ping" request; -/- to print "UNKNOWN COMMAND" when a command is unknown; -/- to print "INTERRUPTED #X#" when a command is interrupted with SIGINT. -[statement(easy to prove wrong, hard to prove right)] - -Requests --------- - -/Command: "noop" -/Params: -/- None -/Action: -/- None -/Returns: -/- Nothing -[test_basic_noop] - -/Command: "ping" -/Params: -/- None -/Action: -/- Prints "ALIVE" on stderr -/Returns: -/- Nothing -[test_basic_ping NEED(stderr is being used)] - -/Command: "exit" -/Params: -/- None -/Action: -/- The gatherer process returns 0 -/Returns: -/- Nothing -[test_exit] - -/Command: "glob" -/Params: -/- The globbing pattern -/Action: -/- Performs a glob.glob() -/Returns: -/- On the first line, a number of results, n -/- On the following n lines, filenames, line by line -[test_basic_glob, test_empty_glob] - -Command: "exec" -Params: -- The command to send to a shell -Action: -- Executes the command in a shell using subprocess.Popen -Returns: -- The return code of the command -- The length of its stdout output as return by len(), in decimal. -- Its stdout output, followed by a trailing '\n' -- The length of its stderr output as return by len(), in decimal. -- Its stderr output, followed by a trailing '\n' - -Command: "cp" --- to be defined after staring at the current sosreport code. - -Command: "globcp" --- to be defined after staring at the current sosreport code. diff --git a/worker/worker.py b/worker/worker.py deleted file mode 100644 index e9977019..00000000 --- a/worker/worker.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env python - -class Request: - Commands = {} - - @staticmethod - def Register(name): - def decorate(cls): - Request.Commands[name] = cls - return cls - return decorate - - @staticmethod - def ReadCommand(shell): - cmd = shell.read_line().strip() - request = Request.Commands[cmd](shell) - return request - - def __init__(self, shell): - self.shell = shell - - def read_params(self): - pass - - def execute(self): - raise NotImplementedError() - - -@Request.Register("noop") -class NoopRequest(Request): - - def execute(self): - pass - -@Request.Register("ping") -class PingRequest(Request): - - def execute(self): - self.shell.status("ALIVE") - - -@Request.Register("exit") -class ExitRequest(Request): - - def execute(self): - self.shell.exit() - - -@Request.Register("glob") -class GlobRequest(Request): - - def read_params(self): - self.pattern = self.shell.read_line() - - def execute(self): - from glob import glob - results = glob(self.pattern) - self.shell.write("%i\n" % len(results)) - for result in results: - self.shell.write(result+"\n") - - -@Request.Register("exec") -class ExecRequest(Request): - - def read_params(self): - self.cmd = self.shell.read_line() - - def execute(self): - from subprocess import Popen, PIPE - proc = Popen(self.cmd, shell=True, stdout=PIPE, stderr=PIPE, bufsize=-1) - stdout, stderr = proc.communicate() - self.shell.write("%i\n" % proc.returncode) - self.shell.write_blob(stdout) - self.shell.write_blob(stderr) - -class Shell: - def __init__(self, input_stream, output_stream, status_stream, - bork_action = None): - self.__input_stream__ = input_stream - self.__output_stream__ = output_stream - self.__status_stream__ = status_stream - self.__bork_action__ = bork_action or self.exit - self.__exit__ = False - self.__req_counter__ = 0 - - def loop(self): - while self.__exit__ == False: - self.show_prompt() - try: request = Request.ReadCommand(self) - except KeyboardInterrupt: - self.exit() - except KeyError: - self.status("UNKNOWN COMMAND"); - self.bork() - else: - try: request.read_params() - except KeyboardInterrupt: - pass - else: - self.__req_counter__ += 1 - try: - request.execute() - except KeyboardInterrupt: - self.status("INTERRUPTED"); - - def exit(self): - self.__exit__ = True - - def bork(self): - self.__bork_action__() - - def show_prompt(self): - self.write("#%i#\n" % self.__req_counter__) - - def status(self, str): - print >> self.__status_stream__, str - - def write(self, msg): - self.__output_stream__.write(msg) - - def write_blob(self, blob): - self.write("%i\n" % len(blob)) - self.write(str(blob)+"\n") - - def read_line(self): - while True: - try: - return self.__input_stream__.readline().strip() - except IOError: - pass - - def read_blob(self, length): - try: - blob = self.__input_stream__.read(length) - assert self.__input_stream__.read(1) == "\n" - except: - raise IOError() - else: - return blob - -if __name__ == "__main__": - from sys import stdin, stdout, stderr, exit - from signal import signal, SIGUSR1 - def handler(signum, frame): - print >> stderr, "ALIVE" - signal(SIGUSR1, handler) - def bork(): - exit(-1) - Shell(stdin, stdout, stderr, bork_action = bork).loop() |