def deploy_add(request): if request.method == "GET": # serverList = Server_Assets.objects.all() groupList = Group.objects.all() return render( request, 'deploy/deploy_add.html', { "user": request.user, "groupList": groupList, 'baseAssets': getBaseAssets(), "project_dir": settings.WORKSPACES }) elif request.method == "POST": # serverList = Server_Assets.objects.all() ipList = request.POST.get('server') try: proAssets = Project_Assets.objects.get( id=request.POST.get('project_id')) except Exception, ex: return JsonResponse({ 'msg': "部署项目添加失败".format(ex=ex), "code": 500, 'data': [] }) try: project = Project_Config.objects.create( project=proAssets, project_service=request.POST.get('project_service'), project_type=request.POST.get('project_type'), project_env=request.POST.get('project_env'), project_name=request.POST.get('project_name'), project_repertory=request.POST.get('project_repertory'), project_address=request.POST.get('project_address'), project_repo_dir=request.POST.get('project_repo_dir'), project_remote_command=request.POST.get( 'project_remote_command'), project_local_command=request.POST.get( 'project_local_command'), project_dir=request.POST.get('project_dir'), project_uuid=uuid.uuid4(), project_exclude=request.POST.get('project_exclude', '.git').rstrip(), project_user=request.POST.get('project_user', 'root'), project_model=request.POST.get('project_model'), project_status=0, project_repo_user=request.POST.get('project_repo_user'), project_repo_passwd=request.POST.get('project_repo_passwd'), project_audit_group=request.POST.get('project_audit_group', None), ) recordProject.delay(project_user=str(request.user), project_id=project.id, project_name=project.project_name, project_content="添加项目") except Exception, ex: logger.error(msg="部署项目添加失败: {ex}".format(ex=ex)) return JsonResponse({ 'msg': "部署项目添加失败: {ex}".format(ex=ex), "code": 500, 'data': [] })
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.project_name,project_content="初始化项目") return JsonResponse({'msg':"初始化成功","code":200,'data':[]})
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) if project.project_type == 'compile':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_detail(request, id,format=None): """ Retrieve, update or delete a server assets instance. """ try: snippet = Project_Config.objects.get(id=id) except Project_Config.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = serializers.ProjectConfigSerializer(snippet) return Response(serializer.data) elif request.method == 'DELETE': if not request.user.has_perm('OpsManage.delete_project_config'): return Response(status=status.HTTP_403_FORBIDDEN) recordProject.delay(project_user=str(request.user),project_id=id,project_name=snippet.project.project_name,project_content="删除项目") snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)
def deploy_detail(request, id,format=None): """ Retrieve, update or delete a server assets instance. """ try: snippet = Project_Config.objects.get(id=id) except Project_Config.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = ProjectConfigSerializer(snippet) return Response(serializer.data) elif request.method == 'DELETE': if not request.user.has_perm('OpsManage.delete_project_config'): return Response(status=status.HTTP_403_FORBIDDEN) recordProject.delay(project_user=str(request.user),project_id=id,project_name=snippet.project_name,project_content="删除项目") snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)
def deploy_add(request): if request.method == "GET": serverList = Server_Assets.objects.all() groupList = Group.objects.all() return render(request,'deploy/deploy_add.html',{"user":request.user,"groupList":groupList, "serverList":serverList,'baseAssets':getBaseAssets(), "project_dir":settings.WORKSPACES}) elif request.method == "POST": serverList = Server_Assets.objects.all() ipList = request.POST.get('server') try: proAssets = Project_Assets.objects.get(id=request.POST.get('project_id')) except Exception, ex: return JsonResponse({'msg':"部署项目添加失败".format(ex=ex),"code":500,'data':[]}) try: project = Project_Config.objects.create( project = proAssets, project_service = request.POST.get('project_service'), project_type = request.POST.get('project_type'), project_env = request.POST.get('project_env'), project_name = request.POST.get('project_name'), project_repertory = request.POST.get('project_repertory'), project_address = request.POST.get('project_address'), project_repo_dir = request.POST.get('project_repo_dir'), project_remote_command = request.POST.get('project_remote_command'), project_local_command = request.POST.get('project_local_command'), project_dir = request.POST.get('project_dir'), project_uuid = uuid.uuid4(), project_exclude = request.POST.get('project_exclude','.git').rstrip(), project_user = request.POST.get('project_user','root'), project_model = request.POST.get('project_model'), project_status = 0, project_repo_user = request.POST.get('project_repo_user'), project_repo_passwd = request.POST.get('project_repo_passwd'), project_audit_group = request.POST.get('project_audit_group',None), ) recordProject.delay(project_user=str(request.user),project_id=project.id,project_name=project.project_name,project_content="添加项目") except Exception, ex: logger.error(msg="部署项目添加失败: {ex}".format(ex=ex)) return JsonResponse({'msg':"部署项目添加失败: {ex}".format(ex=ex),"code":500,'data':[]})
def deploy_add(request): if request.method == "GET": serverList = Server_Assets.objects.all() groupList = Group.objects.all() return render(request,'deploy/deploy_add.html',{"user":request.user,"groupList":groupList, "serverList":serverList,'baseAssets':getBaseAssets()}) elif request.method == "POST": serverList = Server_Assets.objects.all() ipList = request.POST.getlist('server') try: proAssets = Project_Assets.objects.get(id=request.POST.get('project_id')) except Exception, ex: return render(request,'deploy/deploy_add.html',{"user":request.user,"errorInfo":"部署服务器信息添加错误:%s" % str(ex)},) try: project = Project_Config.objects.create( project = proAssets, project_service = request.POST.get('project_service'), project_env = request.POST.get('project_env'), project_name = request.POST.get('project_name'), project_repertory = request.POST.get('project_repertory'), project_address = request.POST.get('project_address'), project_repo_dir = request.POST.get('project_repo_dir'), project_remote_command = request.POST.get('project_remote_command'), project_local_command = request.POST.get('project_local_command'), project_dir = request.POST.get('project_dir'), project_uuid = uuid.uuid4(), project_exclude = request.POST.get('project_exclude','.git').rstrip(), project_user = request.POST.get('project_user','root'), project_model = request.POST.get('project_model'), project_status = 0, project_repo_user = request.POST.get('project_repo_user'), project_repo_passwd = request.POST.get('project_repo_passwd'), project_audit_group = request.POST.get('project_audit_group',None), ) recordProject.delay(project_user=str(request.user),project_id=project.id,project_name=project.project_name,project_content="添加项目") except Exception,e: return render(request,'deploy/deploy_add.html',{"user":request.user, "serverList":serverList,"errorInfo":"部署服务器信息添加错误:%s" % str(e)},)
def deploy_add(request): if request.method == "GET": serverList = Server_Assets.objects.all() groupList = Group.objects.all() return render(request,'deploy/deploy_add.html',{"user":request.user,"groupList":groupList, "serverList":serverList,'baseAssets':getBaseAssets()}) elif request.method == "POST": serverList = Server_Assets.objects.all() ipList = request.POST.getlist('server') try: proAssets = Project_Assets.objects.get(id=request.POST.get('project_id')) except Exception, ex: return render(request,'deploy/deploy_add.html',{"user":request.user,"errorInfo":"部署服务器信息添加错误:%s" % str(ex)},) try: project = Project_Config.objects.create( project = proAssets, project_service = request.POST.get('project_service'), project_env = request.POST.get('project_env'), project_repertory = request.POST.get('project_repertory'), project_address = request.POST.get('project_address'), project_repo_dir = request.POST.get('project_repo_dir'), project_remote_command = request.POST.get('project_remote_command'), project_local_command = request.POST.get('project_local_command'), project_dir = request.POST.get('project_dir'), project_uuid = uuid.uuid4(), project_exclude = request.POST.get('project_exclude','.git').rstrip(), project_user = request.POST.get('project_user','root'), project_model = request.POST.get('project_model'), project_status = 0, project_repo_user = request.POST.get('project_repo_user'), project_repo_passwd = request.POST.get('project_repo_passwd'), project_audit_group = request.POST.get('project_audit_group',None), ) recordProject.delay(project_user=str(request.user),project_id=project.id,project_name=proAssets.project_name,project_content="添加项目") except Exception,e: return render(request,'deploy/deploy_add.html',{"user":request.user, "serverList":serverList,"errorInfo":"部署服务器信息添加错误:%s" % str(e)},)
def deploy_modf(request,pid): try: project = Project_Config.objects.select_related().get(id=pid) tagret_server = Project_Number.objects.filter(project=project) serverList = [ s.server_assets for s in Assets.objects.filter(project=project.project.id) ] except: return render(request,'deploy/deploy_modf.html',{"user":request.user, "errorInfo":"项目不存在,可能已经被删除."}, ) if request.method == "GET": serviceList = Service_Assets.objects.filter(project=project.project) groupList = Group.objects.all() server = [ s.server for s in tagret_server] for ds in serverList: if ds.ip in server:ds.count = 1 else:ds.count = 0 return render(request,'deploy/deploy_modf.html', {"user":request.user,"project":project,"server":tagret_server, "serverList":serverList,"groupList":groupList,"serviceList":serviceList}, ) elif request.method == "POST": ipList = request.POST.getlist('server',None) try: Project_Config.objects.filter(id=pid).update( project_env = request.POST.get('project_env'), project_service = request.POST.get('project_service'), project_repertory = request.POST.get('project_repertory'), project_address = request.POST.get('project_address'), project_repo_dir = request.POST.get('project_repo_dir'), project_remote_command = request.POST.get('project_remote_command'), project_local_command = request.POST.get('project_local_command'), project_dir = request.POST.get('project_dir'), project_exclude = request.POST.get('project_exclude','.git').rstrip(), project_user = request.POST.get('project_user'), project_audit_group = request.POST.get('project_audit_group'), project_repo_user = request.POST.get('project_repo_user'), project_repo_passwd = request.POST.get('project_repo_passwd'), ) recordProject.delay(project_user=str(request.user),project_id=pid,project_name=project.project.project_name,project_content="修改项目") except Exception,e: return render(request,'deploy/deploy_modf.html', {"user":request.user,"errorInfo":"更新失败:"+str(e)}, ) if ipList: tagret_server_list = [ s.server for s in tagret_server ] postServerList = [] for sid in ipList: try: server = Server_Assets.objects.get(id=sid) postServerList.append(server.ip) if server.ip not in tagret_server_list: Project_Number.objects.create(dir=request.POST.get('dir'), server=server.ip, project=project) elif server.ip in tagret_server_list and request.POST.get('dir'): try: Project_Number.objects.filter(project=project,server=server.ip).update(dir=request.POST.get('dir')) except Exception,e: print e pass except Exception,e: return render(request,'deploy/deploy_modf.html',{"user":request.user, "serverList":serverList, "errorInfo":"目标服务器信息添加错误:%s" % str(e)}, ) #清除目标主机 - delList = list(set(tagret_server_list).difference(set(postServerList))) for ip in delList: Project_Number.objects.filter(project=project,server=ip).delete()
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,"serverList":serverList, "bList":bList,"vList":vList}, ) elif request.method == "POST": if request.POST.getlist('project_server',None): serverList = [ Project_Number.objects.get(project=project,server=ds) for ds in request.POST.getlist('project_server') ] allServerList = [ ds.server for ds in Project_Number.objects.filter(project=project) ] #获取项目目标服务器列表与分批部署服务器(post提交)列表的差集 tmpServer = [ i for i in allServerList if i not in request.POST.getlist('project_server') ] elif request.POST.get('project_model',None) == "rollback":tmpServer = None else:return JsonResponse({'msg':"项目部署失败:未选择目标服务器","code":500,'data':[]}) 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_model',None) == "rollback": if project.project_model == 'branch': bName = request.POST.get('project_version') 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': bName = request.POST.get('project_branch') 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')) #创建版本目录 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.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':[]}) #获取要排除的文件 exclude = None if project.project_exclude: try: exclude = '' for s in project.project_exclude.split(','): exclude = '--exclude "{file}"'.format(file=s.replace('\r\n','').replace('\n','').strip()) + ' ' + exclude except Exception,e: return JsonResponse({'msg':str(e),"code":500,'data':[]}) 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') + '/' verName = bName + '_' + 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 + '/' verName = 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.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':[]}) #获取要排除的文件 exclude = None if project.project_exclude: try: exclude = '' for s in project.project_exclude.split(','): exclude = '--exclude "{file}"'.format(file=s.replace('\r\n','').replace('\n','').strip()) + ' ' + exclude except Exception,e: return JsonResponse({'msg':str(e),"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: #配置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 data["username"] = server.username 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 exclude:args = '''src={srcDir} dest={desDir} links=yes recursive=yes compress=yes delete=yes rsync_opts="{exclude}"'''.format(srcDir=softdir, desDir=ds.dir,exclude=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.project_name,project_content="部署项目", project_branch=verName) return JsonResponse({'msg':"项目部署成功","code":200,'data':tmpServer})
project_repo_dir=request.POST.get('project_repo_dir'), project_remote_command=request.POST.get( 'project_remote_command'), project_local_command=request.POST.get( 'project_local_command'), project_dir=request.POST.get('project_dir'), project_exclude=request.POST.get('project_exclude', '.git').rstrip(), project_user=request.POST.get('project_user'), project_audit_group=request.POST.get('project_audit_group'), project_repo_user=request.POST.get('project_repo_user'), project_repo_passwd=request.POST.get('project_repo_passwd'), project_model=request.POST.get('project_model'), ) recordProject.delay(project_user=str(request.user), project_id=pid, project_name=project.project_name, project_content="修改项目") except Exception, ex: logger.error(msg="部署项目修改失败: {ex}".format(ex=ex)) return JsonResponse({ 'msg': "部署项目修改失败: {ex}".format(ex=ex), "code": 500, 'data': [] }) if ipList: tagret_server_list = [s.server for s in tagret_server] postServerList = [] for sid in ipList.split(','): try: assets = Assets.objects.get(id=sid) if hasattr(assets, 'server_assets'):
project_type = request.POST.get('project_type'), project_service = request.POST.get('project_service'), project_repertory = request.POST.get('project_repertory'), project_address = request.POST.get('project_address'), project_repo_dir = request.POST.get('project_repo_dir'), project_remote_command = request.POST.get('project_remote_command'), project_local_command = request.POST.get('project_local_command'), project_dir = request.POST.get('project_dir'), project_exclude = request.POST.get('project_exclude','.git').rstrip(), project_user = request.POST.get('project_user'), project_audit_group = request.POST.get('project_audit_group'), project_repo_user = request.POST.get('project_repo_user'), project_repo_passwd = request.POST.get('project_repo_passwd'), project_model = request.POST.get('project_model'), ) recordProject.delay(project_user=str(request.user),project_id=pid,project_name=project.project_name,project_content="修改项目") except Exception,ex: logger.error(msg="部署项目修改失败: {ex}".format(ex=ex)) return JsonResponse({'msg':"部署项目修改失败: {ex}".format(ex=ex),"code":500,'data':[]}) if ipList: tagret_server_list = [ s.server for s in tagret_server ] postServerList = [] for sid in ipList.split(','): try: server = Server_Assets.objects.get(id=sid) postServerList.append(server.ip) if server.ip not in tagret_server_list: Project_Number.objects.create(dir=request.POST.get('dir'), server=server.ip, project=project) elif server.ip in tagret_server_list and request.POST.get('dir'):
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,"serverList":serverList, "bList":bList,"vList":vList}, ) elif request.method == "POST": if request.POST.getlist('project_server',None): serverList = [ Project_Number.objects.get(project=project,server=ds) for ds in request.POST.getlist('project_server') ] allServerList = [ ds.server for ds in Project_Number.objects.filter(project=project) ] #获取项目目标服务器列表与分批部署服务器(post提交)列表的差集 tmpServer = [ i for i in allServerList if i not in request.POST.getlist('project_server') ] elif request.POST.get('project_model',None) == "rollback":tmpServer = None else:return JsonResponse({'msg':"项目部署失败:未选择目标服务器","code":500,'data':[]}) 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_model',None) == "rollback": if project.project_model == 'branch': bName = request.POST.get('project_version') 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': bName = request.POST.get('project_branch') 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')) #创建版本目录 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.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':[]}) #获取要排除的文件 exclude = None if project.project_exclude: try: exclude = '' for s in project.project_exclude.split(','): exclude = '--exclude "{file}"'.format(file=s.replace('\r\n','').replace('\n','').strip()) + ' ' + exclude except Exception,e: return JsonResponse({'msg':str(e),"code":500,'data':[]}) 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') + '/' verName = bName + '_' + 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 + '/' verName = 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.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':[]}) #获取要排除的文件 exclude = None if project.project_exclude: try: exclude = '' for s in project.project_exclude.split(','): exclude = '--exclude "{file}"'.format(file=s.replace('\r\n','').replace('\n','').strip()) + ' ' + exclude except Exception,e: return JsonResponse({'msg':str(e),"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: #配置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 exclude:args = '''src={srcDir} dest={desDir} links=yes recursive=yes compress=yes delete=yes rsync_opts="{exclude}"'''.format(srcDir=softdir, desDir=ds.dir,exclude=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.project_name,project_content="部署项目", project_branch=verName) return JsonResponse({'msg':"项目部署成功","code":200,'data':tmpServer})