Skip to content

Commit 5a599d6

Browse files
committed
Merge branch 'master' into new-reorderable-list
2 parents a6025d5 + 2dc2c4b commit 5a599d6

16 files changed

+107
-310
lines changed

.mvn/extensions.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
<extension>
33
<groupId>io.jenkins.tools.incrementals</groupId>
44
<artifactId>git-changelist-maven-extension</artifactId>
5-
<version>1.8</version>
5+
<version>1.10</version>
66
</extension>
77
</extensions>

pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<parent>
3030
<groupId>org.jenkins-ci.plugins</groupId>
3131
<artifactId>plugin</artifactId>
32-
<version>5.3</version>
32+
<version>5.18</version>
3333
<relativePath/>
3434
</parent>
3535

@@ -69,8 +69,8 @@
6969
<changelist>999999-SNAPSHOT</changelist>
7070
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
7171
<!-- https://www.jenkins.io/doc/developer/plugin-development/choosing-jenkins-baseline/ -->
72-
<jenkins.baseline>2.479</jenkins.baseline>
73-
<jenkins.version>2.494-rc35897.275e517b_f858</jenkins.version>
72+
<jenkins.baseline>2.504</jenkins.baseline>
73+
<jenkins.version>${jenkins.baseline}.1</jenkins.version>
7474

7575
<hpi.compatibleSinceVersion>2.0.0</hpi.compatibleSinceVersion>
7676
<no-test-jar>false</no-test-jar>
@@ -81,7 +81,7 @@
8181
<dependency>
8282
<groupId>io.jenkins.tools.bom</groupId>
8383
<artifactId>bom-${jenkins.baseline}.x</artifactId>
84-
<version>3893.v213a_42768d35</version>
84+
<version>5043.v855ff4819a_0f</version>
8585
<type>pom</type>
8686
<scope>import</scope>
8787
</dependency>

