Skip to content

Commit

Permalink
Merge branch 'master' into new-plugin-manager-1
Browse files Browse the repository at this point in the history
  • Loading branch information
timja authored Jul 6, 2022
2 parents dbc96f4 + 250540e commit 6e64c68
Show file tree
Hide file tree
Showing 34 changed files with 1,378 additions and 1,210 deletions.
7 changes: 7 additions & 0 deletions core/src/main/java/hudson/Functions.java
Original file line number Diff line number Diff line change
Expand Up @@ -1936,6 +1936,13 @@ public boolean hyperlinkMatchesCurrentPage(String href) {
return url.endsWith(href);
}

/**
* @deprecated From JEXL expressions ({@code ${…}}) in {@code *.jelly} files
* you can use {@code [obj]} syntax to construct an {@code Object[]}
* (which may be usable where a {@link List} is expected)
* rather than {@code h.singletonList(obj)}.
*/
@Deprecated
public <T> List<T> singletonList(T t) {
return List.of(t);
}
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/java/hudson/model/Run.java
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ private enum State {
/**
* Creates a new {@link Run}.
* @param job Owner job
* @see LazyBuildMixIn#newBuild
*/
protected Run(@NonNull JobT job) throws IOException {
this(job, System.currentTimeMillis());
Expand Down Expand Up @@ -347,6 +348,7 @@ protected Run(@NonNull JobT job, long timestamp) {

/**
* Loads a run from a log file.
* @see LazyBuildMixIn#loadBuild
*/
protected Run(@NonNull JobT project, @NonNull File buildDir) throws IOException {
this.project = project;
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/hudson/model/View.java
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,7 @@ public void updateByXml(Source source) throws IOException {
public ModelObjectWithContextMenu.ContextMenu doChildrenContextMenu(StaplerRequest request, StaplerResponse response) throws Exception {
ModelObjectWithContextMenu.ContextMenu m = new ModelObjectWithContextMenu.ContextMenu();
for (TopLevelItem i : getItems())
m.add(i.getShortUrl(), i.getDisplayName());
m.add(Functions.getRelativeLinkTo(i), Functions.getRelativeDisplayNameFrom(i, getOwner().getItemGroup()));
return m;
}

Expand Down
26 changes: 4 additions & 22 deletions core/src/main/java/hudson/util/DoubleLaunchChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,12 @@
import hudson.triggers.SafeTimerTask;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import jenkins.model.Jenkins;
import jenkins.util.Timer;
Expand All @@ -63,10 +60,6 @@
* this file. In this way, while we cannot detect the problem right away, within a reasonable time frame
* we can detect the collision.
*
* <p>
* More traditional way of doing this is to use a lock file with PID in it, but unfortunately in Java,
* there's no reliable way to obtain PID.
*
* @author Kohsuke Kawaguchi
* @since 1.178
*/
Expand Down Expand Up @@ -110,6 +103,7 @@ protected void execute() {
}
// we noticed that someone else have updated this file.
// switch GUI to display this error.
// TODO seems drastic; could this just be switched to an AdministrativeMonitor?
Jenkins.get().servletContext.setAttribute("app", this);
LOGGER.severe("Collision detected. timestamp=" + t + ", expected=" + lastWriteTime);
// we need to continue updating this file, so that the other Hudson would notice the problem, too.
Expand All @@ -130,20 +124,7 @@ protected void execute() {
* Figures out a string that identifies this instance of Hudson.
*/
public String getId() {
Jenkins h = Jenkins.get();

// in servlet 2.5, we can get the context path
String contextPath = "";
try {
Method m = ServletContext.class.getMethod("getContextPath");
contextPath = " contextPath=\"" + m.invoke(h.servletContext) + "\"";
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
// maybe running with Servlet 2.4
}

return h.hashCode() + contextPath + " at " + ManagementFactory.getRuntimeMXBean().getName();
return Long.toString(ProcessHandle.current().pid());
}

public String getCollidingId() {
Expand All @@ -155,7 +136,7 @@ public String getCollidingId() {
*/
public void schedule() {
// randomize the scheduling so that multiple Hudson instances will write at the file at different time
long MINUTE = 1000 * 60;
long MINUTE = 1000 * 60; // TODO use TimeUnit.MINUTE.toMillis

Timer.get()
.schedule(new SafeTimerTask() {
Expand All @@ -168,6 +149,7 @@ protected void doRun() {

@Initializer(after = JOB_CONFIG_ADAPTED)
public static void init() {
// TODO AperiodicWork would be more idiomatic
new DoubleLaunchChecker().schedule();
}

Expand Down
47 changes: 15 additions & 32 deletions core/src/main/java/hudson/util/RingBufferLogHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,42 +24,22 @@

package hudson.util;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.ref.SoftReference;
import java.util.AbstractList;
import java.util.List;
import java.util.Objects;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;

/**
* Log {@link Handler} that stores the log records into a ring buffer.
*
* @author Kohsuke Kawaguchi
*/
@SuppressFBWarnings(
value = "RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT",
justification = "to guard against potential future compiler optimizations")
public class RingBufferLogHandler extends Handler {

private static final int DEFAULT_RING_BUFFER_SIZE = Integer.getInteger(RingBufferLogHandler.class.getName() + ".defaultSize", 256);

private static final class LogRecordRef extends SoftReference<LogRecord> {
LogRecordRef(LogRecord referent) {
super(referent);
}
}

static {
// Preload the LogRecordRef class to avoid an ABBA deadlock between agent class loading and logging.
LogRecord r = new LogRecord(Level.INFO, "<preloading>");
// We call Objects.hash() to guard against potential future compiler optimizations.
Objects.hash(new LogRecordRef(r).get());
}

private int start = 0;
private final LogRecordRef[] records;
private final LogRecord[] records;
private int size;

/**
Expand All @@ -73,7 +53,7 @@ public RingBufferLogHandler() {
}

public RingBufferLogHandler(int ringSize) {
records = new LogRecordRef[ringSize];
records = new LogRecord[ringSize];
}

/**
Expand All @@ -86,13 +66,18 @@ public static int getDefaultRingBufferSize() {
}

@Override
public synchronized void publish(LogRecord record) {
int len = records.length;
records[(start + size) % len] = new LogRecordRef(record);
if (size == len) {
start = (start + 1) % len;
} else {
size++;
public void publish(LogRecord record) {
if (record == null) {
return;
}
synchronized (this) {
int len = records.length;
records[(start + size) % len] = record;
if (size == len) {
start = (start + 1) % len;
} else {
size++;
}
}
}

Expand All @@ -114,9 +99,7 @@ public List<LogRecord> getView() {
public LogRecord get(int index) {
// flip the order
synchronized (RingBufferLogHandler.this) {
LogRecord r = records[(start + (size - (index + 1))) % records.length].get();
// We cannot just omit collected entries due to the List interface.
return r != null ? r : new LogRecord(Level.OFF, "<discarded>");
return records[(start + (size - (index + 1))) % records.length];
}
}

Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/jenkins/model/lazy/LazyBuildMixIn.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ public RunT create(File dir) throws IOException {

/**
* Loads an existing build record from disk.
* The default implementation just calls the ({@link Job}, {@link File}) constructor of {@link #getBuildClass}.
* The default implementation just calls the ({@link Job}, {@link File}) constructor of {@link #getBuildClass},
* which will call {@link Run#Run(Job, File)}.
*/
public RunT loadBuild(File dir) throws IOException {
try {
Expand All @@ -174,7 +175,7 @@ public RunT loadBuild(File dir) throws IOException {

/**
* Creates a new build of this project for immediate execution.
* Calls the ({@link Job}) constructor of {@link #getBuildClass}.
* Calls the ({@link Job}) constructor of {@link #getBuildClass}, which will call {@link Run#Run(Job)}.
* Suitable for {@link SubTask#createExecutable}.
*/
public final synchronized RunT newBuild() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ newerVersionEntry=\
unavailable=Unavailable

deprecationWarning=<strong>This plugin is deprecated.</strong> In general, this means that it is either obsolete, no longer being developed, or may no longer work. <a href="{0}" rel="noopener noreferrer" target="_blank">Learn more.</a>
loading=Loading
100 changes: 54 additions & 46 deletions core/src/main/resources/hudson/diagnosis/OldDataMonitor/manage.jelly
Original file line number Diff line number Diff line change
Expand Up @@ -30,39 +30,43 @@ THE SOFTWARE.
<h1>${%Manage Old Data}</h1>
<p>${%blurb.1}</p>
<p>${%blurb.2}</p>
<table class="sortable pane bigtable width-auto">
<tr>
<th initialSortDir="down">${%Type}</th>
<th>${%Name}</th>
<th>${%Version}</th>
<th>${%Error}</th>
</tr>
<j:forEach var="item" items="${it.data.entrySet()}">
<j:set var="obj" value="${item.key}"/>
<j:choose>
<j:when test="${item.value!=''}">
<tr>
<td>${obj.class.name}</td>
<!-- fullName is first to avoid calling User.get(String) for User object -->
<td>${obj.fullName?:obj.fullDisplayName?:obj.displayName?:obj.name}</td>
<td>
<j:choose>
<j:when test="${item.value.isOld(150)}">
<b title="${%Very old version}">${item.value}</b>
</j:when>
<j:otherwise>
${item.value}
</j:otherwise>
</j:choose>
</td>
<td style="white-space:normal">${item.value.extra}</td>
</tr>
</j:when>
<j:otherwise>
<j:if test="${item.value.extra!=null}"><j:set var="hasExtra" value="${true}"/></j:if>
</j:otherwise>
</j:choose>
</j:forEach>
<table class="jenkins-table sortable">
<thead>
<tr>
<th initialSortDir="down">${%Type}</th>
<th>${%Name}</th>
<th>${%Version}</th>
<th>${%Error}</th>
</tr>
</thead>
<tbody>
<j:forEach var="item" items="${it.data.entrySet()}">
<j:set var="obj" value="${item.key}"/>
<j:choose>
<j:when test="${item.value!=''}">
<tr>
<td>${obj.class.name}</td>
<!-- fullName is first to avoid calling User.get(String) for User object -->
<td>${obj.fullName?:obj.fullDisplayName?:obj.displayName?:obj.name}</td>
<td>
<j:choose>
<j:when test="${item.value.isOld(150)}">
<b title="${%Very old version}">${item.value}</b>
</j:when>
<j:otherwise>
${item.value}
</j:otherwise>
</j:choose>
</td>
<td style="white-space:normal">${item.value.extra}</td>
</tr>
</j:when>
<j:otherwise>
<j:if test="${item.value.extra!=null}"><j:set var="hasExtra" value="${true}"/></j:if>
</j:otherwise>
</j:choose>
</j:forEach>
</tbody>
</table>
<j:set var="vers" value="${it.versionList}"/>
<j:choose>
Expand Down Expand Up @@ -90,22 +94,26 @@ THE SOFTWARE.
<br/>
<h2>${%Unreadable Data}</h2>
<p>${%blurb.6}</p>
<table class="sortable pane bigtable width-auto">
<tr>
<table class="jenkins-table sortable">
<thead>
<tr>
<th initialSortDir="down">${%Type}</th>
<th>${%Name}</th>
<th>${%Error}</th>
</tr>
<j:forEach var="item" items="${it.data.entrySet()}">
<j:if test="${item.value.extra!=null and item.value==''}">
<j:set var="obj" value="${item.key}"/>
<tr>
<td>${obj.class.name}</td>
<td>${obj.fullName?:obj.fullDisplayName?:obj.displayName?:obj.name}</td>
<td style="white-space:normal">${item.value.extra}</td>
</tr>
</j:if>
</j:forEach>
</tr>
</thead>
<tbody>
<j:forEach var="item" items="${it.data.entrySet()}">
<j:if test="${item.value.extra!=null and item.value==''}">
<j:set var="obj" value="${item.key}"/>
<tr>
<td>${obj.class.name}</td>
<td>${obj.fullName?:obj.fullDisplayName?:obj.displayName?:obj.name}</td>
<td style="white-space:normal">${item.value.extra}</td>
</tr>
</j:if>
</j:forEach>
</tbody>
</table>
<br/>
<form action="discard" method="POST" name="discardUnreadable">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ THE SOFTWARE.
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:s="/lib/form">
<l:ajax>
<t:executors computers="${h.singletonList(it)}" />
<t:executors computers="${[it]}"/>
</l:ajax>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ THE SOFTWARE.
<j:forEach var="box" items="${it.computerPanelBoxs}">
<st:include it="${box}" page="box.jelly" />
</j:forEach>
<t:executors computers="${h.singletonList(it)}" />
<t:executors computers="${[it]}"/>
</l:side-panel>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ name={0} name
Save=Save
Apply=Apply
Config={0} Config
LOADING=Loading
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
# THE SOFTWARE.

description=This build requires parameters:
LOADING=Loading
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
LOADING=Loading
6 changes: 3 additions & 3 deletions core/src/main/resources/hudson/model/UpdateCenter/body.jelly
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ THE SOFTWARE.
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<l:ajax>

<table id="log">
<j:forEach var="i" items="${it.jobs}">
<st:include it="${i}" page="row.jelly" />
</j:forEach>
</table>

<div id="scheduleRestartBlock" style="padding-top:2em">
<form method="post" id="scheduleRestart" action="">
<p class="info" style="font-weight: normal">
Expand All @@ -49,7 +49,7 @@ THE SOFTWARE.
<l:icon class="icon-red icon-md"/>
<l:icon class="icon-nobuilt icon-md"/>
</div>
<p class="info" style="font-weight: normal">
<p class="info jenkins-checkbox" style="font-weight: normal">
<j:if test="${app.lifecycle.canRestart()}">
<j:if test="${app.isQuietingDown() or it.isRestartScheduled()}">
<input id="scheduleRestartCheckbox" onchange="submitScheduleForm(this)" type="checkbox" checked="checked" />
Expand Down
Loading

0 comments on commit 6e64c68

Please sign in to comment.