예제 #1
0
        def failure_record(self, project_deploy_info, message):
            """
            记录失败信息
            :param project_deploy_info: 项目部署信息模型对象
            :param message: 消息信息
            :return:
            """
            # 保存进度信息
            self.project_docker.status = '3'
            self.project_docker.save()
            # 保存进度详情
            project_deploy_info.step_status = 2
            project_deploy_info.content += "<br/><span style='color:red'>%s</span>" % str(
                message)
            project_deploy_info.save()

            # 失败后删除目录
            saltapi_manager.minion_run(salt_master_dict['api_url'],
                                       salt_master_dict['username'],
                                       salt_master_dict['password'],
                                       salt_master_dict['eauth'], minion_id,
                                       'cmd.run', "rm -rf %s" % base_path)

            celery_task_log.info(message)
            raise Exception(message)
예제 #2
0
 def success_record(self,
                    project_deploy_info,
                    deploy_progress_step,
                    message,
                    is_step_end=False,
                    all_end=False):
     """
     记录成功信息
     :param project_deploy_info: 项目部署信息模型对象
     :param deploy_progress_step: 增加的进度(int型)
     :param message: 信息
     :param is_step_end: 是否该步骤结束
     :param is_step_end: 是否全部结束
     :return:
     """
     # 保存进度信息
     self.project_docker.progress += int(deploy_progress_step)
     if all_end:
         # 完成后删除目录
         saltapi_manager.minion_run(salt_master_dict['api_url'],
                                    salt_master_dict['username'],
                                    salt_master_dict['password'],
                                    salt_master_dict['eauth'],
                                    minion_id, 'cmd.run',
                                    "rm -rf %s" % base_path)
         self.project_docker.status = '2'
         end_time = time.clock()
         used_time = str(round(end_time - start_time, 2))
         self.project_docker.time_consume = used_time
     self.project_docker.save()
     # 保存进度详情
     if is_step_end:
         project_deploy_info.step_status = 1
     project_deploy_info.content += "<br/><span style='color:white'>%s</span>" % str(
         message)
     project_deploy_info.save()
예제 #3
0
def get_host_ps_info(salt_master_dict, salt_minion_id):
    salt_minion_obj = models.SaltMinion.objects.get(id=salt_minion_id)
    minion_id = salt_minion_obj.minion_id
    # 删除旧的数据
    models.HostPs.objects.filter(salt_minion=salt_minion_obj).delete()
    # 查询
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'cmd.run', "ps -aeo pid,user,%cpu,%mem,stat,time,command --sort -%mem")
    if _status:
        if _message[0].has_key(minion_id):
            result_info = _message[0][minion_id]
            result_row = result_info.split('\n')
            tmp = []
            for index, row_data in enumerate(result_row):
                if index > 1:
                    row_data_list = re.findall('(\S+)', row_data)
                    result = {
                        'pid': row_data_list[0],
                        'user': row_data_list[1],
                        'cpu_rate': row_data_list[2],
                        'mem_rate': row_data_list[3],
                        'stat': row_data_list[4],
                        'run_time': row_data_list[5],
                        'command': ' '.join(row_data_list[6:])
                    }
                    if float(result['cpu_rate']) > 0 or float(
                            result['mem_rate']) > 0:
                        tmp.append(result)
            # 保存数据
            for data in tmp:
                models.HostPs.objects.create(salt_minion=salt_minion_obj,
                                             view_time=timezone.now(),
                                             **data)
        else:
            celery_task_log.error('查询失败!' + _message[0].encode('utf-8'))
            raise Exception('查询失败!' + _message[0].encode('utf-8'))
    else:
        celery_task_log.error('主机连接失败!')
        raise Exception('主机连接失败!')
