pipeline: it seems pipeline-build-step (build job) ignores node assignment

2,478 views
Skip to first unread message

alexand...@gmail.com

unread,
Dec 14, 2016, 7:23:57 AM12/14/16
to Jenkins Users
Hi,

I'm trying to run a job at the node assigned (not the master node), but the job runs at any free node available (often it is the master node actually).

Here's my pipeline script:

node('label1') {
  echo
"Actual node name: $env.NODE_NAME ."
  build job
: 'job1'
}
node
('master') {
  echo
"Actual node name: $env.NODE_NAME ."
}

My master node is not labeled with label 'label1'.
Only one of my slave nodes is labeled with label 'label1'.

I see at a build's Console Output that the 1st echo is executed at the slave node with label 'label1'. And the 2nd echo is executed at the master node.
But 'job1' is executed at the master node also.
I think that for my pipeline script 'job1' should be executed at the slave node labeled with 'label1'.
'job1' is allowed to run at any node (this is configured at the job's configuration).

Is this behavior is correct? Or is it a bug when build-job-step ignores pipeline node assignment?

For now I use Jenkins 2.8 and Pipeline Plugin 2.4 .
I've tried both Windows and Linux slaves node with this case (got the same result). My master node is on Linux.

Best regards,
Alexander.

Michael Pailloncy

unread,
Dec 14, 2016, 7:42:09 AM12/14/16
to jenkins...@googlegroups.com
IIUC, it's a normal behaviour.

The "build" pipeline step triggers the job job1 without any node "context" (a bit like if you trigger it manually), so the default label of job1 is used in this case. 

If you want to trigger job1 with a specific label, you should have a look to this plugin : https://wiki.jenkins-ci.org/display/JENKINS/NodeLabel+Parameter+Plugin  
However, I never used it inside a Jenkins Pipeline.

Michaël

--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/77c72577-5898-4ccb-b0eb-cb9d1dab1d7e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

alexand...@gmail.com

unread,
Dec 14, 2016, 8:18:24 AM12/14/16
to Jenkins Users
Thank you for fast reply, Michael.
I got the point.

I've already tried NodeLabel Parameter plugin with parameterized pipeline build job step. But it haven't worked for me.
Soon I'll publish appropriate topic about this way you proposed that doesn't work for me for unknown reason.
The pipeline script I've tried is:

build job: 'job2',
    parameters
: [
       
[
         $class
: 'LabelParameterValue',
           name
: 'NODE_NAME',
          value
: 'label1'
       
]
   
]

At this case 'job2' is configured with NodeLabel Parameter plugin to accept 'NODE_NAME' named parameter as Label Parameter.
The job 'job2' is triggered successfully at the certain node if I use a job with appropriate Parameterized Trigger post-build action with NodeLabel-parameter NODE_NAME and label 'label1' as upstream one.


And at the 1st case without NodeLabel Parameter plugin but with pipeline 'node'-construct
it seems strange to me that the pipeline "build" step triggers jobs without node context. This implies web-interface driven configuration of a job to be made and the cumbersome parameterized "build" step syntax to be used to run the job at the proper node.
As far as I know, Pipeline plugin is meant to get rid of such inconveniences.
So as for me it would be pretty natural and convenient if pipeline-build-step triggered jobs with pipeline node context (nodes assigned through pipeline 'node'-construct like:
'node (<label expression>) { <build-job steps> }'
).

Kind regards,
Alexander.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-use...@googlegroups.com.

alexand...@gmail.com

unread,
Dec 15, 2016, 4:56:03 AM12/15/16
to Jenkins Users
Eventually I managed to trigger a job with a specific label at the pipeline-build-step via NodeLabel Parameter Plugin you mentioned.

So thanks again, Michael. The way you proposed works fine.

Maybe the actual way I did this can be useful for someone.
The correct way is presented at the Pipeline DSL code snippet:

build job: 'job2',
    parameters
: [
       
[
         $class
: 'LabelParameterValue',
           name
: 'NODE_NAME',

          label
: 'label1'
       
]
   
]

The difference with my previous try is at the name of the 3rd Groovy map-entry at the Pipeline DSL code snippet above. The actual key for this map-entry when using the NodeLabel Parameter Plugin should be 'label' and not 'value'. This is due the constructors of LabelParameterValue:
https://github.com/jenkinsci/nodelabelparameter-plugin/blob/nodelabelparameter-1.7.2/src/main/java/org/jvnet/jenkins/plugins/nodelabelparameter/LabelParameterValue.java
---- the 2nd parameter at the constructors where the 2nd parameter is presented has name 'label' and not 'value'. And the logic of constructor parameter passing when ParameterValue objects are created is a comparison of a map-entry key with a Java-code constructor parameter name:
https://github.com/jenkinsci/structs-plugin/blob/structs-parent-1.5/plugin/src/main/java/org/jenkinsci/plugins/structs/describable/DescribableModel.java
---- see methods
instantiate(Map<String, ?> arguments)
and
buildArguments(Map<String,?> bag, Type[] types, String[] names, boolean callEvenIfNoArgs)

Thus it seems quite obscure how to compose a map corresponding to a parameter of plugin (especially due lack of documentation) until one will look into the actual code of a corresponding ParamValue subclass.
For instance for StringParameterValue (for any simple parameterized job) the 2nd parameter is 'value' (and not 'label').

Hope it will help someone.
This helped me to workaround the inability to build job via pipeline-build-step with node assigned by a pipeline through 'node (..) {..}'-clause.

Best regards,

Alexander.


On Wednesday, December 14, 2016 at 3:42:09 PM UTC+3, mpapo - Michael Pailloncy wrote:

Steve Turner

unread,
Oct 23, 2017, 12:33:35 PM10/23/17
to Jenkins Users
I wouldn't call that behavior "normal".  I'm new to Jenkins pipelines and Groovy scripting, and this has been the single most maddening thing to overcome in my attempts to learn the environment.  On what planet does it make sense that enclosing something in a node block, where the only argument is a node label, and where the block is enclosed in {} braces (which defines an isolated "scope" in every other language I can think of) does not cause the label to become used as the default for everything defined therein?  The backflips you have to go through to overcome this are ridiculous.  I find both the "node" and "agent" constructs as implemented by the Jenkins pipeline mechanism to be completely useless.

Robert Hales

unread,
Oct 23, 2017, 4:04:31 PM10/23/17
to Jenkins Users
In reference to this:  >>it seems strange to me that the pipeline "build" step triggers jobs without node context. This implies web-interface driven configuration of a job to be made and the cumbersome parameterized "build" step syntax to be used to run the job at the proper node.

As far as I know, Pipeline plugin is meant to get rid of such inconveniences.

I think maybe you are missing the point of a pipeline. The OLD way was to link a bunch of jobs together in a sudo pipeline. The pipeline scripts are meant to bring all those individual jobs together into a single pipeline script, now divided into stages (instead of independent jobs). If you want to join a bunch of jobs in and upstream and downstream configuration, you can do that with freestyle jobs and a couple plugins. If you want to build a pipeline, put it all in one job with advanced logic and greater control of how to combine those pieces together (including things like controlling the node).  

One big question is why do you want to keep it on the same node? If you are trying to access files in build B that were created in build A using a pipeline, then keeping them on the same node is prone to failures. There is no guarantee where those files will end up or that they will always exist.  Usually Stash and Unstash is the right way to handle this rather than forcing a node. 

Robert Hales

unread,
Oct 23, 2017, 4:09:48 PM10/23/17
to Jenkins Users
Enclosing a 'build' step in a node can be roughly equivalent to enclosing an ssh command in the node. That ssh command is kicking off some external process. The build step is kicking off an external process. This seems like completely normal behavior to me. The jobs are not related to each other in any way, and they have their own configuration about which nodes they want to run on. It doesn't make sense to expect to independent jobs to have some kind of coupling like that. 

Can you give some examples of how the node block does not define the node properly for any internally executed steps? I have never seen any steps run on the wrong node.
Reply all
Reply to author
Forward
0 new messages