使用Pipeline script from SCM无法指定节点

大家好,最近我在编写pipeline遇到一个问题。由于本人公司网络安全的原因,只有Jenkins master能访问内部Gitlab,其他Jenkins slave都无法加载代码。

在Jenkins在直接编辑Pipeline script基本没啥问题,但是这样做违背了Pipeline as Code的原则,后期不好管理维护Pipeline,所以我尝试了Pipeline script from SCM,但是每次执行时发现下载该代码仓库的节点时随机的,不在master执行的话,无法获取pipeline脚本。我期望能指定master,像自由风格里Job的配置Restrict where this project can be run一样。

请问下这种场景有什么解决方案吗?

不会吧,应该是按照jenkinsfile里的指定走的
如果指定多个节点,应该就会把jenkinsfile下载到多个节点

另外提醒一点,这种方式下载代码的话,我现在是这么做的:
pipeline的正常流程是先下载jenkinsfile,后下载代码,而我的需求是在每次下载代码前先清空工作空间内不受版本控制的文件,所以如果两个下载都直接下载在同一空间下,就会导致下载代码时会删除jenkinsfile,所以我的做法是将你如图这块的配置中将jenkinsfile下载到空间中的一个子目录下,就不会出现我上述描述的问题了

为啥都喜欢用 Pipeline script from SCM 呢?

我就直接使用下面的方式,没有遇到啥特殊问题。

当然是便于版本控制啦

我现在就是用这个方式。但是不方便编辑维护,改错了出问题不好立即恢复。CasC(配置即代码)的理念是pipeline推崇的,也非常好管理

嗯,里面指定agent是没问题的。不过你可能理解过我的意思。Pipeline script from SCM可以分为两步:

  1. 从代码仓库下载Jenkinsfile
  2. 执行Jenkinsfile内的内容

步骤2执行Jenkinsfile内容时,指定agent是没问题的。问题是步骤1下载代码我需要在master节点上执行,但没地方指定,在非master节点执行会导致获取Jenkinsfile失败。我需要一个类似自由风格Job这样配置:


应该没理解错吧。不过我这边的配置确实是这样——只要在jenkinsfile中指定了agent,jenkinsfile就会下载到那个agent上面去,按照能看到的流程确实应该是先下载才去执行,但是我也不清楚为什么就能做到下载也能下载到jenkinsfile中指定的agent上。
刚才看了下,感觉上会不会是在开始启动job后,jenkins会自动从scm上下载jenkinsfile到jenkins服务器的安装目录下的jobs下对应的jobs下去,我在该目录下没有找到对应的原文件,但是能在已有文件中找到不同的步骤。如果猜想成立,应该是将jenkinsfile缓存到jobs下,然后再按照相应的流程再去执行jenkinsfile,而在jenkinsfile中指定的agent上下载到的jenkinsfile有可能不是直接从scm上获取,而是从服务器的jobs下获取?或者是job启动后在jobs下预读了jenkinsfile,知道要去哪个agent上执行,才去在对应的agent开始执行你上面所说的两步。
你有没有试过呢?如果就是在jenkinsfile中指定了master,难道不能下载到master吗?

强调下:我这边网络安全原因,只有master能访问gitlab,slave访问不了。

首先感谢你的回复解答。我刚刚也测试了下,我之前对Jenkins对理解可能错误了。
刚刚通过一番测试,我得出以下结论:

  1. 使用Pipeline script from SCM时,在启动时,执行pipeline块内容前。master节点已经根据我们配置对地址和分支下载对应对Jenkinsfile了,但是并没有在工作空间出现,可能在master节点对内存或其他地方。以为启动日志第2行会这这么一句:

    Obtained Jenkinsfile from git xxx.git
    
  2. 由于步骤1,Jenkins master已经知道了Jenkinsfile,接下来就按照pipeline块内容逐步执行,每次显示指定agent时,都会在对应的agent节点上先下载Pipeline script from SCM配置的仓库,再执行stage内容。

  3. pipeline块下的agent会先执行下载仓库,默认会多一个名为Declarative: Checkout SCM的stage,stage里只要配置了agent,那么到该节点时也会下载仓库。

总结

本来我想用Gitlab来管理多个流水线Jenkinsfile,但是由于网络局限,只有master能下载到Jenkinsfile。slave节点没发获取Jenkinfile内容。估计暂时只不能用Pipeline script from SCM功能了。

1赞

根据你的回复,推断你的场景是:用master下载jenkinsfile,然后在slave上执行后面的构建?
不知道你的代码是在哪里?看你的描述貌似是在本地?如果也是在scm上,那就即便jenkinsfile下载到master上,代码怎么进入slave?
那么问题是不是变成了,如何借助master从scm下载文件到slave?简单一点的方案应该就是将jenkinsfile和代码都下载到master上,然后再传输到slave上,最后在slave上进行构建。
如果上述方案可行。我这边是使用声明式,可以在脚本一开始指定agent none,然后在下载阶段指定为master,后续阶段都指定到slave。
是不是感觉我很牛皮糖? :joy:希望能帮助到你

嗯,所有下代码确实都是都master下载的,再传slave。

主要这边要做一些流程抽象复用,所以Jenkinsfile是独立的仓库管理,业务代码对Jenkinsfile是无感知的,也不想给抽共享库给他们用。

pipeline配置的scm是独立的jenkisnfile仓库地址,业务代码下载控制我在pipeline里面控制的(master下载业务代码后stash,在slave unstash后就可以开始构建)。这样我定义一个pipeline,通过参数化构建就可以给其他所有业务项目使用。

但是我解决不了如上说的问题,就是到slave后,默认会触发下载jenkisnfile仓库代码,网络原因导致失败。

PS:网络原因在使用上确实有点奇葩,还是十分谢谢你啦,兄dei

哦,对的,这块我确实忽略了,你这么一说我想起来了,确实是这样,不管你把哪一个stage指定到哪一个agent上,当执行这个stage的时候都会去这个agent上下载jenkinsfile。
我这边没有这样的需求,所以没有去摸索过,应该有人有过这样的场景的,看看别人怎么说吧。
害你解释这么多,最终对问题的解决没有任何帮助,惭愧

不不不,你的答复还是帮助了我很多,帮助我理解了一些Jenkins处理机制。感谢 :smile: