~ubuntu-branches/ubuntu/trusty/jenkins/trusty

« back to all changes in this revision

Viewing changes to core/src/main/java/hudson/model/Job.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:
26
26
import com.google.common.base.Function;
27
27
import com.google.common.collect.Collections2;
28
28
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
 
29
import hudson.BulkChange;
29
30
import hudson.EnvVars;
30
31
import hudson.Extension;
31
32
import hudson.ExtensionPoint;
52
53
import hudson.util.DescribableList;
53
54
import hudson.util.FormApply;
54
55
import hudson.util.Graph;
 
56
import hudson.util.ProcessTree;
55
57
import hudson.util.RunList;
56
58
import hudson.util.ShiftedCategoryAxis;
57
59
import hudson.util.StackedAreaRenderer2;
59
61
import hudson.widgets.HistoryWidget;
60
62
import hudson.widgets.HistoryWidget.Adapter;
61
63
import hudson.widgets.Widget;
 
64
import jenkins.model.BuildDiscarder;
62
65
import jenkins.model.Jenkins;
63
66
import jenkins.model.ProjectNamingStrategy;
 
67
import jenkins.scm.SCMCheckoutStrategy;
64
68
import jenkins.security.HexStringConfidentialKey;
65
69
import jenkins.util.io.OnMaster;
66
70
import net.sf.json.JSONException;
123
127
     */
124
128
    private transient volatile boolean holdOffBuildUntilSave;
125
129
 
126
 
    private volatile LogRotator logRotator;
 
130
    private volatile BuildDiscarder logRotator;
127
131
 
128
132
    /**
129
133
     * Not all plugins are good at calculating their health report quickly.
188
192
        } else {
189
193
            // From the old Hudson, or doCreateItem. Create this file now.
190
194
            saveNextBuildNumber();
191
 
            save(); // and delete it from the config.xml
192
195
        }
193
196
 
194
197
        if (properties == null) // didn't exist < 1.72
303
306
    }
304
307
 
305
308
    /**
 
309
     * Builds up the environment variable map that's sufficient to identify a process
 
310
     * as ours. This is used to kill run-away processes via {@link ProcessTree#killAll(Map)}.
 
311
     */
 
312
    public EnvVars getCharacteristicEnvVars() {
 
313
        EnvVars env = new EnvVars();
 
314
        env.put("JENKINS_SERVER_COOKIE",SERVER_COOKIE.get());
 
315
        env.put("HUDSON_SERVER_COOKIE",SERVER_COOKIE.get()); // Legacy compatibility
 
316
        env.put("JOB_NAME",getFullName());
 
317
        return env;
 
318
    }
 
319
 
 
320
    /**
 
321
     * Creates an environment variable override for launching processes for this project.
 
322
     *
 
323
     * <p>
 
324
     * This is for process launching outside the build execution (such as polling, tagging, deployment, etc.)
 
325
     * that happens in a context of a specific job.
 
326
     *
 
327
     * @param node
 
328
     *      Node to eventually run a process on. The implementation must cope with this parameter being null
 
329
     *      (in which case none of the node specific properties would be reflected in the resulting override.)
 
330
     */
 
331
    public EnvVars getEnvironment(Node node, TaskListener listener) throws IOException, InterruptedException {
 
332
        EnvVars env;
 
333
 
 
334
        if (node!=null)
 
335
            env = node.toComputer().buildEnvironment(listener);
 
336
        else
 
337
            env = new EnvVars();
 
338
 
 
339
        env.putAll(getCharacteristicEnvVars());
 
340
 
 
341
        // servlet container may have set CLASSPATH in its launch script,
 
342
        // so don't let that inherit to the new child process.
 
343
        // see http://www.nabble.com/Run-Job-with-JDK-1.4.2-tf4468601.html
 
344
        env.put("CLASSPATH","");
 
345
 
 
346
        return env;
 
347
    }
 
348
 
 
349
    /**
306
350
     * Programatically updates the next build number.
307
351
     * 
308
352
     * <p>
321
365
    }
322
366
 
323
367
    /**
324
 
     * Returns the log rotator for this job, or null if none.
 
368
     * Returns the configured build discarder for this job, or null if none.
 
369
     */
 
370
    public BuildDiscarder getBuildDiscarder() {
 
371
        return logRotator;
 
372
    }
 
373
 
 
374
    public void setBuildDiscarder(BuildDiscarder bd) throws IOException {
 
375
        this.logRotator = bd;
 
376
        save();
 
377
    }
 
378
 
 
379
    /**
 
380
     * Left for backward compatibility. Returns non-null if and only
 
381
     * if {@link LogRotator} is configured as {@link BuildDiscarder}.
 
382
     *
 
383
     * @deprecated as of 1.503
 
384
     *      Use {@link #getBuildDiscarder()}.
325
385
     */
326
386
    public LogRotator getLogRotator() {
327
 
        return logRotator;
 
387
        if (logRotator instanceof LogRotator)
 
388
            return (LogRotator) logRotator;
 
389
        return null;
328
390
    }
329
391
 
