Issue with Jenkins pipeline and java.nio.file.* methods
Asked Answered
T

1

7

I am trying to use methods from java.nio.file.* to perform some basic file operations in a Jenkins pipeline. Regardless of the node block in which the code exists, the code executes on the master node. In the pipeline, I have verified that the various node blocks are correct--they uniquely identify specific nodes. However, pathExists (and other code that moves, copies, or deletes files) always executes on the master node. Any ideas what's happening or how to fix it?

import java.nio.file.*

String slavePath = 'C:\\Something\\only\\on\\slave\\node'
String masterPath = 'D:\\Something\\only\\on\\master\\node'

def pathExists (String pathName)
{
    def myPath = new File(pathName)
    return (myPath.exists()) 
}

stage('One') 
{
    node ('slave')
    {
        bat returnStatus: true, script: 'set'
        println (pathExists(slavePath))     // Should be true but is false.
        println (pathExists(masterPath))    // Should be false but is true.
    }
    node ('master')
    {
        bat returnStatus: true, script: 'set'
        println (pathExists(slavePath))     // false
        println (pathExists(masterPath))    // true
    }
}
Terse answered 28/9, 2016 at 17:9 Comment(0)
M
6

This is a specification of pipeline script. It's written in the tutorial.

  • readFile step loads a text file from the workspace and returns its content (do not try to use java.io.File methods — these will refer to files on the master where Jenkins is running, not in the current workspace).

  • There is also a writeFile step to save content to a text file in the workspace

  • fileExists step to check whether a file exists without loading it.

You can use those Jenkins steps in a node instead of java.io.File or java.nio.file.Files as below.

String slavePath = 'C:\\Something\\only\\on\\slave\\node'
String masterPath = 'D:\\Something\\only\\on\\master\\node'

stage('One') 
{
    node ('slave')
    {
        bat returnStatus: true, script: 'set'
        println fileExists(slavePath)     // Should be true
        println fileExists(masterPath)    // Should be false
    }
    node ('master')
    {
        bat returnStatus: true, script: 'set'
        println fileExists(slavePath)     // false
        println fileExists(masterPath)    // true
    }
}
Mis answered 1/11, 2016 at 12:31 Comment(4)
I missed that in the documentation. So if I understand correctly, having a single method that works on master and slave nodes, inside and outside of the workspace, on Windows would involve using Groovy to run a bat file that returns the answer, perhaps by running PowerShell Test-File?Terse
Umm I didn't get what you mean. Isn't it another question that is not related to the java.io.File issue? I added an example in my answer, which runs as you expected just in case.Mis
According to the documentation, fileExists only works for files in the job's workspace. When I originally tried it, that was the case. Running your example worked properly, even when the file was not in the workspace. I've verified this with Jenkins 2.24 and 2.28.Terse
I got your point. Yes, it only works in a workspace (i.e. in a node) as you verifiled. I should have written an example at first.Mis

© 2022 - 2024 — McMap. All rights reserved.