hudson.plugins.tmpcleaner.TmpCleanTask Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tmpcleaner Show documentation
Show all versions of tmpcleaner Show documentation
Cleans garbage in java.io.tmpdir
The newest version!
package hudson.plugins.tmpcleaner;
import hudson.os.PosixAPI;
import hudson.remoting.Callable;
import hudson.util.TimeUnit2;
import java.io.File;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jruby.ext.posix.FileStat;
import org.jruby.ext.posix.POSIX;
import org.kohsuke.stapler.framework.io.IOException2;
/**
* Recursively visits a directory and remove unused files.
*
* @author Kohsuke Kawaguchi
*/
public class TmpCleanTask implements Callable {
private transient long criteria;
private transient POSIX posix;
private transient int euid;
//
private String extraDirectories;
private long days;
public TmpCleanTask(String extraDirectories, long days)
{
this.extraDirectories = extraDirectories;
this.days = days;
}
public Void call() throws IOException {
criteria = (System.currentTimeMillis() - TimeUnit2.DAYS.toMillis(days))/1000; // time_t is # of seconds
posix = PosixAPI.get();
euid = posix.geteuid();
File f = File.createTempFile("tmpclean", null);
f.delete();
visit(f.getParentFile());
LOGGER.fine( "extraDirectories " + extraDirectories + ", days " + days );
try
{
if (extraDirectories != null)
{
StringTokenizer stringTokenizer = new StringTokenizer( extraDirectories, "," );
while (stringTokenizer.hasMoreElements())
{
File dir = new File( stringTokenizer.nextToken() );
if (dir.exists())
{
visit( dir );
}
else
{
LOGGER.fine( "dir "+ dir.getPath() + " not exist ");
}
}
}
} catch (Exception e)
{
LOGGER.log( Level.SEVERE, e.getMessage(), e );
throw new IOException2( e.getMessage(), e );
}
finally
{
LOGGER.log(Level.INFO, " end TmpCleanTask " );
}
return null;
}
private void visit(File dir) {
LOGGER.fine("visit "+dir);
File[] children = dir.listFiles();
if (children==null) return; // just being defensive
for (File child : children) {
// lstat so that we won't visit into directories that are symlinked
FileStat stat;
try {
stat = posix.lstat(child.getPath());
} catch (RuntimeException e) {// handle lstat failure gracefully
LOGGER.log(Level.INFO, "lstat failed on "+child + ", " + e.getMessage());
continue;
}
if (stat.uid()!=euid) {
LOGGER.finer("Skipping "+child+" since we don't own it");
continue;
}
if (stat.isDirectory()) {
visit(child);
String[] contents = child.list();
if (contents!=null && contents.length==0) {
LOGGER.info("Deleting empty directory "+child);
child.delete();
} else {
LOGGER.finer(child+" is not empty");
}
}
long atime = stat.atime();
if (atime < criteria) {
LOGGER.info(String.format("Deleting %s (atime=%d, diff=%d)", child, atime,atime-criteria));
child.delete();
} else {
LOGGER.finer("Skipping "+child+" since it's not old enough");
}
}
}
public static void main(String[] args) throws IOException {
// somehow my JVM on Ubuntu gets iso-8859-1 as the default encoding even though LANG=en_US.UTF-8
// System.setProperty("jna.encoding","UTF-8");
LOGGER.setLevel(Level.FINE);
ConsoleHandler h = new ConsoleHandler();
h.setLevel(Level.FINE);
LOGGER.addHandler(h);
new TmpCleanTask("", 2).call();
}
private static final Logger LOGGER = Logger.getLogger(TmpCleanTask.class.getName());
}