330
 
    public void setLogRotator(LogRotator logRotator) {
331
 
        this.logRotator = logRotator;
 
392
    /**
 
393
     * @deprecated as of 1.503
 
394
     *      Use {@link #setBuildDiscarder(BuildDiscarder)}
 
395
     */
 
396
    public void setLogRotator(LogRotator logRotator) throws IOException {
 
397
        setBuildDiscarder(logRotator);
332
398
    }
333
399
 
334
400
    /**
335
401
     * Perform log rotation.
336
402
     */
337
403
    public void logRotate() throws IOException, InterruptedException {
338
 
        LogRotator lr = getLogRotator();
339
 
        if (lr != null)
340
 
            lr.perform(this);
 
404
        BuildDiscarder bd = getBuildDiscarder();
 
405
        if (bd != null)
 
406
            bd.perform(this);
341
407
    }
342
408
 
343
409
    /**
455
521
 
456
522
    /**
457
523
     * Overrides from job properties.
 
524
     * @see JobProperty#getJobOverrides
458
525
     */
459
526
    public Collection<?> getOverrides() {
460
527
        List<Object> r = new ArrayList<Object>();
506
573
     */
507
574
    @Override
508
575
    public void renameTo(String newName) throws IOException {
 
576
        File oldBuildDir = getBuildDir();
509
577
        super.renameTo(newName);
 
578
        File newBuildDir = getBuildDir();
 
579
        if (oldBuildDir.isDirectory() && !newBuildDir.isDirectory()) {
 
580
            if (!oldBuildDir.renameTo(newBuildDir)) {
 
581
                throw new IOException("failed to rename " + oldBuildDir + " to " + newBuildDir);
 
582
            }
 
583
        }
 
584
    }
 
585
 
 
586
    @Override public synchronized void delete() throws IOException, InterruptedException {
 
587
        super.delete();
 
588
        Util.deleteRecursive(getBuildDir());
510
589
    }
511
590
 
512
591
    /**
520
599
     * 
521
600
     * @return never null. The first entry is the latest build.
522
601
     */
523
 
    @Exported
 
602
    @Exported(name="allBuilds",visibility=-2)
524
603
    @WithBridgeMethods(List.class)
525
604
    public RunList<RunT> getBuilds() {
526
605
        return RunList.fromRuns(_getRuns().values());
527
606
    }
528
607
 
529
608
    /**
 
609
     * Gets the read-only view of the recent builds.
 
610
     *
 
611
     * @since 1.485
 
612
     */
 
613
    @Exported(name="builds")
 
614
    public RunList<RunT> getNewBuilds() {
 
615
        return getBuilds().limit(100);
 
616
    }
 
617
 
 
618
    /**
530
619
     * Obtains all the {@link Run}s whose build numbers matches the given {@link RangeSet}.
531
620
     */
532
621
    public synchronized List<RunT> getBuilds(RangeSet rs) {
602
691
     * This is useful when you'd like to fetch a build but the exact build might
603
692
     * be already gone (deleted, rotated, etc.)
604
693
     */
605
 
    public final RunT getNearestBuild(int n) {
 
694
    public RunT getNearestBuild(int n) {
606
695
        SortedMap<Integer, ? extends RunT> m = _getRuns().headMap(n - 1); // the map should
607
696
                                                                          // include n, so n-1
608
697
        if (m.isEmpty())
616
705
     * This is useful when you'd like to fetch a build but the exact build might
617
706
     * be already gone (deleted, rotated, etc.)
618
707
     */
619
 
    public final RunT getNearestOldBuild(int n) {
 
708
    public RunT getNearestOldBuild(int n) {
620
709
        SortedMap<Integer, ? extends RunT> m = _getRuns().tailMap(n);
621
710
        if (m.isEmpty())
622
711
            return null;
628
717
            StaplerResponse rsp) {
629
718
        try {
630
719
            // try to interpret the token as build number
631
 
            return _getRuns().get(Integer.valueOf(token));
 
720
            return getBuildByNumber(Integer.valueOf(token));
632
721
        } catch (NumberFormatException e) {
633
722
            // try to map that to widgets
634
723
            for (Widget w : getWidgets()) {
655
744
     * 
656
745
     * @see RunMap
657
746
     */
658
 
    protected File getBuildDir() {
 
747
    public File getBuildDir() {
659
748
        return Jenkins.getInstance().getBuildDirFor(this);
660
749
    }
661
750
 
662
751
    /**
663
752
     * Gets all the runs.
664
753
     * 
665
 
     * The resulting map must be immutable (by employing copy-on-write
 
754
     * The resulting map must be treated immutable (by employing copy-on-write
666
755
     * semantics.) The map is descending order, with newest builds at the top.
667
756
     */
668
757
    protected abstract SortedMap<Integer, ? extends RunT> _getRuns();
710
799
    @Exported
711
800
    @QuickSilver
712
801
    public RunT getLastSuccessfulBuild() {
713
 
        RunT r = getLastBuild();
714
 
        // temporary hack till we figure out what's causing this bug
715
 
        while (r != null
716
 
                && (r.isBuilding() || r.getResult() == null || r.getResult()
717
 
                        .isWorseThan(Result.UNSTABLE)))
718
 
            r = r.getPreviousBuild();
719
 
        return r;
 
802
        return (RunT)Permalink.LAST_SUCCESSFUL_BUILD.resolve(this);
720
803
    }
721
804
 
722
805
    /**
977
1060
 
978
1061
            setDisplayName(json.optString("displayNameOrNull"));
979
1062
 
980
 
            if (req.getParameter("logrotate") != null)
981
 
                logRotator = LogRotator.DESCRIPTOR.newInstance(req,json.getJSONObject("logrotate"));
 
1063
            if (json.optBoolean("logrotate"))
 
1064
                logRotator = req.bindJSON(BuildDiscarder.class, json.optJSONObject("buildDiscarder"));
982
1065
            else
983
1066
                logRotator = null;
984
1067
 
1262
1345
        return new BuildTimelineWidget(getBuilds());
1263
1346
    }
1264
1347
 
1265
 
    /*package*/ final static HexStringConfidentialKey SERVER_COOKIE = new HexStringConfidentialKey(Job.class,"serverCookie",16);
 
1348
    private final static HexStringConfidentialKey SERVER_COOKIE = new HexStringConfidentialKey(Job.class,"serverCookie",16);
1266
1349
}