예제 #4
0
def deploy_java_project(salt_master_dict, project_docker_id):
    start_time = time.clock()  # 开始时间

    # 项目Docker信息
    project_docker_obj = models.ProjectDockerInfo.objects.get(
        id=project_docker_id)
    # 项目信息
    project_obj = project_docker_obj.project
    minion_id = project_docker_obj.salt_minion.minion_id
    is_start_container = project_docker_obj.is_start_service

    repo_url = project_obj.lib_url.encode('utf-8')
    repo_branch = project_obj.lib_branch if project_obj.lib_branch else ""
    repo_username = project_obj.lib_username
    repo_password = project_obj.lib_password
    repo_project_path = project_obj.lib_path.encode(
        "utf-8") if project_obj.lib_path else ""
    repo_project_deploy_path = project_obj.lib_deploy_path.encode(
        'utf-8') if project_obj.lib_deploy_path else ""
    deploy_port = str(project_obj.deploy_port).encode(
        'utf-8') if project_obj.deploy_port else ""

    # 保存进度和详情的工具类
    class ProjectDeployRecord(object):
        def __init__(self, project_docker):
            self.project_docker = project_docker
            self.project_docker.status = '1'
            self.project_docker.progress = 3
            self.project_docker.save()

        def start_record(self, project_deploy_info, message):
            project_deploy_info.content += "<br/>%s " % message
            project_deploy_info.save()

        def success_record(self,
                           project_deploy_info,
                           deploy_progress_step,
                           message,
                           is_step_end=False,
                           all_end=False):
            """
            记录成功信息
            :param project_deploy_info: 项目部署信息模型对象
            :param deploy_progress_step: 增加的进度(int型)
            :param message: 信息
            :param is_step_end: 是否该步骤结束
            :param is_step_end: 是否全部结束
            :return:
            """
            # 保存进度信息
            self.project_docker.progress += int(deploy_progress_step)
            if all_end:
                # 完成后删除目录
                saltapi_manager.minion_run(salt_master_dict['api_url'],
                                           salt_master_dict['username'],
                                           salt_master_dict['password'],
                                           salt_master_dict['eauth'],
                                           minion_id, 'cmd.run',
                                           "rm -rf %s" % base_path)
                self.project_docker.status = '2'
                end_time = time.clock()
                used_time = str(round(end_time - start_time, 2))
                self.project_docker.time_consume = used_time
            self.project_docker.save()
            # 保存进度详情
            if is_step_end:
                project_deploy_info.step_status = 1
            project_deploy_info.content += "<br/><span style='color:white'>%s</span>" % str(
                message)
            project_deploy_info.save()

        def failure_record(self, project_deploy_info, message):
            """
            记录失败信息
            :param project_deploy_info: 项目部署信息模型对象
            :param message: 消息信息
            :return:
            """
            # 保存进度信息
            self.project_docker.status = '3'
            self.project_docker.save()
            # 保存进度详情
            project_deploy_info.step_status = 2
            project_deploy_info.content += "<br/><span style='color:red'>%s</span>" % str(
                message)
            project_deploy_info.save()

            # 失败后删除目录
            saltapi_manager.minion_run(salt_master_dict['api_url'],
                                       salt_master_dict['username'],
                                       salt_master_dict['password'],
                                       salt_master_dict['eauth'], minion_id,
                                       'cmd.run', "rm -rf %s" % base_path)

            celery_task_log.info(message)
            raise Exception(message)

        def minion_cmd_run_record(self,
                                  project_deploy_info,
                                  deploy_progress_step,
                                  minion_id,
                                  status,
                                  message,
                                  success_message="",
                                  error_keywords=None,
                                  success_keywords="",
                                  is_step_end=False,
                                  all_end=False):
            # 修改状态
            if error_keywords is None:
                error_keywords = []
            if status:
                # minion节点响应信息
                if message[0].has_key(minion_id):
                    minion_salt_response = "...<br/>" + str(
                        message[0][minion_id]).encode('utf-8')
                else:
                    self.failure_record(project_deploy_info, '主机连接失败,请检查!')
                    raise Exception('主机连接失败')
                if [
                        True if keyword in minion_salt_response else False
                        for keyword in error_keywords
                ].count(True) == 0:
                    if success_keywords in minion_salt_response:
                        self.success_record(
                            project_deploy_info, deploy_progress_step,
                            "<pre readonly style='color:black'>{0}</pre>{1}".
                            format(minion_salt_response,
                                   success_message), is_step_end, all_end)
                    else:
                        self.failure_record(
                            project_deploy_info,
                            "<pre readonly style='color:red'>{0}</pre>".format(
                                minion_salt_response))
                else:
                    self.failure_record(
                        project_deploy_info,
                        "<pre readonly style='color:red'>{0}</pre>".format(
                            minion_salt_response))
            else:
                self.failure_record(project_deploy_info, message)

        def minion_state_record(self,
                                project_deploy_info,
                                deploy_progress_step,
                                minion_id,
                                status,
                                message,
                                success_message="",
                                is_step_end=False,
                                all_end=False):
            ignore_error_keywords = ['already']

            # 修改状态
            if status:
                # minion节点响应信息
                if message[0].has_key(minion_id):
                    minion_salt_response = message[0][minion_id]
                else:
                    self.failure_record(project_deploy_info, '主机连接失败,请检查!')
                    raise Exception('主机连接失败')

                if isinstance(minion_salt_response, list):
                    self.failure_record(project_deploy_info,
                                        minion_salt_response[0])

                elif isinstance(minion_salt_response, str) or isinstance(
                        minion_salt_response, unicode):
                    self.failure_record(project_deploy_info,
                                        minion_salt_response)

                elif isinstance(minion_salt_response, dict):
                    error_list = []
                    for item_reponse in minion_salt_response.values():
                        if not item_reponse['result']:
                            if [True if keyword in item_reponse['comment'] else False for keyword in
                                ignore_error_keywords] \
                                    .count(True) == 0:
                                error_list.append({
                                    'sls_name':
                                    item_reponse['name'].encode('utf-8')
                                    if item_reponse.has_key('name') else '',
                                    'sls_comment':
                                    item_reponse['comment'].encode('utf-8')
                                })
                    if len(error_list) > 0:
                        self.failure_record(
                            project_deploy_info,
                            '操作出错,详情: %s...' % str(error_list)[:800])

                    else:
                        self.success_record(
                            project_deploy_info, deploy_progress_step,
                            minion_salt_response if success_message is None
                            else success_message, is_step_end, all_end)
                else:
                    self.failure_record(project_deploy_info,
                                        minion_salt_response)

            else:
                self.failure_record(project_deploy_info, message)

    # 初始化项目部署信息对象,修改状态(部署中)
    models.ProjectDeployInfo.objects.filter(
        project_docker=project_docker_obj).delete()
    project_deploy_record = ProjectDeployRecord(project_docker_obj)

    # ---------step1:安装系统环境----------------
    project_deploy_info1 = models.ProjectDeployInfo(
        step=1,
        step_status=0,
        title='初始化系统环境',
        content="检测代码仓库...",
        project_docker=project_docker_obj,
        minion_id=minion_id)
    project_deploy_info1.save()

    # 处理git/svn路由地址
    project_name = ""  # 项目名称
    repo_auth_url = ""  # 仓库的认证地址

    try:
        repo_url_split = urlparse(repo_url)
        # 项目名称
        project_word_list = repo_url_split.path.split("/")[-1].split(".")[:-1]
        project_name = '.'.join(project_word_list)

        if not re.match(r'^\w+:/{2}\w.+$', repo_url):
            raise Exception("仓库URL地址错误!")

        repo_url_split = repo_url.split("://")
        repo_url_split.insert(1, "://")
        if repo_username or repo_password:
            repo_url_split.insert(2, urllib.quote(repo_username))
            repo_url_split.insert(3, ":" + urllib.quote(repo_password) + "@")

        # 仓库的认证地址
        repo_auth_url = "".join(repo_url_split)
    except Exception as e:
        project_deploy_record.failure_record(project_deploy_info1,
                                             "克隆项目代码失败,不是规范的git/svn代码url地址")

    # docker镜像和容器名称
    project_deploy_record.start_record(project_deploy_info1, '检查镜像名...')
    docker_container_name = project_docker_obj.docker_container
    docker_img_name = project_docker_obj.docker_img
    if not docker_img_name:
        project_deploy_record.failure_record(
            project_deploy_info1,
            "获取成功,项目Docker镜像为:" + docker_img_name.encode('utf-8'))
    project_path = base_path + project_name + (
        ('/' + repo_project_path) if repo_project_path else "")  # 项目的路径

    # 安装git环境
    project_deploy_record.start_record(project_deploy_info1, '安装git环境...')
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'state.sls', 'git')
    project_deploy_record.minion_state_record(project_deploy_info1,
                                              4,
                                              minion_id,
                                              _status,
                                              _message,
                                              success_message='git安装成功!')

    # 安装jdk环境
    project_deploy_record.start_record(project_deploy_info1, '检查jdk环境...')
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'state.sls', 'jdk')
    project_deploy_record.minion_state_record(project_deploy_info1,
                                              4,
                                              minion_id,
                                              _status,
                                              _message,
                                              success_message='jdk安装成功!')
    # master安装maven环境
    project_deploy_record.start_record(project_deploy_info1, '检查maven环境...')
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'state.sls', 'maven')
    project_deploy_record.minion_state_record(project_deploy_info1,
                                              4,
                                              minion_id,
                                              _status,
                                              _message,
                                              success_message='maven安装成功!')

    # 检测安装docker环境
    project_deploy_record.start_record(project_deploy_info1,
                                       '检测docker环境(请自行安装docker环境)...')
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'cmd.run', 'docker version')
    project_deploy_record.minion_cmd_run_record(
        project_deploy_info1,
        4,
        minion_id,
        _status,
        _message,
        success_keywords='Version',
        is_step_end=True,
        success_message='Docker环境检查成功!')

    # -----------------------------------step2:拉取代码-------------------------------------------------------
    project_deploy_info2 = models.ProjectDeployInfo(
        step=2,
        step_status=0,
        title='拉取项目代码',
        content="拉取项目代码中...",
        project_docker=project_docker_obj,
        minion_id=minion_id)
    project_deploy_info2.save()

    # 拉取克隆代码
    project_deploy_record.success_record(
        project_deploy_info2, 2,
        "mkdir -pv {0}<br/>cd {0}<br/>rm -rf {1}<br/>sudo /usr/local/git/bin/git clone {2} {3}"
        .format(base_path, project_name,
                ("-b " + repo_branch) if repo_branch else "", repo_auth_url))
    # Git代码库
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'cmd.run',
        "mkdir -pv {0};cd {0}; rm -rf {1};sudo /usr/local/git/bin/git clone {2} {3}"
        .format(base_path, project_name,
                ("-b " + repo_branch) if repo_branch else "", repo_auth_url))
    project_deploy_record.minion_cmd_run_record(project_deploy_info2,
                                                10,
                                                minion_id,
                                                _status,
                                                _message,
                                                success_message='拉取代码成功!',
                                                error_keywords=['fatal'],
                                                is_step_end=True)

    # -----------------------------------step3:打包java项目代码-----------------------------------------------------
    project_deploy_info3 = models.ProjectDeployInfo(
        step=3,
        step_status=0,
        title='生成项目JAR包',
        content="检查pom.xml文件...",
        project_docker=project_docker_obj,
        minion_id=minion_id)
    project_deploy_info3.save()
    # 检查pom.xml文件
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'file.file_exists', project_path + '/pom.xml')
    if _status:
        if _message[0][minion_id] is True or _message[0][minion_id] == 'True':
            project_deploy_record.success_record(project_deploy_info3,
                                                 5,
                                                 message='检查pom.xml文件成功!')
        else:
            project_deploy_record.failure_record(
                project_deploy_info3,
                message='目录%s中没有找到pom.xml文件!' % project_path)
    else:
        project_deploy_record.failure_record(project_deploy_info3,
                                             message='没有找到pom.xml文件!')

    # 清理项目jar包
    project_deploy_record.start_record(project_deploy_info3, '清理jar包...')
    project_deploy_record.success_record(
        project_deploy_info3, 6,
        "export PATH=$PATH:/usr/local/jdk/bin/<br/>cd {0}<br/>sudo rm -rf /root/.m2/repository/com/<br/>/usr/local/maven3/bin/mvn clean"
        .format(project_path))
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'cmd.run',
        "export PATH=$PATH:/usr/local/jdk/bin/; cd {0};sudo rm -rf /root/.m2/repository/com/;/usr/local/maven3/bin/mvn clean"
        .format(project_path))
    project_deploy_record.minion_cmd_run_record(
        project_deploy_info3,
        6,
        minion_id,
        _status,
        _message,
        success_keywords='BUILD SUCCESS',
        success_message='清理成功!')
    # 生成项目jar包
    project_deploy_record.start_record(project_deploy_info3, '生成jar包...')
    project_deploy_record.success_record(
        project_deploy_info3, 2,
        "/usr/local/maven3/bin/mvn install".format(project_path))
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'cmd.run',
        "export PATH=$PATH:/usr/local/jdk/bin/; cd {0}; /usr/local/maven3/bin/mvn install"
        .format(project_path))
    project_deploy_record.minion_cmd_run_record(
        project_deploy_info3,
        8,
        minion_id,
        _status,
        _message,
        success_keywords='BUILD SUCCESS',
        success_message='生成成功!',
    )
    # 分析mvn信息获取jar包路径
    project_deploy_record.start_record(project_deploy_info3, '获取jar包路径...')
    deploy_jar_path = ""
    if _status:
        mvn_install_str = _message[0][minion_id]
        result_path_list = list(
            re.findall(r'.*Building jar: (.*)', mvn_install_str))
        no_sources_path_list = filter(lambda item: 'sources' not in item,
                                      result_path_list)
        deploy_jar_path_list = list(
            filter(lambda item: repo_project_deploy_path in item,
                   no_sources_path_list))

        if deploy_jar_path_list:
            deploy_jar_path = deploy_jar_path_list[0]
            _status, _message = saltapi_manager.minion_run(
                salt_master_dict['api_url'], salt_master_dict['username'],
                salt_master_dict['password'], salt_master_dict['eauth'],
                minion_id, 'file.file_exists', "{0}".format(deploy_jar_path))
            if _status:
                if _message[0][minion_id] is True or _message[0][
                        minion_id] == 'True':
                    project_deploy_record.success_record(
                        project_deploy_info3,
                        6,
                        message='获取成功!即将部署的jar包为:' +
                        deploy_jar_path.encode('utf-8'),
                        is_step_end=True)
                else:
                    project_deploy_record.failure_record(project_deploy_info3,
                                                         message='获取jar路径失败!')
            else:
                project_deploy_record.failure_record(project_deploy_info3,
                                                     message='主机连接失败')
        else:
            project_deploy_record.failure_record(project_deploy_info3,
                                                 message='获取jar路径失败!')
    else:
        project_deploy_record.failure_record(project_deploy_info3, _message)

    # ---------step4:构建Docker镜像----------------
    project_deploy_info4 = models.ProjectDeployInfo(
        step=4,
        step_status=0,
        title='构建Docker镜像',
        content="生成Dockerfile...",
        project_docker=project_docker_obj,
        minion_id=minion_id)
    project_deploy_info4.save()
    # 删除原来的镜像和容器
    project_deploy_record.start_record(project_deploy_info4, '删除旧的容器和镜像...')
    project_deploy_record.success_record(
        project_deploy_info4, 2,
        "sudo docker stop %s<br/>sudo docker rm -f %s<br/>sudo docker ps -a | awk '{ print $1,$2 }' | grep  %s| awk '{print $1 }' | xargs -I {} sudo docker rm {}<br/>docker rmi -f %s<br/>"
        % (docker_container_name, docker_container_name, docker_img_name,
           docker_img_name))
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'cmd.run',
        "sudo docker stop %s;sudo docker rm -f %s;sudo docker ps -a | awk '{ print $1,$2 }' | grep  %s| awk '{print $1 }' | xargs -I {} sudo docker rm {};docker rmi -f %s;"
        % (docker_container_name, docker_container_name, docker_img_name,
           docker_img_name))
    project_deploy_record.minion_cmd_run_record(project_deploy_info4,
                                                6,
                                                minion_id,
                                                _status,
                                                _message,
                                                success_message='删除成功!')

    # 生成Dockerfile
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'cmd.run',
        "\cp {0} {1};cd {1};sudo echo -e 'FROM daocloud.io/java\nADD {2} "
        "/var/www/\nWORKDIR /var/www/\n"
        "CMD java -Duser.timezone=GMT+8 -Xms512M -Xmx1024M -Xmn246M -jar {2}"
        "' > {3}; cat Dockerfile".format(deploy_jar_path, project_path,
                                         deploy_jar_path.split("/")[-1],
                                         project_path + '/Dockerfile'))
    project_deploy_record.success_record(
        project_deploy_info4, 2,
        "cd {0}<br/>cat Dockerfile".format(project_path))
    project_deploy_record.minion_cmd_run_record(
        project_deploy_info4,
        4,
        minion_id,
        _status,
        _message,
        error_keywords=['error'],
        success_message='生成Dockerfile成功!')
    # 构建项目的docker镜像
    project_deploy_record.start_record(project_deploy_info4, '生成镜像中...')
    project_deploy_record.success_record(
        project_deploy_info4, 2, "cd %s<br/>sudo docker build -t %s ./" %
        (project_path, docker_img_name))
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'cmd.run',
        "cd %s; sudo docker build -t %s ./" % (project_path, docker_img_name))
    project_deploy_record.minion_cmd_run_record(
        project_deploy_info4,
        8,
        minion_id,
        _status,
        _message,
        success_keywords="Successfully built",
        success_message='构建镜像成功!')
    project_deploy_record.start_record(
        project_deploy_info4,
        '检查镜像{0}...'.format(docker_img_name.encode("utf-8")))
    _status, _message = saltapi_manager.minion_run(
        salt_master_dict['api_url'], salt_master_dict['username'],
        salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
        'cmd.run', "sudo docker images")
    if is_start_container:
        project_deploy_record.minion_cmd_run_record(
            project_deploy_info4,
            2,
            minion_id,
            _status,
            _message,
            success_keywords=docker_container_name.encode("utf-8"),
            success_message='检查镜像{0}成功!'.format(
                docker_container_name.encode("utf-8")),
            is_step_end=True)
        # ---------step5:运行项目Docker容器----------------

        project_deploy_info5 = models.ProjectDeployInfo(
            step=5,
            step_status=0,
            title='运行项目Docker容器',
            content="杀死端口进程...",
            project_docker=project_docker_obj,
            minion_id=minion_id)
        project_deploy_info5.save()
        # 杀死端口进程
        project_deploy_record.success_record(
            project_deploy_info5, 2,
            "sudo kill -9 $(netstat -tlnp | grep :%s | awk '{print $7}' | awk -F '/' '{print $1}')"
            % (deploy_port if deploy_port else 0))
        _status, _message = saltapi_manager.minion_run(
            salt_master_dict['api_url'], salt_master_dict['username'],
            salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
            'cmd.run',
            "sudo kill -9 $(netstat -tlnp | grep :%s | awk '{print $7}' | awk -F '/' '{print $1}')"
            % (deploy_port if deploy_port else 0))
        project_deploy_record.minion_cmd_run_record(
            project_deploy_info5,
            2,
            minion_id,
            _status,
            _message,
            success_message='杀死端口进程成功!')

        # 运行容器
        deploy_docker_run_str = project_obj.deploy_docker_run.encode(
            'utf-8') if project_obj.deploy_docker_run else ""
        project_deploy_record.start_record(
            project_deploy_info5, "启动容器...<br/>sudo " + deploy_docker_run_str)
        _status, _message = saltapi_manager.minion_run(
            salt_master_dict['api_url'], salt_master_dict['username'],
            salt_master_dict['password'], salt_master_dict['eauth'], minion_id,
            'cmd.run', 'sudo ' + deploy_docker_run_str)

        # --------------------运行回调事务-----------------------------------
        if project_obj.success_image_callback:
            # 保存上一个进度
            project_deploy_record.minion_cmd_run_record(
                project_deploy_info5,
                3,
                minion_id,
                _status,
                _message,
                error_keywords=['Error'],
                success_message='运行容器成功!',
                is_step_end=True)
            # 回调step
            project_deploy_info6 = models.ProjectDeployInfo(
                step=6,
                step_status=0,
                title='运行回调操作',
                content="执行命令...<br/>" +
                project_obj.success_image_callback.encode('utf-8'),
                project_docker=project_docker_obj,
                minion_id=minion_id)
            _status, _message = saltapi_manager.minion_run(
                salt_master_dict['api_url'], salt_master_dict['username'],
                salt_master_dict['password'], salt_master_dict['eauth'],
                minion_id, 'cmd.run', project_obj.success_image_callback)
            project_deploy_record.minion_cmd_run_record(
                project_deploy_info6,
                3,
                minion_id,
                _status,
                _message,
                success_message='执行成功!',
                is_step_end=True,
                all_end=True)

        else:
            project_deploy_record.minion_cmd_run_record(
                project_deploy_info5,
                6,
                minion_id,
                _status,
                _message,
                success_message='运行容器成功!',
                is_step_end=True,
                all_end=True)

    else:
        # --------------------运行回调事务-----------------------------------
        if project_obj.success_image_callback:
            # 保存上一个进度
            project_deploy_record.minion_cmd_run_record(
                project_deploy_info4,
                9,
                minion_id,
                _status,
                _message,
                success_keywords=docker_container_name.encode("utf-8"),
                success_message='检查镜像{0}成功!'.format(
                    docker_container_name.encode("utf-8")),
                is_step_end=True)
            # 回调step
            project_deploy_info5 = models.ProjectDeployInfo(
                step=5,
                step_status=0,
                title='运行回调操作',
                content="执行命令...<br/>" +
                project_obj.success_image_callback.encode('utf-8'),
                project_docker=project_docker_obj,
                minion_id=minion_id)
            _status, _message = saltapi_manager.minion_run(
                salt_master_dict['api_url'], salt_master_dict['username'],
                salt_master_dict['password'], salt_master_dict['eauth'],
                minion_id, 'cmd.run', project_obj.success_image_callback)
            project_deploy_record.minion_cmd_run_record(
                project_deploy_info5,
                3,
                minion_id,
                _status,
                _message,
                success_message='执行成功!',
                is_step_end=True,
                all_end=True)
        else:
            project_deploy_record.minion_cmd_run_record(
                project_deploy_info4,
                12,
                minion_id,
                _status,
                _message,
                success_keywords=docker_container_name.encode("utf-8"),
                success_message='检查镜像{0}成功!'.format(
                    docker_container_name.encode("utf-8")),
                is_step_end=True,
                all_end=True)
