Jenkins声明式定时备份流水线如何实现作业停止后独占运行
Jenkins声明式备份流水线独占执行实现方案
实现逻辑
- 利用Jenkins原生*静默模式(Quiet Mode)*特性:开启后不会调度任何新的构建任务,现有运行中的任务可正常执行完成
- 流水线启动后先开启静默模式,再等待所有非自身的运行中任务执行结束,再执行备份操作
- 备份完成后无论执行结果成功/失败,强制关闭静默模式恢复Jenkins正常调度能力
修改后的完整Jenkinsfile
import jenkins.model.Jenkins def BACKUP_DATETIME = new Date().format('yyyy_MM_dd_HH_mm_ss', TimeZone.getTimeZone('Canada/Eastern')) pipeline { agent { label 'master' } options { //Build options disableResume() disableConcurrentBuilds() // 可选配置:最多等待1小时,避免异常情况下无限阻塞 timeout(time: 1, unit: 'HOURS') buildDiscarder( logRotator ( artifactDaysToKeepStr: '10', artifactNumToKeepStr: '1', daysToKeepStr: '30', numToKeepStr: '30' ) ) } triggers { cron('TZ=Canada/Eastern\n0 3 * * *') } environment { GIT_SSH_KEY_ID = 'gitlab_builduser' BACKUP_PREFIX_NAME = 'jenkins-back-' BACKUP_REPO_NAME = "jenkins_backups" BACKUP_REPO_URL = "git@XXX:XX/${env.BACKUP_REPO_NAME}.git" NUMBER_OF_BACKUPS = '7' GOOGLE_CHAT_TOKEN = 'XXXXXF' JENKINS_VERSION = '' } stages { // 新增前置检查阶段 stage('Pre Check') { steps { script { // 开启全局静默模式,阻止新作业调度 Jenkins.instance.doQuietDown() // 循环等待所有非当前备份作业的运行中任务结束 while (true) { def runningJobs = Jenkins.instance.getAllItems(Job.class).collectMany { job -> job.getBuilds().findAll { build -> build.isBuilding() } }.findAll { build -> build.getFullDisplayName() != currentBuild.getFullDisplayName() } if (runningJobs.isEmpty()) { break } println "等待以下运行中任务结束:${runningJobs*.getFullDisplayName()}" sleep 30 // 每30秒检测一次 } } } } stage('Init') { steps { script { env.JENKINS_VERSION = sh(script: "java -jar /usr/share/jenkins/jenkins.war --version", returnStdout: true).trim() } dir("/tmp") { withCredentials([sshUserPrivateKey(credentialsId: "${env.GIT_SSH_KEY_ID}", keyFileVariable: 'SSH_KEY', usernameVariable: 'SSH_USER')]) { withEnv(["GIT_SSH_COMMAND=ssh -i ${SSH_KEY}"]) { sh ''' if [ ! -d ${BACKUP_REPO_NAME} ] then git clone ${BACKUP_REPO_URL} else cd ${BACKUP_REPO_NAME} git fetch origin git reset --hard origin/master fi ''' } } } } } stage('Backup') { steps { dir ('jenkins_backup') { sh """ chmod +x ./jenkins-backup.sh ./jenkins-backup.sh ${JENKINS_HOME} /tmp/${env.BACKUP_REPO_NAME}/${BACKUP_PREFIX_NAME}_${BACKUP_DATETIME}.tar.gz """ } } } stage('Upload') { steps { // TO_DO: SAVE THE BACKUP file dir("/tmp/${env.BACKUP_REPO_NAME}") { withCredentials([sshUserPrivateKey(credentialsId: "${env.GIT_SSH_KEY_ID}", keyFileVariable: 'SSH_KEY', usernameVariable: 'SSH_USER')]) { withEnv(["GIT_SSH_COMMAND=ssh -i ${SSH_KEY}"]) { sh ''' git config user.email "${SSH_USER}@email.com" git config user.name "${SSH_USER}" # backup only keep the lastest X backup-files ls -tp ${BACKUP_PREFIX_NAME}_*.tar.gz | grep -v '/$' | tail -n +$(expr ${NUMBER_OF_BACKUPS} + 1) | xargs -I {} rm -- {} # Push to git git add --all git status git commit --amend -CHEAD --allow-empty git push --force-with-lease origin master env ''' } } } } } } post { always { script { // 无论备份结果如何,强制关闭静默模式恢复正常调度 if (Jenkins.instance.isQuietingDown()) { Jenkins.instance.doCancelQuietDown() } } } failure { hangoutsNotify message: "${JOB_BASE_NAME} faild!",token: "${env.GOOGLE_CHAT_TOKEN}",threadByJob: true } } }
注意事项
- 运行该流水线的账号需要拥有Jenkins管理员权限,否则无法操作静默模式和查询全局任务状态
- 静默模式开启后,用户手动触发的作业也会进入排队状态,等静默模式关闭后自动调度,对多Agent节点集群同样生效
内容的提问来源于stack exchange,提问作者Taher Ben Salem
相关产品推荐
相关产品推荐

