~ubuntu-branches/ubuntu/saucy/jenkins/saucy-proposed

« back to all changes in this revision

Viewing changes to core/src/main/java/hudson/FilePath.java

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-13 12:35:19 UTC
  • mfrom: (1.1.13)
  • Revision ID: package-import@ubuntu.com-20130813123519-tizgfxcr70trl7r0
Tags: 1.509.2+dfsg-1
* New upstream release (Closes: #706725):
  - d/control: Update versioned BD's:
    * jenkins-executable-war >= 1.28.
    * jenkins-instance-identity >= 1.3.
    * libjenkins-remoting-java >= 2.23.
    * libjenkins-winstone-java >= 0.9.10-jenkins-44.
    * libstapler-java >= 1.207.
    * libjenkins-json-java >= 2.4-jenkins-1.
    * libstapler-adjunct-timeline-java >= 1.4.
    * libstapler-adjunct-codemirror-java >= 1.2.
    * libmaven-hpi-plugin-java >= 1.93.
    * libjenkins-xstream-java >= 1.4.4-jenkins-3.
  - d/maven.rules: Map to older version of animal-sniffer-maven-plugin.
  - Add patch for compatibility with guava >= 0.14.
  - Add patch to exclude asm4 dependency via jnr-posix.
  - Fixes the following security vulnerabilities:
    CVE-2013-2034, CVE-2013-2033, CVE-2013-2034, CVE-2013-1808
* d/patches/*: Switch to using git patch-queue for managing patches.
* De-duplicate jars between libjenkins-java and jenkins-external-job-monitor
  (Closes: #701163):
  - d/control: Add dependency between jenkins-external-job-monitor ->
    libjenkins-java.
  - d/rules: 
    Drop installation of jenkins-core in jenkins-external-job-monitor.
  - d/jenkins-external-job-monitor.{links,install}: Link to jenkins-core
    in /usr/share/java instead of included version.
* Wait longer for jenkins to stop during restarts (Closes: #704848):
  - d/jenkins.init: Re-sync init script from upstream codebase.

Show diffs side-by-side

added added

removed removed

Lines of Context:
96
96
import java.util.zip.GZIPInputStream;
97
97
 
98
98
import com.sun.jna.Native;
 
99
import hudson.os.PosixException;
99
100
import java.util.Enumeration;
100
101
import java.util.logging.Logger;
101
102
import org.apache.tools.ant.taskdefs.Chmod;
492
493
        });
493
494
    }
494
495
 
495
 
    private void unzip(File dir, InputStream in) throws IOException {
 
496
    private static void unzip(File dir, InputStream in) throws IOException {
496
497
        File tmpFile = File.createTempFile("tmpzip", null); // uses java.io.tmpdir
497
498
        try {
 
499
            // XXX why does this not simply use ZipInputStream?
498
500
            IOUtils.copy(in, tmpFile);
499
501
            unzip(dir,tmpFile);
500
502
        }
503
505
        }
504
506
    }
505
507
 
506
 
    private void unzip(File dir, File zipFile) throws IOException {
 
508
    static private void unzip(File dir, File zipFile) throws IOException {
507
509
        dir = dir.getAbsoluteFile();    // without absolutization, getParentFile below seems to fail
508
510
        ZipFile zip = new ZipFile(zipFile);
509
511
        @SuppressWarnings("unchecked")
542
544
     */
543
545
    public FilePath absolutize() throws IOException, InterruptedException {
544
546
        return new FilePath(channel,act(new FileCallable<String>() {
 
547
            private static final long serialVersionUID = 1L;
545
548
            public String invoke(File f, VirtualChannel channel) throws IOException {
546
549
                return f.getAbsolutePath();
547
550
            }
559
562
     */
560
563
    public void symlinkTo(final String target, final TaskListener listener) throws IOException, InterruptedException {
561
564
        act(new FileCallable<Void>() {
 
565
            private static final long serialVersionUID = 1L;
562
566
            public Void invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
563
567
                Util.createSymlink(f.getParentFile(),target,f.getName(),listener);
564
568
                return null;
575
579
     */
576
580
    public String readLink() throws IOException, InterruptedException {
577
581
        return act(new FileCallable<String>() {
 
582
            private static final long serialVersionUID = 1L;
578
583
            public String invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
579
584
                return Util.resolveSymlink(f);
580
585
            }
720
725
            if(listener!=null)
721
726
                listener.getLogger().println(message);
722
727
 
 
728
            if (isRemote()) {
 
729
                // First try to download from the slave machine.
 
730
                try {
 
731
                    act(new Unpack(archive));
 
732
                    timestamp.touch(sourceTimestamp);
 
733
                    return true;
 
734
                } catch (IOException x) {
 
735
                    if (listener != null) {
 
736
                        x.printStackTrace(listener.error("Failed to download " + archive + " from slave; will retry from master"));
 
737
                    }
 
738
                }
 
739
            }
 
740
 
723
741
            // for HTTP downloads, enable automatic retry for added resilience
724
742
            InputStream in = archive.getProtocol().startsWith("http") ? ProxyConfiguration.getInputStream(archive) : con.getInputStream();
725
743
            CountingInputStream cis = new CountingInputStream(in);
739
757
        }
740
758
    }
741
759
 
 
760
    private static final class Unpack implements FileCallable<Void> {
 
761
        private final URL archive;
 
762
        Unpack(URL archive) {
 
763
            this.archive = archive;
 
764
        }
 
765
        @Override public Void invoke(File dir, VirtualChannel channel) throws IOException, InterruptedException {
 
766
            InputStream in = archive.openStream();
 
767
            try {
 
768
                CountingInputStream cis = new CountingInputStream(in);
 
769
                try {
 
770
                    if (archive.toExternalForm().endsWith(".zip")) {
 
771
                        unzip(dir, cis);
 
772
                    } else {
 
773
                        readFromTar("input stream", dir, GZIP.extract(cis));
 
774
                    }
 
775
                } catch (IOException x) {
 
776
                    throw new IOException2(String.format("Failed to unpack %s (%d bytes read)", archive, cis.getByteCount()), x);
 
777
                }
 
778
            } finally {
 
779
                in.close();
 
780
            }
 
781
            return null;
 
782
        }
 
783
    }
 
784
 
742
785
    /**
743
786
     * Reads the URL on the current VM, and writes all the data to this {@link FilePath}
744
787
     * (this is different from resolving URL remotely.)
838
881
        if(channel!=null) {
839
882
            // run this on a remote system
840
883
            try {
841
 
                return channel.call(new FileCallableWrapper<T>(callable,cl));
 
884
                DelegatingCallable<T,IOException> wrapper = new FileCallableWrapper<T>(callable, cl);
 
885
                Jenkins instance = Jenkins.getInstance();
 
886
                if (instance != null) { // this happens during unit tests
 
887
                    ExtensionList<FileCallableWrapperFactory> factories = instance.getExtensionList(FileCallableWrapperFactory.class);
 
888
                    for (FileCallableWrapperFactory factory : factories) {
 
889
                        wrapper = factory.wrap(wrapper);
 
890
                    }
 
891
                }
 
892
 
 
893
                return channel.call(wrapper);
842
894
            } catch (TunneledInterruptedException e) {
843
895
                throw (InterruptedException)new InterruptedException(e.getMessage()).initCause(e);
844
896
            } catch (AbortException e) {
854
906
    }
855
907
 
856
908
    /**
 
909
     * This extension point allows to contribute a wrapper around a fileCallable so that a plugin can "intercept" a
 
910
     * call.
 
911
     * <p>The {@link #wrap(hudson.remoting.DelegatingCallable)} method itself will be executed on master
 
912
     * (and may collect contextual data if needed) and the returned wrapper will be executed on remote.
 
913
     *
 
914
     * @since 1.482
 
915
     * @see AbstractInterceptorCallableWrapper
 
916
     */
 
917
    public static abstract class FileCallableWrapperFactory implements ExtensionPoint {
 
918
 
 
919
        public abstract <T> DelegatingCallable<T,IOException> wrap(DelegatingCallable<T,IOException> callable);
 
920
 
 
921
    }
 
922
 
 
923
    /**
 
924
     * Abstract {@link DelegatingCallable} that exposes an Before/After pattern for
 
925
     * {@link hudson.FilePath.FileCallableWrapperFactory} that want to implement AOP-style interceptors
 
926
     * @since 1.482
 
927
     */
 
928
    public static abstract class AbstractInterceptorCallableWrapper<T> implements DelegatingCallable<T, IOException> {
 
929
        private static final long serialVersionUID = 1L;
 
930
 
 
931
        private final DelegatingCallable<T, IOException> callable;
 
932
 
 
933
        public AbstractInterceptorCallableWrapper(DelegatingCallable<T, IOException> callable) {
 
934
            this.callable = callable;
 
935
        }
 
936
 
 
937
        @Override
 
938
        public final ClassLoader getClassLoader() {
 
939
            return callable.getClassLoader();
 
940
        }
 
941
 
 
942
        public final T call() throws IOException {
 
943
            before();
 
944
            try {
 
945
                return callable.call();
 
946
            } finally {
 
947
                after();
 
948
            }
 
949
        }
 
950
 
 
951
        /**
 
952
         * Executed before the actual FileCallable is invoked. This code will run on remote
 
953
         */
 
954
        protected void before() {}
 
955
 
 
956
        /**
 
957
         * Executed after the actual FileCallable is invoked (even if this one failed). This code will run on remote
 
958
         */
 
959
        protected void after() {}
 
960
    }
 
961
 
 
962
 
 
963
    /**
857
964
     * Executes some program on the machine that this {@link FilePath} exists,
858
965
     * so that one can perform local file operations.
859
966
     */
860
967
    public <T> Future<T> actAsync(final FileCallable<T> callable) throws IOException, InterruptedException {
861
968
        try {
 
969
            DelegatingCallable<T,IOException> wrapper = new FileCallableWrapper<T>(callable);
 
970
            Jenkins instance = Jenkins.getInstance();
 
971
            if (instance != null) { // this happens during unit tests
 
972
                ExtensionList<FileCallableWrapperFactory> factories = instance.getExtensionList(FileCallableWrapperFactory.class);
 
973
                for (FileCallableWrapperFactory factory : factories) {
 
974
                    wrapper = factory.wrap(wrapper);
 
975
                }
 
976
            }
 
977
 
862
978
            return (channel!=null ? channel : Jenkins.MasterComputer.localChannel)
863
 
                .callAsync(new FileCallableWrapper<T>(callable));
 
979
                .callAsync(wrapper);
864
980
        } catch (IOException e) {
865
981
            // wrap it into a new IOException so that we get the caller's stack trace as well.
866
982
            throw new IOException2("remote file operation failed",e);
887
1003
     */
888
1004
    public URI toURI() throws IOException, InterruptedException {
889
1005
        return act(new FileCallable<URI>() {
 
1006
            private static final long serialVersionUID = 1L;
890
1007
            public URI invoke(File f, VirtualChannel channel) {
891
1008
                return f.toURI();
892
1009
            }
898
1015
     */
899
1016
    public void mkdirs() throws IOException, InterruptedException {
900
1017
        if(!act(new FileCallable<Boolean>() {
 
1018
            private static final long serialVersionUID = 1L;
901
1019
            public Boolean invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
902
1020
                if(f.mkdirs() || f.exists())
903
1021
                    return true;    // OK
916
1034
     */
917
1035
    public void deleteRecursive() throws IOException, InterruptedException {
918
1036
        act(new FileCallable<Void>() {
 
1037
            private static final long serialVersionUID = 1L;
919
1038
            public Void invoke(File f, VirtualChannel channel) throws IOException {
920
1039
                Util.deleteRecursive(f);
921
1040
                return null;
928
1047
     */
929
1048
    public void deleteContents() throws IOException, InterruptedException {
930
1049
        act(new FileCallable<Void>() {
 
1050
            private static final long serialVersionUID = 1L;
931
1051
            public Void invoke(File f, VirtualChannel channel) throws IOException {
932
1052
                Util.deleteContentsRecursive(f);
933
1053
                return null;
1021
1141
    public FilePath createTempFile(final String prefix, final String suffix) throws IOException, InterruptedException {
1022
1142
        try {
1023
1143
            return new FilePath(this,act(new FileCallable<String>() {
 
1144
                private static final long serialVersionUID = 1L;
1024
1145
                public String invoke(File dir, VirtualChannel channel) throws IOException {
1025
1146
                    File f = File.createTempFile(prefix, suffix, dir);
1026
1147
                    return f.getName();
1076
1197
    public FilePath createTextTempFile(final String prefix, final String suffix, final String contents, final boolean inThisDirectory) throws IOException, InterruptedException {
1077
1198
        try {
1078
1199
            return new FilePath(channel,act(new FileCallable<String>() {
 
1200
                private static final long serialVersionUID = 1L;
1079
1201
                public String invoke(File dir, VirtualChannel channel) throws IOException {
1080
1202
                    if(!inThisDirectory)
1081
1203
                        dir = new File(System.getProperty("java.io.tmpdir"));
1118
1240
    public FilePath createTempDir(final String prefix, final String suffix) throws IOException, InterruptedException {
1119
1241
        try {
1120
1242
            return new FilePath(this,act(new FileCallable<String>() {
 
1243
                private static final long serialVersionUID = 1L;
1121
1244
                public String invoke(File dir, VirtualChannel channel) throws IOException {
1122
1245
                    File f = File.createTempFile(prefix, suffix, dir);
1123
1246
                    f.delete();
1137
1260
     */
1138
1261
    public boolean delete() throws IOException, InterruptedException {
1139
1262
        act(new FileCallable<Void>() {
 
1263
            private static final long serialVersionUID = 1L;
1140
1264
            public Void invoke(File f, VirtualChannel channel) throws IOException {
1141
1265
                Util.deleteFile(f);
1142
1266
                return null;
1150
1274
     */
1151
1275
    public boolean exists() throws IOException, InterruptedException {
1152
1276
        return act(new FileCallable<Boolean>() {
 
1277
            private static final long serialVersionUID = 1L;
1153
1278
            public Boolean invoke(File f, VirtualChannel channel) throws IOException {
1154
1279
                return f.exists();
1155
1280
            }
1165
1290
     */
1166
1291
    public long lastModified() throws IOException, InterruptedException {
1167
1292
        return act(new FileCallable<Long>() {
 
1293
            private static final long serialVersionUID = 1L;
1168
1294
            public Long invoke(File f, VirtualChannel channel) throws IOException {
1169
1295
                return f.lastModified();
1170
1296
            }
1216
1342
     */
1217
1343
    public boolean isDirectory() throws IOException, InterruptedException {
1218
1344
        return act(new FileCallable<Boolean>() {
 
1345
            private static final long serialVersionUID = 1L;
1219
1346
            public Boolean invoke(File f, VirtualChannel channel) throws IOException {
1220
1347
                return f.isDirectory();
1221
1348
            }
1229
1356
     */
1230
1357
    public long length() throws IOException, InterruptedException {
1231
1358
        return act(new FileCallable<Long>() {
 
1359
            private static final long serialVersionUID = 1L;
1232
1360
            public Long invoke(File f, VirtualChannel channel) throws IOException {
1233
1361
                return f.length();
1234
1362
            }
1253
1381
    public void chmod(final int mask) throws IOException, InterruptedException {
1254
1382
        if(!isUnix() || mask==-1)   return;
1255
1383
        act(new FileCallable<Void>() {
 
1384
            private static final long serialVersionUID = 1L;
1256
1385
            public Void invoke(File f, VirtualChannel channel) throws IOException {
1257
1386
                _chmod(f, mask);
1258
1387
 
1300
1429
     * @since 1.311
1301
1430
     * @see #chmod(int)
1302
1431
     */
1303
 
    public int mode() throws IOException, InterruptedException {
 
1432
    public int mode() throws IOException, InterruptedException, PosixException {
1304
1433
        if(!isUnix())   return -1;
1305
1434
        return act(new FileCallable<Integer>() {
 
1435
            private static final long serialVersionUID = 1L;
1306
1436
            public Integer invoke(File f, VirtualChannel channel) throws IOException {
1307
1437
                return IOUtils.mode(f);
1308
1438
            }
1349
1479
            throw new IllegalArgumentException("Non-serializable filter of " + filter.getClass());
1350
1480
        }
1351
1481
        return act(new FileCallable<List<FilePath>>() {
 
1482
            private static final long serialVersionUID = 1L;
1352
1483
            public List<FilePath> invoke(File f, VirtualChannel channel) throws IOException {
1353
1484
                File[] children = f.listFiles(filter);
1354
1485
                if(children ==null)     return null;
1401
1532
     */
1402
1533
    public FilePath[] list(final String includes, final String excludes, final boolean defaultExcludes) throws IOException, InterruptedException {
1403
1534
        return act(new FileCallable<FilePath[]>() {
 
1535
            private static final long serialVersionUID = 1L;
1404
1536
            public FilePath[] invoke(File f, VirtualChannel channel) throws IOException {
1405
1537
                String[] files = glob(f, includes, excludes, defaultExcludes);
1406
1538
 
1438
1570
 
1439
1571
        final Pipe p = Pipe.createRemoteToLocal();
1440
1572
        channel.callAsync(new Callable<Void,IOException>() {
 
1573
            private static final long serialVersionUID = 1L;
1441
1574
            public Void call() throws IOException {
1442
1575
                FileInputStream fis=null;
1443
1576
                try {
1489
1622
        }
1490
1623
 
1491
1624
        return channel.call(new Callable<OutputStream,IOException>() {
 
1625
            private static final long serialVersionUID = 1L;
1492
1626
            public OutputStream call() throws IOException {
1493
1627
                File f = new File(remote).getAbsoluteFile();
1494
1628
                f.getParentFile().mkdirs();
1507
1641
     */
1508
1642
    public void write(final String content, final String encoding) throws IOException, InterruptedException {
1509
1643
        act(new FileCallable<Void>() {
 
1644
            private static final long serialVersionUID = 1L;
1510
1645
            public Void invoke(File f, VirtualChannel channel) throws IOException {
1511
1646
                f.getParentFile().mkdirs();
1512
1647
                FileOutputStream fos = new FileOutputStream(f);
1526
1661
     */
1527
1662
    public String digest() throws IOException, InterruptedException {
1528
1663
        return act(new FileCallable<String>() {
 
1664
            private static final long serialVersionUID = 1L;
1529
1665
            public String invoke(File f, VirtualChannel channel) throws IOException {
1530
1666
                return Util.getDigestOf(new FileInputStream(f));
1531
1667
            }
1541
1677
                throw new IOException("renameTo target must be on the same host");
1542
1678
        }
1543
1679
        act(new FileCallable<Void>() {
 
1680
            private static final long serialVersionUID = 1L;
1544
1681
            public Void invoke(File f, VirtualChannel channel) throws IOException {
1545
1682
                f.renameTo(new File(target.remote));
1546
1683
                return null;
1558
1695
            throw new IOException("pullUpTo target must be on the same host");
1559
1696
        }
1560
1697
        act(new FileCallable<Void>() {
 
1698
            private static final long serialVersionUID = 1L;
1561
1699
            public Void invoke(File f, VirtualChannel channel) throws IOException {
1562
1700
                File t = new File(target.getRemote());
1563
1701
                
1710
1848
        if(this.channel==target.channel) {
1711
1849
            // local to local copy.
1712
1850
            return act(new FileCallable<Integer>() {
 
1851
                private static final long serialVersionUID = 1L;
1713
1852
                public Integer invoke(File base, VirtualChannel channel) throws IOException {
1714
1853
                    if(!base.exists())  return 0;
1715
1854
                    assert target.channel==null;
1752
1891
            final Pipe pipe = Pipe.createLocalToRemote();
1753
1892
 
1754
1893
            Future<Void> future = target.actAsync(new FileCallable<Void>() {
 
1894
                private static final long serialVersionUID = 1L;
1755
1895
                public Void invoke(File f, VirtualChannel channel) throws IOException {
1756
1896
                    try {
1757
1897
                        readFromTar(remote+'/'+fileMask, f,TarCompression.GZIP.extract(pipe.getIn()));
1773
1913
            final Pipe pipe = Pipe.createRemoteToLocal();
1774
1914
 
1775
1915
            Future<Integer> future = actAsync(new FileCallable<Integer>() {
 
1916
                private static final long serialVersionUID = 1L;
1776
1917
                public Integer invoke(File f, VirtualChannel channel) throws IOException {
1777
1918
                    try {
1778
1919
                        return writeToTar(f,fileMask,excludes,TarCompression.GZIP.compress(pipe.getOut()));