def run(self, command, wenv=None, sudo=False, pty=True, exception=True, **kwargs): ''' pty=True/False是直接影响到输出.False较适合在获取文本,True更适合websocket :param command: :param wenv: :param sudo: False/True default False :param exception: False/True default True False return Result(exited=xx, stderr=xx, stdout=xx) for process to raise custom exception by exited code True raise Exception :param kwargs: :return: ''' message = 'deploying task_id=%s [%s@%s]$ %s ' % ( wenv['task_id'], self.user, self.host, command) current_app.logger.info(message) try: if sudo: result = super(Waller, self).sudo(command, pty=pty, **kwargs) else: result = super(Waller, self).run(command, pty=pty, warn=True, watchers=[say_yes()], **kwargs) if result.failed: exitcode, stdout, stderr = result.exited, '', result.stdout if exception: raise Exception(stderr) else: exitcode, stdout, stderr = 0, result.stdout, '' message = 'task_id=%s, user:%s host:%s command:%s status:%s, success:%s, error:%s' % ( wenv['task_id'], self.user, self.host, command, exitcode, stdout, stderr) # TODO ws_dict = { 'user': self.user, 'host': self.host, 'cmd': command, 'status': exitcode, 'stage': wenv['stage'], 'sequence': wenv['sequence'], 'success': stdout, 'error': stderr, } if wenv['console']: emit('console', { 'event': 'task:console', 'data': ws_dict }, room=wenv['task_id']) RecordModel().save_record(stage=wenv['stage'], sequence=wenv['sequence'], user_id=wenv['user_id'], task_id=wenv['task_id'], status=exitcode, host=self.host, user=self.user, command=result.command, success=stdout, error=stderr) current_app.logger.info(result) if exitcode != Code.Ok: current_app.logger.error(message, exc_info=1) current_app.logger.exception(result.stdout.strip(), exc_info=1) return result return result except Exception as e: current_app.logger.exception(e) # TODO 貌似可能的异常有很多种,需要分层才能完美解决 something wrong without e.result error = e.result if 'result' in e else e.message RecordModel().save_record(stage=wenv['stage'], sequence=wenv['sequence'], user_id=wenv['user_id'], task_id=wenv['task_id'], status=1, host=self.host, user=self.user, command=command, success='', error=error) if hasattr(e, 'reason') and hasattr(e, 'result'): message = 'task_id=%s, user:%s host:%s command:%s, status=1, reason:%s, result:%s exception:%s' % ( wenv['task_id'], self.user, self.host, command, e.reason, error, e.message) else: message = 'task_id=%s, user:%s host:%s command:%s, status=1, message:%s' % ( wenv['task_id'], self.user, self.host, command, e.message) current_app.logger.error(message, exc_info=1) # TODO ws_dict = { 'user': self.user, 'host': self.host, 'cmd': command, 'status': 1, 'stage': wenv['stage'], 'sequence': wenv['sequence'], 'success': '', 'error': error, } if wenv['console']: emit('console', { 'event': 'console', 'data': ws_dict }, room=wenv['task_id']) if exception: raise e return Result(exited=-1, stderr=error, stdout=error)
def run(self, command, wenv=None, run_mode=run_mode_remote, pty=True, exception=True, **kwargs): ''' pty=True/False是直接影响到输出.False较适合在获取文本,True更适合websocket :param command: :param wenv: :param sudo: False/True default False :param exception: False/True default True False return Result(exited=xx, stderr=xx, stdout=xx) for process to raise custom exception by exited code True raise Exception :param kwargs: :return: ''' message = 'deploying task_id=%s [%s@%s]$ %s ' % (wenv['task_id'], self.user, self.host, command) current_app.logger.info(message) try: if run_mode == self.run_mode_sudo: result = super(Waller, self).sudo(command, pty=pty, env=self.custom_global_env, **kwargs) elif run_mode == self.run_mode_local: current_app.logger.info(self.custom_global_env) result = super(Waller, self).local(command, pty=pty, warn=True, watchers=[say_yes()], env=self.custom_global_env, **kwargs) else: result = super(Waller, self).run(command, pty=pty, warn=True, watchers=[say_yes()], env=self.custom_global_env, **kwargs) if result.failed: exitcode, stdout, stderr = result.exited, '', result.stdout if exception: raise Exception(stderr) else: exitcode, stdout, stderr = 0, result.stdout, '' message = 'task_id=%s, user:%s host:%s command:%s status:%s, success:%s, error:%s' % ( wenv['task_id'], self.user, self.host, command, exitcode, stdout, stderr ) # TODO ws_dict = { 'user': self.user, 'host': self.host, 'cmd': command, 'status': exitcode, 'stage': wenv['stage'], 'sequence': wenv['sequence'], 'success': stdout, 'error': stderr, } if wenv['console']: emit('console', {'event': 'task:console', 'data': ws_dict}, room=wenv['task_id']) RecordModel().save_record(stage=wenv['stage'], sequence=wenv['sequence'], user_id=wenv['user_id'], task_id=wenv['task_id'], status=exitcode, host=self.host, user=self.user, command=result.command, success=stdout, error=stderr) current_app.logger.info(result) if exitcode != Code.Ok: current_app.logger.error(message, exc_info=1) current_app.logger.exception(result.stdout.strip(), exc_info=1) return result return result except Exception as e: # TODO 貌似可能的异常有很多种,需要分层才能完美解决 something wrong without e.result current_app.logger.exception(e) if hasattr(e, 'message'): error = e.message elif hasattr(e, 'result'): error = e.result else: error = str(e) RecordModel().save_record(stage=wenv['stage'], sequence=wenv['sequence'], user_id=wenv['user_id'], task_id=wenv['task_id'], status=1, host=self.host, user=self.user, command=command, success='', error=error) if hasattr(e, 'reason') and hasattr(e, 'result'): message = 'task_id=%s, user:%s host:%s command:%s, status=1, reason:%s, result:%s exception:%s' % ( wenv['task_id'], self.user, self.host, command, e.reason, error, e.message ) else: message = 'task_id=%s, user:%s host:%s command:%s, status=1, message:%s' % ( wenv['task_id'], self.user, self.host, command, error ) current_app.logger.error(message, exc_info=1) # TODO ws_dict = { 'user': self.user, 'host': self.host, 'cmd': command, 'status': 1, 'stage': wenv['stage'], 'sequence': wenv['sequence'], 'success': '', 'error': error, } if wenv['console']: emit('console', {'event': 'console', 'data': ws_dict}, room=wenv['task_id']) if exception: raise e return Result(exited=-1, stderr=error, stdout=error)