Last active
November 29, 2018 07:25
-
-
Save sirrapa/d22642d110610795253ca14c1367a3dc to your computer and use it in GitHub Desktop.
Groovy script for cleaning up ghost workspaces left on slaves after a job has been deleted. Must be run strictly on the master instance.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hudson.FilePath; | |
// Initialize dryRun parameter to TRUE if not given as script parameter | |
dryRun = true; | |
if( dryRun == true ) { | |
println "** Execute a dryRun - no files will ever be deleted **"; | |
} | |
// shortcut to Jenkins instance | |
def jenkins = jenkins.model.Jenkins.instance; | |
// Search for Projects without custom workspace and collect their name | |
// | |
def jobNames = jenkins.getAllItems(jenkins.model.ParameterizedJobMixIn.ParameterizedJob.class).collect { it.name }; | |
println("Existing Jobs: "); | |
jobNames.each {println " $it"} | |
// Slaves create a workspace for each job under their 'workspaceRoot'. | |
// The subdirectory is named after the job name, possibly with a @ followed by a | |
// number in case of matrix jobs. | |
// We simply list the workspace content and try to find a matching job. If none | |
// is found, the directory is scheduled for deletion. | |
// | |
// This process is done only for slaves that are online. | |
// Master must be done slightly differently. | |
// | |
for (slave in jenkins.slaves) | |
{ | |
println ""; | |
// Make sure slave is online | |
if( ! slave.computer.online ) { | |
println("Slave '$slave.nodeName' is currently offline - skip workspace cleanup"); | |
continue; | |
} | |
// Retrieve the a FilePath to the workspace root | |
def wsRoot = slave.workspaceRoot; | |
if( wsRoot == null ) { | |
printlnt("Slave '$slave.nodeName' has a <null> workspaceRoot - skip workspace cleanup"); | |
continue; | |
} | |
// List workspace content and perform cleanup | |
println("Slave '$slave.nodeName' is online - perform workspace cleanup:"); | |
def subdirs = wsRoot.list(); | |
if( subdirs.size() == 0 ) { | |
println(" (workspace is empty)"); | |
continue; | |
} | |
for(d in subdirs) { | |
// Remove any suffixes from the dir name | |
def dirName = d.name.split("@")[0]; | |
// Find matching job | |
def jobMatch = jobNames.find { it==dirName }; | |
if ( jobMatch != null ) { | |
println(" KEEP: $d --> job:$jobMatch"); | |
} | |
else { | |
if( dryRun == true ) { | |
println(" DELETE: $d (dryRun)"); | |
} | |
else { | |
println(" DELETE: $d"); | |
d.deleteRecursive(); | |
} | |
} | |
} | |
} | |
// Now cleanup master | |
File rawWorkSpace = new File(jenkins.rootDir.absolutePath + "/workspace/") | |
for(d in rawWorkSpace.listFiles()) { | |
// Remove any suffixes from the dir name | |
def dirName = d.name.split("@")[0]; | |
// Find matching job | |
def jobMatch = jobNames.find { it==dirName }; | |
if ( jobMatch != null ) { | |
println(" KEEP: $d --> job:$jobMatch"); | |
} | |
else { | |
if( dryRun == true ) { | |
println(" DELETE: $d (dryRun)"); | |
} | |
else { | |
println(" DELETE: $d"); | |
d.deleteDir(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment