How can I set the job timeout for all jobs using t

2019-09-09 06:56发布

问题:

I read How can I set the job timeout using the Jenkins DSL. That sets the timeout for one job. I want to set it for all jobs, and with slightly different settings: 150%, averaged over 10 jobs, with a max of 30 minutes.

According to the relevant job-dsl-plugin documentation I should use this syntax:

job('example-3') {
    wrappers {
        timeout {
            elastic(150, 10, 30)
            failBuild()
            writeDescription('Build failed due to timeout after {0} minutes')
        }
    }
}

I tested in http://job-dsl.herokuapp.com/ and this is the relevant XML part:

<buildWrappers>
    <hudson.plugins.build__timeout.BuildTimeoutWrapper>
        <strategy class='hudson.plugins.build_timeout.impl.ElasticTimeOutStrategy'>
            <timeoutPercentage>150</timeoutPercentage>
            <numberOfBuilds>10</numberOfBuilds>
            <timeoutMinutesElasticDefault>30</timeoutMinutesElasticDefault>
        </strategy>
        <operationList>
            <hudson.plugins.build__timeout.operations.FailOperation></hudson.plugins.build__timeout.operations.FailOperation>
            <hudson.plugins.build__timeout.operations.WriteDescriptionOperation>
                <description>Build failed due to timeout after {0} minutes</description>
            </hudson.plugins.build__timeout.operations.WriteDescriptionOperation>
        </operationList>
    </hudson.plugins.build__timeout.BuildTimeoutWrapper>
</buildWrappers>

I verified with a job I edited manually before, and the XML is correct. So I know that the Jenkins DSL syntax up to here is correct.


Now I want to apply this to all jobs. First I tried to list all the job names:

import jenkins.model.*

jenkins.model.Jenkins.instance.items.findAll().each {
  println("Job: " + it.name)
}

This works too, all job names are printed to console.


Now I want to plug it all together. This is the full code I use:

import jenkins.model.*

jenkins.model.Jenkins.instance.items.findAll().each {
  job(it.name) {
    wrappers {
      timeout {
        elastic(150, 10, 30)
        failBuild()
        writeDescription('Build failed due to timeout after {0} minutes')
      }
    }
  }
}

When I push this code and Jenkins runs the DSL seed job, I get this error:

ERROR: Type of item "jobname" does not match existing type, item type can not be changed

What am I doing wrong here?

回答1:

The Job-DSL plugin can only be used to maintain jobs that have been created by that plugin before. You're trying to modify the configuration of jobs that have been created in some other way -- this will not work.

For mass-modification of existing jobs (like, in your case, adding the timeout) the most straightforward way is to change the job's XML specification directly,

  • either by changing the config.xml file on disk, or
  • using the REST or CLI API

xmlstarlet is a powerful tool for performing such tasks directly on shell level.

Alternatively, it is possible to perform the change via a Groovy script from the "Script Console" -- but for that you need some understanding of Jenkins' internal workings and data structures.