def deploy_manage(request, pid): try: project = Project_Config.objects.get(id=pid) if project.project_repertory == 'git': version = GitTools() elif project.project_repertory == 'svn': version = SvnTools() except: return render( request, 'deploy/deploy_manage.html', { "user": request.user, "errorInfo": "项目不存在,可能已经被删除." }, ) if request.method == "GET": # 获取最新版本 version.pull(path=project.project_repo_dir) if project.project_model == 'branch': bList = version.branch(path=project.project_repo_dir) elif project.project_model == 'tag': bList = version.tag(path=project.project_repo_dir) vList = version.log(path=project.project_repo_dir, number=50) return render( request, 'deploy/deploy_manage.html', { "user": request.user, "project": project, "bList": bList, "vList": vList }, )
def deploy_version(request, pid): try: project = Project_Config.objects.select_related().get(id=pid) if project.project_repertory == 'git': version = GitTools() except: return render(request, 'deploy/deploy_version.html', {"user": request.user, "errorInfo": "项目不存在,可能已经被删除."}, ) if request.method == "POST": try: project = Project_Config.objects.get(id=pid) if project.project_repertory == 'git': version = GitTools() elif project.project_repertory == 'svn': version = SvnTools() except: return JsonResponse({'msg': "项目资源不存在", "code": 403, 'data': []}) if project.project_status == 0: return JsonResponse({'msg': "请先初始化项目", "code": 403, 'data': []}) if request.POST.get('op') in ['create', 'delete', 'query', 'histroy']: if request.POST.get('op') == 'create': if request.POST.get('model') == 'branch': result = version.createBranch(path=project.project_repo_dir, branchName=request.POST.get('name')) elif request.POST.get('model') == 'tag': result = version.createTag(path=project.project_repo_dir, tagName=request.POST.get('name')) elif request.POST.get('op') == 'delete': if request.POST.get('model') == 'branch': result = version.delBranch(path=project.project_repo_dir, branchName=request.POST.get('name')) elif request.POST.get('model') == 'tag': result = version.delTag(path=project.project_repo_dir, tagName=request.POST.get('name')) elif request.POST.get('op') == 'query': if project.project_model == 'branch': result = version.log(path=project.project_repo_dir, bName=request.POST.get('name'), number=50) return JsonResponse({'msg': "操作成功", "code": 200, 'data': result}) else: result = version.tag(path=project.project_repo_dir) elif request.POST.get('op') == 'histroy': result = version.show(path=project.project_repo_dir, branch=request.POST.get('project_branch'), cid=request.POST.get('project_version', None)) return JsonResponse({'msg': "操作成功", "code": 200, 'data': "<pre> <xmp>" + result[1].replace('<br>', '\n') + "</xmp></pre>"}) else: return JsonResponse({'msg': "非法操作", "code": 500, 'data': []}) if result[0] > 0: return JsonResponse({'msg': result[1], "code": 500, 'data': []}) else: return JsonResponse({'msg': "操作成功", "code": 200, 'data': []})
def deploy_ask(request, pid): try: project = Project_Config.objects.get(id=pid) if project.project_repertory == 'git': version = GitTools() elif project.project_repertory == 'svn': version = SvnTools() except: return render(request, 'deploy/deploy_ask.html', {"user": request.user, "errorInfo": "项目不存在,可能已经被删除."}, ) if request.method == "GET": vList = None version.pull(path=project.project_repo_dir) if project.project_model == 'branch': # 获取最新版本 bList = version.branch(path=project.project_repo_dir) vList = version.log(path=project.project_repo_dir, number=50) elif project.project_model == 'tag': bList = version.tag(path=project.project_repo_dir) audit_group = Group.objects.get(id=project.project_audit_group) userList = [u.get('username') for u in audit_group.user_set.values()] return render(request, 'deploy/deploy_ask.html', {"user": request.user, "project": project, "userList": userList, "bList": bList, "vList": vList}, ) elif request.method == "POST": try: order = ProjectOrder.objects.create( order_user=request.user, order_project=project, order_subject=request.POST.get('order_subject'), order_audit=request.POST.get('order_audit'), order_status=request.POST.get('order_status', 2), order_level=request.POST.get('order_level'), order_content=request.POST.get('order_content'), order_branch=request.POST.get('order_branch', None), order_comid=request.POST.get('order_comid', None), order_tag=request.POST.get('order_tag', None) ) sendEmail.delay(order_id=order.id, mask='【申请中】') except Exception as e: return render(request, 'deploy/deploy_ask.html', {"user": request.user, "errorInfo": "项目部署申请失败:%s" % str(e)}, ) return HttpResponseRedirect('/deploy_ask/{id}/'.format(id=pid))
def deploy_init(request, pid): if request.method == "POST": project = Project_Config.objects.select_related().get(id=pid) if project.project_repertory == 'git': version = GitTools() elif project.project_repertory == 'svn': version = SvnTools() version.mkdir(dir=project.project_repo_dir) version.mkdir(dir=project.project_dir) result = version.clone(url=project.project_address, dir=project.project_repo_dir, user=project.project_repo_user, passwd=project.project_repo_passwd) if result[0] > 0: return JsonResponse({'msg': result[1], "code": 500, 'data': []}) else: Project_Config.objects.filter(id=pid).update(project_status=1) recordProject.delay(project_user=str(request.user), project_id=project.id, project_name=project.project_name, project_content="初始化项目") return JsonResponse({'msg': "初始化成功", "code": 200, 'data': []})
def deploy_run(request, pid): try: project = Project_Config.objects.get(id=pid) serverList = Project_Number.objects.filter(project=project) if project.project_repertory == 'git': version = GitTools() elif project.project_repertory == 'svn': version = SvnTools() except: return render( request, 'deploy/deploy_run.html', { "user": request.user, "errorInfo": "项目不存在,可能已经被删除." }, ) if request.method == "GET": if project.project_model == 'branch': bList = version.branch(path=project.project_repo_dir) elif project.project_model == 'tag': bList = version.tag(path=project.project_repo_dir) # 获取最新版本 version.pull(path=project.project_repo_dir) vList = version.log(path=project.project_repo_dir, number=50) return render( request, 'deploy/deploy_run.html', { "user": request.user, "project": project, "bList": bList, "vList": vList }, ) elif request.method == "POST": if DsRedis.OpsProject.get(redisKey=project.project_uuid + "-locked") is None: # 判断该项目是否有人在部署 # 给项目部署加上锁 DsRedis.OpsProject.set(redisKey=project.project_uuid + "-locked", value=request.user) DsRedis.OpsDeploy.delete(project.project_uuid) if request.POST.get('project_mode', None) == "rollback": if project.project_model == 'branch': trueDir = project.project_dir + project.project_env + '/' + request.POST.get( 'project_version') + '/' DsRedis.OpsDeploy.lpush( project.project_uuid, data="[Start] Start Rollback branch:%s vesion: %s" % (request.POST.get('project_branch'), request.POST.get('project_version'))) elif project.project_model == 'tag': trueDir = project.project_dir + project.project_env + '/' + request.POST.get( 'project_branch') + '/' DsRedis.OpsDeploy.lpush( project.project_uuid, data="[Start] Start Rollback tag:%s" % request.POST.get('project_branch')) else: # 判断版本上线类型再切换分支到指定的分支/Tag if project.project_model == 'branch': bName = request.POST.get('project_branch') result = version.checkOut(path=project.project_repo_dir, name=bName) DsRedis.OpsDeploy.lpush( project.project_uuid, data="[Start] Switched to branch %s" % bName) # reset到指定版本 result = version.reset( path=project.project_repo_dir, commintId=request.POST.get('project_version')) DsRedis.OpsDeploy.lpush( project.project_uuid, data="[Running] Git reset to {comid} info: {info}". format(comid=request.POST.get('project_version'), info=result[1])) trueDir = project.project_dir + project.project_env + '/' + request.POST.get( 'project_version') + '/' elif project.project_model == 'tag': bName = request.POST.get('project_branch') result = version.checkOut(path=project.project_repo_dir, name=bName) DsRedis.OpsDeploy.lpush(project.project_uuid, data="[Start] Switched to tag %s" % bName) trueDir = project.project_dir + project.project_env + '/' + bName + '/' # 创建版本目录 base.mkdir(dirPath=trueDir) DsRedis.OpsDeploy.lpush( project.project_uuid, data="[Running] Mkdir version dir: {dir} ".format( dir=trueDir)) # 创建快捷方式 softdir = project.project_dir + project.project_name + '/' result = base.lns(spath=trueDir, dpath=softdir.rstrip('/')) DsRedis.OpsDeploy.lpush( project.project_uuid, data= "[Running] Make softlink cmd: ln -s {sdir} {ddir} info: {info}" .format(sdir=trueDir, ddir=softdir, info=result[1])) if result[0] > 0: return JsonResponse({ 'msg': result[1], "code": 500, 'data': [] }) # 执行部署命令 - 编译型语言 if project.project_local_command: result = base.cmds(cmds=project.project_local_command) DsRedis.OpsDeploy.lpush( project.project_uuid, data= "[Running] Execute local command: {cmds} info: {info}". format(cmds=project.project_local_command, info=result[1])) if result[0] > 0: return JsonResponse({ 'msg': result[1], "code": 500, 'data': [] }) # 非编译型语言 else: # 获取要排除的文件 exclude = None ansible_exclude_list = None if project.project_exclude: try: exclude = '' ansible_exclude_list = [] for s in project.project_exclude.split(','): exclude = '--exclude "{file}"'.format( file=s.replace('\r\n', '').replace( '\n', '').strip()) + ' ' + exclude exclude_str = '--exclude="{file}"'.format( file=s.replace('\r\n', '').replace( '\n', '').strip()) ansible_exclude_list.append(exclude_str) except Exception as e: return JsonResponse({ 'msg': str(e), "code": 500, 'data': [] }) # 配置rsync同步文件到本地目录 result = base.rsync(sourceDir=project.project_repo_dir, destDir=trueDir, exclude=exclude) DsRedis.OpsDeploy.lpush( project.project_uuid, data="[Running] Rsync {sDir} to {dDir} exclude {exclude}" .format(sDir=project.project_repo_dir, dDir=trueDir, exclude=exclude)) if result[0] > 0: return JsonResponse({ 'msg': result[1], "code": 500, 'data': [] }) # 授权文件 result = base.chown(user=project.project_user, path=trueDir) DsRedis.OpsDeploy.lpush( project.project_uuid, data="[Running] Chown {user} to {path}".format( user=project.project_user, path=trueDir)) if result[0] > 0: return JsonResponse({ 'msg': result[1], "code": 500, 'data': [] }) # 调用ansible同步代码到远程服务器上 resource = [] hostList = [] for ds in serverList: server = Server_Assets.objects.get(ip=ds.server) hostList.append(ds.server) data = dict() if server.keyfile == 1: data['port'] = int(server.port) data["hostname"] = server.ip else: data["hostname"] = server.ip data["port"] = int(server.port) data["username"] = server.username data["password"] = server.passwd resource.append(data) if resource and hostList: if ansible_exclude_list: ansible_exclude = ','.join(ansible_exclude_list) args = '''src={srcDir} dest={desDir} links=yes recursive=yes compress=yes delete=yes rsync_opts="{exclude}"'''.format( srcDir=softdir, desDir=ds.dir, exclude=ansible_exclude) else: args = '''src={srcDir} dest={desDir} links=yes recursive=yes compress=yes delete=yes'''.format( srcDir=softdir, desDir=ds.dir) ANS = ANSRunner(resource) ANS.run_model(host_list=hostList, module_name='synchronize', module_args=args) # 精简返回的结果 dataList = ANS.handle_model_data(ANS.get_model_result(), 'synchronize', module_args=args) for ds in dataList: DsRedis.OpsDeploy.lpush( project.project_uuid, data= "[Running] Rsync project to {host} status: {status} msg: {msg}" .format(host=ds.get('ip'), status=ds.get('status'), msg=ds.get('msg'))) if ds.get('status') == 'failed': result = (1, ds.get('ip') + ds.get('msg')) # 目标服务器执行后续命令 if project.project_remote_command: ANS.run_model(host_list=hostList, module_name='raw', module_args=project.project_remote_command) # 精简返回的结果 dataList = ANS.handle_model_data( ANS.get_model_result(), 'raw', module_args=project.project_remote_command) for ds in dataList: DsRedis.OpsDeploy.lpush( project.project_uuid, data= "[Running] Execute command to {host} status: {status} msg: {msg}" .format(host=ds.get('ip'), status=ds.get('status'), msg=ds.get('msg'))) if ds.get('status') == 'failed': result = (1, "部署错误: " + ds.get('msg')) if result[0] > 0: DsRedis.OpsProject.delete(redisKey=project.project_uuid + "-locked") return JsonResponse({ 'msg': result[1], "code": 500, 'data': [] }) DsRedis.OpsDeploy.lpush(project.project_uuid, data="[Done] Deploy Success.") # 切换版本之后取消项目部署锁 DsRedis.OpsProject.delete(redisKey=project.project_uuid + "-locked") # 异步记入操作日志 if request.POST.get('project_version'): bName = request.POST.get('project_version') recordProject.delay(project_user=str(request.user), project_id=project.id, project_name=project.project_name, project_content="部署项目", project_branch=bName) return JsonResponse({'msg': "项目部署成功", "code": 200, 'data': []}) else: return JsonResponse({ 'msg': "项目部署失败:{user}正在部署改项目,请稍后再提交部署。".format( user=DsRedis.OpsProject.get(redisKey=project.project_uuid + "-locked")), "code": 500, 'data': [] })