예제 #5
0
def salt_minion_install_app(salt_master_dict, salt_minion_id, app_list):
    salt_minion_obj = models.SaltMinion.objects.get(id=salt_minion_id)
    ignore_error_keywords = ['already', 'enabled']

    # 取出一个进行安装(开始)
    for app_install_id in app_list:
        app_install_status_obj = models.AppInstallStatus.objects.filter(salt_minion_id=salt_minion_id,
                                                                        app_install_id=app_install_id).last()
        app_install_status_obj.status = '0'
        app_install_status_obj.save()

        # 请求API
        start_time = time.clock()
        _status, _message = saltapi_manager.minion_run(salt_master_dict['api_url'],
                                                       salt_master_dict['username'],
                                                       salt_master_dict['password'],
                                                       salt_master_dict['eauth'],
                                                       salt_minion_obj.minion_id,
                                                       'state.sls',
                                                       app_install_status_obj.app_install.name
                                                       )
        end_time = time.clock()
        used_time = str(round(end_time - start_time, 2))

        # 修改状态
        if _status:
            # minion节点响应信息
            if _message[0].has_key(salt_minion_obj.minion_id):
                minion_salt_response = _message[0][salt_minion_obj.minion_id]
            else:
                minion_salt_response = '主机连接失败'

            if isinstance(minion_salt_response, list):
                app_install_status_obj.status = '2'
                app_install_status_obj.error_message = minion_salt_response[0]

            elif isinstance(minion_salt_response, str):
                app_install_status_obj.status = '2'
                app_install_status_obj.error_message = minion_salt_response

            elif isinstance(minion_salt_response, dict):
                error_list = []
                for item_reponse in minion_salt_response.values():
                    if not item_reponse['result']:
                        if [True if keyword in item_reponse['comment'] else False for keyword in ignore_error_keywords].count(True) == 0:
                            error_list.append({'sls_name': item_reponse['name'] if item_reponse.has_key('name') else '',
                                               'sls_comment': item_reponse['comment']})
                if len(error_list) > 0:
                    app_install_status_obj.status = '2'
                    app_install_status_obj.error_message = 'sls文件出错,详情: %s' % str(error_list)[:400]

                else:
                    app_install_status_obj.status = '1'
                    app_install_status_obj.error_message = ''
            else:
                app_install_status_obj.status = '2'
                app_install_status_obj.error_message = minion_salt_response

        else:
            app_install_status_obj.status = '2'
            app_install_status_obj.error_message = _message

        app_install_status_obj.used_time = used_time
        app_install_status_obj.save()