src/main/java/jenkins/branch/MetadataActionFolderIcon.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ protected void setOwner(AbstractFolder<?> folder) {
7171
public String getIconClassName() {
7272
if (owner != null) {
7373
if (owner.isDisabled()) {
74-
return "icon-folder-disabled";
74+
return "symbol-folder-disabled-outline plugin-branch-api";
7575
}
7676
AvatarMetadataAction action = owner.getAction(AvatarMetadataAction.class);
7777
if (action != null) {
@@ -100,11 +100,9 @@ public String getIconClassName() {
100100
}
101101
// otherwise the metadata doesn't want to control the icon, so fall back to the descriptor's default
102102
}
103-
if (owner instanceof IconSpec) {
104-
String result = ((IconSpec) owner).getIconClassName();
105-
if (result != null) {
106-
return result;
107-
}
103+
String result = ((IconSpec) owner).getIconClassName();
104+
if (result != null) {
105+
return result;
108106
}
109107
return owner.getDescriptor().getIconClassName();
110108
}

src/main/java/jenkins/branch/MultiBranchProject.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
package jenkins.branch;
2626

27-
import com.cloudbees.hudson.plugins.folder.ChildNameGenerator;
2827
import com.cloudbees.hudson.plugins.folder.FolderIcon;
2928
import com.cloudbees.hudson.plugins.folder.computed.ChildObserver;
3029
import com.cloudbees.hudson.plugins.folder.computed.ComputedFolder;
@@ -131,7 +130,6 @@ public abstract class MultiBranchProject<P extends Job<P, R> & TopLevelItem,
131130
R extends Run<P, R>>
132131
extends ComputedFolder<P> implements SCMSourceOwner, IconSpec {
133132

134-
@SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "Accessible via System Groovy Scripts")
135133
private static /* not final */ boolean FIRE_SCM_SOURCE_BUILDS_AFTER_SAVE =
136134
SystemProperties.getBoolean(MultiBranchProject.class.getName() + ".fireSCMSourceBuildsAfterSave", true);
137135

@@ -2093,21 +2091,16 @@ private void observeExisting(@NonNull SCMHead head, @NonNull SCMRevision revisio
20932091
}
20942092

20952093
private void observeNew(@NonNull SCMHead head, @NonNull SCMRevision revision, @NonNull Branch branch, String rawName, String encodedName, Action[] revisionActions) {
2096-
P project;
20972094
if (!observer.mayCreate(encodedName)) {
20982095
listener.getLogger().println("Ignoring duplicate branch project " + rawName);
20992096
return;
21002097
}
2101-
try (ChildNameGenerator.Trace trace = ChildNameGenerator.beforeCreateItem(
2102-
MultiBranchProject.this, encodedName, branch.getName()
2103-
)) {
2104-
if (getItem(encodedName) != null) {
2105-
throw new IllegalStateException(
2106-
"JENKINS-42511: attempted to redundantly create " + encodedName + " in "
2107-
+ MultiBranchProject.this);
2108-
}
2109-
project = _factory.newInstance(branch);
2098+
if (getItem(encodedName) != null) {
2099+
throw new IllegalStateException(
2100+
"JENKINS-42511: attempted to redundantly create " + encodedName + " in "
2101+
+ MultiBranchProject.this);
21102102
}
2103+
P project = _factory.newInstance(branch);
21112104
if (!project.getName().equals(encodedName)) {
21122105
throw new IllegalStateException(
21132106
"Name of created project " + project + " did not match expected " + encodedName);

src/main/java/jenkins/branch/MultiBranchProjectDescriptor.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import hudson.model.Run;
3535
import hudson.model.TopLevelItem;
3636
import hudson.model.TopLevelItemDescriptor;
37-
import java.io.IOException;
3837
import java.lang.reflect.ParameterizedType;
3938
import java.lang.reflect.Type;
4039
import java.util.ArrayList;
@@ -231,9 +230,9 @@ public String itemNameFromItem(@NonNull MultiBranchProject<P,R> parent, @NonNull
231230
if (factory.isProject(item)) {
232231
return NameEncoder.encode(factory.getBranch(item).getName());
233232
}
234-
String idealName = idealNameFromItem(parent, item);
235-
if (idealName != null) {
236-
return NameEncoder.encode(idealName);
233+
String name = item.getName();
234+
if (name != null) {
235+
return NameEncoder.encode(name);
237236
}
238237
return null;
239238
}
@@ -245,9 +244,9 @@ public String dirNameFromItem(@NonNull MultiBranchProject<P,R> parent, @NonNull
245244
if (factory.isProject(item)) {
246245
return NameMangler.apply(factory.getBranch(item).getName());
247246
}
248-
String idealName = idealNameFromItem(parent, item);
249-
if (idealName != null) {
250-
return NameMangler.apply(idealName);
247+
String name = item.getName();
248+
if (name != null) {
249+
return NameMangler.apply(name);
251250
}
252251
return null;
253252
}
@@ -263,12 +262,5 @@ public String itemNameFromLegacy(@NonNull MultiBranchProject<P, R> parent, @NonN
263262
public String dirNameFromLegacy(@NonNull MultiBranchProject<P, R> parent, @NonNull String legacyDirName) {
264263
return NameMangler.apply(NameEncoder.decode(legacyDirName));
265264
}
266-
267-
@Override
268-
public void recordLegacyName(MultiBranchProject<P, R> parent, P item, String legacyDirName) throws IOException {
269-
// no-op because we already tracked the name in Branch.getName()
270-
}
271-
272265
}
273-
274266
}

src/main/java/jenkins/branch/OrganizationFolder.java

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -852,9 +852,9 @@ public String itemNameFromItem(@NonNull OrganizationFolder parent, @NonNull Mult
852852
if (property != null) {
853853
return NameEncoder.encode(property.getName());
854854
}
855-
String idealName = idealNameFromItem(parent, item);
856-
if (idealName != null) {
857-
return NameEncoder.encode(idealName);
855+
String name = item.getName();
856+
if (name != null) {
857+
return NameEncoder.encode(name);
858858
}
859859
return null;
860860
}
@@ -866,9 +866,9 @@ public String dirNameFromItem(@NonNull OrganizationFolder parent, @NonNull Multi
866866
if (property != null) {
867867
return NameMangler.apply(property.getName());
868868
}
869-
String idealName = idealNameFromItem(parent, item);
870-
if (idealName != null) {
871-
return NameMangler.apply(idealName);
869+
String name = item.getName();
870+
if (name != null) {
871+
return NameMangler.apply(name);
872872
}
873873
return null;
874874
}
@@ -884,12 +884,6 @@ public String itemNameFromLegacy(@NonNull OrganizationFolder parent, @NonNull St
884884
public String dirNameFromLegacy(@NonNull OrganizationFolder parent, @NonNull String legacyDirName) {
885885
return NameMangler.apply(NameEncoder.decode(legacyDirName));
886886
}
887-
888-
@Override
889-
public void recordLegacyName(OrganizationFolder parent, MultiBranchProject<?, ?> item, String legacyDirName)
890-
throws IOException {
891-
item.addProperty(new ProjectNameProperty(legacyDirName));
892-
}
893887
}
894888

895889
/**
@@ -1436,19 +1430,14 @@ private void completeNew(MultiBranchProjectFactory factory, Map<String, Object>
14361430
.println("Ignoring duplicate child " + projectName + " named " + folderName);
14371431
return;
14381432
}
1439-
MultiBranchProject<?, ?> project;
1440-
try (ChildNameGenerator.Trace trace = ChildNameGenerator.beforeCreateItem(
1441-
OrganizationFolder.this, folderName, projectName
1442-
)) {
1443-
if (getItem(folderName) != null) {
1444-
throw new IllegalStateException(
1445-
"JENKINS-42511: attempted to redundantly create " + folderName + " in "
1446-
+ OrganizationFolder.this);
1447-
}
1448-
project = factory.createNewProject(
1449-
OrganizationFolder.this, folderName, sources, attributes, listener
1450-
);
1433+
if (getItem(folderName) != null) {
1434+
throw new IllegalStateException(
1435+
"JENKINS-42511: attempted to redundantly create " + folderName + " in "
1436+
+ OrganizationFolder.this);
14511437
}
1438+
MultiBranchProject<?, ?> project = factory.createNewProject(
1439+
OrganizationFolder.this, folderName, sources, attributes, listener
1440+
);
14521441
BulkChange bc = new BulkChange(project);
14531442
try {
14541443
if (!projectName.equals(folderName)) {

src/main/java/jenkins/branch/WorkspaceLocatorImpl.java

Lines changed: 44 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
import hudson.security.ACLContext;
4444
import hudson.slaves.ComputerListener;
4545
import hudson.slaves.WorkspaceList;
46+
import hudson.util.ClassLoaderSanityThreadFactory;
47+
import hudson.util.DaemonThreadFactory;
48+
import hudson.util.ExceptionCatchingThreadFactory;
49+
import hudson.util.NamingThreadFactory;
4650
import hudson.util.TextFile;
4751
import java.io.BufferedReader;
4852
import java.io.File;
@@ -53,23 +57,31 @@
5357
import java.nio.charset.StandardCharsets;
5458
import java.security.MessageDigest;
5559
import java.security.NoSuchAlgorithmException;
56-
import java.util.concurrent.Semaphore;
60+
import java.util.concurrent.ExecutorService;
5761
import java.util.Iterator;
5862
import java.util.LinkedList;
5963
import java.util.List;
6064
import java.util.Map;
6165
import java.util.Queue;
6266
import java.util.TreeMap;
6367
import java.util.WeakHashMap;
68+
import java.util.concurrent.LinkedBlockingQueue;
69+
import java.util.concurrent.SynchronousQueue;
70+
import java.util.concurrent.ThreadPoolExecutor;
6471
import java.util.concurrent.TimeUnit;
6572
import java.util.logging.Level;
6673
import java.util.logging.Logger;
6774
import java.util.regex.Matcher;
6875
import java.util.regex.Pattern;
76+
import java.util.stream.Collectors;
77+
import java.util.stream.Stream;
6978
import edu.umd.cs.findbugs.annotations.CheckForNull;
7079
import jenkins.MasterToSlaveFileCallable;
7180
import jenkins.model.Jenkins;
81+
import jenkins.security.ImpersonatingExecutorService;
7282
import jenkins.slaves.WorkspaceLocator;
83+
import jenkins.util.ContextResettingExecutorService;
84+
import jenkins.util.ErrorLoggingExecutorService;
7385
import jenkins.util.SystemProperties;
7486
import org.apache.commons.codec.binary.Base32;
7587
import org.apache.commons.lang.StringUtils;
@@ -380,24 +392,49 @@ static String minimize(String name) {
380392
@Extension
381393
public static class Deleter extends ItemListener {
382394

383-
private static /* almost final */ int CLEANUP_THREAD_LIMIT = SystemProperties.getInteger(Deleter.class.getName() + ".CLEANUP_THREAD_LIMIT", Integer.valueOf(0)).intValue();
395+
private static final int CLEANUP_THREAD_LIMIT = SystemProperties.getInteger(Deleter.class.getName() + ".CLEANUP_THREAD_LIMIT", 0);
384396

385-
/** Semaphore for limiting number of scheduled {@link CleanupTask} */
386-
private static Semaphore cleanupPool = new Semaphore(CLEANUP_THREAD_LIMIT, true);
397+
private static final ExecutorService executorService = executorService();
387398

388399
/** Number of {@link CleanupTask} which have been scheduled but not yet completed. */
389400
private static int runningTasks;
390401

402+
private static ExecutorService executorService() {
403+
if (CLEANUP_THREAD_LIMIT > 0) {
404+
ThreadPoolExecutor tpe = new ThreadPoolExecutor(CLEANUP_THREAD_LIMIT, CLEANUP_THREAD_LIMIT, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
405+
new ExceptionCatchingThreadFactory(
406+
new NamingThreadFactory(
407+
new ClassLoaderSanityThreadFactory(new DaemonThreadFactory()),
408+
"Deleter.cleanupTask")));
409+
// Use allowCoreThreadTimeOut to keep a lightweight ThreadPoolExecutor. The Thread pool grows to the
410+
// limit and then queue tasks. Thread will then be removed when idle
411+
tpe.allowCoreThreadTimeOut(true);
412+
return new ContextResettingExecutorService(
413+
new ImpersonatingExecutorService(
414+
new ErrorLoggingExecutorService(tpe),
415+
ACL.SYSTEM2));
416+
} else {
417+
return Computer.threadPoolForRemoting;
418+
}
419+
}
420+
391421
@Override
392422
public void onDeleted(Item item) {
393423
if (!(item instanceof TopLevelItem)) {
394424
return;
395425
}
396426
TopLevelItem tli = (TopLevelItem) item;
397427
Jenkins jenkins = Jenkins.get();
398-
Computer.threadPoolForRemoting.submit(new CleanupTask(tli, jenkins));
399-
// Starts provisioner Thread which is tasked with starting cleanup Threads
400-
new CleanupTaskProvisioner(tli, jenkins.getNodes()).run();
428+
Queue<Node> nodes = Stream
429+
.concat(Stream.of(jenkins), jenkins.getNodes().stream())
430+
.collect(Collectors.toCollection(LinkedList::new));
431+
try {
432+
while (!nodes.isEmpty()){
433+
executorService.execute(new CleanupTask(tli, nodes.remove()));
434+
}
435+
} catch (Exception e) {
436+
LOGGER.log(Level.WARNING, e.getMessage());
437+
}
401438
}
402439

403440
@Override
@@ -412,20 +449,6 @@ public void onLocationChanged(Item item, String oldFullName, String newFullName)
412449
}
413450
}
414451

415-
public void acquireThread() throws InterruptedException {
416-
if (CLEANUP_THREAD_LIMIT <= 0) {
417-
return;
418-
}
419-
cleanupPool.acquire();
420-
}
421-
422-
public void releaseThread() {
423-
if (CLEANUP_THREAD_LIMIT <= 0) {
424-
return;
425-
}
426-
cleanupPool.release();
427-
}
428-
429452
// Visible for testing
430453
static synchronized void waitForTasksToFinish() throws InterruptedException {
431454
while (runningTasks > 0) {
@@ -442,36 +465,6 @@ private static synchronized void taskFinished() {
442465
Deleter.class.notifyAll();
443466
}
444467

445-
private static class CleanupTaskProvisioner implements Runnable{
446-
447-
@NonNull
448-
private final TopLevelItem tli;
449-
450-
@NonNull
451-
private final Queue<Node> nodes;
452-
453-
@NonNull
454-
private final Deleter deleter;
455-
456-
public CleanupTaskProvisioner(TopLevelItem tli, List<Node> nodes) {
457-
this.tli = tli;
458-
this.nodes = new LinkedList<>(nodes);
459-
this.deleter = ExtensionList.lookupSingleton(Deleter.class);
460-
}
461-
462-
@Override
463-
public void run() {
464-
try {
465-
while (!nodes.isEmpty()){
466-
deleter.acquireThread();
467-
Computer.threadPoolForRemoting.submit(new CleanupTask(tli, nodes.remove()));
468-
}
469-
} catch (Exception e) {
470-
LOGGER.log(Level.WARNING, e.getMessage());
471-
}
472-
}
473-
}
474-
475468
private static class CleanupTask implements Runnable {
476469

477470
@NonNull
@@ -480,13 +473,9 @@ private static class CleanupTask implements Runnable {
480473
@NonNull
481474
private final Node node;
482475

483-
@NonNull
484-
private final Deleter deleter;
485-
486476
CleanupTask(TopLevelItem tli, Node node) {
487477
this.tli = tli;
488478
this.node = node;
489-
this.deleter = ExtensionList.lookupSingleton(Deleter.class);
490479
taskStarted();
491480
}
492481

@@ -529,7 +518,6 @@ public void run() {
529518
}
530519
} finally {
531520
t.setName(oldName);
532-
deleter.releaseThread();
533521
taskFinished();
534522
}
535523
}

0 commit comments

Comments
 (0)