Skip to content

Instantly share code, notes, and snippets.

@rajsahae
Forked from rb2k/gist:8372402
Last active May 9, 2018 22:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rajsahae/e0cbd7b88e9221eb99e7adaa0586e67d to your computer and use it in GitHub Desktop.
Save rajsahae/e0cbd7b88e9221eb99e7adaa0586e67d to your computer and use it in GitHub Desktop.
A jenkins script to clean up workspaces on slaves
// Check if a slave has < 2 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
def MIN_FREE_DISK_SPACE = 2 //GB
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) {
continue
}
// skip personal nodes
if (node.getLabelString().contains('personal')) {
println(node.getDisplayName() + ": skipping personal node")
continue
}
// this should keep jenkins master out of harms way
if (node.getDisplayName().startsWith("master")) {
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")
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)) {
continue
}
jobName = item.getFullDisplayName()
workspacePath = node.getWorkspaceFor(item)
if (workspacePath == null) {
continue
}
customWorkspace=""
if (!"${item.class}".contains('Workflow')) {
customWorkspace = item.getCustomWorkspace()
} else {
b = item.getLastBuild()
if(b instanceof WorkflowRun) {
exec = b.getExecution();
if(exec == null) {
continue;
}
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
break
}
}
}
}
}
if (customWorkspace != null) {
workspacePath = node.getRootPath().child(customWorkspace)
}
pathAsString = workspacePath.getRemote()
if (workspacePath.exists()) {
//uncommend next to actually delete dirs
//workspacePath.deleteRecursive()
println(" ...deleted " + pathAsString)
}
}
computer.setTemporarilyOffline(false, null)
println "Set " + node.getDisplayName() + " back online"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment