Skip to content

Instantly share code, notes, and snippets.

Embed
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.*;
def performCleanup(def node, def items) {
for (item in items) {
jobName = item.getFullDisplayName()
println("Cleaning " + jobName)
if(item instanceof com.cloudbees.hudson.plugins.folder.AbstractFolder) {
performCleanup(node, item.items)
continue
}
if (item.isBuilding()) {
println(".. job " + jobName + " is currently running, skipped")
continue
}
println(".. wiping out workspaces of job " + jobName)
workspacePath = node.getWorkspaceFor(item)
if (workspacePath == null) {
println(".... could not get workspace path")
continue
}
println(".... workspace = " + workspacePath)
pathAsString = workspacePath.getRemote()
if (workspacePath.exists()) {
workspacePath.deleteRecursive()
println(".... deleted from location " + pathAsString)
} else {
println(".... nothing to delete at " + pathAsString)
}
}
}
for (node in Jenkins.instance.nodes) {
computer = node.toComputer()
if (computer.getChannel() == null) continue
rootPath = node.getRootPath()
size = DiskSpaceMonitor.DESCRIPTOR.get(computer).size
roundedSize = size / (1024 * 1024 * 1024) as int
println("node: " + node.getDisplayName() + ", free space: " + roundedSize + "GB")
computer.setTemporarilyOffline(true, new hudson.slaves.OfflineCause.ByCLI("disk cleanup"))
performCleanup(node, Jenkins.instance.items)
computer.setTemporarilyOffline(false, null)
}
@TheNitek

This comment has been minimized.

Copy link

TheNitek commented Mar 5, 2018

Nice, works perfectly for me!

@jogamol

This comment has been minimized.

Copy link

jogamol commented Jun 21, 2018

works great. Thanks

@vimalkrishna

This comment has been minimized.

Copy link

vimalkrishna commented Jul 31, 2018

This saved my lots of time writing on my own and Script works on script console of Jenkins (Master)!!
But as a system groovy script through a jenkins job, the latest groovy plugin (v2)doesn't work. We need to downgrade groovy plugin to 1.5 version and have minimum v 1.25 as script security plugin on Ubuntu 16. Also need to enable In-process Script Approval from Jenkins --> Manage Jenkins. Simple hint: Both master /slave machine must have groovy runtime installed with GROOVY_HOME set.

@kusumat

This comment has been minimized.

Copy link

kusumat commented May 16, 2019

Hi,
Why we are checking for instanceof com.cloudbees.hudson.plugins.folder.AbstractFolder
Why dont we simply delete the workspace?

Thanks

@Dretch

This comment has been minimized.

Copy link

Dretch commented Jun 20, 2019

Be aware that this script will skip jobs that are running, even if those jobs are not actually using any workspaces.

If you have pipeline jobs that are waiting for input, for example, then their workspaces will not be cleaned up by this script.

@EvilBeaver

This comment has been minimized.

Copy link
Owner Author

EvilBeaver commented Jun 20, 2019

If you have pipeline jobs that are waiting for input, for example, then their workspaces will not be cleaned up by this script.

I think this is a good behavior. It's not very polite to spoil life of running job, isn't it?

@tullurimanasa

This comment has been minimized.

Copy link

tullurimanasa commented Jul 2, 2019

Hi, Thank you for sharing the snippet.I am testing this on my jenkins and it fails with below error. How do we skip FolderTemplate as isBuilding is not applicable for folder templates. Please advise.
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: com.cloudbees.hudson.plugins.modeling.impl.folder.FolderTemplate.isBuilding() is applicable for argument types: () values: []

@MichaelKorn

This comment has been minimized.

Copy link

MichaelKorn commented Jul 31, 2019

@EvilBeaver THX for sharing
Maybe someone is interested, I added a function to skip younger build:

    buildAgeDays = (System.currentTimeMillis() - item.getLastBuild().getTimeInMillis()) / (1000*60*60*24)
    if(buildAgeDays < 5 ){
      println(".. job " + jobName + " was recently running, last build: " + item.getLastBuild().getTimestampString())
      continue
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.