美文网首页
关于jenkins迁移及自动发布

关于jenkins迁移及自动发布

作者: liurongming | 来源:发表于2021-12-18 18:36 被阅读0次

一、jenkins迁移

# 执行如下三个命令即可完成迁移
scp -r /etc/sysconfig/jenkins/   迁移机器IP:/etc/sysconfig/jenkins
scp -r /usr/lib/jenkins/   迁移机器IP:/usr/lib/jenkins
scp -r /var/lib/jenkins/   迁移机器IP:/var/lib/jenkins

# 改变目录权限
chown -R jenkins:jenkins  /var/lib/jenkins/

# 制作自启动
scp -r /etc/rc.d/init.d/jenkins   迁移机器IP:/etc/rc.d/init.d/

# 调试启动
java -DJENKINS_HOME=/var/lib/jenkins -jar jenkins.war

# 建立非登录用户
useradd -d /var/lib/jenkins -c 'Jenkins Automation Server'   jenkins -s /bin/false

二、常见自动化Pipeline

A、后端

#!/usr/bin/env groovy

pipeline {
    agent any

    options {
        timestamps() // 日志显示时间
        skipDefaultCheckout() // 禁止默认检出
        disableConcurrentBuilds() // 不允许并行执行Pipeline
        timeout(time: 1, unit: 'HOURS') // 设置超时时间
    }

    environment {
        GIT_CREDENTIAL_KEY = "jenkinskprivatekey"
        GIT_URL = "ssh://git@xxxx/group/project.git"
    }

    parameters {
        string defaultValue: "172.18.5.xxx", description: '请输入将要发布的服务器', name: 'deploy_servers', trim: true
        choice(name: 'build_target', choices: ['Shell', 'Docker'], description: '请选择制品方式')
        booleanParam(name: 'skip_test', defaultValue: true, description: '你需要在部署之前执行自动化测试么 ?')
        extendedChoice defaultValue: "xxx-gateway,xxx-system,xxx-exam,xxx-live", description: '请选择要发布的项目', multiSelectDelimiter: ',', name: 'choose_project', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', value: 'xxx-gateway,xxx-system,xxx-exam,xxx-live', visibleItemCount: 10
        listGitBranches branchFilter: '.*', credentialsId: "jenkinskprivatekey", defaultValue: 'refs/heads/release', name: 'choose_branch', quickFilterEnabled: false, remoteURL: "ssh://git@xxxx/group/project.git", selectedValue: 'DEFAULT', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH_TAG'
    }
    stages {
        stage('选择环境') {
            steps {
                timeout(time: 10, unit: 'MINUTES') {
                    script {
                        // 编译环境检测
                        checkBuildEnviroment(build_target)
                    }
                }
            }
        }
        stage('拉取源码') {
            steps {
                // 根据选择分支拉取代码
                checkout([$class           : 'GitSCM',
                          branches         : [[name: "${env.choose_branch}"]],
                          extensions       : [],
                          userRemoteConfigs: [[credentialsId: "${GIT_CREDENTIAL_KEY}",
                                               url          : "${GIT_URL}"]]
                ])
                script  {
                    sh '''
                    # 查看修改配置
                    cd ${WORKSPACE}
                    # find ./ -type f -name '*.yml' | grep -vE 'xxx-common|xxx-api|target'|xargs cat |grep namespace
                    find ./ -type f -name '*.yml' | grep -vE 'xxx-common|xxx-api|target'|xargs cat |grep namespace
                '''
                }
            }
        }
        stage('构建制品') {
            steps {
                script {
                    // 构建制品
                    doBuild(build_target)
                }
            }
        }
        stage('部署发布') {
            steps {
                script {
                    // 部署发布
                    doDeploy(build_target)
                }
            }
        }
        stage('结果通知') {
            steps {
                script {
                    // 结果通知
                    doNotify(build_target)
                }
            }
        }
    }

    post {
        always {
            script {
                sh '''
                    # 环境还原
                    cd ${WORKSPACE}
                    git reset --hard
                '''
            }
        }
        success {
            script {
                // 结果通知
                echo "success======"
            }
        }
        failure {
            script {
                // 结果通知
                echo "failure======"
            }
        }
        aborted {
            script {
                // 结果通知
                echo "aborted======"
            }
        }
    }
}

