Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-55426

Using "for in" loop for generating tasks for "parallel" execution, causes all tasks to have last value from iterated collection

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • groovy-plugin
    • Jenkins 2.150.1, Pipeline-Groovy Plugin 2.57

      When I try to generate tasks for parallel execution using the following code:

      import jenkins.model.Jenkins
      
      pipeline {
          agent none
          stages {
              stage('Preparing machines') {
                  steps {
                      script {
                          def machines = ['agent-windows0', 'agent-windows1', 'agent-redhat0', 'agent-redhat1']
                          def machinePreparations = [:]
      
                          for (machine in machines) {
                              def labelParameters = []
                              labelParameters.add([$class: 'NodeParameterValue', name: 'node_name', labels: [machine], nodeEligibility: [$class: 'AllNodeEligibility']])
                              labelParameters.add([$class: 'StringParameterValue', name: 'ARBITRARY_PARAMETER', value: 'ARBITRARY_VALUE'])
      
                              machinePreparations[machine] = {
                                  stage(machine + ' preparation') {
                                      build job: '../Preparation/' + machine, parameters: labelParameters
      
                                      def node = Jenkins.get().nodes.find({it.name == machine})
                                      node.setLabelString(node.getLabelString() + 'successful')
                                      println(String.format("Job with machine %s successfully done!", machine))
                                  }
                              }
                          }
      
                          parallel machinePreparations
                      }
                  }
              }
          }
      }
      

      I have all the tasks receiving last value from collection ("agent-redhat1") - see screen attached.
      This can be partially fixed by saving "machine" variable into another intermediate variable and using this intermediate variable instead:

      import jenkins.model.Jenkins
      
      pipeline {
          agent none
          stages {
              stage('Preparing machines') {
                  steps {
                      script {
                          def machines = ['agent-windows0', 'agent-windows1', 'agent-redhat0', 'agent-redhat1']
                          def machinePreparations = [:]
      
                          for (machine in machines) {
                              def agentName = machine
                              def labelParameters = []
                              labelParameters.add([$class: 'NodeParameterValue', name: 'node_name', labels: [agentName], nodeEligibility: [$class: 'AllNodeEligibility']])
                              labelParameters.add([$class: 'StringParameterValue', name: 'ARBITRARY_PARAMETER', value: 'ARBITRARY_VALUE'])
      
                              machinePreparations[agentName] = {
                                  stage(agentName + ' preparation') {
                                      build job: '../Preparation/' + agentName, parameters: labelParameters
      
                                      def node = Jenkins.get().nodes.find({it.name == agentName})
                                      node.setLabelString(node.getLabelString() + 'successful')
                                      println(String.format("Job with machine %s successfully done!", agentName))
                                  }
                              }
                          }
      
                          parallel machinePreparations
                      }
                  }
              }
          }
      }
      

      However, this also not fixing problem entirely, see JENKINS-55425

          [JENKINS-55426] Using "for in" loop for generating tasks for "parallel" execution, causes all tasks to have last value from iterated collection

          Alexandr Panshin created issue -
          Alexandr Panshin made changes -
          Description Original: When I try to generate tasks for parallel execution using the following code:
          {code:java}
          import jenkins.model.Jenkins

          pipeline {
              agent none
              stages {
                  stage('Preparing machines') {
                      steps {
                          script {
                              def machines = ['agent-windows0', 'agent-windows1', 'agent-redhat0', 'agent-redhat1']
                              def machinePreparations = [:]

                              for (machine in machines) {
                                  def labelParameters = []
                                  labelParameters.add([$class: 'NodeParameterValue', name: 'node_name', labels: [machine], nodeEligibility: [$class: 'AllNodeEligibility']])
                                  labelParameters.add([$class: 'StringParameterValue', name: 'ARBITRARY_PARAMETER', value: 'ARBITRARY_VALUE'])

                                  machinePreparations[machine] = {
                                      stage(machine + ' preparation') {
                                          build job: '../Preparation/' + machine, parameters: labelParameters

                                          def node = Jenkins.get().nodes.find({it.name == machine})
                                          node.setLabelString(node.getLabelString() + 'successful')
                                          println(String.format("Job with machine %s successfully done!", machine))
                                      }
                                  }
                              }

                              parallel machinePreparations
                          }
                      }
                  }
              }
          }
          {code}
          I have all the tasks receiving last value from collection ("agent-redhat1") - see screen attached.
          This can be partially fixed by saving "machine" variable into another intermediate variable and using this intermediate variable instead:

          {code:java}
          import jenkins.model.Jenkins

          pipeline {
              agent none
              stages {
                  stage('Preparing machines') {
                      steps {
                          script {
                              def machines = ['agent-windows0', 'agent-windows1', 'agent-redhat0', 'agent-redhat1']
                              def machinePreparations = [:]

                              for (machine in machines) {
                                  def agentName = machine
                                  def labelParameters = []
                                  labelParameters.add([$class: 'NodeParameterValue', name: 'node_name', labels: [agentName], nodeEligibility: [$class: 'AllNodeEligibility']])
                                  labelParameters.add([$class: 'StringParameterValue', name: 'ARBITRARY_PARAMETER', value: 'ARBITRARY_VALUE'])

                                  machinePreparations[agentName] = {
                                      stage(agentName + ' preparation') {
                                          build job: '../Preparation/' + agentName, parameters: labelParameters

                                          def node = Jenkins.get().nodes.find({it.name == agentName})
                                          node.setLabelString(node.getLabelString() + 'successful')
                                          println(String.format("Job with machine %s successfully done!", agentName))
                                      }
                                  }
                              }

                              parallel machinePreparations
                          }
                      }
                  }
              }
          }
          {code}

          However, this also not fixing problem entirely, see [#JENKINS-55425]
          New: When I try to generate tasks for parallel execution using the following code:
          {code:java}
          import jenkins.model.Jenkins

          pipeline {
              agent none
              stages {
                  stage('Preparing machines') {
                      steps {
                          script {
                              def machines = ['agent-windows0', 'agent-windows1', 'agent-redhat0', 'agent-redhat1']
                              def machinePreparations = [:]

                              for (machine in machines) {
                                  def labelParameters = []
                                  labelParameters.add([$class: 'NodeParameterValue', name: 'node_name', labels: [machine], nodeEligibility: [$class: 'AllNodeEligibility']])
                                  labelParameters.add([$class: 'StringParameterValue', name: 'ARBITRARY_PARAMETER', value: 'ARBITRARY_VALUE'])

                                  machinePreparations[machine] = {
                                      stage(machine + ' preparation') {
                                          build job: '../Preparation/' + machine, parameters: labelParameters

                                          def node = Jenkins.get().nodes.find({it.name == machine})
                                          node.setLabelString(node.getLabelString() + 'successful')
                                          println(String.format("Job with machine %s successfully done!", machine))
                                      }
                                  }
                              }

                              parallel machinePreparations
                          }
                      }
                  }
              }
          }
          {code}
          I have all the tasks receiving last value from collection ("agent-redhat1") - see screen attached.
          This can be partially fixed by saving "machine" variable into another intermediate variable and using this intermediate variable instead:

          {code:java}
          import jenkins.model.Jenkins

          pipeline {
              agent none
              stages {
                  stage('Preparing machines') {
                      steps {
                          script {
                              def machines = ['agent-windows0', 'agent-windows1', 'agent-redhat0', 'agent-redhat1']
                              def machinePreparations = [:]

                              for (machine in machines) {
                                  def agentName = machine
                                  def labelParameters = []
                                  labelParameters.add([$class: 'NodeParameterValue', name: 'node_name', labels: [agentName], nodeEligibility: [$class: 'AllNodeEligibility']])
                                  labelParameters.add([$class: 'StringParameterValue', name: 'ARBITRARY_PARAMETER', value: 'ARBITRARY_VALUE'])

                                  machinePreparations[agentName] = {
                                      stage(agentName + ' preparation') {
                                          build job: '../Preparation/' + agentName, parameters: labelParameters

                                          def node = Jenkins.get().nodes.find({it.name == agentName})
                                          node.setLabelString(node.getLabelString() + 'successful')
                                          println(String.format("Job with machine %s successfully done!", agentName))
                                      }
                                  }
                              }

                              parallel machinePreparations
                          }
                      }
                  }
              }
          }
          {code}

          However, this also not fixing problem entirely, see [JENKINS-55425|https://issues.jenkins-ci.org/browse/JENKINS-55425]
          Alexandr Panshin made changes -
          Link New: This issue is blocking JENKINS-55748 [ JENKINS-55748 ]
          Sergei S made changes -
          Attachment New: image-2020-04-20-14-01-42-072.png [ 51000 ]

            vjuranek vjuranek
            alpanshin Alexandr Panshin
            Votes:
            2 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: