public class AgentMirrorCleaner implements DirectoryCleanersProvider {
- private final static Logger ourLog = Logger.getInstance(AgentMirrorCleaner.class.getName());
+ private final static Logger LOG = Logger.getInstance(AgentMirrorCleaner.class.getName());
private final MirrorManager myMirrorManager;
public AgentMirrorCleaner(@NotNull MirrorManager mirrorManager) {
public void registerDirectoryCleaners(@NotNull DirectoryCleanersProviderContext context,
@NotNull DirectoryCleanersRegistry registry) {
Set<String> repositoriesUsedInBuild = getRunningBuildRepositories(context);
- for (Map.Entry<String, File> entry : myMirrorManager.getMappings().entrySet()) {
+ final Map<String, File> mappings = myMirrorManager.getMappings();
+ for (Map.Entry<String, File> entry : mappings.entrySet()) {
String repository = entry.getKey();
File mirror = entry.getValue();
if (!repositoriesUsedInBuild.contains(repository)) {
+
+ if (!mirror.isDirectory()) {
+ myMirrorManager.removeMirrorDir(mirror);
+ LOG.debug("Found non existing mirror directory: " + mirror.getAbsolutePath() + ", removed it from the list of mirrors");
+ continue;
+ }
+
if (isCleanupEnabled(mirror)) {
- ourLog.debug("Register cleaner for mirror " + mirror.getAbsolutePath());
+ LOG.debug("Register cleaner for mirror " + mirror.getAbsolutePath());
registry.addCleaner(mirror, new Date(myMirrorManager.getLastUsedTime(mirror)));
} else {
- ourLog.debug("Clean-up is disabled in " + repository + " (" + mirror.getName() + ")");
+ LOG.debug("Clean-up is disabled in " + repository + " (" + mirror.getName() + ")");
}
}
}
try {
GitVcsRoot gitRoot = new GitVcsRoot(myMirrorManager, root);
String repositoryUrl = gitRoot.getRepositoryFetchURL().toString();
- ourLog.debug("Repository " + repositoryUrl + " is used in the build, its mirror won't be cleaned");
+ LOG.debug("Repository " + repositoryUrl + " is used in the build, its mirror won't be cleaned");
repositories.add(gitRoot.getRepositoryFetchURL().toString());
} catch (VcsException e) {
- ourLog.warn("Error while creating git root " + root.getName() + ". If the root has a mirror on agent, the mirror might be cleaned", e);
+ LOG.warn("Error while creating git root " + root.getName() + ". If the root has a mirror on agent, the mirror might be cleaned", e);
}
}
return repositories;
*/
void invalidate(@NotNull File dir);
+ /**
+ * Removes mirror directory
+ * @param dir directory to remove
+ */
+ void removeMirrorDir(@NotNull final File dir);
+
@NotNull
Map<String, File> getMappings();
}
}
+ public void removeMirrorDir(@NotNull final File dir) {
+ synchronized (myLock) {
+ List<String> urlsMappedToDir = getUrlsMappedToDir(dir);
+ for (String url : urlsMappedToDir) {
+ myMirrorMap.remove(url);
+ }
+ saveMappingToFile();
+ FileUtil.delete(dir);
+ }
+ }
@NotNull
public Map<String, File> getMappings() {
private void readMappings() {
synchronized (myLock) {
+ boolean mappingsFileHasObsoleteDirs = false;
+
for (String line : readLines(myMapFile)) {
int separatorIndex = line.lastIndexOf(" = ");
if (separatorIndex == -1) {
} else {
String url = line.substring(0, separatorIndex);
String dirName = line.substring(separatorIndex + 3);
+
+ if (!new File(myBaseMirrorsDir, dirName).isDirectory()) {
+ LOG.info("Skip mapping " + line + ": " + dirName + " because the specified directory does not exist");
+ mappingsFileHasObsoleteDirs = true;
+ continue;
+ }
+
if (myMirrorMap.values().contains(dirName)) {
LOG.error("Skip mapping " + line + ": " + dirName + " is used for url other than " + url);
} else {
}
}
}
+
+ if (mappingsFileHasObsoleteDirs) {
+ saveMappingToFile();
+ }
}
}
@NotNull
private File[] findRepositoryDirs() {
- return myBaseMirrorsDir.listFiles(new FileFilter() {
+ final File[] dirs = myBaseMirrorsDir.listFiles(new FileFilter() {
public boolean accept(File f) {
return f.isDirectory() && new File(f, "config").exists();
}
});
+ return dirs != null ? dirs : new File[0];
}
myMirrorManager.invalidate(dir);
}
+ @Override
+ public void removeMirrorDir(@NotNull final File dir) {
+ myMirrorManager.removeMirrorDir(dir);
+ }
+
@NotNull
public Map<String, File> getMappings() {
package jetbrains.buildServer.buildTriggers.vcs.git.tests;
+import jetbrains.buildServer.TempFiles;
import jetbrains.buildServer.agent.AgentRunningBuild;
import jetbrains.buildServer.agent.DirectoryCleanersProviderContext;
import jetbrains.buildServer.agent.DirectoryCleanersRegistry;
import org.testng.annotations.Test;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
}
- public void should_register_mirrors_not_used_in_current_build() {
- final DirectoryCleanersRegistry registry = myContext.mock(DirectoryCleanersRegistry.class);
- final File r3mirror = new File("r3");
- final File r4mirror = new File("r4");
- final Date r3lastAccess = Dates.makeDate(2012, 10, 29);
- final Date r4lastAccess = Dates.makeDate(2012, 10, 27);
- List<String> repositoriesInBuild = asList("git://some.org/r1", "git://some.org/r2");
- myContext.checking(new Expectations() {{
- one(myMirrorManager).getMappings(); will(returnValue(map("git://some.org/r1", new File("r1"),
- "git://some.org/r2", new File("r2"),
- "git://some.org/r3", r3mirror,
- "git://some.org/r4", r4mirror)));
- one(myMirrorManager).getLastUsedTime(r3mirror); will(returnValue(r3lastAccess.getTime()));
- one(myMirrorManager).getLastUsedTime(r4mirror); will(returnValue(r4lastAccess.getTime()));
+ public void should_register_mirrors_not_used_in_current_build() throws IOException {
+ TempFiles tmpFiles = new TempFiles();
+ try {
+ final DirectoryCleanersRegistry registry = myContext.mock(DirectoryCleanersRegistry.class);
+ final File r3mirror = tmpFiles.createTempDir();
+ final File r4mirror = tmpFiles.createTempDir();
+ final Date r3lastAccess = Dates.makeDate(2012, 10, 29);
+ final Date r4lastAccess = Dates.makeDate(2012, 10, 27);
+ List<String> repositoriesInBuild = asList("git://some.org/r1", "git://some.org/r2");
+ myContext.checking(new Expectations() {{
+ one(myMirrorManager).getMappings(); will(returnValue(map("git://some.org/r1", tmpFiles.createTempDir(),
+ "git://some.org/r2", tmpFiles.createTempDir(),
+ "git://some.org/r3", r3mirror,
+ "git://some.org/r4", r4mirror)));
+ one(myMirrorManager).getLastUsedTime(r3mirror); will(returnValue(r3lastAccess.getTime()));
+ one(myMirrorManager).getLastUsedTime(r4mirror); will(returnValue(r4lastAccess.getTime()));
- one(registry).addCleaner(r3mirror, r3lastAccess);
- one(registry).addCleaner(r4mirror, r4lastAccess);
- }});
- myAgentMirrorCleaner.registerDirectoryCleaners(createCleanerContext(repositoriesInBuild), registry);
+ one(registry).addCleaner(r3mirror, r3lastAccess);
+ one(registry).addCleaner(r4mirror, r4lastAccess);
+ }});
+ myAgentMirrorCleaner.registerDirectoryCleaners(createCleanerContext(repositoriesInBuild), registry);
+ } finally {
+ tmpFiles.cleanup();
+ }
}
import jetbrains.buildServer.TempFiles;
import jetbrains.buildServer.buildTriggers.vcs.git.*;
import jetbrains.buildServer.serverSide.ServerPaths;
+import jetbrains.buildServer.util.FileUtil;
import org.eclipse.jgit.transport.URIish;
import org.jetbrains.annotations.NotNull;
import org.testng.annotations.AfterMethod;
}
}
+ public void should_ignore_non_existing_directories() throws Exception {
+ File baseMirrorsDir = myConfig.getCachesDir();
+ File map = new File(baseMirrorsDir, "map");
+
+ FileUtil.writeFileAndReportErrors(map, "git://some.org/repository1.git = git-11111111.git\n" +
+ "git://some.org/repository2.git = git-22222222.git");
+
+ getRepository(new File(baseMirrorsDir, "git-22222222.git"), new URIish("git://some.org/repository2.git"));
+
+ MirrorManager mirrorManager = new MirrorManagerImpl(myConfig, new HashCalculatorImpl());
+ assertEquals(1, mirrorManager.getMappings().size());
+ assertTrue(mirrorManager.getMappings().containsKey("git://some.org/repository2.git"));
+
+ String mapping = FileUtil.readText(map);
+ assertFalse(mapping.contains("git-11111111.git"));
+ }
+
public void should_give_different_dirs_for_same_url_if_dir_was_invalidated() {
MirrorManager mirrorManager = new MirrorManagerImpl(myConfig, new HashCalculatorImpl());