/** 执行环境检测 */
def checkBuildEnviroment(String option) {
    println("选择项目:${env.choose_project}")
    println("选择分支:${env.choose_branch}")

    switch (option) {
        case "Shell":
            println("选择 Shell 原生制品")
            sh '''
                                echo "构建环境检测"
                                pwd
                                java -version
                                mvn -v
                            '''
            break
        case "Docker":
            println("选择 Docker 镜像制品")
            sh '''
                                echo "构建环境检测"
                                pwd
                                java -version
                                mvn -v
                                docker -v
                            '''
            break
    }
}

/** 执行编译 */
def doBuild(String option) {
    if (option == 'Docker') {
        sh '''
            # 镜像构建
            mvn -f pom.xml clean package -Dmaven.test.skip=true -U docker:build
        '''
    } else {
        sh '''
           # 原生构建
           mvn -f pom.xml clean package -Dmaven.test.skip=true -U 
        '''
    }
}

/** 执行发布 */
def doDeploy(String option) {
    if (option == 'Shell') {
        echo "选择Shell部署发布中..."
        def tasks = [:]
        for (toServer in  deploy_servers.tokenize(',')) {
            def sendServer = toServer
            tasks["deploying-${sendServer}"] = {
                for (curProject in  choose_project.tokenize(',')) {
                    def sendProject = curProject
                    println("正在 ${sendServer} 上 - 执行部署:${sendProject} ...")
                    dir("${sendProject}") {
                        def cmdDeploy = "find /home/xxx/ -maxdepth 1 -type f -name '${sendProject}*'|awk -F '/' '{print \$NF}'|xargs -i srvctl {} deploy"
                        sshPublisher(publishers: [sshPublisherDesc(configName: "${sendServer}", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${cmdDeploy}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/xxx', remoteDirectorySDF: false, removePrefix: 'target', sourceFiles: 'target/*.jar')], usePrxxxtionTimestamp: false, useWorkspaceInPrxxxtion: false, verbose: true)])
                    }
                }
            }
        }
        parallel tasks
    } else {
        echo "Docker部署发布..."
    }
}

/** 结果通知 */
def doNotify(String option) {
    if (option == 'Shell') {
        echo "结果通知..."
    } else {
        echo "结果通知..."
    }
}

B、前端

#!/usr/bin/env groovy

pipeline {
    agent any

    options {
        timestamps() // 日志显示时间
        skipDefaultCheckout() // 禁止默认检出
        disableConcurrentBuilds() // 不允许并行执行Pipeline
        timeout(time: 1, unit: 'HOURS') // 设置超时时间
    }

    environment {
        GIT_CREDENTIAL_KEY = "jenkinskprivatekey"
        GIT_URL = "ssh://git@xxx.git"
    }

    parameters {
        string defaultValue: "172.18.5.xxx", description: '请输入将要发布的服务器', name: 'deploy_servers', trim: true
        choice(name: 'build_target', choices: ['Shell', 'Docker'], description: '请选择制品方式')
        listGitBranches branchFilter: '.*', credentialsId: "jenkinskprivatekey", defaultValue: 'refs/heads/release', name: 'choose_branch', quickFilterEnabled: false, remoteURL: "ssh://git@xxx.git", selectedValue: 'DEFAULT', sortMode: 'NONE', tagFilter: '*', type: 'PT_BRANCH_TAG'
    }
    stages {
        stage('选择环境') {
            steps {
                timeout(time: 10, unit: 'MINUTES') {
                    script {
                        // 编译环境检测
                        checkBuildEnviroment(build_target)
                    }
                }
            }
        }
        stage('拉取源码') {
            steps {
                // 根据选择分支拉取代码
                checkout([$class           : 'GitSCM',
                          branches         : [[name: "${env.choose_branch}"]],
                          extensions       : [],
                          userRemoteConfigs: [[credentialsId: "${GIT_CREDENTIAL_KEY}",
                                               url          : "${GIT_URL}"]]
                ])
            }
        }
        stage('构建制品') {
            steps {
                script {
                    // 构建制品
                    doBuild(build_target)
                }
            }
        }
        stage('部署发布') {
            steps {
                script {
                    // 部署发布
                    doDeploy(build_target)
                }
            }
        }
        stage('结果通知') {
            steps {
                script {
                    // 结果通知
                    doNotify(build_target)
                }
            }
        }
    }

    post {
        always {
            script {
                sh '''
                    # 环境还原
                    cd ${WORKSPACE}
                    git reset --hard
                '''
            }
        }
        success {
            script {
                // 结果通知
                echo "success======"
            }
        }
        failure {
            script {
                // 结果通知
                echo "failure======"
            }
        }
        aborted {
            script {
                // 结果通知
                echo "aborted======"
            }
        }
    }
}

/** 执行环境检测 */
def checkBuildEnviroment(String option) {
    println("选择项目:${env.choose_project}")
    println("选择分支:${env.choose_branch}")

    switch (option) {
        case "Shell":
            println("选择 Shell 原生制品")
            sh '''
                                echo "构建环境检测"
                                pwd
                                node -v
                            '''
            break
        case "Docker":
            println("选择 Docker 镜像制品")
            sh '''
                                echo "构建环境检测"
                                pwd   
                                node -v
                                docker -v
                            '''
            break
    }
}

/** 执行编译 */
def doBuild(String option) {
    if (option == 'Docker') {
        sh '''
            # 镜像构建
           echo "docker build"
        '''
    } else {
        sh '''
           # 原生构建
           cd $WORKSPACE && rm -rf dist && yarn && yarn build
        '''
    }
}

/** 执行发布 */
def doDeploy(String option) {
    if (option == 'Shell') {
        echo "选择Shell部署发布中..."
        def tasks = [:]
        for (toServer in  deploy_servers.tokenize(',')) {
            def sendServer = toServer
            tasks["deploying-${sendServer}"] = {
                println("正在 ${sendServer} 上 - 执行部署 ...")
                dir("${WORKSPACE}") {
                    sh '''
                        tar czf dist.tar.gz dist/
                    '''
                    def cmdDeploy = "webctl deploy"
                    sshPublisher(publishers: [sshPublisherDesc(configName: "${sendServer}", transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "${cmdDeploy}", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/omo', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'dist.tar.gz')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: true)]) 
                }
            }
        }
        parallel tasks
    } else {
        echo "Docker部署发布..."
    }
}

/** 结果通知 */
def doNotify(String option) {
    if (option == 'Shell') {
        echo "结果通知..."
    } else {
        echo "结果通知..."
    }
}

三、对应Shell

A、后端

#!/bin/sh

# 当前时间
CUR_YEAR=$(date "+%Y")
CUR_MONTH=$(date "+%Y%m")
CUR_DATE=$(date "+%Y%m%d")
CUR_TIME=$(date "+%H%M%S")
CUR_DATE_TIME="${CUR_DATE}_${CUR_TIME}" 

# 项目名称
# 取命令行第3个参数
# 默认取值:'pj_xxx'
IN_PJ_NMAE=$3
PJ_NAME=${IN_PJ_NAME:-'pj_xxx'}

# 应用文件
APP_NAME=`echo $1 |awk -F '/' '{print $NF}'` 
# 运行环境
# 取命令行第4个参数
# 默认取值:'dev'
IN_CE=$4
CE=${IN_CE:-'sit'}

# 部署目录
APP_DIR="/online/${PJ_NAME}"
# 上传目录
UPLOAD_DIR="/home/${PJ_NAME}"
# 备份路径
BACKUP_DIR="/backup/${PJ_NAME}"
# 指定日志路径
LOG_DIR="/home/srv.log"
# 内存参数
# 取命令行第5个参数
# 默认取MEM_OPTS值
IN_MEM_OPTS=$5
MEM_OPTS=${IN_MEM_OPTS:-"-Xms512m -Xmx512m -Xss1024K -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m"}
# Encoding
ENCODING_PARAM="-Dfile.encoding=UTF-8"
 
# 使用说明,用来提示输入参数
usage() {
    echo "Usage: srvctl app_name.jar [start|stop|restart|status|backup|deploy|setup|syn] [pj_name(default sywn) ce(default dev) mem_opts(default -Xms512m)]"
    exit 1
}
 
# 检查程序是否在运行
is_exist() {
    pid=`ps -ef |grep -w ${APP_NAME} |grep -vE 'grep|sh' |awk '{print \$2}' `
    # 如果不存在返回1,存在返回0
    if [ -z "${pid}" ]; then
        return 1
    else
        return 0
    fi
}

# 部署
deploy(){
    # 加载环境变量
    source /etc/profile && env
    echo ${CUR_DATE_TIME} >>${LOG_DIR}
    echo "${APP_NAME}" >>${LOG_DIR} 
    echo "$PATH" >> ${LOG_DIR}
    echo "${NACOS_NAMESPACE}"-"${CE}">>${LOG_DIR}
    whoami >>${LOG_DIR}
    echo "--------------------------------">> ${LOG_DIR}
    backup
    syn && restart  
}

# 初始化安装目录
function setup(){
    # 应用文件放在
    # /online/应用名/
    # 临时备份放在
    # 备份按日期时间版本归档压缩tar.gz
    # /backup/应用名/
    
    # 日志文件放在
    # on  - 在线日志
    # off - 归档日志
    # /data/logs/应用名/{on,off}/
    
    # core文件放在
    # hot - 可对外
    # ice - 非对外
    # /data/corefile/应用名/{hot,ice}/{日期}/{分类}/
    
    # 持久化备份放在
    # 归档压缩tar.gz文件
    # keep - 在运行
    # fixed - 已归档
    # 备份按日期时间归档压缩tar.gz
    # /data/backup/应用名/{keep,fixed}/{日期}/{分类}/

    mkdir -p /{online,backup}/${PJ_NAME}
    mkdir -p /data/{logs/${PJ_NAME}/{on,off},corefile/${PJ_NAME}/{hot,ice},backup/${PJ_NAME}/{keep,fixed}}
}

# 同步文件
syn() {

        # 判断上传文件目录是否存在
        if [ ! -d ${UPLOAD_DIR} ];then
                echo "${UPLOAD_DIR} is not exist"
                exit 1
        fi

        # 判断文件
        cd ${UPLOAD_DIR}
        if [ ! -f ${APP_NAME} ];then
                echo "${APP_NAME} is not exist"
                exit 2
        fi

        # 拷贝文件
        rsync -a --delete  ${UPLOAD_DIR}/${APP_NAME} ${APP_DIR}/
        if [ $? -eq "0" ]; then
                echo "sync ${APP_NAME} success"
                return 0
        else
                echo "sync ${APP_NAME} failed!"
                return 1
        fi

}

# 临时备份
backup() {
    # 判断文件
    cd ${APP_DIR}
    if [ ! -f ${APP_NAME} ];then
        echo "${APP_NAME} is not exist"
        return 1
    fi
    
    if [ ! -d ${BACKUP_DIR} ];then
        echo "${APP_NAME} is not exist"
        mkdir -p ${BACKUP_DIR}
    fi
    
    # 备份
    tar -czf $BACKUP_DIR/${APP_NAME}.${CUR_DATE_TIME}.tar.gz ${APP_NAME}
    if [ $? -ne "0" ]; then 
        echo "${APP_NAME}  tar is not ok"
        return 1
    fi

    # 每日仅保留10个版本
    cd ${BACKUP_DIR}
        ls -lt |grep ${APP_NAME}|grep ${CUR_DATE} |grep -vE '*.jar$'|awk 'NR>10 {print $NF}' |xargs -i mv {} /tmp
        # 每月仅保留30个版本
    ls -lt |grep ${APP_NAME}|grep ${CUR_MONTH} |grep -vE '*.jar$'|awk 'NR>30 {print $NF}' |xargs -i mv {} /tmp
    
    # 提示
    echo "$APP_NAME backup is done!"
}
 
# 启动方法
start(){
    is_exist
    if [ $? -eq "0" ]; then
        echo "${APP_NAME} is already running. pid=${pid} ."
    else
         # 判断文件
            cd ${APP_DIR}
            if [ ! -f ${APP_NAME} ];then
                    echo "${APP_NAME} is not exist"
            echo "${APP_NAME} start failed"
                    exit 1
            fi

        nohup java -server $MEM_OPTS $ENCODING_PARAM -jar ${APP_DIR}/${APP_NAME} --spring.profiles.active=${CE} >/dev/null 2>&1 &
        if [ $? -eq "0" ];then
            echo "Belong to project ${PJ_NAME}"
            echo "Starting in ${APP_DIR}" 
            echo "Starting CE is ${CE}"
            echo "Starting MEM_OPTS is ${MEM_OPTS}"
            echo "${APP_NAME} start success"
        else
            echo "Belong to project ${PJ_NAME}"
            echo "Starting in ${APP_DIR}" 
            echo "Starting CE is ${CE}"
            echo "Starting MEM_OPTS is ${MEM_OPTS}"
            echo "${APP_NAME} start failed"

        fi
    fi
}
 
# 停止方法
stop(){
    is_exist
    if [ $? -eq "0" ]; then
        kill -9 $pid
    else
         echo "${APP_NAME} is stop."
    fi 
}
 
# 输出运行状态
status(){
    is_exist
    if [ $? -eq "0" ]; then
        echo "The ${APP_NAME} is running and pid is ${pid}"
    else
        echo "${APP_NAME} is stop."
    fi
}
 
# 重启
restart(){
    stop
    start
}
 
# 根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$2" in
 "start")
    start
    ;;
 "stop")
    stop
    ;;
 "status")
    status
    ;;
 "restart")
    restart
    ;;
 "backup")
    backup
    ;;
 "deploy")
    deploy
    ;;
 "setup")
    setup
    ;;
"syn")
    syn
    ;;
 *)
    usage
    ;;
esac

B、前端

#!/bin/sh

# 当前时间
CUR_YEAR=$(date "+%Y")
CUR_MONTH=$(date "+%Y%m")
CUR_DATE=$(date "+%Y%m%d")
CUR_TIME=$(date "+%H%M%S")
CUR_DATE_TIME="${CUR_DATE}_${CUR_TIME}" 

# 项目名称
# 取命令行第3个参数
# 默认取值:'pj_xxx'
IN_PJ_NMAE=$2
PJ_NAME=${IN_PJ_NAME:-'pj_xxx'}

# 应用文件
APP_NAME='dist'

# 部署目录
APP_DIR="/online/${PJ_NAME}"
# 上传目录
UPLOAD_DIR="/home/${PJ_NAME}"
# 备份路径
BACKUP_DIR="/backup/${PJ_NAME}"

# 使用说明,用来提示输入参数
usage() {
    echo "Usage: webctl [deploy|setup] [pj_name(default pj_xxx)]"
    exit 1
}

# 初始化安装目录
function setup(){
    # 应用文件放在
    # /online/应用名/
    # 临时备份放在
    # 备份按日期时间版本归档压缩tar.gz
    # /backup/应用名/
    
    # 日志文件放在
    # on  - 在线日志
    # off - 归档日志
    # /data/logs/应用名/{on,off}/
    
    # core文件放在
    # hot - 可对外
    # ice - 非对外
    # /data/corefile/应用名/{hot,ice}/{日期}/{分类}/
    
    # 持久化备份放在
    # 归档压缩tar.gz文件
    # keep - 在运行
    # fixed - 已归档
    # 备份按日期时间归档压缩tar.gz
    # /data/backup/应用名/{keep,fixed}/{日期}/{分类}/

    mkdir -p /{online,backup}/${PJ_NAME}
    mkdir -p /data/{logs/${PJ_NAME}/{on,off},corefile/${PJ_NAME}/{hot,ice},backup/${PJ_NAME}/{keep,fixed}}
}

# 同步文件
deploy() {

        # 判断上传文件目录是否存在
        if [ ! -d ${UPLOAD_DIR} ];then
                echo "${UPLOAD_DIR} is not exist"
                exit 1
        fi

        # 解压文件
        cd ${UPLOAD_DIR} && tar zxvf dist.tar.gz

        # 判断文件
        cd ${UPLOAD_DIR}
        if [ ! -d ${APP_NAME} ];then
                echo "${APP_NAME} is not exist"
                exit 2
        fi

        # 拷贝文件
        rsync -a --delete  ${UPLOAD_DIR}/${APP_NAME} ${APP_DIR}/
        if [ $? -eq "0" ]; then
                echo "sync ${APP_NAME} success"
                cd ${UPLOAD_DIR} 
                [ -d ${APP_NAME} ] && rm dist -rf 
                return 0
        else
                echo "sync ${APP_NAME} failed!"
                cd ${UPLOAD_DIR} 
                [ -d ${APP_NAME} ] && rm dist -rf 
                return 1
        fi

}
 
# 根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
 "deploy")
    deploy
    ;;
 "setup")
        setup
    ;;
 *)
    usage
    ;;
esac

image.png
M2_HOME
/usr/local/maven
NODE_HOME
/usr/local/node

PATH+EXTRA
$PATH:$M2_HOME/bin:$NODE_HOME/bin

相关文章

网友评论

      本文标题:关于jenkins迁移及自动发布

      本文链接:https://www.haomeiwen.com/subject/pvvgfrtx.html