automated deletion of workspaces

809 views
Skip to first unread message

Tim Gover

unread,
Sep 8, 2011, 3:06:00 PM9/8/11
to Jenkins Users
Is there a way to schedule the deletion of a workspace on all nodes ?

Most of our builds are configured to be incremental builds because clean builds take ages. Occasionally the workspaces get corrupted e.g. orphaned intermediate files when the makefiles change or even the local git / repo instances gets corrupted.

I'd like to do something simple e.g.

a) Delete the workspaces for a defined set of jobs on every node.
b) Allow (a) to be triggered manually e.g. an admin can hit the 'reset' button

The best I have so far is a Groovy post build step that wipes out the workspace after the first build that day but it's a pain to configure that in every job.

cheers,
Tim

Gareth Bowles

unread,
Sep 8, 2011, 3:30:14 PM9/8/11
to jenkins...@googlegroups.com
This is fairly easy to do with a system Groovy script; here's one adapted from a script we have that deletes all workspaces on build slaves that are not the active workspace and are more than 4 days old (not guaranteed to work as-is since I've taken out a lot of the conditional logic):

import hudson.node_monitors.*
import hudson.slaves.*

hudson = Hudson.instance

for (slave in hudson.slaves) {
try {
wsRoot = slave.getWorkspaceRoot()
space = DiskSpaceMonitor.DESCRIPTOR.get(slave.computer)
if (!wsRoot || !space) return
for (dir in wsRoot.list()) {
try {
item = hudson.getItem(dir.name)
if (item instanceof AbstractProject) { processProject(slave, item, dir) }
} catch (Exception e) {
println " workspace: ${dir.name}, has no Hudson object, will delete"
processDeadDir(slave, dir)
}
}
} catch (InterruptedException ie) {
throw ie
} catch (Exception e) {
println " ERR in slave processing: ${e}"
}

def processProject(slave, proj, dir) {
try {
printWS(slave, proj, dir)
if (proj.getLastBuiltOn() != slave) {
age = new Date() - new Date(dir.lastModified())
if (age > 4) {
println " => deleting: ${dir} on ${slave.name} "
tryDelete(slave, proj, dir)
}
}
} catch (InterruptedException ie) {
throw ie
} catch (Exception e) {
println " ERR in processProject: ${e}"
}
}

def processDeadDir(slave, dir) {
try {
println " => deleting: ${dir} on ${slave.name} "
dir.deleteRecursive()
} catch (InterruptedException ie) {
throw ie
} catch (Exception e) {
println " ERR in processDeadDir: ${e}"
}
}

def printWS(slave, proj, dir) {
try {
age = new Date() - new Date(dir.lastModified())
lastBuiltOn = proj.getLastBuiltOn()
same = (lastBuiltOn == slave)
where = lastBuiltOn instanceof DumbSlave ? lastBuiltOn.name : lastBuiltOn
println " workspace: ${dir.name}, age: ${age} days, last built on: ${where}, ${same ? 'keep' : 'could delete'}"
} catch (Exception e) {
println " ERR in print: ${e}"
}
}

def tryDelete(slave, proj, dir) {
if (proj.scm.processWorkspaceBeforeDeletion(proj, dir, slave)) {
dir.deleteRecursive()

R. Tyler Croy

unread,
Sep 8, 2011, 4:09:31 PM9/8/11
to jenkins...@googlegroups.com

On Thu, 08 Sep 2011, Gareth Bowles wrote:

> This is fairly easy to do with a system Groovy script; here's one adapted from a script we have that deletes all workspaces on build slaves that are not the active workspace and are more than 4 days old (not guaranteed to work as-is since I've taken out a lot of the conditional logic):

This would be pretty great to have as a plugin, in case anybody wants a weekend
project :)


- R. Tyler Croy
--------------------------------------
Code: http://github.com/rtyler
Chatter: http://identi.ca/agentdero
http://twitter.com/agentdero

Daniel Doubrovkine

unread,
Sep 8, 2011, 4:27:31 PM9/8/11
to jenkins...@googlegroups.com

Tim Gover

unread,
Sep 9, 2011, 4:56:17 AM9/9/11
to jenkins...@googlegroups.com
Yes, perhaps a "max workspace age" parameter could be added. If the workspace on the current node has not been deleted in the timeframe specified by that parameter then it would be automatically deleted before the build is run.

Looking at the code for this plug-in I think it would get possible to walk the previous builds and find the last time that the job was built on the node. It could then see if a tag was set to indicate that the workspace was deleted.

Tim

Paul G. Weiss

unread,
Sep 13, 2011, 7:59:50 AM9/13/11
to jenkins...@googlegroups.com, Tim Gover
The use case I'd like for this plugin is as a replacement for the current
"Delete workspace" functionality in core Jenkins. That merely deletes the
workspace from the slave that did the last build. Instead I'd like it to
set a flag so that when the job is built on _any_ node, it checks to see
if this is the first build on that node since the flag was set, and if so,
deletes the workspace before the build. Subsequent builds on that node
would not delete the workspace.

-P

>> dblock.org <http://www.dblock.org> -
>> @dblockdotorg<http://twitter.com/#!/dblockdotorg>
>>

David Shaw

unread,
Feb 23, 2015, 8:55:23 AM2/23/15
to jenkins...@googlegroups.com
Digging up an old post but does anyone know how I can enable the checkbox via groovy?

I've got thousands of jobs that need this setting....

Thanks

Dave

Baptiste Mathus

unread,
Feb 23, 2015, 11:21:47 AM2/23/15
to jenkins...@googlegroups.com
Which one, please be a bit more specific.

--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/f911351a-6e95-4cb9-bcc9-5ccb7efe2418%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Baptiste <Batmat> MATHUS - http://batmat.net
Sauvez un arbre,
Mangez un castor !

Baptiste Mathus

unread,
Feb 23, 2015, 11:29:03 AM2/23/15
to jenkins...@googlegroups.com
FWIW, if you're using the WS cleanup plugin, I found that old java-like :-) groovy script in our internal housekeeping repo:

import hudson.model.*
import hudson.tasks.*
import hudson.plugins.emailext.*
import hudson.triggers.*  
import hudson.maven.*
import hudson.model.FreeStyleProject;
import hudson.model.JDK;
import hudson.maven.MavenModuleSet;
import hudson.tasks.Maven;
import hudson.maven.reporters.*  
import hudson.plugins.ws_cleanup.*;
import java.util.*;

def patterns = new ArrayList()
patterns.add(new Pattern("**/target", Pattern.PatternType.INCLUDE))

for(AbstractProject item in Jenkins.getInstance().getItems()) {
def workspaceCleanup = new WsCleanup(patterns, true, true, true, false);

def result = false
if(item instanceof MavenModuleSet) {
result = true;
}
else if(item instanceof FreeStyleProject) {
        // parcourt de tous les builders pour savoir s'il y a au moins un Maven
        for (builder in item.builders){
        if(builder instanceof Maven) {
        result = true
        break
        }
        }            
}
if(result) {
item.getPublishersList().add(workspaceCleanup);
   item.save();
   println "Ajout de workspaceCleanup sur " + item.name
}
}

HTH
Reply all
Reply to author
Forward
0 new messages