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:
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).
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.