提交 50b2dbdd 编写于 作者: D Daniel Beck

Merge branch 'stable-2.107' of git://github.com/jenkinsci/jenkins into stable-2.107

......@@ -5,7 +5,7 @@
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.107.1-SNAPSHOT</version>
<version>2.107.2-SNAPSHOT</version>
</parent>
<artifactId>cli</artifactId>
......@@ -54,7 +54,7 @@
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>1.6.0</version>
<version>1.7.0</version>
<optional>true</optional> <!-- do not expose to core -->
</dependency>
<dependency>
......
......@@ -29,7 +29,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.107.1-SNAPSHOT</version>
<version>2.107.2-SNAPSHOT</version>
</parent>
<artifactId>jenkins-core</artifactId>
......
......@@ -87,6 +87,9 @@ import javax.annotation.Nullable;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
/**
* Various utility methods that don't have more proper home.
*
......@@ -179,43 +182,54 @@ public class Util {
}
/**
* Loads the contents of a file into a string.
* Reads the entire contents of the text file at <code>logfile</code> into a
* string using the {@link Charset#defaultCharset() default charset} for
* decoding. If no such file exists, an empty string is returned.
* @param logfile The text file to read in its entirety.
* @return The entire text content of <code>logfile</code>.
* @throws IOException If an error occurs while reading the file.
* @deprecated call {@link #loadFile(java.io.File, java.nio.charset.Charset)}
* instead to specify the charset to use for decoding (preferably
* {@link java.nio.charset.StandardCharsets#UTF_8}).
*/
@Nonnull
@Deprecated
public static String loadFile(@Nonnull File logfile) throws IOException {
return loadFile(logfile, Charset.defaultCharset());
}
/**
* Reads the entire contents of the text file at <code>logfile</code> into a
* string using <code>charset</code> for decoding. If no such file exists,
* an empty string is returned.
* @param logfile The text file to read in its entirety.
* @param charset The charset to use for decoding the bytes in <code>logfile</code>.
* @return The entire text content of <code>logfile</code>.
* @throws IOException If an error occurs while reading the file.
*/
@Nonnull
public static String loadFile(@Nonnull File logfile, @Nonnull Charset charset) throws IOException {
if(!logfile.exists())
return "";
StringBuilder str = new StringBuilder((int)logfile.length());
// We're not using Files.newBufferedReader() here because there is a
// difference in how an InputStreamReader constructed from a Charset and
// the reader returned by Files.newBufferedReader() handle malformed and
// unmappable byte sequences for the specified encoding; the latter is
// more picky and will throw a CharacterCodingException. See:
// https://issues.jenkins-ci.org/browse/JENKINS-49060?focusedCommentId=325989&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-325989
// Note: Until charset handling is resolved (e.g. by implementing
// https://issues.jenkins-ci.org/browse/JENKINS-48923 ), this method
// must be able to handle character encoding errors. As reported at
// https://issues.jenkins-ci.org/browse/JENKINS-49112 Run.getLog() calls
// loadFile() to fully read the generated log file. This file might
// contain unmappable and/or malformed byte sequences. We need to make
// sure that in such cases, no CharacterCodingException is thrown.
//
// As reported at https://issues.jenkins-ci.org/browse/JENKINS-49112
// Run.getLog() calls loadFile() to fully read the generated log file.
// Until charset handling is resolved (e.g. by implementing
// https://issues.jenkins-ci.org/browse/JENKINS-48923 ), malformed
// bytes will need to be tolerated.
try (InputStream rawIn = Files.newInputStream(fileToPath(logfile));
Reader r = new BufferedReader(new InputStreamReader(rawIn, charset))) {
char[] buf = new char[1024];
int len;
while ((len = r.read(buf, 0, buf.length)) > 0)
str.append(buf, 0, len);
// One approach that cannot be used is to call Files.newBufferedReader()
// because there is a difference in how an InputStreamReader constructed
// from a Charset and the reader returned by Files.newBufferedReader()
// handle malformed and unmappable byte sequences for the specified
// encoding; the latter is more picky and will throw an exception.
// See: https://issues.jenkins-ci.org/browse/JENKINS-49060?focusedCommentId=325989&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-325989
try {
return FileUtils.readFileToString(logfile, charset);
} catch (FileNotFoundException e) {
return "";
} catch (Exception e) {
throw new IOException("Failed to fully read " + logfile + " using charset " + charset.name(), e);
throw new IOException("Failed to fully read " + logfile, e);
}
return str.toString();
}
/**
......
......@@ -1198,7 +1198,12 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
return true; // no SCM
FilePath workspace = build.getWorkspace();
workspace.mkdirs();
if(workspace!=null){
workspace.mkdirs();
} else {
throw new AbortException("Cannot checkout SCM, workspace is not defined");
}
boolean r = scm.checkout(build, launcher, workspace, listener, changelogFile);
if (r) {
......
......@@ -459,7 +459,6 @@ public class Executor extends Thread implements ModelObject {
if (asynchronousExecution == null) {
finish2();
}
executableEstimatedDuration = DEFAULT_ESTIMATED_DURATION;
}
}
......@@ -490,6 +489,7 @@ public class Executor extends Thread implements ModelObject {
if (this instanceof OneOffExecutor) {
owner.remove((OneOffExecutor) this);
}
executableEstimatedDuration = DEFAULT_ESTIMATED_DURATION;
queue.scheduleMaintenance();
}
......
......@@ -87,7 +87,7 @@ public class ParametersAction implements RunAction2, Iterable<ParameterValue>, Q
private Set<String> safeParameters;
private final List<ParameterValue> parameters;
private @Nonnull List<ParameterValue> parameters;
private List<String> parameterDefinitionNames;
......@@ -99,7 +99,7 @@ public class ParametersAction implements RunAction2, Iterable<ParameterValue>, Q
private transient Run<?, ?> run;
public ParametersAction(List<ParameterValue> parameters) {
public ParametersAction(@Nonnull List<ParameterValue> parameters) {
this.parameters = new ArrayList<>(parameters);
String paramNames = SystemProperties.getString(SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME);
safeParameters = new TreeSet<>();
......@@ -284,6 +284,9 @@ public class ParametersAction implements RunAction2, Iterable<ParameterValue>, Q
}
private Object readResolve() {
if (parameters == null) { // JENKINS-39495
parameters = Collections.emptyList();
}
if (build != null)
OldDataMonitor.report(build, "1.283");
if (safeParameters == null) {
......@@ -296,7 +299,7 @@ public class ParametersAction implements RunAction2, Iterable<ParameterValue>, Q
public void onAttached(Run<?, ?> r) {
ParametersDefinitionProperty p = r.getParent().getProperty(ParametersDefinitionProperty.class);
if (p != null) {
this.parameterDefinitionNames = p.getParameterDefinitionNames();
this.parameterDefinitionNames = new ArrayList<>(p.getParameterDefinitionNames());
} else {
this.parameterDefinitionNames = Collections.emptyList();
}
......
......@@ -91,6 +91,11 @@ public class ProxyView extends View implements StaplerFallback {
return getProxiedView().contains(item);
}
@Override
public TopLevelItem getItem(String name) {
return getProxiedView().getItem(name);
}
@Override
protected void submit(StaplerRequest req) throws IOException, ServletException, FormException {
String proxiedViewName = req.getSubmittedForm().getString("proxiedViewName");
......
......@@ -24,10 +24,12 @@
*/
package hudson.model;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import hudson.BulkChange;
import hudson.Extension;
import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.Util;
......@@ -64,7 +66,10 @@ import hudson.model.queue.WorkUnitContext;
import hudson.security.ACL;
import hudson.security.AccessControlled;
import java.nio.file.Files;
import hudson.util.Futures;
import jenkins.security.QueueItemAuthenticatorProvider;
import jenkins.util.SystemProperties;
import jenkins.util.Timer;
import hudson.triggers.SafeTimerTask;
import java.util.concurrent.TimeUnit;
......@@ -93,7 +98,6 @@ import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Condition;
......@@ -102,6 +106,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.GuardedBy;
import javax.servlet.ServletException;
import jenkins.model.Jenkins;
......@@ -3009,4 +3014,75 @@ public class Queue extends ResourceController implements Saveable {
public static void init(Jenkins h) {
h.getQueue().load();
}
/**
* Schedule <tt>Queue.save()</tt> call for near future once items change. Ignore all changes until the time the save
* takes place.
*
* Once queue is restored after a crash, items stages might not be accurate until the next #maintain() - this is not
* a problem as the items will be reshuffled first and then scheduled during the next maintainance cycle.
*
* Implementation note: Queue.load() calls QueueListener hooks for every item deserialized that can hammer the persistance
* on load. The problem is avoided by delaying the actual save for the time long enough for queue to load so the save
* operations will collapse into one. Also, items are persisted as buildable or blocked in vast majority of cases and
* those stages does not trigger the save here.
*/
@Extension
@Restricted(NoExternalUse.class)
public static final class Saver extends QueueListener implements Runnable {
/**
* All negative values will disable periodic saving.
*/
@VisibleForTesting
/*package*/ static /*final*/ int DELAY_SECONDS = SystemProperties.getInteger("hudson.model.Queue.Saver.DELAY_SECONDS", 60);
private final Object lock = new Object();
@GuardedBy("lock")
private Future<?> nextSave;
@Override
public void onEnterWaiting(WaitingItem wi) {
push();
}
@Override
public void onLeft(Queue.LeftItem li) {
push();
}
private void push() {
if (DELAY_SECONDS < 0) return;
synchronized (lock) {
// Can be done or canceled in case of a bug or external intervention - do not allow it to hang there forever
if (nextSave != null && !(nextSave.isDone() || nextSave.isCancelled())) return;
nextSave = Timer.get().schedule(this, DELAY_SECONDS, TimeUnit.SECONDS);
}
}
@Override
public void run() {
try {
Jenkins j = Jenkins.getInstanceOrNull();
if (j != null) {
j.getQueue().save();
}
} finally {
synchronized (lock) {
nextSave = null;
}
}
}
@VisibleForTesting @Restricted(NoExternalUse.class)
/*package*/ @Nonnull Future<?> getNextSave() {
synchronized (lock) {
return nextSave == null
? Futures.precomputed(null)
: nextSave
;
}
}
}
}
......@@ -13,4 +13,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse;
@Restricted(NoExternalUse.class)
@RestrictedSince("2.91")
public abstract class AbstractTaskListener implements TaskListener {
private static final long serialVersionUID = 7217626701881006422L;
}
......@@ -29,10 +29,9 @@ import hudson.model.RunMap;
import java.io.File;
import java.io.IOException;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
......@@ -336,9 +335,9 @@ public abstract class AbstractLazyLoadRunMap<R> extends AbstractMap<Integer,R> i
return null;
case DESC:
// TODO again could be made more efficient
List<Integer> reversed = new ArrayList<Integer>(numberOnDisk);
Collections.reverse(reversed);
for (int m : reversed) {
ListIterator<Integer> iterator = numberOnDisk.listIterator(numberOnDisk.size());
while(iterator.hasPrevious()) {
int m = iterator.previous();
if (m > n) {
continue;
}
......
......@@ -20,4 +20,4 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
Allow\ users\ to\ sign\ up=Sta gebruikers toe in te loggen
Allow\ users\ to\ sign\ up=Sta gebruikers toe zichzelf te registreren
......@@ -39,12 +39,12 @@ installWizard_installComplete_installComplete_restartRequiredNotSupportedMessage
installWizard_installComplete_restartLabel=Restart
installWizard_installIncomplete_title=Resume Installation
installWizard_installIncomplete_banner=Resume Installation
installWizard_installIncomplete_message=Jenkins was restarted during installation and some plugins didn''t seem to get installed.
installWizard_installIncomplete_message=Jenkins was restarted during installation and some plugins did not seem to get installed.
installWizard_installIncomplete_resumeInstallationButtonLabel=Resume
installWizard_saveFirstUser=Save and Finish
installWizard_skipFirstUser=Continue as admin
installWizard_firstUserSkippedMessage=<div class="alert alert-warning fade in">\
You''ve skipped creating an admin user. To log in, use the username: "admin" and \
You have skipped creating an admin user. To log in, use the username: "admin" and \
the administrator password you used to access the setup wizard.\
</div>
installWizard_addFirstUser_title=Getting Started
......@@ -63,7 +63,7 @@ installWizard_continue=Continue
installWizard_retry=Retry
installWizard_upgradePanel_title=Upgrade
installWizard_upgradePanel_banner=Welcome to Jenkins {0}!
installWizard_upgradePanel_message=Jenkins {0} includes some great new features that we think you''ll love, install these additional plugins to take advantage of them!
installWizard_upgradePanel_message=Jenkins {0} includes some great new features that we think you will love, install these additional plugins to take advantage of them!
installWizard_upgradePanel_skipRecommendedPlugins=No thanks
installWizard_upgradeComplete_title=Upgrade
installWizard_pluginsInstalled_banner=Welcome to Jenkins {0}!
......
installWizard_welcomePanel_title=Per iniziare
installWizard_welcomePanel_banner=Personalizza Jenkins
installWizard_welcomePanel_message=I plugin estendono Jenkins con funzionalit aggiuntive per far fronte a molte necessit differenti.
installWizard_welcomePanel_message=I plugin estendono Jenkins con funzionalit\u00E0 aggiuntive per far fronte a molte necessit\u00E0 differenti.
installWizard_welcomePanel_recommendedActionTitle=Installa plugin consigliati
installWizard_welcomePanel_recommendedActionDetails=Installa i plugin che la comunit di Jenkins ritiene maggiormente utili.
installWizard_welcomePanel_recommendedActionDetails=Installa i plugin che la comunit\u00E0 di Jenkins ritiene maggiormente utili.
installWizard_welcomePanel_customizeActionTitle=Seleziona i plugin da installare
installWizard_welcomePanel_customizeActionDetails=Seleziona e installa i plugin pi adatti per le proprie necessit.
installWizard_jenkinsVersionTitle=Jenkins
installWizard_welcomePanel_customizeActionDetails=Seleziona e installa i plugin pi\u00F9 adatti per le proprie necessit\u00E0.
installWizard_jenkinsVersionTitle=Jenkins
installWizard_offline_title=Non in linea
installWizard_offline_message=Sembra che quest''istanza di Jenkins non sia in linea. \
installWizard_offline_message=Sembra che questa istanza di Jenkins non sia in linea. \
<p style="font-size:18px; margin-top: 6%"> \
Per informazioni sull''installazione di Jenkins in assenza di una connessione a Internet, si veda la \
<a href="https://jenkins.io/redirect/offline-installation" target="_blank">documentazione sull''installazione non in linea di Jenkins</a>. <br/><br/> \
possibile scegliere di continuare configurando un proxy o ignorando l''installazione dei plugin. \
</p>
installWizard_error_header=Si verificato un errore
installWizard_error_message=Si verificato un errore durante l''installazione:
Per informazioni sul processo di installazione Jenkins in assenza di una connessione a Internet, si veda la \
<a href="https://jenkins.io/redirect/offline-installation" target="_blank">relativa documentazione</a>. <br/><br/> \
\u00C8 possibile scegliere di continuare configurando un proxy o saltando la parte di installazione dei plugins.</p>
installWizard_error_header=Si \u00E8 verificato un errore
installWizard_error_message=Si \u00E8 verificato un errore durante il processo di installazione:
installWizard_error_connection=Impossibile connettersi a Jenkins
installWizard_error_restartNotSupported=Il riavvio non supportato, riavviare manualmente quest''istanza
installWizard_error_restartNotSupported=Il riavvio non \u00E8 supportato, riavviare manualmente questa istanza
installWizard_installCustom_title=Per iniziare
installWizard_installCustom_selectAll=Tutti
installWizard_installCustom_selectNone=Nessuno
installWizard_installCustom_selectRecommended=Suggeriti
installWizard_installCustom_selected=Selezionati
installWizard_installCustom_dependenciesPrefix=Dipendenze
installWizard_installCustom_pluginListDesc=Si noti che qui non viene visualizzato l''elenco completo dei plugin. possibile installare plugin aggiuntivi nel <strong>Gestore plugin</strong> una volta completata l''installazione iniziale. <a href="https://jenkins.io/redirect/installation-wizard" target="_blank">Si veda il Wiki per ulteriori informazioni</a>.
installWizard_installCustom_pluginListDesc=Si noti che qui non viene visualizzata la lista completa di plugins. \u00C8 possibile installare plugin aggiuntivi nel <strong>Gestore plugin</strong> una volta completata la fase di installazione iniziale. <a href="https://jenkins.io/redirect/installation-wizard" target="_blank">Si veda il Wiki per ulteriori informazioni</a>.
installWizard_goBack=Indietro
installWizard_goInstall=Installa
installWizard_installing_title=Per iniziare
installWizard_installing_detailsLink=Dettagli...
installWizard_installComplete_title=Per iniziare
installWizard_installComplete_banner=Jenkins pronto!
installWizard_installComplete_bannerRestart=Jenkins quasi pronto!
installWizard_pluginsInstalled_message=L''installazione dei plugin stata completata.
installWizard_installComplete_message=L''installazione di Jenkins stata completata.
installWizard_installComplete_banner=Jenkins \u00E8 pronto!
installWizard_installComplete_bannerRestart=Jenkins \u00E8 quasi pronto!
installWizard_pluginsInstalled_message=Installazione dei plugins completata.
installWizard_installComplete_message=Installazione di Jenkins completata.
installWizard_installComplete_finishButtonLabel=Inizia a utilizzare Jenkins
installWizard_installComplete_installComplete_restartRequiredMessage=L''installazione di Jenkins stata completata, ma alcuni plugin richiedono il riavvio di Jenkins.
installWizard_installComplete_installComplete_restartRequiredNotSupportedMessage=L''installazione di Jenkins stata completata, ma alcuni plugin richiedono il riavvio di Jenkins e sembra che quest''istanza non supporti il riavvio automatico. Riavviare manualmente quest''istanza ora per completare l''installazione.
installWizard_installComplete_installComplete_restartRequiredMessage=Installazione di Jenkins completata, ma alcuni plugin richiedono il riavvio di Jenkins.
installWizard_installComplete_installComplete_restartRequiredNotSupportedMessage=Installazione di Jenkins completata, ma alcuni plugin richiedono il riavvio di Jenkins e sembra che questa istanza non supporti il riavvio automatico. Riavviare manualmente questa istanza ora per completare l''installazione.
installWizard_installComplete_restartLabel=Riavvia
installWizard_installIncomplete_title=Riprendi installazione
installWizard_installIncomplete_banner=Riprendi installazione
installWizard_installIncomplete_message=Jenkins stato riavviato durante l''installazione e sembra che alcuni plugin non siano stati installati.
installWizard_installIncomplete_message=Jenkins \u00E8 stato riavviato durante il processo di installazione e sembra che alcuni plugin non siano stati installati.
installWizard_installIncomplete_resumeInstallationButtonLabel=Riprendi
installWizard_saveFirstUser=Salva e finisci
installWizard_skipFirstUser=Continua come amministratore
installWizard_firstUserSkippedMessage=<div class="alert alert-warning fade in">\
Si ignorata la creazione di un utente amministratore. Per eseguire l''accesso, \
utilizzare il nome utente ''admin'' e la password di amministratore utilizzata \
per accedere alla procedura guidata di installazione.\
Si \u00E8 ignorata la creazione di un utente amministratore. Per accedere, \
utilizzare il nome utente <pre>admin</pre> e la password di amministratore utilizzata \
durante la procedura guidata di installazione.\
</div>
installWizard_addFirstUser_title=Per iniziare
installWizard_configureProxy_label=Configura proxy
......@@ -58,21 +57,21 @@ installWizard_installIncomplete_dependenciesLabel=Dipendenze
installWizard_installingConsole_dependencyIndicatorNote=** - dipendenza obbligatoria
installWizard_websiteLinkLabel=Sito Web
installWizard_pluginInstallFailure_title=Errori di installazione
installWizard_pluginInstallFailure_message=Alcuni plugin non sono stati installati correttamente, possibile riprovare ad installarli o continuare mantenendo i plugin la cui installazione non riuscita
installWizard_pluginInstallFailure_message=Alcuni plugin non sono stati installati correttamente, \u00E8 possibile riprovare ad installarli o continuare mantenendo i plugin la cui installazione non \u00E8 riuscita
installWizard_continue=Continua
installWizard_retry=Riprova
installWizard_upgradePanel_title=Aggiorna
installWizard_upgradePanel_banner=Benvenuto in Jenkins {0}!
installWizard_upgradePanel_message=Jenkins {0} include nuove funzionalit che pensiamo possano piacere, si installino questi plugin aggiuntivi per sfruttarle!
installWizard_upgradePanel_message=Jenkins {0} include nuove funzionalit\u00E0 che pensiamo possano piacere, si installino questi plugin aggiuntivi per sfruttarle!
installWizard_upgradePanel_skipRecommendedPlugins=No, grazie
installWizard_upgradeComplete_title=Aggiorna
installWizard_pluginsInstalled_banner=Benvenuto in Jenkins {0}!
installWizard_upgradeComplete_message=Congratulazioni! Si effettuato l''aggiornamento a Jenkins {0}.</p><p>Per saperne di pi sulle sue nuove funzionalit, si visiti <a target="_blank" href="https://jenkins.io/2.0/">il sito Web di Jenkins</a>!
installWizard_upgradeComplete_message=Congratulazioni! Si \u00E8 effettuato l'aggiornamento a Jenkins {0}.</p><p>Per saperne di pi\u00F9 sulle sue nuove funzionalit\u00E0, si visiti <a target="_blank" href="https://jenkins.io/2.0/">il sito Web di Jenkins</a>!
installWizard_upgradeSkipped_title=Aggiorna
installWizard_upgradeSkipped_banner=Funzionalit non installate
installWizard_upgradeSkipped_banner=Funzionalit\u00E0 non installate
installWizard_upgradeSkipped_message=<div class="alert alert-warning fade in">I plugin consigliati non saranno installati.</div> \
<p style="padding: 0 4px"> possibile installare le nuove funzionalit anche dal Gestore plugin nel caso in cui si cambi idea.</p> \
<p style="padding: 0 4px">Si scopra come queste nuove funzionalit possano migliorare l''esperienza Jenkins \
<p style="padding: 0 4px">\u00C8 possibile installare le nuove funzionalit\u00E0 anche dal Gestore plugin nel caso in cui si cambi idea.</p> \
<p style="padding: 0 4px">Si scopra come queste nuove funzionalit\u00E0 possano migliorare l'esperienza Jenkins \
<a target="_blank" href="https://jenkins.io/2.0/">visitando la pagina iniziale</a>.</p>
installWizard_upgrading_title=Installazione plugin in corso
installWizard_upgradeComplete_finishButtonLabel=Fine
......@@ -122,6 +122,7 @@ java.util.TreeSet
java.util.UUID
java.util.Vector
java.util.concurrent.ConcurrentHashMap
java.util.concurrent.ConcurrentLinkedQueue
java.util.concurrent.ConcurrentSkipListMap
java.util.concurrent.CopyOnWriteArrayList
java.util.concurrent.CopyOnWriteArraySet
......@@ -151,6 +152,7 @@ net.bull.javamelody.internal.model.TomcatInformations
org.acegisecurity.userdetails.User
org.apache.commons.fileupload.disk.DiskFileItem
org.apache.commons.fileupload.util.FileItemHeadersImpl
org.apache.tools.ant.Location
# TODO remove when git-client 2.7.1+ is widely adopted
org.eclipse.jgit.lib.ObjectId
......
......@@ -129,7 +129,7 @@ THE SOFTWARE.
<j:forEach var="c" items="${computers}">
<j:set var="cDisplayExecutors" value="${c.displayExecutors}"/>
<tr>
<j:if test="${computersSize gt 1 and !cDisplayExecutors.isEmpty()}">
<j:if test="${(computersSize gt 1 and !cDisplayExecutors.isEmpty()) or (c.node == app and c.offline)}">
<th class="pane" colspan="3">
<local:computerCaption title="${c.displayName}" />
</th>
......
......@@ -33,7 +33,7 @@ THE SOFTWARE.
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.107.1-SNAPSHOT</version>
<version>2.107.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Jenkins main module</name>
......
......@@ -28,7 +28,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.107.1-SNAPSHOT</version>
<version>2.107.2-SNAPSHOT</version>
</parent>
<artifactId>test</artifactId>
......@@ -53,7 +53,7 @@ THE SOFTWARE.
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jenkins-test-harness</artifactId>
<version>2.32</version>
<version>2.33</version>
<scope>test</scope>
<exclusions>
<exclusion>
......
/*
* The MIT License
*
* Copyright (c) Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.model;
import hudson.ExtensionList;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runners.model.Statement;
import org.jvnet.hudson.test.RestartableJenkinsRule;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class QueueRestartTest {
@Rule
public RestartableJenkinsRule j = new RestartableJenkinsRule();
@Test
public void persistQueueOnRestart() {
j.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
Queue.Saver.DELAY_SECONDS = 24 * 60 * 60; // Avoid period save as we are after the explicit one
scheduleSomeBuild();
assertBuildIsScheduled();
}
});
j.addStep(new Statement() {
@Override public void evaluate() {
assertBuildIsScheduled();
}
});
}
@Test
public void persistQueueOnCrash() {
j.addStepWithDirtyShutdown(new Statement() {
@Override public void evaluate() throws Throwable {
Queue.Saver.DELAY_SECONDS = 0; // Call Queue#save() on every queue modification simulating time has passed before crash
scheduleSomeBuild();
assertBuildIsScheduled();
// Save have no delay though is not synchronous
ExtensionList.lookup(Queue.Saver.class).get(0).getNextSave().get(3, TimeUnit.SECONDS);
assertTrue("queue.xml does not exist", j.j.jenkins.getQueue().getXMLQueueFile().exists());
}
});
j.addStep(new Statement() {
@Override public void evaluate() {
assertBuildIsScheduled();
}
});
}
private void assertBuildIsScheduled() {
assertEquals(1, j.j.jenkins.getQueue().getItems().length);
}
private void scheduleSomeBuild() throws IOException {
FreeStyleProject p = j.j.createFreeStyleProject();
p.setAssignedLabel(Label.get("waitforit"));
p.scheduleBuild2(0);
}
}
......@@ -46,6 +46,7 @@ import hudson.model.Queue.BlockedItem;
import hudson.model.Queue.Executable;
import hudson.model.Queue.WaitingItem;
import hudson.model.labels.LabelExpression;
import hudson.model.listeners.SaveableListener;
import hudson.model.queue.CauseOfBlockage;
import hudson.model.queue.QueueTaskDispatcher;
import hudson.model.queue.QueueTaskFuture;
......@@ -1018,4 +1019,22 @@ public class QueueTest {
assertEquals(expected.getShortDescription(), actual.getShortDescription());
}
@Test @LocalData
public void load_queue_xml() {
Queue q = r.getInstance().getQueue();
Queue.Item[] items = q.getItems();
assertEquals(Arrays.asList(items).toString(), 11, items.length);
assertEquals("Loading the queue should not generate saves", 0, QueueSaveSniffer.count);
}
@TestExtension("load_queue_xml")
public static final class QueueSaveSniffer extends SaveableListener {
private static int count = 0;
@Override public void onChange(Saveable o, XmlFile file) {
if (o instanceof Queue) {
count++;
}
}
}
}
<?xml version='1.0' encoding='UTF-8'?>
<hudson>
<disabledAdministrativeMonitors/>
<version>2.103-SNAPSHOT (private-01/18/2018 15:13 GMT-ogondza)</version>
<installState class="jenkins.install.InstallState$5">
<isSetupComplete>true</isSetupComplete>
<name>RESTART</name>
</installState>
<numExecutors>2</numExecutors>
<mode>NORMAL</mode>
<useSecurity>true</useSecurity>
<authorizationStrategy class="hudson.security.AuthorizationStrategy$Unsecured"/>
<securityRealm class="hudson.security.HudsonPrivateSecurityRealm">
<disableSignup>true</disableSignup>
<enableCaptcha>false</enableCaptcha>
</securityRealm>
<disableRememberMe>false</disableRememberMe>
<projectNamingStrategy class="jenkins.model.ProjectNamingStrategy$DefaultProjectNamingStrategy"/>
<workspaceDir>${JENKINS_HOME}/workspace/${ITEM_FULL_NAME}</workspaceDir>
<buildsDir>${ITEM_ROOTDIR}/builds</buildsDir>
<markupFormatter class="hudson.markup.EscapedMarkupFormatter"/>
<jdks/>
<viewsTabBar class="hudson.views.DefaultViewsTabBar"/>
<myViewsTabBar class="hudson.views.DefaultMyViewsTabBar"/>
<clouds/>
<scmCheckoutRetryCount>0</scmCheckoutRetryCount>
<views>
<hudson.model.AllView>
<owner class="hudson" reference="../../.."/>
<name>all</name>
<filterExecutors>false</filterExecutors>
<filterQueue>false</filterQueue>
<properties class="hudson.model.View$PropertyList"/>
</hudson.model.AllView>
</views>
<primaryView>all</primaryView>
<slaveAgentPort>-1</slaveAgentPort>
<disabledAgentProtocols>
<string>JNLP-connect</string>
<string>JNLP2-connect</string>
</disabledAgentProtocols>
<label></label>
<crumbIssuer class="hudson.security.csrf.DefaultCrumbIssuer">
<excludeClientIPFromCrumb>false</excludeClientIPFromCrumb>
</crumbIssuer>
<nodeProperties/>
<globalNodeProperties/>
</hudson>
\ No newline at end of file
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<assignedNode>!master</assignedNode>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/>
</project>
<?xml version='1.0' encoding='UTF-8'?>
<hudson.model.Queue_-State>
<counter>17</counter>
<items>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>17</id>
<task class="hudson.model.FreeStyleProject">k</task>
<inQueueSince>1516354024440</inQueueSince>
<buildableStartMilliseconds>1516354024440</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>16</id>
<task class="hudson.model.FreeStyleProject">j</task>
<inQueueSince>1516354003647</inQueueSince>
<buildableStartMilliseconds>1516354003648</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>15</id>
<task class="hudson.model.FreeStyleProject">i</task>
<inQueueSince>1516354001887</inQueueSince>
<buildableStartMilliseconds>1516354001888</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>14</id>
<task class="hudson.model.FreeStyleProject">h</task>
<inQueueSince>1516353999191</inQueueSince>
<buildableStartMilliseconds>1516353999192</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>13</id>
<task class="hudson.model.FreeStyleProject">g</task>
<inQueueSince>1516353998031</inQueueSince>
<buildableStartMilliseconds>1516353998032</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>12</id>
<task class="hudson.model.FreeStyleProject">f</task>
<inQueueSince>1516353996504</inQueueSince>
<buildableStartMilliseconds>1516353996504</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>11</id>
<task class="hudson.model.FreeStyleProject">e</task>
<inQueueSince>1516353995471</inQueueSince>
<buildableStartMilliseconds>1516353995472</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>10</id>
<task class="hudson.model.FreeStyleProject">d</task>
<inQueueSince>1516353993872</inQueueSince>
<buildableStartMilliseconds>1516353993873</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>9</id>
<task class="hudson.model.FreeStyleProject">c</task>
<inQueueSince>1516353991671</inQueueSince>
<buildableStartMilliseconds>1516353991672</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>8</id>
<task class="hudson.model.FreeStyleProject">b</task>
<inQueueSince>1516353989177</inQueueSince>
<buildableStartMilliseconds>1516353989177</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
<hudson.model.Queue_-BuildableItem>
<actions>
<hudson.model.CauseAction>
<causeBag class="linked-hash-map">
<entry>
<hudson.model.Cause_-UserIdCause/>
<int>1</int>
</entry>
</causeBag>
</hudson.model.CauseAction>
</actions>
<id>7</id>
<task class="hudson.model.FreeStyleProject">a</task>
<inQueueSince>1516353986148</inQueueSince>
<buildableStartMilliseconds>1516353986151</buildableStartMilliseconds>
<isPending>false</isPending>
</hudson.model.Queue_-BuildableItem>
</items>
</hudson.model.Queue_-State>
\ No newline at end of file
......@@ -28,7 +28,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.107.1-SNAPSHOT</version>
<version>2.107.2-SNAPSHOT</version>
</parent>
<artifactId>jenkins-war</artifactId>
......@@ -49,7 +49,7 @@ THE SOFTWARE.
<dependency>
<groupId>org.jenkins-ci</groupId>
<artifactId>executable-war</artifactId>
<version>1.37</version>
<version>1.38</version>
<scope>provided</scope>
</dependency>
<dependency>
......@@ -89,7 +89,7 @@ THE SOFTWARE.
-->
<groupId>org.jenkins-ci</groupId>
<artifactId>winstone</artifactId>
<version>4.1</version>
<version>4.1.2</version>
<scope>test</scope>
</dependency>
<dependency>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册