def workflow_deploy(running, **kwargs): if running: text = '执行步骤 ' + str(kwargs['idx']) print(text) message = {'color': 'darkcyan', 'text': '执行步骤 %d' % kwargs['idx']} kwargs['logtext'] = [ message, ] wf = Workflow(**kwargs) emit_notification(kwargs['id'], {'message': message}) return wf.deploy_run() return running
def workflow_deploylog(deploy_type, **kwargs): out_file = settings.SALT_LOG + '/' + deploy_type + '/%s.log' % kwargs[ 'task_id'] recode = workflow_sendlog(out_file, kwargs['task_id']) instance = Business.objects.get(id=kwargs['id']) if recode: instance.status = 'success' emit_notification(kwargs['task_id'], {'message': 'end'}) else: instance.status = 'failed' emit_notification(kwargs['task_id'], {'message': 'end'}) instance.save() return recode
def copyPackage(instance, task, package_name, tasklog=None): """拷贝部署包到静态资源目录""" static_dir = os.path.join(settings.SALT_STATIC, instance.name) logtext = [] cmd = ['cp -rf %s %s' % (package_name, static_dir)] command = ' && '.join(cmd) print("执行命令: %s" % command) recode, data = localComannd(command) if recode == 0: text = "拷贝(%s)部署包到(%s)静态资源目录成功" % (package_name, 'static') message = {'color': 'darkcyan', 'text': text} emit_notification(str(task.id), {'message': message}) logtext.append(message) logtext = json.dumps(json.loads(tasklog.log_text) + logtext) tasklog.log_text = logtext tasklog.save() else: text = "拷贝(%s)部署包到(%s)静态资源目录失败" % (package_name, 'static') message = {'color': 'red', 'text': text} emit_notification(str(task.id), {'message': message}) emit_notification(str(task.id), {'message': 'end'}) logtext.append(message) print("拷贝部署包到静态资源目录失败原因: %s" % str(data)) task.status = 'failed' task.save() logtext = json.dumps(json.loads(tasklog.log_text) + logtext) tasklog.log_text = logtext tasklog.save() raise AssertionError(message)
def basic_event(task_id, deploy_type): basic = Basic.objects.get(id=task_id) task_log = TaskLog.objects.get( id=basic.log_id) if len(basic.log_id) > 0 else TaskLog() logtext = [] local_file, state_file, filename = generate_states_file(basic) basic.status = 'running' basic.log_id = task_log.id basic.save() SFTPCommand(local_file, '/srv/salt/common', filename) if state_file: message = {'color': 'darkcyan', 'text': '生成states文件成功'} emit_notification(task_id, {'message': message}) logtext.append(message) task_log.log_text = json.dumps(logtext) task_log.save() servers = json.loads(basic.servers) tgt = ', '.join(servers) pillar = '{}' out_file = settings.SALT_LOG + '/' + deploy_type + '/%s.log' % task_id if not os.path.exists(settings.SALT_LOG + '/' + deploy_type): os.makedirs(settings.SALT_LOG + '/' + deploy_type, 0o755) if len(servers) <= 1: cmd = "salt '%s' state.sls %s pillar='%s' --force-color" % ( tgt, state_file, pillar) else: cmd = "salt -L '%s' state.sls %s pillar='%s' --force-color" % ( tgt, state_file, pillar) print("执行命令: %s" % cmd) recode = SSHCommand(cmd, out_file) with open(out_file, 'a') as f: f.write('end\n') if recode == 0: return True else: return False
def post(self, request): task_id = self.request.query_params.get('task_id', None) deploy_type = self.request.query_params.get('deploy_type', None) if task_id is None or deploy_type is None: return Response(status=status.HTTP_400_BAD_REQUEST, data={}) if deploy_type == 'workflow': wf = WorkFlow.objects.get(id=task_id) steps = json.loads(wf.steps) chains = [] for idx, step in enumerate(steps): step['created_at'] = Version(wf.created_at) step['id'] = task_id if idx == 0: # workflow_deploy(running=True, **step) chains.append(workflow_deploy.s(running=True, **step)) else: # workflow_deploy(running=True, **step) chains.append(workflow_deploy.s(**step)) ret = chain(chains)() if ret.get(): emit_notification(task_id, {'message': 'end'}) else: deploy_run(task_id, deploy_type) return Response(status=status.HTTP_200_OK, data={})
def initLocalWorkSpace(instance, task, tasklog=None): """初始化宿主机临时空间""" workspace = _getWorkSpace(instance) git_dir, svn_dir, cmd = None, None, None logtext = [] temp_workspace = os.path.join(workspace, Version(task.created_at)) if os.path.exists(temp_workspace): recode, data = localComannd("rm -rf %s" % temp_workspace) if recode == 0: print("清理临时目录(%s)成功" % temp_workspace) else: print("清理临时目录(%s)失败, 原因: %s" % (temp_workspace, str(data))) # status, output = subprocess.getstatusoutput("rm -rf %s" % temp_workspace) if instance.repo_type == 'git': git_dir = os.path.join(instance.repo_work, instance.env, instance.name) cmd = ['cp -rf %s %s' % (git_dir, temp_workspace)] if instance.repo_type == 'svn': svn_dir = os.path.join(instance.repo_work, instance.env, instance.name) cmd = ['cp -rf %s %s' % (svn_dir, temp_workspace)] command = ' && '.join(cmd) print("执行命令: %s" % command) recode, data = localComannd(command) if recode == 0: text = "%s 代码拷贝到 %s 临时空间成功" % (instance.name, workspace) print(text) message = {'color': 'darkcyan', 'text': text} emit_notification(str(task.id), {'message': message}) logtext.append(message) logtext = json.dumps(json.loads(tasklog.log_text) + logtext) tasklog.log_text = logtext tasklog.save() else: text = "%s 代码拷贝到 %s 临时空间失败" % (instance.name, workspace) print(text) print("拷贝临时空间失败原因: %s" % str(data)) message = {'color': 'red', 'text': text} emit_notification(str(task.id), {'message': message}) emit_notification(str(task.id), {'message': 'end'}) logtext.append(message) task.status = 'failed' task.save() logtext = json.dumps(json.loads(tasklog.log_text) + logtext) tasklog.log_text = logtext tasklog.save() raise AssertionError(message)
def packageFile(instance, task, tasklog=None): """部署资源打包""" excludes = instance.repo_ignore.split('\n') workspace = _getWorkSpace(instance) temp_workspace = os.path.join(workspace, Version(task.created_at)) package_name = ''.join([ temp_workspace, datetime.now().strftime('%Y%m%d-%H%M%S'), '-', task.version, '.tar.gz' ]) files = get_files(task) logtext = [] cmd = [ "cd %s" % temp_workspace, "tar -p %s -cz -f %s %s" % (_excludes(excludes), package_name, files) ] command = ' && '.join(cmd) print("执行命令: %s" % command) recode, data = localComannd(cmd=command) if recode == 0: text = "%s 打包到 %s 成功" % (package_name, workspace) print(text) message = {'color': 'darkcyan', 'text': text} emit_notification(str(task.id), {'message': message}) logtext.append(message) logtext = json.dumps(json.loads(tasklog.log_text) + logtext) tasklog.log_text = logtext tasklog.save() return package_name else: text = "%s 打包到 %s 失败" % (package_name, workspace) print(text) message = {'color': 'red', 'text': text} emit_notification(str(task.id), {'message': message}) logtext.append(message) emit_notification(str(task.id), {'message': 'end'}) print("打包失败原因: %s" % str(data)) task.status = 'failed' task.save() logtext = json.dumps(json.loads(tasklog.log_text) + logtext) tasklog.log_text = logtext tasklog.save() raise AssertionError(text)
def _emit_notification(self, message): emit_notification(self.task_id, message)
def workflow_sendlog(outfile, task_id): while True: if os.path.exists(outfile): break else: time.sleep(3) logfile = open(outfile, 'r') print("%s 日志文件打开成功" % outfile) lines = '' state = None status = [] recode = None while True: current_position = logfile.tell() line = logfile.readline() if state: if re.match('(?=^\S+)(\W+\S+)*(?<= s)', lines): logfile.seek(current_position) color_line = lines.split('\n') detail = [] for l in color_line: detail.append(set_color(l)) if re.findall('Failed:\W+\d+', lines)[0].split(' ')[-1] == '0': failed = False recode = True else: failed = True recode = False host = re.findall('^\S+\d+\S+', lines)[0].split(':')[0].replace('[0;32m', '').replace('[0;1;31m', '').replace('[0;31m', '').replace('[0;0m', '') print({'host': host, 'failed': failed, 'detail': detail}) if failed: text = '%s Failed' % host color = 'red' message = {'color': color, 'text': text, 'detail': detail, 'failed': failed, 'host': host} emit_notification(task_id, {'message': message}) else: text = '%s Success' % host color = 'green' message = {'color': color, 'text': text, 'detail': detail, 'failed': failed, 'host': host} emit_notification(task_id, {'message': message}) status.append(str(failed)) state = '' lines = '' if re.search('Total run time', str(line)): state = True if re.findall('No response', lines) or re.findall('No minions', lines): recode = True detail = [] color_line = lines.split('\n') for l in color_line: detail.append(set_color(l)) host = re.findall('^\S+\d+\S+', lines)[0].split(':')[0].replace('[0;32m', '').replace('[0;1;31m', '').replace('[0;31m', '').replace('[0;0m', '').replace('[0;36m', '') text = '%s Failed' % host color = 'red' message = {'color': color, 'text': text, 'detail': detail, 'failed': True, 'host': host} emit_notification(task_id, {'message': message}) lines = '' if str(line) == 'end\n': logfile.close() print("文件读取结束") emit_notification(task_id, {'message': 'end'}) break lines += str(line) return recode
def send_log(outfile, task_id, deploy_type): while True: if os.path.exists(outfile): break else: time.sleep(3) logfile = open(outfile, 'r') print("%s 日志文件打开成功" % outfile) tasklog = None if deploy_type == 'bs': from main.models import Business, TaskLog task = Business.objects.get(id=task_id) tasklog = TaskLog.objects.get(id=task.log_id) if deploy_type == 'bc': from main.models import Basic, TaskLog task = Basic.objects.get(id=task_id) tasklog = TaskLog.objects.get(id=task.log_id) logtext = [] lines = '' state = None status = [] recode = None while True: # current_position = logfile.tell() line = logfile.readline() if state: if re.match('(?=^\S+)(\W+\S+)*(?<= s)', lines): # logfile.seek(current_position) color_line = lines.split('\n') detail = [] for l in color_line: detail.append(set_color(l)) if re.findall('Failed:\W+\d+', lines)[0].split(' ')[-1] == '0': failed = False recode = True else: recode = False failed = True host = re.findall('^\S+\d+\S+', lines)[0].split(':')[0].replace('[0;32m', '').replace('[0;1;31m', '').replace('[0;31m', '').replace('[0;0m', '') print({'host': host, 'failed': failed, 'detail': detail}) if failed: text = '%s Failed' % host color = 'red' message = {'color': color, 'text': text, 'detail': detail, 'failed': failed, 'host': host} emit_notification(task_id, {'message': message}) logtext.append(message) else: text = '%s Success' % host color = 'green' message = {'color': color, 'text': text, 'detail': detail, 'failed': failed, 'host': host} emit_notification(task_id, {'message': message}) logtext.append(message) status.append(str(failed)) state = '' lines = '' if re.search('Total run time', str(line)): state = True if re.findall('No response', lines) or re.findall('No minions', lines): recode = False detail = [] color_line = lines.split('\n') for l in color_line: detail.append(set_color(l)) try: host = re.findall('^\S+\d+\S+', lines)[0].split(':')[0].replace('[0;32m', '').replace('[0;1;31m', '').replace('[0;31m', '').replace('[0;0m', '').replace('[0;36m', '') except Exception as e: host = '' text = '%s Failed' % host color = 'red' message = {'color': color, 'text': text, 'detail': detail, 'failed': True, 'host': host} emit_notification(task_id, {'message': message}) lines = '' if str(line) == 'end\n': logfile.close() print("文件读取结束") if len(lines) > 0: detail = [] color_line = lines.split('\n') for l in color_line: detail.append(set_color(l)) try: host = re.findall('^\S+\d+\S+', lines)[0].split(':')[0].replace('[0;32m', '').replace('[0;1;31m', '').replace('[0;31m', '').replace('[0;0m', '').replace('[0;36m', '') except Exception as e: pass text = '%s Failed' % host color = 'red' message = {'color': color, 'text': text, 'detail': detail, 'failed': True, 'host': host} emit_notification(task_id, {'message': message}) lines = '' emit_notification(task_id, {'message': 'end'}) break lines += str(line) logtext = json.dumps(json.loads(tasklog.log_text) + logtext) tasklog.log_text = logtext tasklog.save() return recode