def _shell_command_execution(self, task_id): dt = datetime.now() cmd_type = str(Command.get_by(test_id=self.test_id, id=task_id).cmd_type) command = str(Command.get_by(test_id=self.test_id, id=task_id).command) if cmd_type == 'shell': from AreteSlave.modules.Daemon import Daemon manager = Daemon.get_manager() test_dir = manager.workdir + os.sep + self.test_id if not os.path.isdir(test_dir): os.mkdir(test_dir) os.chdir(test_dir) try: command = Scheduler.subst(command, self.test_id) args = shlex.split(str(command)) logging.info("[ Test %s ] Running task '%s' : %s" \ % (self.test_id, task_id, command)) p = subprocess.Popen(args, stdout=subprocess.PIPE, \ stderr=subprocess.STDOUT) task = Task.get_by(test_id=self.test_id, id=task_id) self.pids[task_id] = p.pid task.pid = p.pid session.commit() p.wait() td = datetime.now() - dt except (OSError, ResolvError) as e: logging.error(e) logging.error("[ Test %s ] Running task '%s' failed." \ % (self.test_id, task_id)) Invocation(command=Command.get_by(test_id=self.test_id, \ id=task_id), start_time=dt) session.commit() else: Invocation(\ command=Command.get_by(test_id=self.test_id, \ id=task_id), output=p.stdout.read(), start_time=dt, \ duration=td, return_code=p.returncode) session.commit() elif cmd_type == 'notify': from AreteSlave.modules.Daemon import Daemon manager = Daemon.get_manager() manager.notify_handlers[self.test_id](self.test_id, command) Invocation(command=Command.get_by(test_id=self.test_id, \ id=task_id), start_time=dt) session.commit()
def resolve_ref(matchobj): to_resolv = matchobj.group('ref') ref = to_resolv.split('.') if len(ref) is 2: id = ref[0] param = ref[1] if id in cmd_ids: cmd = Command.get_by(test_id=test_id, id=unicode(id)) param_map = {} if len(cmd.invocations) > 0: param_map['returncode'] = \ cmd.invocation[-1].return_code if cmd.row_type == u'task': if cmd.pid is not None: param_map['pid'] = cmd.pid else: raise ResolvError("[ Test %s ] Task '%s' hasn't \ been run yet." % (test_id, cmd.id)) if param in param_map.keys(): return str(param_map[param]) elif id in file_ids: file = File.get_by(test_id=test_id, id=unicode(id)) param_map = {} param_map['size'] = file.size param_map['name'] = file.name if param in param_map.keys(): return str(param_map[param]) elif len(ref) is 1: if ref[0].startswith('poke') and len(ref[0].split(' ')) is 2: from AreteSlave.modules.Daemon import Daemon manager = Daemon.get_manager() return '"arete-poker %s %s %s"' \ % (test_id, ref[0].split(' ')[1], str(manager.port)) raise ResolvError("[ Test %s ] Cannot resolve '%s'." \ % (test_id, to_resolv))
def handle(self): from AreteSlave.modules.Daemon import Daemon manager = Daemon.get_manager() try: line = self.receive() if line == '': raise socket.error elif line.startswith('poke'): line = unicode(line[5:]).split(':') test_id = line[0] poke_name = line[1] logging.info("[ Test %s ] Running poke: %s" % (test_id, poke_name)) manager.run_poke(test_id, poke_name) else: logging.info("[ Connection %s ] Handling" % self.client_address[0]) parent = None parent_id = None types_and_actions = { 'test' : manager.create_test, 'test_check' : manager.add_check_command, 'test_setup' : manager.add_setup_command, 'test_task' : manager.add_task_command, 'test_clean' : manager.add_clean_command, 'test_file' : manager.add_file, 'test_delete' : manager.delete_command_or_file, 'results' : manager.open_results, 'results_get' : manager.get_results, 'delete' : manager.delete_test, 'prepare' : manager.prepare_test, 'start' : manager.start_test, 'stop' : manager.stop_test, 'trigger' : manager.run_trigger, 'time' : self.send_time } while 1: if line: logging.info("[ Connection %s ] [ %s ] Received: %s" % (self.client_address[0], datetime.datetime.now(), line)) try: type, params = parse(line, parent) if types_and_actions.get(type): result = types_and_actions.get(type)(parent_id, **params) except (DaemonError, CommandError) as e: logging.error(e) if isinstance(e, CommandError): self.send_cmd_error(e.cmd_id) elif isinstance(e, SetupTooLongError): self.send_setup_too_long() else: self.send_bad_request() else: if type in ['test', 'results']: parent = type parent_id = params['id'] if type.endswith('end'): parent = None parent_id = None if type == 'test_file': name = result[0] size = result[1] copied = 0 test_dir = manager.workdir + os.sep + parent_id if not os.path.isdir(test_dir): os.mkdir(test_dir) with open(test_dir + os.sep + name, 'wb') as f: while copied < size: read = min(size - copied, 1000000) f.write(self.rfile.read(read)) copied += read if type == 'results_get': type = result[0] to_send = result[1] if type == 'multi': kind = result[2] size_list = [] for output in to_send: if output != None: if kind == 'duration': output = str(float(output.seconds)+(output.microseconds/1000000.0)) elif kind == 'returncode': output = str(output) elif kind == 'start_time': output = output.isoformat() output_len = len(output) size_list.append(output_len) else: size_list.append(-1) self.send_ok(sizes=size_list) for output in to_send: if output != None: if kind == 'duration': output = str(float(output.seconds)+(output.microseconds/1000000.0)) elif kind == 'returncode': output = str(output) elif kind == 'start_time': output = output.isoformat() self.wfile.write(output) elif type == 'list': self.send_list(to_send) else: if to_send != None: self.send_ok(sizes=[len(to_send)]) self.wfile.write(to_send) else: self.send_ok(sizes=[-1]) else: if type not in ['trigger', 'time']: self.send_ok() if type == 'start': run_value = result print params['id'] manager.setup_test(params['id']) now = time.time() tooLong = False if run_value < now: logging.error("[ Test %s ] [ %s < %s ] Setup took too much time." % (params['id'], run_value, now)) tooLong = True manager.register_handler(params['id'], self.send_100) if not tooLong: manager.start_tasks(parent_id, **params) line = self.receive() if line == '': raise socket.error except socket.error, IOError: logging.info("[ Connection %s ] Dropped" % self.client_address[0])