Jenkins正在重新使用管道工作区,我希望每个构建都拥有唯一的工作区

时间:2018-10-31 00:02:16

标签: jenkins jenkins-pipeline

因此,我在此主题上发现的大多数问题和答案都是针对那些希望将SAME工作区用于不同运行的人们的。 (这让我感到困惑,但是每次我开始工作时,我都需要一个整洁的板凳。剩下的东西只会破坏东西)

我的问题恰恰相反-我必须每次运行都必须有一个单独的工作区(或者我需要知道如何在不同的运行中创建具有相同名称的文件,而该文件只能与该运行一起使用,并且可以通过管道启动的bash脚本轻松访问!)

所以,我的问题是-如何强制Jenkins不要在不同主机上的两个同时运行的作业中使用同一工作空间,或者我可以在“自定义工作空间”字段中使用什么变量来完成此任务? >

回答@Joerg S的问题后,我意识到我说的是Joerg S所说的不可能发生的事,正是我所观察的! Jenkins将SAME工作区用于2个不同主机上的2个不同的并发作业。 这是詹金斯管道漏洞吗?

请参阅下面的大量信息。

鉴于在运行期间必须进出节点的方式,我发现我可以在同一作业的不同主机上启动两个不同的构建,并且它们共享工作区目录!由于每个作业都有shell脚本,这些脚本正忙于将文件写入该目录,所以这非常糟糕。

Custom workspace in jenkins中,我们被告知要使用自定义工作区,而我的设置就是这样

Jenkins: how to run builds in unique directories中,我们被告知在上面的自定义工作区字段中使用$ {BUILD_NUMBER},所以我尝试的是:

 ${JENKINS_HOME}/workspace/${ITEM_FULLNAME}/${BUILD_NUMBER}

当我使用时,发生的所有事情就是工作区名称为“ $ {BUILD_NUMBER}”(出于很好的考虑,我什至得到了“ $ {BUILD_NUMBER} @ 2”!)< / p>

我尝试过{$ BUILD_ID},同样的事情(从字面上使用它,不能替代数字)。

我启用了“允许并发构建”。

我只使用管道。

作为正常执行的一部分,此处的所有作业都会导致非主从属主机重新引导到无法运行slave.jar的操作系统(实际上,它根本没有网络访问权限),因此我无法在该主机上运行整个管道。

所有作业在其内部某处都使用以下构造:

    tests=Arrays.asList(tests.split("\\r?\n"))
    shellerror=231
    for( line in tests){

因此,让我们将示例作业“ foo”称为遍历列表的循环,如上所述,我想在2个不同的主机上运行。该作业的管道开始在主服务器上运行(因为上述 for(测试中的行)必须在节点上运行!))。然后,通常在主服务器和从服务器之间来回切换多次。

如果我大约在主机A和主机B上同时开始这项工作,他们将同时使用工作区$ {JENKINS_HOME} / workspace / $ {JOB_NAME},或者在我的情况下是/ var / lib / jenkins / jenkins / workspace / job

由于它们将不同的数据写入该目录中具有相同名称的文件,因此我显然立即被破坏了。

那么,如何迫使Jenkins在每个工作中使用唯一的工作区?

或者,什么?

其他内容:管道构建步骤版本2.5.1,Jenkins 2.46.2

我一直在尝试使工作区语句('ws')正常工作,但这也没有按我预期的那样工作-有些文件在我明确命名的工作区中,而有些文件仍在'内置的工作区(workspace/)。

我被要求提供代码。我使用的“标准”管道约为26K字节,大约590行。所以,我将大大减少。话虽这么说:

node("master") { // 1
   ..... lots of stuff....
}  // this matches the "node('master')" above
node(HOST) {
  echo "on $HOST, check what os"
  if (isUnix()) 
      ...some more stuff...
} // end of 'node(HOST)' above
if (isok == 0 ) {
   node("master") { 
      echo "----------------- Running on MASTER 19 $shellerror waiting on boot out of windows ------------"
      sleep 120
      echo "----------------- Leaving MASTER ------------"
   }
}
 ... lots 'o code ...

node(HOST) {
  ... etc 
} // matches the latest 'node HOST' above
node("master") { // 120
    .... code ...
    for( line in tests) {
        ...code...
    }
}
... and on and on and on, switching back and forth from one to the other

FWIW,当我尝试使上述名称使用'ws'以便确定ws名称是唯一的时,我只是在(几乎)每个'node'开口下方直接添加了'ws wsname'块,因此

node(name) { ws (wsname) { ..stuff that was in node block before... } }

但是接下来我有两个目录需要担心检查-“默认”工作空间/ jobname目录和新的wsname目录。

3 个答案:

答案 0 :(得分:1)

尝试使用customWorkspace节点常用选项:

pipeline {
  agent {
    node {
      label 'node(s)-defined-label'
      customWorkspace "${JENKINS_HOME}/workspace/${JOB_NAME}/${BUILD_NUMBER}"
    }
  }
  stages {
    // Your pipeline logic here
  }
}
  

customWorkspace

     

一个字符串。运行管道或个人阶段   代理应用于此自定义工作空间中,而不是   默认。它可以是相对路径,在这种情况下,   工作空间将位于节点上的工作空间根目录下,或者是绝对位置   路径。

编辑

因为这不适用于您复杂的管道。也许尝试以下愚蠢的解决方案:

def WORKSPACE = "${JENKINS_HOME}/workspace/${JOB_NAME}/${BUILD_NUMBER}"

node(HOST) {
   sh(script: "mkdir -p ${WORKSPACE}")
   sh(script: "cd ${WORKSPACE}")
   //Do stuff here
}

或dir()是否可访问:

def WORKSPACE = "${JENKINS_HOME}/workspace/${JOB_NAME}/${BUILD_NUMBER}"

node(HOST) {
   sh(script: "mkdir -p ${WORKSPACE}")
   dir(WORKSPACE) {
   //Do stuff here
   }
}

答案 1 :(得分:0)

'${SOMEVAR}'

不会被替换

"${SOMEVAR}"

will-这是处理groovy字符串的方式 参见groovy string handling

所以,如果您有

ws("/some/path/somewhere/${BUILD_ID}")
{
   //something
}

在管道Jenkinsfile中的节点上,这方面应该可以解决问题

当您允许并发构建项目时,@ 2工作区可能会出现问题-我在使用@ 2的自定义ws()时遇到了完全相同的问题-只是不允许并发构建或解决该问题。

答案 2 :(得分:0)

customWorkspace对我不起作用。 有效的方法:

stages {
    stage("SCM (For commit trigger)"){
        steps {
            ws('custom-workspace') { // Because we don't want to switch from the pipeline checkout
                // Generated from http://lstool01:8080/job/Permanent%20Build/pipeline-syntax/
                checkout(xxx)
            }
        }
    }