Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
A jenkins script to clean up workspaces on slaves
// Check if a slave has < 10 GB of free space, wipe out workspaces if it does
import hudson.model.*;
import hudson.util.*;
import jenkins.model.*;
import hudson.FilePath.FileCallable;
import hudson.slaves.OfflineCause;
import hudson.node_monitors.*;
import org.jenkinsci.plugins.workflow.job.WorkflowRun
import org.jenkinsci.plugins.workflow.flow.FlowExecution;
import org.jenkinsci.plugins.workflow.graph.FlowGraphWalker;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.graph.StepStartNode;
import org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode;
import org.jenkinsci.plugins.workflow.actions.WorkspaceAction
boolean shouldSkip(item) {
jobName = item.getFullDisplayName()
if ( !item instanceof Job ||
"${item.class}".contains('Folder') ||
!item.metaClass.respondsTo(item, "isBuilding")) {
return true
if (item.isBuilding()) {
println(".. job " + jobName + " is currently running, skipped")
return true
return false
for (node in Jenkins.instance.nodes) {
computer = node.toComputer()
if (computer.getChannel() == null) {
//this should keep jenkins master out of harms way
//change prefix to match your env
if (!node.getDisplayName().startsWith("slave-")) {
rootPath = node.getRootPath()
size = DiskSpaceMonitor.DESCRIPTOR.get(computer).size
roundedSize = size / (1024 * 1024 * 1024) as int
println("node: " + node.getDisplayName() + ", free space: " + roundedSize + "GB")
if (roundedSize <= MIN_FREE_DISK_SPACE) {
computer.setTemporarilyOffline(true, new hudson.slaves.OfflineCause.ByCLI("disk cleanup"))
println "Set " + node.getDisplayName() + " temporarily offline"
for (item in Jenkins.instance.getAllItems(TopLevelItem)) {
if (shouldSkip(item)) {
jobName = item.getFullDisplayName()
workspacePath = node.getWorkspaceFor(item)
if (workspacePath == null) {
if (!"${item.class}".contains('Workflow')) {
customWorkspace = item.getCustomWorkspace()
} else {
b = item.getLastBuild()
if(b instanceof WorkflowRun) {
exec = b.getExecution();
if(exec == null) {
FlowGraphWalker w = new FlowGraphWalker(exec);
for (FlowNode n : w) {
if (n instanceof StepStartNode) {
action = n.getAction(WorkspaceAction);
if(action) {
String workspace = action.getPath().toString();
customWorkspace = workspace
if (customWorkspace != null) {
workspacePath = node.getRootPath().child(customWorkspace)
pathAsString = workspacePath.getRemote()
if (workspacePath.exists()) {
//uncommend next to actually delete dirs
println(" ...deleted " + pathAsString)
computer.setTemporarilyOffline(false, null)
println "Set " + node.getDisplayName() + " back online"
Copy link

TheNitek commented Mar 5, 2018

Gives me a compilation error. I think the "}" on line 89 needs to be removed.

Copy link

TheNitek commented Mar 5, 2018

The script tried to delete my /opt/jenkins on my linux node (which luckily failed due to the permissions) so it doesn't seem safe to run.

Copy link

zerogvt commented Mar 14, 2018

  • Fixed syntax error (wrong }). Sorry about that - I removed some printouts before pasting the code and I guess I overdid it.
  • I don't understand how you got the result you describe in your second commend. Jenkins master node is not returned in the nodes array (line 33) as clearly stated in the API. I also tested on a local instance but I couldn't reproduce. Anyhow I added a check (line 40) that should keep jenkins master - out of the way in the unlikely case it is being returned by the call to getNodes().
    Keep in mind that this -being a gist and not a complete program- is only supposed to be a starting point. There might be other assumptions in my code that won't fit your case.

Copy link

burnettk commented May 14, 2018

i don't think it's about running on master. i added a println of the directory it was trying to delete on an agent, since it was getting "remote file operation failed" and i was curious why, and it said it was trying to delete /opt/jenkins, which is not a workspace dir, but the jenkins root directory on the agent.

Copy link

stephan2012 commented May 30, 2018

item.isBuilding() fails if item is a WorkflowMultiBranchProject:

groovy.lang.MissingMethodException: No signature of method: org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject.isBuilding() is applicable for argument types: () values: []
Possible solutions: isBuildable(), isBuildable()
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(
	at hudson.model.Job$ Source)
	at groovy.lang.GroovyShell.evaluate(
	at groovy.lang.GroovyShell.evaluate(
	at groovy.lang.GroovyShell.evaluate(
	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SecureGroovyScript.evaluate(
	at hudson.plugins.groovy.SystemGroovy.perform(
	at hudson.tasks.BuildStepMonitor$1.perform(
	at hudson.model.AbstractBuild$AbstractBuildExecution.perform(
	at hudson.model.Build$
	at hudson.model.Build$BuildExecution.doRun(
	at hudson.model.AbstractBuild$
	at hudson.model.Run.execute(
	at hudson.model.ResourceController.execute(

Not sure yet how to handle this best.

Copy link

kumar0608 commented May 1, 2020

my workspace having some files with root permission, Is there any suggestion on this ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment