Jenkins Multibranch Pipeline:构建结束时清理工作区/删除目录

时间:2017-07-06 12:40:05

标签: jenkins jenkins-pipeline

我们使用Jenkins multibranch(脚本化)管道并行运行多个构建。每个人都将创建一个新的,唯一命名的目录来检查代码并运行测试。目录具有唯一名称,因为它们包含分支名称,但也包含随机部分,如" JAA2A5HUZB7TRE4OTVXU7S ..."。

这意味着在每个构建X目录(X =并行作业数*分支数)之后,保留在Jenkins节点上,填充磁盘空间。

我想知道如何自动删除这些目录。

我的初始管道的简化版本如下所示

// Initialize the matrix
def matrix = [
  'foo',
  'bar',
]

// Initialize empty tasks map
def tasks = [:]

// Job status
successful = true

// Fill our tasks map from the Matrix data
for (x in matrix) {

  def job_name = x

  tasks[job_name] = {
    node('libvirt') {
        // Checkout repository first
        stage("$job_name - Checkout") {
          checkout scm
        }

        // Then build the machine
        gitlabCommitStatus('build') {
            stage("$job_name - Build") {
                  sh "./bin/build.sh ${job_name}"
            }
        }
      }
    }
  }
}


//// Pipeline ////

notifyBuild('STARTED')

// Run tasks in parallel
try {
  parallel tasks
} catch(e) {
  throw e
} finally {
  if (successful) {
    notifyBuild('SUCCESS')
  } else {
    notifyBuild('FAILED')
  }
}

// Methods
def notifyBuild(String buildStatus = 'STARTED') {
   // used to send formatted e-mails 
}

我首先添加了deleteDir()这样的

} finally {
  if (successful) {
    notifyBuild('SUCCESS')
  } else {
    notifyBuild('FAILED')
  }
  node('libvirt') {
    deleteDir()
  }
}

它会引发错误并使构建失败。

然后我添加了cleanWs()这样的

} finally {
  if (successful) {
    notifyBuild('SUCCESS')
  } else {
    notifyBuild('FAILED')
  }
  node('libvirt') {
    cleanWs()
  }
}

输出

Running on node in /srv/jenkins/workspace/pipeline-deletedir-DRD7EKBEMMWJQZW6KKMQVVBTJTPTKLRAE2ITDK7V7IB5PTFXZUZA
[Pipeline] {
[Pipeline] step
[WS-CLEANUP] Deleting project workspace...[WS-CLEANUP] done
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

但目录/ srv / jenkins / workspace / pipeline-deletedir-DRD7EKBEMMWJQZW6KKMQVVBTJTPTKLRAE2ITDK7V7IB5PTFXZUZA仍然存在。

我正在寻找任何解决方案来调整这个脚本化管道(如果你知道怎么做的声明性管道),能够删除构建创建的所有目录。

4 个答案:

答案 0 :(得分:2)

解决方案是在阶段(“$ job_name - Build”)步骤中添加try / catch / finally,类似于

file_2.txt

这不会删除所有涉及的目录(因为这个Jenkins问题https://issues.jenkins-ci.org/browse/JENKINS-41805)但它删除了所有大量目录(包含代码/构建/工件......)。

您需要添加“raise e”或者build将始终返回Success,即使其中一个失败也是如此。

答案 1 :(得分:1)

首先,您无法删除构建仍在运行的目录deleteDir()步骤只会删除工作区的内容。

您可以触发在构建完成后运行的作业,删除这些目录。为此,您可以使用pipeline-deletedir-*等模式。

答案 2 :(得分:1)

我认为最好的方法是在所有阶段之后添加帖子部分:

    stages {
         stage("$job_name - Build") {
             sh "./bin/build.sh ${job_name}"
         }
    }
        
    post {
         always {
             echo 'One way or another, I have finished'
             deleteDir() /* clean up our workspace */
         }
    }

答案 3 :(得分:0)

这并没有直接回答你的问题(我个人使用deleteDir()并且对我来说它有效)但作为保存磁盘位置的替代方法,你可以考虑丢弃" old"在您的multibranch管道中构建:

stage ('Remove old builds') {
    //keep 10 builds per branch
    properties([[$class: 'BuildDiscarderProperty', strategy: [$class: 'LogRotator', artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '10']]]); 
}