-
Bug
-
Resolution: Duplicate
-
Major
-
None
-
Jenkins 2.19.3 with pipeline 2.4
We are trying to write some administrative jobs using pipeline that need to iterate through some subset of slaves and run maintenance tasks on them. To this end we wrote the following Global Library function a while ago, and it works fine:
@NonCPS def static getSlaveMetadata() { Hudson.instance.slaves.collect { slave -> def isOnline = slave.computer.isOnline() [ name: slave.getNodeName(), description: slave.getNodeDescription(), // getOSDescription() throw null pointer error if slave is off line. os: isOnline ? slave.computer.getOSDescription() : null, isUnix: slave.computer.isUnix(), remoteHomeDir: slave.getRemoteFS(), labels: slave.getAssignedLabels().collect { l -> l.toString() }, isOnline: isOnline ] as Map } }
Recently we tried to add a filter to function as follows:
@NonCPS def static getSlaveMetadata(Closure filter = { s -> true } ) { Hudson.instance.slaves.collect { slave -> ... }.findAll(filter) }
This failed to work if a non-default filter was used (even if { s -> true } was passed as the filter). In such cases, we got the behavior described in -JENKINS-26307. That is, the function returned either `true` or `false` depending how the filter evaluated the first time it executed.
So remembering this bug was there, we tried this:
@NonCPS static List getSlaveMetadataFiltered(Closure filter = { s -> true}) { List slaves = Hudson.instance.slaves.collect { slave -> ... } List filtered = [] for(slave : slaves){ if (filter(slave)){ filtered << slave } } filtered }
This returned the exact same results as the first attempt!
Ultimately we found that this worked:
def static getSlaveMetadata(Closure filter) { List slaves = getSlaveMetadata() List filtered = [] for(slave in slaves){ if (filter(slave)){ filtered << slave } } filtered } @NonCPS def static getSlaveMetadata() { ... original implementation ... }
And this only works because the overload does not require @NonCPS. If we decorated it with @NonCPS it again fails in the manner described.
In all cases, our test pipeline script was the following:
@Library('kb-testing') List justSomethingForLibraryToDecorate(){} def slv = jenkins.SlaveUtils.getSlaveMetadata({Map s -> s['labels'].contains('docker')}) println slv
- duplicates
-
JENKINS-26481 Mishandling of binary methods accepting Closure
- Resolved
- is related to
-
JENKINS-26300 CPS interpreter fails on calls to find(), findAll() default methods
- Resolved
-
JENKINS-26307 CPS Groovy collection.find() returns Boolean
- Resolved