Cleaning up Jenkins Workspaces

When running a Jenkins server with many jobs and many agents, you can quickly run out of disk space because of orphan workspaces.

These groovy scripts can either be executed in Jenkins Script Console or as part of a scheduled maintenance job

This script wipes out the workspaces of all jobs on your Jenkins Master Server

import hudson.model.*
deleteWorkspace (Hudson.instance.items)
def deleteWorkspace (items) {
for (item in items) {
if (item.class.canonicalName != null
&& item.class.canonicalName != "com.cloudbees.hudson.plugins.folder.Folder"
&& item.class.canonicalName != "org.jenkinsci.plugins.workflow.job.WorkflowJob"
&& item.class.canonicalName != "com.github.mjdetullio.jenkins.plugins.multibranch.MavenMultiBranchProject"
&& item.class.canonicalName != "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject"
&& item.class.canonicalName != "hudson.model.ExternalJob") {
println("Item of type "+item.class.canonicalName+" found")
if(!item.isBuilding()) {
println("Wiping out workspace of job "+item.name)
item.doDoWipeOutWorkspace()
} else {
println("Skipping job "+item.name+", currently building")
}
} else if (item.class.canonicalName == "com.cloudbees.hudson.plugins.folder.Folder") {
println("Item is folder with name "+item.name)
deleteWorkspace(((com.cloudbees.hudson.plugins.folder.Folder) item).getItems())
} else {
println("Item of type "+item.class.canonicalName + " cannot have its workspace cleaned")
}
}
}

This script iterates through all workspace directories on all agents, and deletes a workspace if it is older than one day.

This assumes that all jobs use the default workspace location

def deleted = []
def oneDayAgo = new Date() - 1
jenkins.model.Jenkins.instance.nodes.each { hudson.model.Node node ->
node.workspaceRoot.listDirectories().each { hudson.FilePath path ->
def pathName = path.getRemote()
if (path.name.startsWith(".")) {
println "Skipping internal dir $node.displayName:$pathName"
} else {
def lastModified = new Date(path.lastModified())
if (lastModified < oneDayAgo) {
println "Deleting workspace at $node.displayName:$pathName (last modified $lastModified)"
path.deleteRecursive()
deleted << "$node.displayName:$pathName"
} else {
println "Skipping workspace at $node.displayName:$pathName (last modified $lastModified)"
}
}
}
}
"Deleted workspaces: \n\t" + deleted.sort().join("\n\t")

References