From 488a73ee471ab3461571994efddff082a9bd4ca0 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 1 Feb 2016 14:24:21 +0100 Subject: [PATCH 1/2] add new command hobo_batch got agent.common to launch commands trough a pipe (#9821) --- .../agent/common/management/commands/hobo_batch.py | 76 ++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 hobo/agent/common/management/commands/hobo_batch.py diff --git a/hobo/agent/common/management/commands/hobo_batch.py b/hobo/agent/common/management/commands/hobo_batch.py new file mode 100644 index 0000000..4c0ff45 --- /dev/null +++ b/hobo/agent/common/management/commands/hobo_batch.py @@ -0,0 +1,76 @@ +import sys +import struct +import StringIO +import traceback + +from django.core.management.base import BaseCommand, CommandError +from django.core.management import call_command + + +class Command(BaseCommand): + def write_buffer(self, b): + sys.stdout.write(b) + + def write_integer(self, i): + self.write_buffer(struct.pack('!I', i)) + + def write_string(self, s): + self.write_integer(len(s)) + self.write_buffer(s) + + def read_string(self): + length = self.read_integer() + if length > 100000: + raise CommandError('string too big') + return self.read_buffer(length) + + def read_buffer(self, length): + s = '' + while len(s) != length: + b = sys.stdin.read(length - len(s)) + if not b: + raise CommandError('EOF') + s += b + return s + + def read_fmt(self, fmt): + n = struct.calcsize(fmt) + s = self.read_buffer(n) + return struct.unpack(fmt, s) + + def read_integer(self): + return self.read_fmt('!I')[0] + + def handle(self, *args, **options): + while True: + args = self.read_integer() + if args > 100: + raise CommandError('too much args') + argv = [] + for i in range(args): + argv.append(self.read_string()) + stdin = self.read_string() + result, output = self.run_hobo_command(argv, stdin) + self.write_integer(result) + self.write_string(output) + sys.stdout.flush() + + def run_hobo_command(self, argv, stdin): + old_stdin = sys.stdin + old_stdout = sys.stdout + errcode = 0 + try: + sys.stdin = StringIO.StringIO(stdin) + sys.stdout = StringIO.StringIO() + call_command(*argv) + except Exception, e: + output = sys.stdout.getvalue() + traceback.print_tb(sys.last_traceback, None, sys.stdout) + errcode = 1 + else: + output = sys.stdout.getvalue() + finally: + sys.stdout = old_stdout + sys.stdin = old_stdin + return errcode, output + -- 2.1.4