#!/usr/bin/env groovy
pipeline {

    agent any
    // using the Timestamps plugin we can add timestamps to the console log
    options {
        timestamps()
    }

    environment {

        GROUPID = readMavenPom().getGroupId()//com.storlead
        ARTIFACTID = readMavenPom().getArtifactId()//sp-salary-management
        VERSION = readMavenPom().getVersion()//1.0
    }
    // 参数
    parameters {

        choice(
                name: 'modulePrefix',
                choices: 'api\nui',
                description: '选择要部署 API or UI'
        )
        choice(
                name: 'module',
                choices: 'sp-salary-management',
                description: '选择要部署的项目'
        )
        choice(
                name: 'profile',
                choices: ['test', 'prod'],
                description: '选择要部署的配置文件'
        )
    }

    stages {

        stage('处理参数') {
            steps {
                script {
                    echo "处理参数"
                    script {
                        //服务器配置
                        SERVER_SSH_PORT = 53023
                        SERVER_HOST = "node1.storlead.com"
                        SWARM_INIT_REPLICAS_NUM = 1

                        //服务配置
                        API_PORT = 8703
                        API_REMOTE_DEBUG_PORT = 8006
                        API_NAMESPACE_RESTFUL = "api"

                        //DOCKER配置
                        DOCKER_REGISTRY = "reg-aliyun"
                        DOCKER_HOST = "registry.cn-shenzhen.aliyuncs.com"
                        //Docker私服登陆url https://registry-vpc.cn-shenzhen.aliyuncs.com
                        DOCKER_LOGIN_REGISTRY = "https://${DOCKER_HOST}"

                        BUILD_PREFIX = "storlead-huawei"
                        //镜像完整名称 registry-vpc.cn-shenzhen.aliyuncs.com/sp-salary-management-prod:1.0
                        DOCKER_IMG_NAME = "${DOCKER_HOST}/${BUILD_PREFIX}/${ARTIFACTID}-${params.profile}:${VERSION}"
                        //镜像名 sp-salary-management-prod:1.0
                        IMG_NAME = "${BUILD_PREFIX}/${params.module}-${params.profile}:${VERSION}"

                        PUSH_DOCK_IMG = true

                        if (params.profile == "dev-local") {
                            SERVER_HOST = "192.168.1.101"
                            SERVER_SSH_PORT = 22
                            API_PORT = 8701
                            API_REMOTE_DEBUG_PORT = 8704
                            DOCKER_HOST = "192.168.1.101:5000"
                            DOCKER_LOGIN_REGISTRY = "http://${DOCKER_HOST}"
                            DOCKER_IMG_NAME = "${DOCKER_HOST}/${BUILD_PREFIX}/${ARTIFACTID}-${params.profile}:${VERSION}"
                        }
                        if (params.profile == "test") {
                            SERVER_HOST = "test1.storlead.com"
                            API_PORT = 8702
                            API_REMOTE_DEBUG_PORT = 8705
                        }
                        if (params.profile == "prod") {
                            SERVER_HOST = "110.41.82.21"
                            API_PORT = 8703
                            API_REMOTE_DEBUG_PORT = 8706
                        }
                    }
                }
            }
        }

        stage('Node 编译') {
            when {
                environment name: 'modulePrefix', value: 'ui'
            }
            agent {
                docker {
                    image "registry.cn-shenzhen.aliyuncs.com/storlead/node:10-alpine-npm"
                    args '-v /app:/app/:z -v /etc/localtime:/etc/localtime:ro -u root'
                    reuseNode true
                }
            }
            steps {
                withCredentials([
                        usernamePassword(credentialsId: 'storleadHW', usernameVariable: 'usernameHW', passwordVariable: 'passwordHW'),
                        usernamePassword(credentialsId: 'storlead', usernameVariable: 'username', passwordVariable: 'password')
                ]) {
                    script {
                        echo "发布 UI 代码"

                        def remote = [:]
                        remote.allowAnyHosts = true
                        remote.name = "${SERVER_HOST}"
                        remote.host = "${SERVER_HOST}"
                        remote.port = 53023
                        remote.user = username
                        remote.password = password

                        if (params.profile == "prod") {
                            remote.port = 22
                            remote.user = "root"
                            remote.user = usernameHW
                            remote.password = passwordHW
                        }

                        sh """cd ${params.modulePrefix}/${params.module} && npm install && npm run ${params.profile}"""

                        sshCommand remote: remote, command: "mkdir -p /app/sp/ui/sp-salary-management"
                        sshCommand remote: remote, command: "rm -rf /app/sp/ui/sp-salary-management/*"
                        sshPut remote: remote, from: "${params.modulePrefix}/${params.module}/www/", into: "/app/sp/ui/sp-salary-management/"
                        sshCommand remote: remote, command: "cp -rf /app/sp/ui/sp-salary-management/www/* /app/sp/ui/sp-salary-management/"

                    }
                }
            }
        }

        stage('Maven 编译') {
            when {
                environment name: 'modulePrefix', value: 'api'
            }
            agent {
                docker {
                    image 'maven:3-amazoncorretto-11'
                    //让docker 使用 host 宿主机的 m2仓库 使用root用户来运行 以让指定的~/.m2/config/setting.xml 阿里加速下载maven 依赖生效
                    args '-v /app:/app:z -v $HOME/.m2:/root/.m2:z -u root'
                    reuseNode true
                }
            }

            steps {
                echo "编译 API 代码"
                sh "mvn clean package -U -am -pl ${modulePrefix}/${params.module} -P${params.profile} -Dmaven.test.skip=true"
            }
        }

        // 项目打包到镜像并推送到镜像仓库
        stage('构建Docker镜像') {
            when {
                environment name: 'modulePrefix', value: 'api'
            }
            steps {
                echo "构建Dcoker镜像"
                script {
                    docker.withRegistry(DOCKER_LOGIN_REGISTRY, DOCKER_REGISTRY) {

                        //  BASE_IMAGE = 'registry.cn-shenzhen.aliyuncs.com/storlead/centos7-openjdk8:latest'
                        //  BASE_IMAGE = 'amazoncorretto:11-alpine'
                        //  BASE_IMAGE = 'blankhang/alpine-3.12:openjdk11'
                        BASE_IMAGE = 'registry.cn-shenzhen.aliyuncs.com/storlead/openjdk:11'
                        //获取最新的镜像底包
                        sh "docker pull ${BASE_IMAGE}"

                        sh """
                        echo '
                        FROM ${BASE_IMAGE}
                        COPY ${modulePrefix}/${params.module}/target/${params.module}-${VERSION}.jar app.jar
                        EXPOSE ${API_PORT}
                        EXPOSE ${API_REMOTE_DEBUG_PORT}
                        HEALTHCHECK --interval=1m --timeout=10s CMD curl -f http://localhost:${API_PORT}/${API_NAMESPACE_RESTFUL}/actuator/health
                        ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-Djava.awt.headless=true","-Dspring.profiles.active=${params.profile}", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:${API_REMOTE_DEBUG_PORT}","-jar","/app.jar"]' > Dockerfile
                        docker build -t ${DOCKER_IMG_NAME} .
                       """
                        sh "docker push ${DOCKER_IMG_NAME}"
                    }
                }
            }
        }

        stage('启动服务') {
            when {
                environment name: 'modulePrefix', value: 'api'
            }
            steps {
                withCredentials([
                        usernamePassword(credentialsId: 'storleadHW', usernameVariable: 'usernameHW', passwordVariable: 'passwordHW'),
                        usernamePassword(credentialsId: 'storlead', usernameVariable: 'username', passwordVariable: 'password'),
                        usernamePassword(credentialsId: 'reg-aliyun', usernameVariable: 'aliUsername', passwordVariable: 'aliPassword'),
                ]) {
                    script {

                        echo "启动服务"

                        def remote = [:]
                        remote.name = "${SERVER_HOST}"
                        remote.host = "${SERVER_HOST}"
                        remote.port = 53023
                        remote.user = username
                        remote.password = password
                        remote.allowAnyHosts = true

                        //因为使用 docker swarm 发布 只能在 manage node 执行部署
                        if (params.profile == "dev") {
                            remote.port = 22
                            remote.user = "root"
                        }

                        if (params.profile == "prod") {
                            remote.port = 22
                            remote.user = "root"
                            remote.user = usernameHW
                            remote.password = passwordHW
                        }

                        if (PUSH_DOCK_IMG) {
                            //docker 认证
                            sshCommand remote: remote, command: "docker login -u ${aliUsername} -p ${aliPassword} ${DOCKER_LOGIN_REGISTRY}"
                            //如果选择推送才使用远程的版本 如果不选择推送到远程则直接运行本机刚打包的镜像版本即可
                            sshCommand remote: remote, command: "docker pull ${DOCKER_IMG_NAME}"
                        }
                        sh """
                        echo '
version: "3.7"
services:
  ${ARTIFACTID}-${params.profile}:
    image: ${DOCKER_IMG_NAME}
    restart: always
    deploy:
      replicas: ${SWARM_INIT_REPLICAS_NUM}
      update_config:
        parallelism: 1
        delay: 1m
      restart_policy:
        condition: on-failure
        # 最多连续重试3次如果仍然失败则放弃重试
        max_attempts: 3
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:${API_PORT}/${API_NAMESPACE_RESTFUL}/actuator/health"]
      interval: 1m
      timeout: 5s
      retries: 3
      start_period: 30s
    environment:
      - "TZ=Asia/Shanghai"
      - "SPRING_PROFILES_ACTIVE=${params.profile}"
    volumes:
      - /app:/app
    ports:
      - "${API_PORT}:${API_PORT}"
      - "${API_REMOTE_DEBUG_PORT}:${API_REMOTE_DEBUG_PORT}"
    networks:
      - ${ARTIFACTID}
    extra_hosts:
      - "www.storlead.com:172.18.194.161"
      - "node1:110.41.82.21"
      - "node2:110.41.174.46"
      - "node3:121.37.226.174"
      - "test1.storlead.com:172.18.194.168"
      - "test2.storlead.com:172.18.194.163"
networks:
  ${ARTIFACTID}:
    driver: overlay
    attachable: true
                        ' > ${ARTIFACTID}-${params.profile}-stack.yml
                       """
                        sshPut remote: remote, from: "${ARTIFACTID}-${params.profile}-stack.yml", into: "/docker/sp/${ARTIFACTID}-${params.profile}-stack.yml"
                        sshCommand remote: remote, command: "docker stack deploy --resolve-image=always --with-registry-auth -c /docker/sp/${ARTIFACTID}-${params.profile}-stack.yml ${ARTIFACTID}-${params.profile}"
                    }
                }
            }
        }

    }
}
