Skip to content

Commit

Permalink
[JENKINS-26519] Attempting to improve diagnostics in case rename fails.
Browse files Browse the repository at this point in the history
  • Loading branch information
jglick committed Jan 27, 2015
1 parent 71a0904 commit 0633bee
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 9 deletions.
51 changes: 42 additions & 9 deletions core/src/main/java/jenkins/model/RunIdMigrator.java
Expand Up @@ -34,6 +34,9 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.DateFormat;
Expand Down Expand Up @@ -206,11 +209,8 @@ private void doMigrate(File dir) {
}
try {
Integer.parseInt(name);
if (kid.delete()) {
LOGGER.log(FINE, "deleted build number symlink {0} → {1}", new Object[] {name, link});
} else {
LOGGER.log(WARNING, "could not delete build number symlink {0} → {1}", new Object[] {name, link});
}
LOGGER.log(FINE, "deleting build number symlink {0} → {1}", new Object[] {name, link});
Util.deleteFile(kid);
} catch (NumberFormatException x) {
LOGGER.log(FINE, "skipping other symlink {0} → {1}", new Object[] {name, link});
}
Expand Down Expand Up @@ -259,10 +259,7 @@ private void doMigrate(File dir) {
String nl = m.group(2);
xml = m.replaceFirst(" <id>" + name + "</id>" + nl + " <timestamp>" + timestamp + "</timestamp>" + nl);
File newKid = new File(dir, Integer.toString(number));
if (!kid.renameTo(newKid)) {
LOGGER.log(WARNING, "failed to rename {0} to {1}", new Object[] {name, number});
continue;
}
move(kid, newKid);
FileUtils.writeStringToFile(new File(newKid, "build.xml"), xml, Charsets.UTF_8);
LOGGER.log(FINE, "fully processed {0} → {1}", new Object[] {name, number});
idToNumber.put(name, number);
Expand All @@ -272,6 +269,42 @@ private void doMigrate(File dir) {
}
}

/**
* Tries to move/rename a file from one path to another.
* Uses {@link java.nio.file.Files#move} when available.
* Does not use {@link java.nio.file.StandardCopyOption#REPLACE_EXISTING} or any other options.
* TODO candidate for moving to {@link Util}
*/
static void move(File src, File dest) throws IOException {
Class<?> pathC;
try {
pathC = Class.forName("java.nio.file.Path");
} catch (ClassNotFoundException x) {
// Java 6, do our best
if (dest.exists()) {
throw new IOException(dest + " already exists");
}
if (src.renameTo(dest)) {
return;
}
throw new IOException("could not move " + src + " to " + dest);
}
try {
Method toPath = File.class.getMethod("toPath");
Class<?> copyOptionAC = Class.forName("[Ljava.nio.file.CopyOption;");
Class.forName("java.nio.file.Files").getMethod("move", pathC, pathC, copyOptionAC).invoke(null, toPath.invoke(src), toPath.invoke(dest), Array.newInstance(copyOptionAC.getComponentType(), 0));
} catch (InvocationTargetException x) {
Throwable cause = x.getCause();
if (cause instanceof IOException) {
throw (IOException) cause;
} else {
throw new IOException(cause);
}
} catch (Exception x) {
throw new IOException(x);
}
}

/**
* Look up a historical run by ID.
* @param id a nonnumeric ID which may be a valid {@link Run#getId}
Expand Down
14 changes: 14 additions & 0 deletions core/src/test/java/jenkins/model/RunIdMigratorTest.java
Expand Up @@ -27,6 +27,7 @@
import hudson.Util;
import hudson.util.StreamTaskListener;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.TimeZone;
Expand Down Expand Up @@ -173,4 +174,17 @@ private static String summarize(File dir) throws Exception {
return m.toString();
}

@Test public void move() throws Exception {
File src = tmp.newFile();
File dest = new File(tmp.getRoot(), "dest");
RunIdMigrator.move(src, dest);
File dest2 = tmp.newFile();
try {
RunIdMigrator.move(dest, dest2);
fail();
} catch (IOException x) {
System.err.println("Got expected move exception: " + x);
}
}

}

0 comments on commit 0633bee

Please sign in to comment.