[FIXED JENKINS-17330] FilePath.installIfNecessaryFrom should avoid routing download over remoting channel.

This commit is contained in:
Jesse Glick committed 2013-03-27 19:11:06 -04:00
1 parent 1c64ad15b1
commit b67272e726
2 files changed
+44 -2

No files matched your search

+41 -2
View File
@@ -493,9 +493,10 @@ public final class FilePath implements Serializable {
});
}
private void unzip(File dir, InputStream in) throws IOException {
private static void unzip(File dir, InputStream in) throws IOException {
File tmpFile = File.createTempFile("tmpzip", null); // uses java.io.tmpdir
try {
// XXX why does this not simply use ZipInputStream?
IOUtils.copy(in, tmpFile);
unzip(dir,tmpFile);
}
@@ -504,7 +505,7 @@ public final class FilePath implements Serializable {
}
}
private void unzip(File dir, File zipFile) throws IOException {
static private void unzip(File dir, File zipFile) throws IOException {
dir = dir.getAbsoluteFile(); // without absolutization, getParentFile below seems to fail
ZipFile zip = new ZipFile(zipFile);
@SuppressWarnings("unchecked")
@@ -724,6 +725,19 @@ public final class FilePath implements Serializable {
if(listener!=null)
listener.getLogger().println(message);
if (isRemote()) {
// First try to download from the slave machine.
try {
act(new Unpack(archive));
timestamp.touch(sourceTimestamp);
return true;
} catch (IOException x) {
if (listener != null) {
x.printStackTrace(listener.error("Failed to download " + archive + " from slave; will retry from master"));
}
}
}
// for HTTP downloads, enable automatic retry for added resilience
InputStream in = archive.getProtocol().startsWith("http") ? ProxyConfiguration.getInputStream(archive) : con.getInputStream();
CountingInputStream cis = new CountingInputStream(in);
@@ -743,6 +757,31 @@ public final class FilePath implements Serializable {
}
}
private static final class Unpack implements FileCallable<Void> {
private final URL archive;
Unpack(URL archive) {
this.archive = archive;
}
@Override public Void invoke(File dir, VirtualChannel channel) throws IOException, InterruptedException {
InputStream in = archive.openStream();
try {
CountingInputStream cis = new CountingInputStream(in);
try {
if (archive.toExternalForm().endsWith(".zip")) {
unzip(dir, cis);
} else {
readFromTar("input stream", dir, GZIP.extract(cis));
}
} catch (IOException x) {
throw new IOException2(String.format("Failed to unpack %s (%d bytes read)", archive, cis.getByteCount()), x);
}
} finally {
in.close();
}
return null;
}
}
/**
* Reads the URL on the current VM, and writes all the data to this {@link FilePath}
* (this is different from resolving URL remotely.)