Yuhao Zhang
Yuhao Zhang

Reputation: 490

Providing different values in Jenkins dsl configure block to create different jobs

I need my builds to timeout at a specific time (deadline) but currently Jenkins dsl only support the "absolute" strategy. So I tried to write the configure block but couldn't create jobs with different deadline values.

def settings = [
    [
        jobname: 'job1',
        ddl: '13:10:00'
    ], 
    [
        jobname: 'job2',
        ddl: '14:05:00'
    ]
]


for (i in settings) {
    job(i.jobname) {
        configure {
            it / buildWrappers << 'hudson.plugins.build__timeout.BuildTimeoutWrapper' {
                strategy(class:'hudson.plugins.build_timeout.impl.DeadlineTimeOutStrategy') {
                    deadlineTime(i.ddl)
                    deadlineToleranceInMinutes(1)
                }
            }
        }
        steps {
            // some stuff to do here
        }
    }
}

The above script gives me two jobs with the same deadline time(14:05:00):

<project>
    <actions></actions>
    <description></description>
    <keepDependencies>false</keepDependencies>
    <properties></properties>
    <scm class='hudson.scm.NullSCM'></scm>
    <canRoam>true</canRoam>
    <disabled>false</disabled>
    <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
    <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
    <triggers></triggers>
    <concurrentBuild>false</concurrentBuild>
    <builders></builders>
    <publishers></publishers>
    <buildWrappers>
        <hudson.plugins.build__timeout.BuildTimeoutWrapper>
            <strategy class='hudson.plugins.build_timeout.impl.DeadlineTimeOutStrategy'>
                <deadlineTime>14:05:00</deadlineTime>
                <deadlineToleranceInMinutes>1</deadlineToleranceInMinutes>
            </strategy>
        </hudson.plugins.build__timeout.BuildTimeoutWrapper>
    </buildWrappers>
</project>

I found this question but still couldn't get it to work.

Upvotes: 0

Views: 981

Answers (2)

ptha
ptha

Reputation: 916

I saw very similar behaviour to this in a Jenkins DSL groovy script. I was looping over a List of Maps in a for each, and I also have a configure closure like your example.

The behaviour I saw was that the Map object in the configure closure seemed to be the same for all iterations of the for each loop. Similar to how you are seeing the same deadline time. I was actually referencing the same value in the Map both inside and outside the configure closure and the DSL was outputting different values. Outside the configure closure was as expected, but inside was the same value for all iterations.

My solution was just to use a variable to reference the Map value and use that both inside and outside the configure closure, when I did that, the value was consistent.

For your example (just adding a deadlineValue variable, and setting it outside the configure closure):

for (i in settings) {
    def deadlineValue = i.ddl
    job(i.jobname) {
        configure {
            it / buildWrappers << 'hudson.plugins.build__timeout.BuildTimeoutWrapper' {
                strategy(class:'hudson.plugins.build_timeout.impl.DeadlineTimeOutStrategy') {
                    deadlineTime(deadlineValue)
                    deadlineToleranceInMinutes(1)
                }
            }
        }
        steps {
            // some stuff to do here
        }
    }
}

I would not expect this to make a difference, but it worked for me.

However I agree as per the the other solution it is better to use buildTimeoutWrapper, so you can avoid using the configure block.

See: <Your Jenkins URL>/plugin/job-dsl/api-viewer/index.html#path/javaposse.jobdsl.dsl.DslFactory.job-wrappers-buildTimeoutWrapper-strategy-deadlineTimeOutStrategy for more details, obviously you'll need the Build Timeout plugin installed.

For my example I still needed the configure closure for the MultiJob plugin where some parameters were still not configurable via the DSL api.

Upvotes: 0

KeepCalmAndCarryOn
KeepCalmAndCarryOn

Reputation: 9075

You can use the Automatic Generated API

The generated DSL is only supported when running in Jenkins, e.g. it is
not available when running from the command line or in the Playground.

Use The Configure Block to generate custom config elements when not 
running in Jenkins.

The generated DSL will not work for all plugins, e.g. if a plugin does
not use the @DataBoundConstructor and @DataBoundSetter annotations to 
declare parameters. In that case The Configure Block can be used to 
generate the config XML.

Fortunately the Timeout plugin support DataBoundConstructors

@DataBoundConstructor
public DeadlineTimeOutStrategy(String deadlineTime, int deadlineToleranceInMinutes) {
    this.deadlineTime = deadlineTime;
    this.deadlineToleranceInMinutes = deadlineToleranceInMinutes <= MINIMUM_DEADLINE_TOLERANCE_IN_MINUTES ? MINIMUM_DEADLINE_TOLERANCE_IN_MINUTES
            : deadlineToleranceInMinutes;
}

So you should be able to do something like

def settings = [
    [
        jobname: 'job1',
        ddl: '13:10:00'
    ], 
    [
        jobname: 'job2',
        ddl: '14:05:00'
    ]
]


for (i in settings) {
    job(i.jobname) {          
        wrappers {
          buildTimeoutWrapper {
            strategy {
              deadlineTimeOutStrategy {
                deadlineTime(i.ddl)
                deadlineToleranceInMinutes(1)
              }
            }
            timeoutEnvVar('WHAT_IS_THIS_FOR')
          }
        }

        steps {
            // some stuff to do here
        }
    }
}

There is an extra layer in BuildTimeoutWrapper which houses the different strategies

When using nested classes you need to set the first letter of the class to lowercase


EDIT

You can see this in your own Jenkins install by using the 'Job DSL API Reference' link in a jobs page

http://<your jenkins>/plugin/job-dsl/api-viewer/index.html#method/javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext.buildTimeoutWrapper

enter image description here

Upvotes: 2

Related Questions