sharedLibsPath = "${env.WORKSPACE}/sharedLibs" backup_destination = '/var/jenkins_home/backups' backup_targetFile = 'dockerImage.tar' // 获取镜像URL generateFullImageUri = {Map DOCKER, String base_branch, String BUILD_NUMBER -> return "${DOCKER.registry}/${DOCKER.image}:${base_branch}-${BUILD_NUMBER}" } // 获取镜像名 generateImageName = {Map DOCKER, String base_branch, String BUILD_NUMBER -> return "${DOCKER.image}:${base_branch}-${BUILD_NUMBER}" } def generateImageName(String imageName, String base_branch, String BUILD_NUMBER) { return "${imageName}:${base_branch}-${BUILD_NUMBER}" } def generateDockerfile(Object SERVICE, String pathOfDockerfile='projdir') { def module = SERVICE.module == null ? '' : (SERVICE.module[-1] == '/' ? SERVICE.module : SERVICE.module + '/') echo "-----> Generating Dockerfile: ${pathOfDockerfile}/Dockerfile ..." sh """cat > ${pathOfDockerfile}/Dockerfile< Building docker image: ${imageUri} ..." dir(projDir) { docker.withRegistry("http://${DOCKER.registry}", "${DOCKER.push_credentialId}") { def imageName = generateImageName(DOCKER, base_branch, BUILD_NUMBER) def image = docker.build(imageName) image.push() sh "docker rmi ${imageName}" if(filter2Remove != null) sh "docker image prune --filter label=${filter2Remove} -f" } } return imageUri } def restoreDockerImage(Object DOCKER, String workspace, String base_branch, String rollbackBuildNumber) { dir(workspace) { imageUri = generateFullImageUri(DOCKER, base_branch, rollbackBuildNumber) sh "docker load -i ${backup_targetFile}" // in case, docker image doesn't exist in remote registry docker.withRegistry("http://${DOCKER.registry}", "${DOCKER.push_credentialId}") { def image = docker.image(imageUri) image.push() } } return imageUri } def cleanDockerImage(String dockerImgName) { sh "docker rmi ${dockerImgName}" } def backupDockerImage(String dockerImgName) { echo "-----> Backup artifact(docker image : ${dockerImgName}) ..." path = "${backup_destination}/${JOB_NAME}/${BUILD_NUMBER}" sh """ docker save ${dockerImgName} -o ${backup_targetFile} if [ -d ${path} ]; then echo \"${path} already exists\" else mkdir -p ${path} mv ${backup_targetFile} ${path} fi """ } def backupK8sConfigs(String[] files2backup) { path = "${backup_destination}/${JOB_NAME}/${BUILD_NUMBER}/k8s" sh """if [ -d ${path} ]; then echo \"${path} already exists!\" else mkdir -p ${path} fi """ for(file in files2backup) { sh "cp ${file} ${path}" } } def applyDeployment(SERVICE, K3S, String base_branch) { print "loading ${sharedLibsPath}/k3sUtil.groovy..." def k3sUtils = load "${sharedLibsPath}/k3sUtil.groovy" kvs = [:] kvs.put('', SERVICE.name) kvs.put('', SERVICE.version) kvs.put('', base_branch) kvs.put('', COMMIT_SHA) kvs.put('', K3S.pull_secretId) kvs.put('', imageUri) k3sUtils.generateDeployment(kvs, 'deployment.yaml') k3sUtils.applyDeployment(K3S) k3sUtils.generateService(kvs, 'service.yaml') k3sUtils.applyService(K3S) } // Jenkins pipeline stages def execute(CONFIG, base_branch, closures=[:]) { stage('source code check out') { println "loading ${sharedLibsPath}/gitUtil.groovy..." def gitUtils = load "${sharedLibsPath}/gitUtil.groovy" COMMIT_SHA = closures.GITCLONE == null ? gitUtils.clone(CONFIG.git, base_branch) : closures.GITCLONE() } stage("docker image build") { def projDir = 'projdir' if (closures.GENERATEDOCKERFILE != null) projDir = closures.GENERATEDOCKERFILE() else projDir = generateDockerfile(CONFIG.service) //default if (closures.BUILDIMAGE != null) imageUri = closures.BUILDIMAGE() else imageUri = buildDockerImage(CONFIG.service, CONFIG.docker, base_branch, projDir, 'stage=STATICRES-BUILD') } stage("apply K8S Deployment") { if (closures.K3SDEPLOY != null) { closures.K3SDEPLOY() return } applyDeployment(CONFIG.service, CONFIG.k3s, base_branch) } } def upgrade(Object CONFIG, String base_branch, String[] k8sBackupFiles, closures=[:]) { stage('source code check out') { println "loading ${sharedLibsPath}/gitUtil.groovy..." def gitUtils = load "${sharedLibsPath}/gitUtil.groovy" COMMIT_SHA = closures.GITCLONE == null ? gitUtils.clone(CONFIG.git, base_branch) : closures.GITCLONE() } stage("docker image build") { def projDir = 'projdir' if (closures.GENERATEDOCKERFILE != null) projDir = closures.GENERATEDOCKERFILE() else projDir = generateDockerfile(CONFIG.service) //default if (closures.BUILDIMAGE != null) imageUri = closures.BUILDIMAGE() else imageUri = buildDockerImage(CONFIG.service, CONFIG.docker, base_branch, projDir, 'stage=STATICRES-BUILD') // stage("Docker Image backup") { backupDockerImage(imageUri) envFile = new File("${backup_destination}/${JOB_NAME}/${BUILD_NUMBER}/env") envFile << "${COMMIT_SHA}\n" envFile << "${base_branch}\n" // } // stage("K8s configs backup") { backupK8sConfigs(k8sBackupFiles) // } cleanDockerImage(imageUri) } stage("apply K8S Deployment") { if (closures.K3SDEPLOY != null) { closures.K3SDEPLOY() return } applyDeployment(CONFIG.service, CONFIG.k3s, base_branch) } stage("Clear older backup version") { // 清理旧的备份 dir("${backup_destination}/${JOB_NAME}") { echo "-----> Clear older backup version ..." sh """ save_file=`ls -ltr | tail -5 | awk '{print \$NF}'` ls | grep -v "\$save_file" | xargs rm -rf """ } } } def rollback(Object CONFIG, String rollbackBuildNumber, closures=[:]) { path = "${backup_destination}/${JOB_NAME}/${rollbackBuildNumber}" if (fileExists(path)) { envFile = new File("${backup_destination}/${JOB_NAME}/${rollbackBuildNumber}/env") def lines = envFile.readLines() COMMIT_SHA = lines[0] BASE_BRANCH = lines[1] stage('source code check out') { print("souce code check out. Skipped!") } stage("docker image build") { print("restore docker image from rollbackNo. #${rollbackBuildNumber}") imageUri = restoreDockerImage(CONFIG.docker, path, BASE_BRANCH, rollbackBuildNumber) cleanDockerImage(imageUri) } stage("apply K8S Deployment") { if (closures.K3SDEPLOY != null) { closures.K3SDEPLOY() return } dir("${backup_destination}/${JOB_NAME}/${rollbackBuildNumber}/k8s") { applyDeployment(CONFIG.service, CONFIG.k3s, BASE_BRANCH) } } stage("Clear rollback workspace") { // 清理rollback工作目录 dir("${backup_destination}/${JOB_NAME}") { echo "-----> Clear rollback workspace ..." sh "rm -rf *@tmp" } } } } return this