def get(self, request, project_name, format=None): try: size = settings.DEPLOY.get('ROLLBACK_SIZE', 1) # orders = DeploymentOrder.objects.filter(project__name=project_name, # status=D_SUCCESSFUL, # type=ONLINE)[0:size] orders = DeploymentOrder.objects.filter( project__name=project_name, status=D_SUCCESSFUL).filter(~Q(type=ROLLBACK))[0:size] data = [] for order in orders: try: h = History.objects.get(order_id=order.id, deploy_times=order.deploy_times) data.append({ 'content': h.id, 'title': order.title, 'branche': order.branche, 'commit_id': order.commit_id, 'commit': order.commit, 'env': order.env }) except: continue return Response(data) except Exception as e: logger.exception(e) return Response(status=status.HTTP_400_BAD_REQUEST)
def __post(self, data): try: ret = requests.post(self.__webhook, data=json.dumps(data), headers=self.__headers) if ret.json().get('errcode') != 0: raise Exception('钉钉机器人发送消息失败') except Exception as e: logger.exception(e)
def start_job(cache_name, order_obj, assign_to, *args, **kwargs): try: deploy_job = DeployJob(cache_name, order_obj, assign_to) deploy_job.init_job() #################jenkins构建################ deploy_job.build() ###################下载代码################## deploy_job.download_package() ###################生成镜像################## deploy_job.make_docker_image() ##################执行SLS文件################ deploy_job.deploy_state_sls() ##################完成发布################ deploy_job.end_job(order_data={ 'status': D_SUCCESSFUL, 'result_msg': '上线完成', 'complete_time': datetime.now() }, his_data={ 'result': H_SUCCESSFUL, 'end': datetime.now() }, cache_data={ 'is_lock': False, 'status': S_SUCCESSFUL }, write_msg='部署成功') return True except Exception as e: logger.exception(e) deploy_job.end_job(order_data={ 'status': D_FAILED, 'result_msg': str(e), 'complete_time': datetime.now() }, his_data={ 'result': H_FAILED, 'error_msg': str(e), 'end': datetime.now() }, cache_data={ 'is_lock': False, 'status': S_FAILED }, write_msg='部署失败') return False
def perform_update(self, serializer): obj = self.get_object() serializer.save() try: new_name = serializer.data.get('name') if new_name != obj.name: History.objects.filter(project_name=obj.name).update( project_name=new_name) except Exception as e: logger.exception(e) logger.warning(e)
def post(self, request, pk, format=None): try: order_obj = self.get_object() cache_name = 'deploy-{}'.format(order_obj.project.name) deploy_cache = cache.get(cache_name) if not deploy_cache or not deploy_cache.get('is_lock'): raise Exception DeployJob.set_step_cache(cache_name, deploy_cache) return Response(status=status.HTTP_200_OK) except Exception as e: logger.exception(e) return Response(status=status.HTTP_400_BAD_REQUEST)
def get(self, request, pk, format=None): try: order_obj = self.get_object() cache_name = 'deploy-{}'.format(order_obj.project.name) deploy_cache = cache.get(cache_name, {}) log_file = deploy_cache.get('log') lineno = int(request.GET.get('lineno', 1)) if not deploy_cache: return Response({'detial': '找不到此工单的实时上线信息'}, status=status.HTTP_404_NOT_FOUND) linecache.clearcache() lines = linecache.getlines(log_file)[lineno - 1:] return Response(lines) except Exception as e: logger.exception(e) return Response(status=status.HTTP_400_BAD_REQUEST)
def post(self, request, pk, format=None): order_obj = self.get_object() o_status = order_obj.status o_type = order_obj.type try: deploy = DeployAPI(order_obj, request.user.name) deploy.restart_deploy() except DeployError as e: logger.exception(e) return Response({'detail': e.detail}, status=status.HTTP_200_OK) except Exception as e: update_obj(order_obj, **{'status': o_status, 'type': o_type}) update_cache_value(deploy.cache_name, **{ 'is_lock': False, 'status': S_FAILED }) logger.exception(e) return Response({'detail': '任务启动失败'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({'detail': '任务已启动'}, status=status.HTTP_200_OK)
def post(self, request, pk, format=None): order_obj = self.get_object() try: # cache_name = 'deploy-{}'.format(order_obj.project.name) # self.start_deploy(cache_name, order_obj, request.user.name) deploy = DeployAPI(order_obj, request.user.name) deploy.start_deploy() except DeployError as e: logger.exception(e) return Response({'detail': e.detail}, status=status.HTTP_200_OK) except Exception as e: logger.exception(e) update_cache_value(deploy.cache_name, **{ 'is_lock': False, 'status': S_FAILED }) return Response({'detail': '任务启动失败'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response({'detail': '任务已启动'}, status=status.HTTP_200_OK)
def wrapper(*args, **kwargs): try: order_obj = args[1] dingtalk_chatbot.text_msg('{}开始{} {}'.format( order_obj.env.name, TYPE[order_obj.type][1], order_obj.project.name)) realtime_log_url = '{}/deploy/log/{}'.format( settings.FRONT_END_URL, order_obj.id) dingtalk_chatbot.send_link('实时日志', '点击查看日志', realtime_log_url) except Exception as e: logger.exception(e) start = time.time() ret = f(*args, **kwargs) s_ret = '成功' if ret else '失败' end = time.time() elapsed_time = round((end - start), 0) dingtalk_chatbot.text_msg('{}{}{}{},耗时 {}'.format( order_obj.env.name, order_obj.project.name, TYPE[order_obj.type][1], s_ret, timedelta(seconds=elapsed_time)))
def init_job(self): # 上线工单需要获取最新分支信息 try: if self.order_obj.type != ROLLBACK: branch_info = gitlab_api.get_branch_info( self.order_obj.project.gitlab_project, self.order_obj.branche) commit_id = branch_info.commit.get('id') commit = branch_info.commit.get('message') # 设置版本号 self.order_obj.version = self.order_obj.project.version else: raise Exception except Exception as e: logger.exception(e) commit_id = self.order_obj.commit_id commit = self.order_obj.commit self.f = open(self.deploy_cache.get('log'), 'a') # 记录日志 self.his_obj = History.objects.create( **{ 'order_id': self.order_obj.id, 'deploy_times': self.order_obj.deploy_times, 'title': self.order_obj.title, 'project_name': self.order_obj.project.name, 'env': self.order_obj.env.name, 'type': self.order_obj.type, 'servers_ip': self.order_obj.servers_ip, 'servers_saltID': self.order_obj.servers_saltID, 'branche': self.order_obj.branche, 'commit_id': commit_id, 'commit': commit, 'jk_number': -1, 'applicant': self.order_obj.applicant.name, 'reviewer': self.order_obj.reviewer.name, 'assign_to': self.assign_to, 'log_file': self.deploy_cache.get('log'), 'result': H_UNKNOWN })
def log(self, request, pk): try: obj = self.get_object() lineno = int(request.GET.get('lineno', 1)) size = int(request.GET.get('size', 0)) line_count = len(linecache.getlines(obj.log_file)) if line_count == 0: return Response({ 'detail': '不存在日志文件或者日志文件无内容', 'is_tail': True }, status=status.HTTP_404_NOT_FOUND) elif line_count >= lineno: lines = linecache.getlines(obj.log_file)[lineno - 1:lineno - 1 + size] is_tail = bool(line_count < (lineno + size)) return Response({'content': lines, 'is_tail': is_tail}) except Exception as e: logger.exception(e) logger.error(e) return Response({'detail': '获取日志失败'}, status=status.HTTP_400_BAD_REQUEST)
def build(self): # 回滚需要先从历史记录获取jenkins的build_number if self.order_obj.type == ROLLBACK: try: history = History.objects.get(pk=self.order_obj.content) build_number = history.jk_number except: raise Exception('获取回滚版本信息失败') else: logger.debug('开始构建项目') self.f.write('> 开始构建项目\n') self.f.flush() line_number = 0 job_name = self.order_obj.project.jenkins_job build_number = jenkins_api.get_next_build_number(job_name) # 获取jenkins参数 parameters = literal_eval(self.order_obj.project.jenkins_params) parameters['BRANCH'] = self.order_obj.branche parameters['ENV'] = self.order_obj.sub_env_code # queue_id = jenkins_api.build_job(job_name, parameters={'BRANCH': self.order_obj.branche, 'ENV': self.order_obj.env.code}) try: queue_id = jenkins_api.build_job(job_name, parameters=parameters) except Exception as e: logger.exception(e) self.f.write('> 启动jenkins任务失败\n') self.f.write(str(e)) self.f.flush() raise Exception('启动jenkins任务失败') update_cache_value(self.cache_name, self.deploy_cache, **{'build_number': build_number}) self.set_step_cache(self.cache_name, self.deploy_cache) # 最多等待 jenkins 20分 for i in range(240): time.sleep(5) build_info = jenkins_api.get_build_info(job_name, build_number) if build_info and queue_id != build_info.get('queueId'): raise Exception('获取jenkins build number 失败') # 构建中 elif build_info and build_info.get('building') == True: logger.debug('构建中') # 获取jenkins日志 line_number = self.__jenkins_log(job_name, build_number, line_number) continue # 构建成功 elif build_info and build_info.get( 'building') == False and build_info.get( 'result') == 'SUCCESS': logger.debug('构建完成') self.__jenkins_log(job_name, build_number, line_number) update_obj(self.his_obj, **{'jk_result': build_info.get('result')}) break # 构建失败 elif build_info and build_info.get( 'building' ) == False and build_info.get('result') != 'SUCCESS': logger.debug('构建失败') self.__jenkins_log(job_name, build_number, line_number) update_obj(self.his_obj, **{'jk_result': build_info.get('result')}) raise Exception('构建失败') # 构建未开始 else: logger.debug('等待jenkins创建任务') self.f.write('> 构建完成\n') self.f.flush() update_obj(self.his_obj, **{'jk_number': build_number})
def get_build_console_output(self, name, number): try: return self.__server.get_build_console_output(name, number) except JenkinsException as e: logger.exception(e) return None
def get_build_info(self, name, build_number): try: return self.__server.get_build_info(name, build_number) except Exception as e: logger.exception(e) return None