10
votes

In Jenkins pipeline, when a build is run on a particular node, a workspace is allocated on that agent. We do not set the workspace path, so it's automatically determined. I understand that the workspace must contain the executor number to isolate builds when the same job is running concurrently on the same agent.

But... How exactly is the workspace path constructed?

Our build is assigned to a particular node (with 4 executors) and is configured to not allow concurrent builds. Usually it was assigned:

EXECUTOR_NUMBER=1
WORKSPACE=xxx\yyy\jobname

At some point, the build started to run on executor 2, but still using the same workspace as before.

Later on, the build was again running on executor 1, but now using

WORKSPACE=xxx\yyy\jobname@2

which broke the build because it can't handle the '@' sign in the path. From that point on, the build continued to use that workspace, even after setting number of executors on the build machine to 1, manually removing the agent's workspace dir etc.

So my questions are:

  • How exactly is the workspace path being determined? Why does it get @2 suffix suddenly?
  • Does Jenkins re-use previous workspace, regardless of executor number?
  • If so, where is this information stored? I could not find anything in the job configs related to last used workspace path...

Thanks for any insights!

We're using Jenkins LTS 2.107.2 and up-to-date Pipeline plugins (I don't know which version is of special interest).

3

3 Answers

10
votes

The workspace allocation is done in WorkspaceList.java.

There can be locks acquired on a workspace which then leads to the @<number>suffix, see the allocate method which states This method doesn't block prolonged amount of time. Whenever a desired workspace is in use, the unique variation is added.Check out the COMBINATOR variable at the end.

If this is really such a big issue you could compile jenkins yourself and change this separator. Less hassle would probably be to allocate workspaces yourself, i.e. choose your own paths whilst somehow checking they are not in use (or using some timestamp suffix), but be aware that this separator is also used for some other paths that might be used i.e. when using Global Shared Libraries which use paths like workspace@script etc.

Edit: Missed your other questions. As you can see in this sourcefile, executor number is irrelevant for workspace naming. Sole reason is when some lock is on the base workspace path without suffix+number(inUse.get(candidate.getRemote());. So once a workspace is inUse it will just check the next candidate with @n+1 As far as i know Jenkins will reuse workspaces. Depending on your scm checkout strategy you might even consider manually cleaning a workspace before your build with deleteDir, just to be sure to not get side-effects.

1
votes

Default value for workspace suffix separator (i.e. @) can be changed manually without recompilation of Jenkins using "hudson.slaves.WorkspaceList" property (see this article for details). I.e. in Debian i've changed it to '-' with this line in /etc/default/jenkins:

JAVA_ARGS="-Djava.awt.headless=true -Dhudson.slaves.WorkspaceList=-"
0
votes

the worksdpaces should not influence your pipeline script.

in my jobs I just do

def workspace = pwd()

at the start of the node scope and uses the workspace as a variable and it works like a charm.

if you open a new node scope you should be aware that it might use a different workspace folder. just open a dir scope :

dir (worspace){
 do something
}

with the workspace variable so you could control it in order to use the exact same workspaces as the previous node scope.

I hope it helps