Jenkins多分支管道:生成结束时清理工作区/删除目录

Jenkins多分支管道:生成结束时清理工作区/删除目录,jenkins,jenkins-pipeline,Jenkins,Jenkins Pipeline,我们使用Jenkins多分支(脚本化)管道并行运行多个构建。每一个都将创建一个新的、唯一命名的目录来签出代码并运行测试。目录是唯一命名的,因为它们包含分支名称,但也包含随机部分,如“JAA2A5HUZB7TRE4OTVXU7S…” 这意味着在每次构建之后,X个目录(X=并行作业数*分支数)将保留在Jenkins节点上,以填充磁盘空间 我想知道如何自动删除这些目录 我的初始管道的简化版本如下所示 //初始化矩阵 def矩阵=[ "福",, “酒吧”, ] //初始化空任务映射 def任务=[:]

我们使用Jenkins多分支(脚本化)管道并行运行多个构建。每一个都将创建一个新的、唯一命名的目录来签出代码并运行测试。目录是唯一命名的,因为它们包含分支名称,但也包含随机部分,如“JAA2A5HUZB7TRE4OTVXU7S…”

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

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

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

//初始化矩阵
def矩阵=[
"福",,
“酒吧”,
]
//初始化空任务映射
def任务=[:]
//工作状态
成功=正确
//根据矩阵数据填写我们的任务图
对于(矩阵中的x){
def job_name=x
任务[作业名称]={
节点('libvirt'){
//首先签出存储库
阶段($job\u name-签出){
校验scm
}
//然后制造机器
gitlabCommitStatus(“构建”){
阶段($job\u name-Build){
sh“/bin/build.sh${job_name}”
}
}
}
}
}
}
////管道////
notifyBuild('已启动')
//并行运行任务
试一试{
并行任务
}捕获(e){
掷e
}最后{
如果(成功){
notifyBuild('成功')
}否则{
notifyBuild('失败')
}
}
//方法
def notifyBuild(字符串buildStatus='STARTED'){
//用于发送格式化的电子邮件
}
我首先像这样添加了
deleteDir()

}最后{
如果(成功){
notifyBuild('成功')
}否则{
notifyBuild('失败')
}
节点('libvirt'){
deleteDir()
}
}
它会引发错误并使生成失败

然后我像这样添加了一个
cleanWs()

}最后{
如果(成功){
notifyBuild('成功')
}否则{
notifyBuild('失败')
}
节点('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-drd7ekbemmwjqzw6kkmqvbtjttklrae2itdk7v7ib5ptfxzuza目录仍然存在


< P>我正在寻找任何解决方案来适应这个脚本化的流水线(如果你知道如何声明,可以删除由Bug创建的所有目录。

< P>)这不直接回答你的问题(我个人使用DeleDeDRE()),对我来说它是有效的。但是,作为一个替代保存磁盘的地方,你可以考虑丢弃“旧”。在多分支管道中生成:

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

首先,您不能删除生成仍在运行的目录。
deleteDir()
步骤只是删除工作区的内容


您可以触发生成完成后运行的作业,该作业将删除这些目录。为此,您可以使用类似于
pipeline deletedir-*

的模式。解决方案是在stage($job\u name-Build)步骤中添加try/catch/finally,例如

gitlabCommitStatus('build') {
    stage("$job_name - Build") {
        try {
            sh "./bin/build.sh ${job_name}"
         } catch (Exception e) {
            raise e
         } finally {
            deleteDir()
         }
    }
}
这不会删除所有涉及的目录(因为Jenkins问题),但会删除所有大量目录(包含代码/构建/工件…)


您需要添加“raise e”或build将始终返回成功,即使其中一个失败。

我认为最好的方法是在所有阶段之后添加post-section:

    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 */
         }
    }

我知道BuildDiscard会删除UI上的所有日志、工件和列表,但我很确定它不会删除旧目录,因为我们将此属性设置为5天,并且目录(在节点上,而不是在主节点上)仍然存在。很抱歉,这没有多大帮助,我知道构建丢弃器正在删除主服务器上的作业目录。另外,我实际上在管道开始的某些情况下执行deleteDir()。我希望我能指出文档(Jenkins有时很难找到东西),但我看了我的一个构建,它做到了这一点,Jenkins似乎总是在每个分支上使用相同的工作区(除非有一个并行构建-因此我不会得到大量的工作区目录),但这只是我注意到我的环境中的行为和你的里程可能会有所不同。事实上,在简单管道中,它使用相同的目录,所以作业开始时的deleteDir()是可以的。我们首先从那开始,所以问题没有出现。当移动到多分支管道时,出现了这个随机命名目录功能,并且这个deleteDir()提示不再起作用。事实上,对于管道来说,很难找到完整的文档,而且还没有实现所有的功能。要在与作业完全相同的节点上运行,请执行2。此节点上的确切目录名。如果我理解正确,似乎deleteDir()应该可以工作。部分解决方案是利用“孤立项策略”和积极的值。这不回答OP,因为它仅适用于已删除的分支(以及已关闭的PR的PR分支)。但它应该在一定程度上有助于限制磁盘空间的使用。“孤立项策略”是否会在远程代理集群中删除失效分支的旧工作区?(包括注意到分支删除时的离线代理)。