When your Jenkins server runs on for a while, your hard disk usage grows up because the default setting of each job is that every job build and build artifact obtained from this are stored in a build history. Limiting this build history can save hard disk usage. Each job has a setting option called Discard Old Builds. In this setting you can set how long (in days) old builds keep in the build history (criteria 1) or how many old builds keep at most in the build history (criteria 2). Jenkins matches first criteria 1 and then criteria 2. Beyond that there exists advanced setting options. This advanced setting options can configured how long and how many builds with build artifacts have to keep in the build history. After that Jenkins deletes the build artifact, but the logs, history, reports, etc for the build will be kept. These will be kept so as long as they match the criteria in the normal setting options.
When you have many jobs, you don’t want to configure every job manually. For that you can modify the Discard Old Builds setting in each job over a Groovy script at one go. Jenkins has a so-called Script Console [1]. In this console you have to put the following Groovy script and every job is modified to discard its old builds.
def daysToKeep = 28 def numToKeep = 10 def artifactDaysToKeep = -1 def artifactNumToKeep = -1 Jenkins.instance.items.each { item -> println("=====================") println("JOB: " + item.name) println("Job type: " + item.getClass()) if(item.buildDiscarder == null) { println("No BuildDiscarder") println("Set BuildDiscarder to LogRotator") } else { println("BuildDiscarder: " + item.buildDiscarder.getClass()) println("Found setting: " + "days to keep=" + item.buildDiscarder.daysToKeepStr + "; num to keep=" + item.buildDiscarder.numToKeepStr + "; artifact day to keep=" + item.buildDiscarder.artifactDaysToKeepStr + "; artifact num to keep=" + item.buildDiscarder.artifactNumToKeepStr) println("Set new setting") } item.buildDiscarder = new hudson.tasks.LogRotator(daysToKeep,numToKeep, artifactDaysToKeep, artifactNumToKeep) item.save() println("") }
This script is tested with Jenkins version 1.534 and Jenkins Subversion Plugin version 1.53.
In my last posts ([2], [3]) I showed two other use cases for the Jenkins Script Console. All Groovy scripts can be found in GitHub [4]
Links
[1] Jenkins Script Console
[2] Post about how to rename Subversion host name in every job
[3] Post about how to add or modify Subversion repository browser in every job
[4] GitHub repository with several Groovy scripts for Jenkins script console
January 13, 2015 at 12:52
Thanks! This saved plenty of my development time
LikeLike
February 4, 2015 at 02:37
How to use it in a periodic job?
LikeLike
February 4, 2015 at 09:59
Hi Robson,
maybe the Jenkins plugin Groovy Postbuild Plugin can help you. But I don’t try it out by myself.
Greets,
Sandra
LikeLike
February 4, 2015 at 11:07
Thanks Sandra.
I’m using the System Groovy Script from https://wiki.jenkins-ci.org/display/JENKINS/Groovy+plugin
LikeLike
February 5, 2015 at 10:27
Then I think, the combination Groovy Plugin with the job option build schedule should solve your problem.
LikeLike
February 5, 2015 at 12:30
I did it and are working like a charm.
LikeLike
March 27, 2015 at 14:59
For some reason I can’t post the modifications to your script, but I adjusted it to take into account folders (free plugin). When processing items in a Jenkins Groovy script one should always check the item type, and if it is a folder, process recursively.
LikeLike
October 27, 2015 at 18:23
To work with folders (free plugin).
import hudson.model.*
disableChildren(Hudson.instance.items)
def disableChildren(items) {
def daysToKeep = 90
def numToKeep = 10
def artifactDaysToKeep = -1
def artifactNumToKeep = -1
for (item in items) {
if (item.class.canonicalName != ‘com.cloudbees.hudson.plugins.folder.Folder’) {
println(“=====================”)
println(“JOB: ” + item.name)
println(“Job type: ” + item.getClass())
if(item.buildDiscarder == null) {
println(“No BuildDiscarder”)
println(“Set BuildDiscarder to LogRotator”)
} else {
println(“BuildDiscarder: ” + item.buildDiscarder.getClass())
println(“Found setting: ” + “days to keep=” + item.buildDiscarder.daysToKeepStr + “; num to keep=” + item.buildDiscarder.numToKeepStr + “; artifact day to keep=” + item.buildDiscarder.artifactDaysToKeepStr + “; artifact num to keep=” + item.buildDiscarder.artifactNumToKeepStr)
println(“Set new setting”)
}
item.buildDiscarder = new hudson.tasks.LogRotator(daysToKeep,numToKeep, artifactDaysToKeep, artifactNumToKeep)
item.save()
println(“”)
} else {
disableChildren(((com.cloudbees.hudson.plugins.folder.Folder) item).getItems())
}
}
}
LikeLike
October 28, 2015 at 21:04
Thank you for sharing.
LikeLike
February 1, 2017 at 20:12
Hi Sandra,
I am working on migrating and cleaning up of around 350 CI jobs. I am new to groovy scripting. Is there a way I can get a crash course on how to navigate jenkins jobs.
For ex: After the migration I see that all the jobs have a default JDK in them instead of custom JDK version. I need to script out groovy in such a way that I select my custom JDK from the drop down of JDK list and set that for all the jobs.
LikeLike
February 1, 2017 at 20:20
May be this would be more accurate question: In the above example which you gave provided (by the way thank u very much I used it and ran it successfully) how did you know item.buildDiscarder is Discard old build check box?
In eclipse if I do item and hit control space I get the class names. Here how should I find them?
LikeLike
February 2, 2017 at 21:27
Hi Sharat,
I studied the source code of Jenkins to find out which parameter I have to adjust. I recommend Intellij IDEA Community Edition or Netbeans for Groovy scripting (IMHO they support Groovy better than Eclipse) and set up a Maven project that has Jenkins Core and Jenkins Plugins (that you need) in its dependencies declaration (Here is an POM example).
I hope that helps.
Best regards,
Sandra
LikeLike
February 3, 2017 at 00:04
Thanks Sandra I will try it out
LikeLike
April 21, 2017 at 21:01
Fails for me with:
groovy.lang.MissingPropertyException: No such property: buildDiscarder for class: org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject
LikeLike
April 24, 2017 at 18:19
The reason is because the script was written when WorkflowMultiBranchProject didn’t exist. So you have to adjust the script to your situation.
LikeLike
November 24, 2017 at 12:02
I’m getting an error while running the script. I’ve fixed the issue with Folders with Rogerios’ help. But getting error for WorkflowMultiBranchProject. Any inputs?
LikeLike
November 25, 2017 at 17:15
Hi,
the property buildDiscarder is field of the class hudson.model.Job and the WorkflowMultiBranchProject is a wrapper class that wraps many jobs. That’s the cause why it fails. You have to adjust your code, so that you can iterate over a list of jobs.
Best regards,
Sandra
LikeLike