首页 > 其他 > 详细

代码发布6 点击发布按钮(执行节点对应的操作), 写入的执行代码处理

时间:2020-04-19 23:12:57      阅读:99      评论:0      收藏:0      [点我收藏+]

点击发布按钮真正的执行节点背后对应的操作

  • 先假设所有的节点操作都是正常执行
# 1 开始节点 开始节点无需任何操作 直接成功即可
            start_node = models.Node.objects.filter(text=开始,task_id=task_id).first()
            # 修改开始节点颜色数据
            start_node.status = green
            start_node.save()
            # 将修改的数据变动发送给前端
            async_to_sync(self.channel_layer.group_send)(task_id,{type:my.send,
                                                                  message:{code:deploy,
                                                                             node_id:start_node.pk,
                                                                             color:start_node.status
                                                                             }
                                                                  }
                                                         )

            # 2 下载前
            if task_obj.before_download_script:
                # TODO:真正的下载脚本内容并在本地执行
                before_download_node = models.Node.objects.filter(text=下载前,task_id=task_id).first()
                before_download_node.status = green
                before_download_node.save()
                # 将修改的数据变动发送给前端
                async_to_sync(self.channel_layer.group_send)(task_id, {type: my.send,
                                                                       message: {code: deploy,
                                                                                   node_id: before_download_node.pk,
                                                                                   color: before_download_node.status
                                                                                   }
                                                                       }
  • 代码优化
# 将真正操作节点的所有操作封装成一个类的方法
  • channel-layers小bug修复
# 我们尝试着先模拟延迟 看看是否能够直接在前端展示出延时的效果
if text == deploy:
   # 调用deploy方法 完成发布操作
   # self.deploy(task_id,task_obj)  类似于单线程无法实现节点渐变式效果(会等待数据放入队列全部完成,统一群发)

   # 自己开设一个线程处理发布任务
   thread = threading.Thread(target=self.deploy,args=(task_id,task_obj))
            thread.start()
  • 等代码能够正常运行了之后再去真正的书写执行代码

 

真正的书写执行代码

  • 从远程仓库下载的代码和脚本应该存储在特定的位置

技术分享图片

"""这里我们直接采用存储在本地的方式 (你可以存储到远程服务器)"""
# 文件结构
-codes
    --bbs
  --cmdb
  --luffycity
      --luffycity-test-v1-12313
        --luffycity
          --项目代码
      --scripts
          -- 脚本文件

                import os
        from django.conf import settings
        project_name = task_obj.project.title
        uid = task_obj.uid
        script_folder = os.path.join(settings.DEPLOY_CODE_PATH,project_name,uid,scripts)
        project_folder = os.path.join(settings.DEPLOY_CODE_PATH,project_name,uid,project_name)

        # 如果代码判断文件夹是否存在并决定是否动态创建
        if not os.path.exists(script_folder):
            # 如何一次性创建多级目录 makedirs
            os.makedirs(script_folder)
        if not os.path.exists(project_folder):
            os.makedirs(project_folder)    
  • 一旦某一个环节执行错误 应该立刻停止下面所有的操作,没必要再执行
# 2 下载前
        if task_obj.before_download_script:
            # TODO:真正的下载脚本内容并在本地执行
            """
            1 将钩子脚本内容下载到本地
            2 在本地执行该脚本
            """
            script_name = before_download_script.py
            script_path = os.path.join(script_folder,script_name)
            # 文件操作存储内容
            with open(script_path,w,encoding=utf-8) as f:
                f.write(task_obj.before_download_script)

            # 执行脚本内容  subprocess  该模块可以模拟计算机的终端
            import subprocess
            status = green
            try:
                subprocess.check_output(python {0}.format(script_name),
                                        shell = True,
                                        cwd = script_folder
                                        # 先切换到script_folder路径下再执行命令
                                        )
            except Exception as e:
                # 只要报异常 说明脚本文件内的代码写的不对
                status = red

            before_download_node = models.Node.objects.filter(text=下载前, task_id=task_id).first()
            before_download_node.status = status
            before_download_node.save()
            # 将修改的数据变动发送给前端
            async_to_sync(self.channel_layer.group_send)(task_id, {type: my.send,
                                                                   message: {code: deploy,
                                                                               node_id: before_download_node.pk,
                                                                               color: status
                                                                               }
                                                                   }
                                                         )
            # 一旦允许出错 代码就不应该继续往下允许
            if status == red:
                return
  • 下载和上传代码真正实现
# 参考今日代码
status = green
        try:
            # from app01.utils.ab_git import GitRepository
            # obj = GitRepository(project_folder,task_obj.project.repo,task_obj.tag)
            # 借助于gitpython模块下载代码
            from git.repo import Repo
            # 下载远程仓库的代码可以怎么搞   clone  pull
            # 先定义代码的存放位置
            Repo.clone_from(task_obj.project.repo, to_path=project_folder, branch=master)
            pass
        except Exception as e:
            status = red
        # 模拟下载延迟
        # time.sleep(3)
        download_node = models.Node.objects.filter(text=下载, task_id=task_id).first()
        # 修改开始节点颜色数据
        download_node.status = status
        download_node.save()
        # 将修改的数据变动发送给前端
        async_to_sync(self.channel_layer.group_send)(task_id, {type: my.send,
                                                               message: {code: deploy,
                                                                           node_id: download_node.pk,
                                                                           color: status
                                                                           }
                                                               }
                                                     )
        if status == red:
            return
  • 需要服务器上面的操作 需要用continue
        for server_obj in task_obj.project.servers.all():
            # 6.1 服务器
            # time.sleep(3)
            status = green
            try:
                # 将代码上传到服务器上  习惯将数据打包降低大小提升传输速率 这里我们也一样 对代码数据继续打包再上传
                upload_folder_path = os.path.join(settings.DEPLOY_CODE_PATH,project_name,uid)
                # 对上述文件继续压缩
                """针对压缩之后的文件夹存储位置 也是单独存储"""
                import shutil
                pack_path = shutil.make_archive(
                    base_name=os.path.join(package_folder,uid+.zip),  # 压缩包路径,
                    format = zip,  # zip tar rar
                    root_dir= upload_folder_path  # 待压缩的文件
                )
                # 上传代码  paramiko模块
                from app01.utils.ssh import SSHProxy
                with SSHProxy(server_obj.hostname,22,root,jason123) as ssh:
                    # 远程服务器也应该有一个存储代码的位置
                    remote_folder = os.path.join(settings.SERVER_PACKAGE_PATH,project_name)
                    ssh.command(mkdir -p {0}.format(remote_folder))
                    upload_path = os.path.join(remote_folder,uid+.zip) #运行过程中,/变为\
                    upload_path = upload_path.replace(\\,/)  # 替换当中标识符号
                    print(upload_path:,upload_path)
                    obj.upload(pack_path,upload_path)
            except Exception as e:
                status = red
            server_node = models.Node.objects.filter(text=server_obj.hostname,
                                                     task_id=task_id,
                                                     server=server_obj
                                                     ).first()
            # 修改开始节点颜色数据
            server_node.status = status
            server_node.save()
            # 将修改的数据变动发送给前端
            async_to_sync(self.channel_layer.group_send)(task_id, {type: my.send,
                                                                   message: {code: deploy,
                                                                               node_id: server_node.pk,
                                                                               color: status
                                                                               }
                                                                   }
                                                         )
            if status == red:  # 因为是多台服务器 一台出错了 结束当前服务器循环开始下一个服务器循环
                continue

 

拓展

1. 补全发布前和发布后的钩子脚本运行

2. 发布页面实时展示日志信息

代码发布6 点击发布按钮(执行节点对应的操作), 写入的执行代码处理

原文:https://www.cnblogs.com/ludingchao/p/12734913.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!