From de2bf198c9eb02869e055a970a79e6ff88fa5402 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Fri, 22 Nov 2019 14:17:40 +0100 Subject: [PATCH 01/12] Add extensible background build discarders Default implementation: Run per-job configured discarder periodically --- .../model/BackgroundBuildDiscarder.java | 77 +++++++++++++++++ .../BackgroundBuildDiscarderStrategy.java | 82 +++++++++++++++++++ ...roundBuildDiscarderStrategyDescriptor.java | 37 +++++++++ ...faultBackgroundBuildDiscarderStrategy.java | 65 +++++++++++++++ .../GlobalBuildDiscarderConfiguration.java | 72 ++++++++++++++++ .../model/GlobalBuildDiscarderStrategy.java | 71 ++++++++++++++++ .../resources/hudson/model/Run/logKeep.jelly | 2 +- .../config.jelly | 27 ++++++ .../config.groovy | 33 ++++++++ .../GlobalBuildDiscarderStrategy/config.jelly | 4 + 10 files changed, 469 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java create mode 100644 core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java create mode 100644 core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategyDescriptor.java create mode 100644 core/src/main/java/jenkins/model/DefaultBackgroundBuildDiscarderStrategy.java create mode 100644 core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java create mode 100644 core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java create mode 100644 core/src/main/resources/jenkins/model/DefaultBackgroundBuildDiscarderStrategy/config.jelly create mode 100644 core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy create mode 100644 core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.jelly diff --git a/core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java b/core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java new file mode 100644 index 000000000000..447c3b559429 --- /dev/null +++ b/core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java @@ -0,0 +1,77 @@ +/* + * The MIT License + * + * Copyright 2019 Daniel Beck + * + * 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 jenkins.model; + +import hudson.Extension; +import hudson.model.AsyncPeriodicWork; +import hudson.model.Job; +import hudson.model.TaskListener; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.io.IOException; +import java.util.function.Consumer; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Background task actually running background build discarders. + * + * @see GlobalBuildDiscarderConfiguration + * @see BackgroundBuildDiscarderStrategy + */ +@Restricted(NoExternalUse.class) +@Extension +public class BackgroundBuildDiscarder extends AsyncPeriodicWork { + private static final Logger LOGGER = Logger.getLogger(BackgroundBuildDiscarder.class.getName()); + + public BackgroundBuildDiscarder() { + super("Periodic background build discarder"); // TODO i18n + } + + @Override + protected void execute(TaskListener listener) throws IOException, InterruptedException { + for (Job job : Jenkins.get().allItems(Job.class)) { + listener.getLogger().println("Processing " + job.getFullName()); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().forEach(strategy -> { + String displayName = strategy.getDescriptor().getDisplayName(); + listener.getLogger().println("Offering " + job.getFullName() + " to " + displayName); + if (strategy.isApplicable(job)) { + listener.getLogger().println(job.getFullName() + " accepted by " + displayName); + try { + strategy.apply(job); + } catch (Exception ex) { + listener.error("An exception occurred when executing " + displayName + ": " + ex.getMessage()); + LOGGER.log(Level.WARNING, "An exception occurred when executing " + displayName, ex); + } + } + }); + } + } + + @Override + public long getRecurrencePeriod() { + return HOUR; + } +} diff --git a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java new file mode 100644 index 000000000000..164a818b3594 --- /dev/null +++ b/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java @@ -0,0 +1,82 @@ +/* + * The MIT License + * + * Copyright 2019 Daniel Beck + * + * 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 jenkins.model; + +import hudson.ExtensionPoint; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Job; +import hudson.model.Run; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Extension point for global background build discarders. + * + * @see BackgroundBuildDiscarder + * @see GlobalBuildDiscarderConfiguration + * @see DefaultBackgroundBuildDiscarderStrategy + */ +public abstract class BackgroundBuildDiscarderStrategy extends AbstractDescribableImpl implements ExtensionPoint { + private static final Logger LOGGER = Logger.getLogger(BackgroundBuildDiscarderStrategy.class.getName()); + + /** + * Returns true if and only if this strategy applies to the given job. + * @param job + * @return true if and only if this strategy applies to the given job. + */ + public abstract boolean isApplicable(Job job); + + /** + * Applies this build discarder strategy to the given job, i.e. delete builds based on this strategy's configuration. + * + * The default implementation calls {@link #apply(Run)} on each build. + * + * @param job + * @throws IOException + * @throws InterruptedException + */ + public void apply(Job job) throws IOException, InterruptedException { + job.getBuilds().forEach(run -> { + try { + apply(run); + } catch (IOException|InterruptedException ex) { + // TODO should these actually be caught, or just thrown up to stop applying? + LOGGER.log(Level.WARNING, "Failed to delete " + run.getFullDisplayName(), ex); + } + }); + } + + /** + * Applies this build discarder strategy to the given run, i.e. delete builds based on this strategy's configuration. + * + * @param run + * @throws IOException + * @throws InterruptedException + */ + public void apply(Run run) throws IOException, InterruptedException { + // no-op by default + } +} diff --git a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategyDescriptor.java b/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategyDescriptor.java new file mode 100644 index 000000000000..c8d73e7205b7 --- /dev/null +++ b/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategyDescriptor.java @@ -0,0 +1,37 @@ +/* + * The MIT License + * + * Copyright 2019 Daniel Beck + * + * 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 jenkins.model; + +import hudson.DescriptorExtensionList; +import hudson.model.Descriptor; + +/** + * {@link Descriptor} for {@link BackgroundBuildDiscarder}. + */ +public abstract class BackgroundBuildDiscarderStrategyDescriptor extends Descriptor { + + public static DescriptorExtensionList all() { + return Jenkins.get().getDescriptorList(BackgroundBuildDiscarderStrategy.class); + } +} diff --git a/core/src/main/java/jenkins/model/DefaultBackgroundBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/DefaultBackgroundBuildDiscarderStrategy.java new file mode 100644 index 000000000000..4b8c1eaea707 --- /dev/null +++ b/core/src/main/java/jenkins/model/DefaultBackgroundBuildDiscarderStrategy.java @@ -0,0 +1,65 @@ +/* + * The MIT License + * + * Copyright 2019 Daniel Beck + * + * 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 jenkins.model; + +import hudson.Extension; +import hudson.model.Job; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import java.io.IOException; + +/** + * Periodically call a job's configured build discarder in the background. + */ +@Restricted(NoExternalUse.class) +public class DefaultBackgroundBuildDiscarderStrategy extends BackgroundBuildDiscarderStrategy { + + @DataBoundConstructor + public DefaultBackgroundBuildDiscarderStrategy() { + // required for data binding + } + + @Override + public boolean isApplicable(Job job) { + return job.getBuildDiscarder() != null; + } + + @Override + public void apply(Job job) throws IOException, InterruptedException { + job.logRotate(); + } + + @Extension @Symbol("jobBuildDiscarder") + public static class DescriptorImpl extends BackgroundBuildDiscarderStrategyDescriptor { + @Nonnull + @Override + public String getDisplayName() { + return "Periodically run project-specific build discarder"; // TODO i18n + } + } +} diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java new file mode 100644 index 000000000000..572c3d332929 --- /dev/null +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java @@ -0,0 +1,72 @@ +/* + * The MIT License + * + * Copyright 2019 Daniel Beck + * + * 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 jenkins.model; + +import hudson.Extension; +import hudson.ExtensionList; +import hudson.util.DescribableList; +import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.StaplerRequest; + +import java.io.IOException; +import java.util.Collections; + +/** + * Global configuration UI for background build discarders + * + * @see BackgroundBuildDiscarderStrategy + * @see BackgroundBuildDiscarder + */ +@Restricted(NoExternalUse.class) +@Extension @Symbol("globalBuildDiscarders") +public class GlobalBuildDiscarderConfiguration extends GlobalConfiguration { + public static GlobalBuildDiscarderConfiguration get() { + return ExtensionList.lookupSingleton(GlobalBuildDiscarderConfiguration.class); + } + + private final DescribableList configuredBuildDiscarders = + new DescribableList<>(this, Collections.singletonList(new DefaultBackgroundBuildDiscarderStrategy())); + + private Object readResolve() { + configuredBuildDiscarders.setOwner(this); + return this; + } + + public DescribableList getConfiguredBuildDiscarders() { + return configuredBuildDiscarders; + } + + @Override + public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + try { + configuredBuildDiscarders.rebuildHetero(req, json, BackgroundBuildDiscarderStrategyDescriptor.all(), "configuredBuildDiscarders"); + return true; + } catch (IOException x) { + throw new FormException(x, "artifactManagerFactories"); + } + } +} diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java new file mode 100644 index 000000000000..d314234e3e2e --- /dev/null +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java @@ -0,0 +1,71 @@ +/* + * The MIT License + * + * Copyright 2019 Daniel Beck + * + * 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 jenkins.model; + +import hudson.Extension; +import hudson.model.Job; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; + +import javax.annotation.Nonnull; +import java.io.IOException; + +/** + * Apply a user-specified build discarder periodically on all jobs. + */ +public class GlobalBuildDiscarderStrategy extends BackgroundBuildDiscarderStrategy { + + private BuildDiscarder discarder; + + @DataBoundConstructor + public GlobalBuildDiscarderStrategy(BuildDiscarder discarder) { + this.discarder = discarder; + } + + public BuildDiscarder getDiscarder() { + return discarder; + } + + @Override + public boolean isApplicable(Job job) { + return true; + } + + @Override + public void apply(Job job) throws IOException, InterruptedException { + if (discarder != null) { + discarder.perform(job); + } + } + + @Extension + @Symbol("globalBuildDiscarder") + public static class DescriptorImpl extends BackgroundBuildDiscarderStrategyDescriptor { + @Nonnull + @Override + public String getDisplayName() { + return "Periodically run custom build discarder"; // TODO i18n + } + } +} diff --git a/core/src/main/resources/hudson/model/Run/logKeep.jelly b/core/src/main/resources/hudson/model/Run/logKeep.jelly index 19ccd4820fc3..ded35123d484 100644 --- a/core/src/main/resources/hudson/model/Run/logKeep.jelly +++ b/core/src/main/resources/hudson/model/Run/logKeep.jelly @@ -27,7 +27,7 @@ THE SOFTWARE. --> - +
diff --git a/core/src/main/resources/jenkins/model/DefaultBackgroundBuildDiscarderStrategy/config.jelly b/core/src/main/resources/jenkins/model/DefaultBackgroundBuildDiscarderStrategy/config.jelly new file mode 100644 index 000000000000..e60a13a6c7d6 --- /dev/null +++ b/core/src/main/resources/jenkins/model/DefaultBackgroundBuildDiscarderStrategy/config.jelly @@ -0,0 +1,27 @@ + + + + + diff --git a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy new file mode 100644 index 000000000000..7b53dbfa1ec6 --- /dev/null +++ b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy @@ -0,0 +1,33 @@ +/* + * The MIT License + * + * Copyright 2019 Daniel Beck + * + * 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 jenkins.model.GlobalBuildDiscarderConfiguration + +f = namespace(lib.FormTagLib) + +f.section(title: _("Periodically Run Build Discarders")) { + f.block() { + f.repeatableHeteroProperty(field: "configuredBuildDiscarders", hasHeader: true) + } +} diff --git a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.jelly b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.jelly new file mode 100644 index 000000000000..6f12ad680fcb --- /dev/null +++ b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.jelly @@ -0,0 +1,4 @@ + + + + From 6795cd7c6aaaa11ab58b5ab70de2c8ef7e9aef17 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Tue, 26 Nov 2019 12:04:54 +0100 Subject: [PATCH 02/12] Prevent use of the specific strategy from plugins --- .../main/java/jenkins/model/GlobalBuildDiscarderStrategy.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java index d314234e3e2e..84e604bc2962 100644 --- a/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java @@ -26,6 +26,8 @@ import hudson.Extension; import hudson.model.Job; import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; import javax.annotation.Nonnull; @@ -34,6 +36,7 @@ /** * Apply a user-specified build discarder periodically on all jobs. */ +@Restricted(NoExternalUse.class) public class GlobalBuildDiscarderStrategy extends BackgroundBuildDiscarderStrategy { private BuildDiscarder discarder; From 326ca35db5e9b246cd4769d726c414384359c2e7 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 8 Dec 2019 18:59:30 +0100 Subject: [PATCH 03/12] Apply global discarders after build finalization, i18n, etc. --- .../model/BackgroundBuildDiscarder.java | 33 +++--- .../BackgroundBuildDiscarderListener.java | 28 +++++ .../BackgroundBuildDiscarderStrategy.java | 2 +- .../GlobalBuildDiscarderConfiguration.java | 4 +- .../model/GlobalBuildDiscarderStrategy.java | 2 +- ... JobBackgroundBuildDiscarderStrategy.java} | 6 +- .../config.groovy | 2 +- .../GlobalBuildDiscarderStrategy/config.jelly | 3 + .../config.properties | 1 + .../config.jelly | 5 +- .../config.properties | 3 + .../jenkins/model/Messages.properties | 3 + .../model/GlobalBuildDiscarderTest.java | 109 ++++++++++++++++++ 13 files changed, 177 insertions(+), 24 deletions(-) create mode 100644 core/src/main/java/jenkins/model/BackgroundBuildDiscarderListener.java rename core/src/main/java/jenkins/model/{DefaultBackgroundBuildDiscarderStrategy.java => JobBackgroundBuildDiscarderStrategy.java} (89%) create mode 100644 core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.properties rename core/src/main/resources/jenkins/model/{DefaultBackgroundBuildDiscarderStrategy => JobBackgroundBuildDiscarderStrategy}/config.jelly (91%) create mode 100644 core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties create mode 100644 test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java diff --git a/core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java b/core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java index 447c3b559429..94385940c800 100644 --- a/core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java +++ b/core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java @@ -31,7 +31,6 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import java.io.IOException; -import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; @@ -53,23 +52,27 @@ public BackgroundBuildDiscarder() { @Override protected void execute(TaskListener listener) throws IOException, InterruptedException { for (Job job : Jenkins.get().allItems(Job.class)) { - listener.getLogger().println("Processing " + job.getFullName()); - GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().forEach(strategy -> { - String displayName = strategy.getDescriptor().getDisplayName(); - listener.getLogger().println("Offering " + job.getFullName() + " to " + displayName); - if (strategy.isApplicable(job)) { - listener.getLogger().println(job.getFullName() + " accepted by " + displayName); - try { - strategy.apply(job); - } catch (Exception ex) { - listener.error("An exception occurred when executing " + displayName + ": " + ex.getMessage()); - LOGGER.log(Level.WARNING, "An exception occurred when executing " + displayName, ex); - } - } - }); + processJob(listener, job); } } + public static void processJob(TaskListener listener, Job job) { + listener.getLogger().println("Processing " + job.getFullName()); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().forEach(strategy -> { + String displayName = strategy.getDescriptor().getDisplayName(); + listener.getLogger().println("Offering " + job.getFullName() + " to " + displayName); + if (strategy.isApplicable(job)) { + listener.getLogger().println(job.getFullName() + " accepted by " + displayName); + try { + strategy.apply(job); + } catch (Exception ex) { + listener.error("An exception occurred when executing " + displayName + ": " + ex.getMessage()); + LOGGER.log(Level.WARNING, "An exception occurred when executing " + displayName, ex); + } + } + }); + } + @Override public long getRecurrencePeriod() { return HOUR; diff --git a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderListener.java b/core/src/main/java/jenkins/model/BackgroundBuildDiscarderListener.java new file mode 100644 index 000000000000..fabdcfdddf6d --- /dev/null +++ b/core/src/main/java/jenkins/model/BackgroundBuildDiscarderListener.java @@ -0,0 +1,28 @@ +package jenkins.model; + +import hudson.Extension; +import hudson.model.Job; +import hudson.model.Run; +import hudson.model.listeners.RunListener; +import hudson.util.LogTaskListener; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Run background build discarders on an individual job once a build is finalized + */ +@Extension +@Restricted(NoExternalUse.class) +public class BackgroundBuildDiscarderListener extends RunListener { + + private static final Logger LOGGER = Logger.getLogger(BackgroundBuildDiscarderListener.class.getName()); + + @Override + public void onFinalized(Run run) { + Job job = run.getParent(); + BackgroundBuildDiscarder.processJob(new LogTaskListener(LOGGER, Level.FINE), job); + } +} diff --git a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java index 164a818b3594..2d30141ccfc9 100644 --- a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java +++ b/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java @@ -37,7 +37,7 @@ * * @see BackgroundBuildDiscarder * @see GlobalBuildDiscarderConfiguration - * @see DefaultBackgroundBuildDiscarderStrategy + * @see JobBackgroundBuildDiscarderStrategy */ public abstract class BackgroundBuildDiscarderStrategy extends AbstractDescribableImpl implements ExtensionPoint { private static final Logger LOGGER = Logger.getLogger(BackgroundBuildDiscarderStrategy.class.getName()); diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java index 572c3d332929..7190dcb9d3d8 100644 --- a/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java @@ -42,14 +42,14 @@ * @see BackgroundBuildDiscarder */ @Restricted(NoExternalUse.class) -@Extension @Symbol("globalBuildDiscarders") +@Extension @Symbol("buildDiscarders") public class GlobalBuildDiscarderConfiguration extends GlobalConfiguration { public static GlobalBuildDiscarderConfiguration get() { return ExtensionList.lookupSingleton(GlobalBuildDiscarderConfiguration.class); } private final DescribableList configuredBuildDiscarders = - new DescribableList<>(this, Collections.singletonList(new DefaultBackgroundBuildDiscarderStrategy())); + new DescribableList<>(this, Collections.singletonList(new JobBackgroundBuildDiscarderStrategy())); private Object readResolve() { configuredBuildDiscarders.setOwner(this); diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java index 84e604bc2962..0c35dcf88386 100644 --- a/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java @@ -68,7 +68,7 @@ public static class DescriptorImpl extends BackgroundBuildDiscarderStrategyDescr @Nonnull @Override public String getDisplayName() { - return "Periodically run custom build discarder"; // TODO i18n + return Messages.GlobalBuildDiscarderStrategy_displayName(); } } } diff --git a/core/src/main/java/jenkins/model/DefaultBackgroundBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/JobBackgroundBuildDiscarderStrategy.java similarity index 89% rename from core/src/main/java/jenkins/model/DefaultBackgroundBuildDiscarderStrategy.java rename to core/src/main/java/jenkins/model/JobBackgroundBuildDiscarderStrategy.java index 4b8c1eaea707..fd78c461a29a 100644 --- a/core/src/main/java/jenkins/model/DefaultBackgroundBuildDiscarderStrategy.java +++ b/core/src/main/java/jenkins/model/JobBackgroundBuildDiscarderStrategy.java @@ -37,10 +37,10 @@ * Periodically call a job's configured build discarder in the background. */ @Restricted(NoExternalUse.class) -public class DefaultBackgroundBuildDiscarderStrategy extends BackgroundBuildDiscarderStrategy { +public class JobBackgroundBuildDiscarderStrategy extends BackgroundBuildDiscarderStrategy { @DataBoundConstructor - public DefaultBackgroundBuildDiscarderStrategy() { + public JobBackgroundBuildDiscarderStrategy() { // required for data binding } @@ -59,7 +59,7 @@ public static class DescriptorImpl extends BackgroundBuildDiscarderStrategyDescr @Nonnull @Override public String getDisplayName() { - return "Periodically run project-specific build discarder"; // TODO i18n + return Messages.DefaultBackgroundBuildDiscarderStrategy_displayName(); } } } diff --git a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy index 7b53dbfa1ec6..c650ba02abb7 100644 --- a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy +++ b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy @@ -28,6 +28,6 @@ f = namespace(lib.FormTagLib) f.section(title: _("Periodically Run Build Discarders")) { f.block() { - f.repeatableHeteroProperty(field: "configuredBuildDiscarders", hasHeader: true) + f.repeatableHeteroProperty(field: "configuredBuildDiscarders", hasHeader: true, oneEach: true) } } diff --git a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.jelly b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.jelly index 6f12ad680fcb..8e9f880f9a6f 100644 --- a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.jelly +++ b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.jelly @@ -1,4 +1,7 @@ + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.properties b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.properties new file mode 100644 index 000000000000..b5f8d3fa8657 --- /dev/null +++ b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.properties @@ -0,0 +1 @@ +blurb = The selected build discarder with be run periodically for all jobs. diff --git a/core/src/main/resources/jenkins/model/DefaultBackgroundBuildDiscarderStrategy/config.jelly b/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.jelly similarity index 91% rename from core/src/main/resources/jenkins/model/DefaultBackgroundBuildDiscarderStrategy/config.jelly rename to core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.jelly index e60a13a6c7d6..c694ee85584e 100644 --- a/core/src/main/resources/jenkins/model/DefaultBackgroundBuildDiscarderStrategy/config.jelly +++ b/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.jelly @@ -22,6 +22,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --> - + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties b/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties new file mode 100644 index 000000000000..4fd0cb544a33 --- /dev/null +++ b/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties @@ -0,0 +1,3 @@ +blurb = By default, build discarders are only run after a build finishes. \ + This option runs jobs' configured build discarders periodically, applying configuration changes even when no new builds are run. \ + This has no effect if there is no build discarder configured for a job. diff --git a/core/src/main/resources/jenkins/model/Messages.properties b/core/src/main/resources/jenkins/model/Messages.properties index eb5effcbfdc0..f388b1dd06ab 100644 --- a/core/src/main/resources/jenkins/model/Messages.properties +++ b/core/src/main/resources/jenkins/model/Messages.properties @@ -76,3 +76,6 @@ CLI.disable-job.shortDescription=Disables a job. CLI.enable-job.shortDescription=Enables a job. GlobalCloudConfiguration.DisplayName=Configure Clouds + +GlobalBuildDiscarderStrategy.displayName=Periodically run custom build discarder +DefaultBackgroundBuildDiscarderStrategy.displayName=Periodically run project-specific build discarder diff --git a/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java b/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java new file mode 100644 index 000000000000..e926b185f7fe --- /dev/null +++ b/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java @@ -0,0 +1,109 @@ +package jenkins.model; + +import hudson.ExtensionList; +import hudson.model.FreeStyleProject; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.tasks.LogRotator; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; + +public class GlobalBuildDiscarderTest { + @Rule + public JenkinsRule j = new JenkinsRule(); + + @Test + public void testJobBuildDiscarder() throws Exception { + FreeStyleProject p = j.createFreeStyleProject(); + { // no discarder + j.buildAndAssertSuccess(p); + j.buildAndAssertSuccess(p); + j.buildAndAssertSuccess(p); + j.buildAndAssertSuccess(p); + j.buildAndAssertSuccess(p); + Assert.assertArrayEquals("all 5 builds exist", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{5, 4, 3, 2, 1}); + } + + { // job build discarder + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new JobBackgroundBuildDiscarderStrategy()); + p.setBuildDiscarder(new LogRotator(null, "3", null, null)); + Assert.assertArrayEquals("all 5 builds exist", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{5, 4, 3, 2, 1}); + + ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); + Assert.assertArrayEquals("only 3 builds left", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{5, 4, 3}); + + j.buildAndAssertSuccess(p); + Assert.assertArrayEquals("still only 3 builds", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{6, 5, 4}); + + p.setBuildDiscarder(null); + j.buildAndAssertSuccess(p); + j.buildAndAssertSuccess(p); + Assert.assertArrayEquals("5 builds again", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{8, 7, 6, 5, 4}); + + ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); + Assert.assertArrayEquals("still 5 builds", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{8, 7, 6, 5, 4}); + } + + { // global build discarder + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new GlobalBuildDiscarderStrategy(new LogRotator(null, "2", null, null))); + ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); + Assert.assertArrayEquals("newest 2 builds", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{8, 7}); + j.buildAndAssertSuccess(p); + j.buildAndAssertSuccess(p); + + // run global discarders once a build finishes + Assert.assertArrayEquals("2 builds because of BackgroundBuildDiscarderListener", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{10, 9}); + + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().clear(); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new GlobalBuildDiscarderStrategy(new LogRotator(null, "1", null, null))); + + // apply global config changes periodically + ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); + Assert.assertArrayEquals("2 builds again", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{10}); + } + + // reset global config + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().clear(); + + { // job and global build discarder + FreeStyleProject p1 = j.createFreeStyleProject(); + j.buildAndAssertSuccess(p1); + j.buildAndAssertSuccess(p1); + j.buildAndAssertSuccess(p1); + j.buildAndAssertSuccess(p1); + j.buildAndAssertSuccess(p1); + j.buildAndAssertSuccess(p1); + j.buildAndAssertSuccess(p1); + Assert.assertArrayEquals("job with 5 builds", p1.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{7,6,5,4,3,2,1}); + p1.setBuildDiscarder(new LogRotator(null, "5", null, null)); + + FreeStyleProject p2 = j.createFreeStyleProject(); + j.buildAndAssertSuccess(p2); + j.buildAndAssertSuccess(p2); + j.buildAndAssertSuccess(p2); + j.buildAndAssertSuccess(p2); + j.buildAndAssertSuccess(p2); + j.buildAndAssertSuccess(p2); + Assert.assertArrayEquals("job with 3 builds", p2.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{6,5,4,3,2,1}); + p2.setBuildDiscarder(new LogRotator(null, "3", null, null)); + + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new GlobalBuildDiscarderStrategy(new LogRotator(null, "4", null, null))); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new JobBackgroundBuildDiscarderStrategy()); + + { // job 1 with builds more aggressively deleted by global strategy + j.buildAndAssertSuccess(p1); + j.buildAndAssertSuccess(p1); + Assert.assertArrayEquals("job 1 discards down to 5, but global override is for 4", p1.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{9, 8, 7, 6}); + ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); + Assert.assertArrayEquals("job 1 discards down to 5, but global override is for 4", p1.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{9, 8, 7, 6}); + } + + { // job 2 with more aggressive local build discarder + j.buildAndAssertSuccess(p2); + Assert.assertArrayEquals("job 1 discards down to 3", p2.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{7,6,5}); + } + } + } +} From 7a0cd426b49e92ea08a165c1eaf4431056bf7f52 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 15 Dec 2019 21:01:21 +0100 Subject: [PATCH 04/12] Fix field name reference in string --- .../java/jenkins/model/GlobalBuildDiscarderConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java index 7190dcb9d3d8..3da012972ad3 100644 --- a/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java @@ -66,7 +66,7 @@ public boolean configure(StaplerRequest req, JSONObject json) throws FormExcepti configuredBuildDiscarders.rebuildHetero(req, json, BackgroundBuildDiscarderStrategyDescriptor.all(), "configuredBuildDiscarders"); return true; } catch (IOException x) { - throw new FormException(x, "artifactManagerFactories"); + throw new FormException(x, "configuredBuildDiscarders"); } } } From 9e2c3d36e647ee11bf260d8c5da40d08c118e1cd Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 15 Dec 2019 21:01:31 +0100 Subject: [PATCH 05/12] Fix localized string --- .../model/JobBackgroundBuildDiscarderStrategy/config.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties b/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties index 4fd0cb544a33..72d25dea6cd2 100644 --- a/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties +++ b/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties @@ -1,3 +1,3 @@ blurb = By default, build discarders are only run after a build finishes. \ - This option runs jobs' configured build discarders periodically, applying configuration changes even when no new builds are run. \ + This option runs jobs'' configured build discarders periodically, applying configuration changes even when no new builds are run. \ This has no effect if there is no build discarder configured for a job. From cffa9fe5e7abe0ee081af682581ad885c3c280e5 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 15 Dec 2019 21:06:00 +0100 Subject: [PATCH 06/12] Rename the strategy --- ...derStrategy.java => SimpleBuildDiscarderStrategy.java} | 8 ++++---- core/src/main/resources/jenkins/model/Messages.properties | 2 +- .../config.jelly | 0 .../config.properties | 0 .../test/java/jenkins/model/GlobalBuildDiscarderTest.java | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) rename core/src/main/java/jenkins/model/{GlobalBuildDiscarderStrategy.java => SimpleBuildDiscarderStrategy.java} (90%) rename core/src/main/resources/jenkins/model/{GlobalBuildDiscarderStrategy => SimpleBuildDiscarderStrategy}/config.jelly (100%) rename core/src/main/resources/jenkins/model/{GlobalBuildDiscarderStrategy => SimpleBuildDiscarderStrategy}/config.properties (100%) diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/SimpleBuildDiscarderStrategy.java similarity index 90% rename from core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java rename to core/src/main/java/jenkins/model/SimpleBuildDiscarderStrategy.java index 0c35dcf88386..393fb28a8a76 100644 --- a/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java +++ b/core/src/main/java/jenkins/model/SimpleBuildDiscarderStrategy.java @@ -37,12 +37,12 @@ * Apply a user-specified build discarder periodically on all jobs. */ @Restricted(NoExternalUse.class) -public class GlobalBuildDiscarderStrategy extends BackgroundBuildDiscarderStrategy { +public class SimpleBuildDiscarderStrategy extends BackgroundBuildDiscarderStrategy { private BuildDiscarder discarder; @DataBoundConstructor - public GlobalBuildDiscarderStrategy(BuildDiscarder discarder) { + public SimpleBuildDiscarderStrategy(BuildDiscarder discarder) { this.discarder = discarder; } @@ -63,12 +63,12 @@ public void apply(Job job) throws IOException, InterruptedException { } @Extension - @Symbol("globalBuildDiscarder") + @Symbol("simpleBuildDiscarder") public static class DescriptorImpl extends BackgroundBuildDiscarderStrategyDescriptor { @Nonnull @Override public String getDisplayName() { - return Messages.GlobalBuildDiscarderStrategy_displayName(); + return Messages.SimpleBuildDiscarderStrategy_displayName(); } } } diff --git a/core/src/main/resources/jenkins/model/Messages.properties b/core/src/main/resources/jenkins/model/Messages.properties index f388b1dd06ab..0cf502ea9e80 100644 --- a/core/src/main/resources/jenkins/model/Messages.properties +++ b/core/src/main/resources/jenkins/model/Messages.properties @@ -77,5 +77,5 @@ CLI.enable-job.shortDescription=Enables a job. GlobalCloudConfiguration.DisplayName=Configure Clouds -GlobalBuildDiscarderStrategy.displayName=Periodically run custom build discarder +SimpleBuildDiscarderStrategy.displayName=Periodically run custom build discarder DefaultBackgroundBuildDiscarderStrategy.displayName=Periodically run project-specific build discarder diff --git a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.jelly b/core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.jelly similarity index 100% rename from core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.jelly rename to core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.jelly diff --git a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.properties b/core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.properties similarity index 100% rename from core/src/main/resources/jenkins/model/GlobalBuildDiscarderStrategy/config.properties rename to core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.properties diff --git a/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java b/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java index e926b185f7fe..ed64f8325660 100644 --- a/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java +++ b/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java @@ -47,7 +47,7 @@ public void testJobBuildDiscarder() throws Exception { } { // global build discarder - GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new GlobalBuildDiscarderStrategy(new LogRotator(null, "2", null, null))); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new SimpleBuildDiscarderStrategy(new LogRotator(null, "2", null, null))); ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); Assert.assertArrayEquals("newest 2 builds", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{8, 7}); j.buildAndAssertSuccess(p); @@ -57,7 +57,7 @@ public void testJobBuildDiscarder() throws Exception { Assert.assertArrayEquals("2 builds because of BackgroundBuildDiscarderListener", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{10, 9}); GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().clear(); - GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new GlobalBuildDiscarderStrategy(new LogRotator(null, "1", null, null))); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new SimpleBuildDiscarderStrategy(new LogRotator(null, "1", null, null))); // apply global config changes periodically ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); @@ -89,7 +89,7 @@ public void testJobBuildDiscarder() throws Exception { Assert.assertArrayEquals("job with 3 builds", p2.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{6,5,4,3,2,1}); p2.setBuildDiscarder(new LogRotator(null, "3", null, null)); - GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new GlobalBuildDiscarderStrategy(new LogRotator(null, "4", null, null))); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new SimpleBuildDiscarderStrategy(new LogRotator(null, "4", null, null))); GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new JobBackgroundBuildDiscarderStrategy()); { // job 1 with builds more aggressively deleted by global strategy From 64445eb93a6cf108c6c574cdfa79028666c4006d Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 15 Dec 2019 21:17:05 +0100 Subject: [PATCH 07/12] Wording changes in global build discarder UI --- .../model/GlobalBuildDiscarderConfiguration/config.groovy | 2 +- .../JobBackgroundBuildDiscarderStrategy/config.properties | 4 ++-- core/src/main/resources/jenkins/model/Messages.properties | 4 ++-- .../model/SimpleBuildDiscarderStrategy/config.properties | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy index c650ba02abb7..1c96790de913 100644 --- a/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy +++ b/core/src/main/resources/jenkins/model/GlobalBuildDiscarderConfiguration/config.groovy @@ -26,7 +26,7 @@ package jenkins.model.GlobalBuildDiscarderConfiguration f = namespace(lib.FormTagLib) -f.section(title: _("Periodically Run Build Discarders")) { +f.section(title: _("Global Build Discarders")) { f.block() { f.repeatableHeteroProperty(field: "configuredBuildDiscarders", hasHeader: true, oneEach: true) } diff --git a/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties b/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties index 72d25dea6cd2..dfc73510afd5 100644 --- a/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties +++ b/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties @@ -1,3 +1,3 @@ -blurb = By default, build discarders are only run after a build finishes. \ +blurb = Build discarders configured for a job are only run after a build finishes. \ This option runs jobs'' configured build discarders periodically, applying configuration changes even when no new builds are run. \ - This has no effect if there is no build discarder configured for a job. + This option no effect if there is no build discarder configured for a job. diff --git a/core/src/main/resources/jenkins/model/Messages.properties b/core/src/main/resources/jenkins/model/Messages.properties index 0cf502ea9e80..7815f1ba17cd 100644 --- a/core/src/main/resources/jenkins/model/Messages.properties +++ b/core/src/main/resources/jenkins/model/Messages.properties @@ -77,5 +77,5 @@ CLI.enable-job.shortDescription=Enables a job. GlobalCloudConfiguration.DisplayName=Configure Clouds -SimpleBuildDiscarderStrategy.displayName=Periodically run custom build discarder -DefaultBackgroundBuildDiscarderStrategy.displayName=Periodically run project-specific build discarder +SimpleBuildDiscarderStrategy.displayName=Specific Build Discarder +DefaultBackgroundBuildDiscarderStrategy.displayName=Project Build Discarder diff --git a/core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.properties b/core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.properties index b5f8d3fa8657..621323e43ad5 100644 --- a/core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.properties +++ b/core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.properties @@ -1 +1 @@ -blurb = The selected build discarder with be run periodically for all jobs. +blurb = The selected build discarder with be applied after any build finishes, as well as periodically. From 5499716f0d056130d709baca7ba3ba5a8620987b Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 15 Dec 2019 21:34:30 +0100 Subject: [PATCH 08/12] Stop using 'background' in favor of 'global' (except for the periodic work thread) --- ...va => BackgroundGlobalBuildDiscarder.java} | 8 ++++---- .../GlobalBuildDiscarderConfiguration.java | 12 +++++------ ...java => GlobalBuildDiscarderListener.java} | 6 +++--- ...java => GlobalBuildDiscarderStrategy.java} | 8 ++++---- ...obalBuildDiscarderStrategyDescriptor.java} | 8 ++++---- ...a => JobGlobalBuildDiscarderStrategy.java} | 8 ++++---- ...> SimpleGlobalBuildDiscarderStrategy.java} | 6 +++--- .../config.jelly | 0 .../config.properties | 0 .../jenkins/model/Messages.properties | 4 ++-- .../config.jelly | 0 .../config.properties | 0 .../model/GlobalBuildDiscarderTest.java | 20 +++++++++---------- 13 files changed, 40 insertions(+), 40 deletions(-) rename core/src/main/java/jenkins/model/{BackgroundBuildDiscarder.java => BackgroundGlobalBuildDiscarder.java} (93%) rename core/src/main/java/jenkins/model/{BackgroundBuildDiscarderListener.java => GlobalBuildDiscarderListener.java} (67%) rename core/src/main/java/jenkins/model/{BackgroundBuildDiscarderStrategy.java => GlobalBuildDiscarderStrategy.java} (89%) rename core/src/main/java/jenkins/model/{BackgroundBuildDiscarderStrategyDescriptor.java => GlobalBuildDiscarderStrategyDescriptor.java} (75%) rename core/src/main/java/jenkins/model/{JobBackgroundBuildDiscarderStrategy.java => JobGlobalBuildDiscarderStrategy.java} (86%) rename core/src/main/java/jenkins/model/{SimpleBuildDiscarderStrategy.java => SimpleGlobalBuildDiscarderStrategy.java} (89%) rename core/src/main/resources/jenkins/model/{JobBackgroundBuildDiscarderStrategy => JobGlobalBuildDiscarderStrategy}/config.jelly (100%) rename core/src/main/resources/jenkins/model/{JobBackgroundBuildDiscarderStrategy => JobGlobalBuildDiscarderStrategy}/config.properties (100%) rename core/src/main/resources/jenkins/model/{SimpleBuildDiscarderStrategy => SimpleGlobalBuildDiscarderStrategy}/config.jelly (100%) rename core/src/main/resources/jenkins/model/{SimpleBuildDiscarderStrategy => SimpleGlobalBuildDiscarderStrategy}/config.properties (100%) diff --git a/core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java b/core/src/main/java/jenkins/model/BackgroundGlobalBuildDiscarder.java similarity index 93% rename from core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java rename to core/src/main/java/jenkins/model/BackgroundGlobalBuildDiscarder.java index 94385940c800..84329dd97763 100644 --- a/core/src/main/java/jenkins/model/BackgroundBuildDiscarder.java +++ b/core/src/main/java/jenkins/model/BackgroundGlobalBuildDiscarder.java @@ -38,14 +38,14 @@ * Background task actually running background build discarders. * * @see GlobalBuildDiscarderConfiguration - * @see BackgroundBuildDiscarderStrategy + * @see GlobalBuildDiscarderStrategy */ @Restricted(NoExternalUse.class) @Extension -public class BackgroundBuildDiscarder extends AsyncPeriodicWork { - private static final Logger LOGGER = Logger.getLogger(BackgroundBuildDiscarder.class.getName()); +public class BackgroundGlobalBuildDiscarder extends AsyncPeriodicWork { + private static final Logger LOGGER = Logger.getLogger(BackgroundGlobalBuildDiscarder.class.getName()); - public BackgroundBuildDiscarder() { + public BackgroundGlobalBuildDiscarder() { super("Periodic background build discarder"); // TODO i18n } diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java index 3da012972ad3..9b0ca5aaf8ad 100644 --- a/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderConfiguration.java @@ -38,8 +38,8 @@ /** * Global configuration UI for background build discarders * - * @see BackgroundBuildDiscarderStrategy - * @see BackgroundBuildDiscarder + * @see GlobalBuildDiscarderStrategy + * @see BackgroundGlobalBuildDiscarder */ @Restricted(NoExternalUse.class) @Extension @Symbol("buildDiscarders") @@ -48,22 +48,22 @@ public static GlobalBuildDiscarderConfiguration get() { return ExtensionList.lookupSingleton(GlobalBuildDiscarderConfiguration.class); } - private final DescribableList configuredBuildDiscarders = - new DescribableList<>(this, Collections.singletonList(new JobBackgroundBuildDiscarderStrategy())); + private final DescribableList configuredBuildDiscarders = + new DescribableList<>(this, Collections.singletonList(new JobGlobalBuildDiscarderStrategy())); private Object readResolve() { configuredBuildDiscarders.setOwner(this); return this; } - public DescribableList getConfiguredBuildDiscarders() { + public DescribableList getConfiguredBuildDiscarders() { return configuredBuildDiscarders; } @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { try { - configuredBuildDiscarders.rebuildHetero(req, json, BackgroundBuildDiscarderStrategyDescriptor.all(), "configuredBuildDiscarders"); + configuredBuildDiscarders.rebuildHetero(req, json, GlobalBuildDiscarderStrategyDescriptor.all(), "configuredBuildDiscarders"); return true; } catch (IOException x) { throw new FormException(x, "configuredBuildDiscarders"); diff --git a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderListener.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderListener.java similarity index 67% rename from core/src/main/java/jenkins/model/BackgroundBuildDiscarderListener.java rename to core/src/main/java/jenkins/model/GlobalBuildDiscarderListener.java index fabdcfdddf6d..377a755b4f6d 100644 --- a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderListener.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderListener.java @@ -16,13 +16,13 @@ */ @Extension @Restricted(NoExternalUse.class) -public class BackgroundBuildDiscarderListener extends RunListener { +public class GlobalBuildDiscarderListener extends RunListener { - private static final Logger LOGGER = Logger.getLogger(BackgroundBuildDiscarderListener.class.getName()); + private static final Logger LOGGER = Logger.getLogger(GlobalBuildDiscarderListener.class.getName()); @Override public void onFinalized(Run run) { Job job = run.getParent(); - BackgroundBuildDiscarder.processJob(new LogTaskListener(LOGGER, Level.FINE), job); + BackgroundGlobalBuildDiscarder.processJob(new LogTaskListener(LOGGER, Level.FINE), job); } } diff --git a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java similarity index 89% rename from core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java rename to core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java index 2d30141ccfc9..3ec744280774 100644 --- a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategy.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java @@ -35,12 +35,12 @@ /** * Extension point for global background build discarders. * - * @see BackgroundBuildDiscarder + * @see BackgroundGlobalBuildDiscarder * @see GlobalBuildDiscarderConfiguration - * @see JobBackgroundBuildDiscarderStrategy + * @see JobGlobalBuildDiscarderStrategy */ -public abstract class BackgroundBuildDiscarderStrategy extends AbstractDescribableImpl implements ExtensionPoint { - private static final Logger LOGGER = Logger.getLogger(BackgroundBuildDiscarderStrategy.class.getName()); +public abstract class GlobalBuildDiscarderStrategy extends AbstractDescribableImpl implements ExtensionPoint { + private static final Logger LOGGER = Logger.getLogger(GlobalBuildDiscarderStrategy.class.getName()); /** * Returns true if and only if this strategy applies to the given job. diff --git a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategyDescriptor.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategyDescriptor.java similarity index 75% rename from core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategyDescriptor.java rename to core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategyDescriptor.java index c8d73e7205b7..8e19c3180ddf 100644 --- a/core/src/main/java/jenkins/model/BackgroundBuildDiscarderStrategyDescriptor.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategyDescriptor.java @@ -27,11 +27,11 @@ import hudson.model.Descriptor; /** - * {@link Descriptor} for {@link BackgroundBuildDiscarder}. + * {@link Descriptor} for {@link BackgroundGlobalBuildDiscarder}. */ -public abstract class BackgroundBuildDiscarderStrategyDescriptor extends Descriptor { +public abstract class GlobalBuildDiscarderStrategyDescriptor extends Descriptor { - public static DescriptorExtensionList all() { - return Jenkins.get().getDescriptorList(BackgroundBuildDiscarderStrategy.class); + public static DescriptorExtensionList all() { + return Jenkins.get().getDescriptorList(GlobalBuildDiscarderStrategy.class); } } diff --git a/core/src/main/java/jenkins/model/JobBackgroundBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/JobGlobalBuildDiscarderStrategy.java similarity index 86% rename from core/src/main/java/jenkins/model/JobBackgroundBuildDiscarderStrategy.java rename to core/src/main/java/jenkins/model/JobGlobalBuildDiscarderStrategy.java index fd78c461a29a..bb5523f68bc6 100644 --- a/core/src/main/java/jenkins/model/JobBackgroundBuildDiscarderStrategy.java +++ b/core/src/main/java/jenkins/model/JobGlobalBuildDiscarderStrategy.java @@ -37,10 +37,10 @@ * Periodically call a job's configured build discarder in the background. */ @Restricted(NoExternalUse.class) -public class JobBackgroundBuildDiscarderStrategy extends BackgroundBuildDiscarderStrategy { +public class JobGlobalBuildDiscarderStrategy extends GlobalBuildDiscarderStrategy { @DataBoundConstructor - public JobBackgroundBuildDiscarderStrategy() { + public JobGlobalBuildDiscarderStrategy() { // required for data binding } @@ -55,11 +55,11 @@ public void apply(Job job) throws IOException, InterruptedException { } @Extension @Symbol("jobBuildDiscarder") - public static class DescriptorImpl extends BackgroundBuildDiscarderStrategyDescriptor { + public static class DescriptorImpl extends GlobalBuildDiscarderStrategyDescriptor { @Nonnull @Override public String getDisplayName() { - return Messages.DefaultBackgroundBuildDiscarderStrategy_displayName(); + return Messages.JobGlobalBuildDiscarderStrategy_displayName(); } } } diff --git a/core/src/main/java/jenkins/model/SimpleBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/SimpleGlobalBuildDiscarderStrategy.java similarity index 89% rename from core/src/main/java/jenkins/model/SimpleBuildDiscarderStrategy.java rename to core/src/main/java/jenkins/model/SimpleGlobalBuildDiscarderStrategy.java index 393fb28a8a76..ac8cc9c788f3 100644 --- a/core/src/main/java/jenkins/model/SimpleBuildDiscarderStrategy.java +++ b/core/src/main/java/jenkins/model/SimpleGlobalBuildDiscarderStrategy.java @@ -37,12 +37,12 @@ * Apply a user-specified build discarder periodically on all jobs. */ @Restricted(NoExternalUse.class) -public class SimpleBuildDiscarderStrategy extends BackgroundBuildDiscarderStrategy { +public class SimpleGlobalBuildDiscarderStrategy extends GlobalBuildDiscarderStrategy { private BuildDiscarder discarder; @DataBoundConstructor - public SimpleBuildDiscarderStrategy(BuildDiscarder discarder) { + public SimpleGlobalBuildDiscarderStrategy(BuildDiscarder discarder) { this.discarder = discarder; } @@ -64,7 +64,7 @@ public void apply(Job job) throws IOException, InterruptedException { @Extension @Symbol("simpleBuildDiscarder") - public static class DescriptorImpl extends BackgroundBuildDiscarderStrategyDescriptor { + public static class DescriptorImpl extends GlobalBuildDiscarderStrategyDescriptor { @Nonnull @Override public String getDisplayName() { diff --git a/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.jelly b/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config.jelly similarity index 100% rename from core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.jelly rename to core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config.jelly diff --git a/core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties b/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config.properties similarity index 100% rename from core/src/main/resources/jenkins/model/JobBackgroundBuildDiscarderStrategy/config.properties rename to core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config.properties diff --git a/core/src/main/resources/jenkins/model/Messages.properties b/core/src/main/resources/jenkins/model/Messages.properties index 7815f1ba17cd..64bf784b3ca1 100644 --- a/core/src/main/resources/jenkins/model/Messages.properties +++ b/core/src/main/resources/jenkins/model/Messages.properties @@ -77,5 +77,5 @@ CLI.enable-job.shortDescription=Enables a job. GlobalCloudConfiguration.DisplayName=Configure Clouds -SimpleBuildDiscarderStrategy.displayName=Specific Build Discarder -DefaultBackgroundBuildDiscarderStrategy.displayName=Project Build Discarder +SimpleGlobalBuildDiscarderStrategy.displayName=Specific Build Discarder +JobGlobalBuildDiscarderStrategy.displayName=Project Build Discarder diff --git a/core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.jelly b/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config.jelly similarity index 100% rename from core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.jelly rename to core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config.jelly diff --git a/core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.properties b/core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config.properties similarity index 100% rename from core/src/main/resources/jenkins/model/SimpleBuildDiscarderStrategy/config.properties rename to core/src/main/resources/jenkins/model/SimpleGlobalBuildDiscarderStrategy/config.properties diff --git a/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java b/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java index ed64f8325660..4544e5c881bb 100644 --- a/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java +++ b/test/src/test/java/jenkins/model/GlobalBuildDiscarderTest.java @@ -27,11 +27,11 @@ public void testJobBuildDiscarder() throws Exception { } { // job build discarder - GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new JobBackgroundBuildDiscarderStrategy()); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new JobGlobalBuildDiscarderStrategy()); p.setBuildDiscarder(new LogRotator(null, "3", null, null)); Assert.assertArrayEquals("all 5 builds exist", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{5, 4, 3, 2, 1}); - ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); + ExtensionList.lookupSingleton(BackgroundGlobalBuildDiscarder.class).execute(TaskListener.NULL); Assert.assertArrayEquals("only 3 builds left", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{5, 4, 3}); j.buildAndAssertSuccess(p); @@ -42,13 +42,13 @@ public void testJobBuildDiscarder() throws Exception { j.buildAndAssertSuccess(p); Assert.assertArrayEquals("5 builds again", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{8, 7, 6, 5, 4}); - ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); + ExtensionList.lookupSingleton(BackgroundGlobalBuildDiscarder.class).execute(TaskListener.NULL); Assert.assertArrayEquals("still 5 builds", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{8, 7, 6, 5, 4}); } { // global build discarder - GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new SimpleBuildDiscarderStrategy(new LogRotator(null, "2", null, null))); - ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new SimpleGlobalBuildDiscarderStrategy(new LogRotator(null, "2", null, null))); + ExtensionList.lookupSingleton(BackgroundGlobalBuildDiscarder.class).execute(TaskListener.NULL); Assert.assertArrayEquals("newest 2 builds", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{8, 7}); j.buildAndAssertSuccess(p); j.buildAndAssertSuccess(p); @@ -57,10 +57,10 @@ public void testJobBuildDiscarder() throws Exception { Assert.assertArrayEquals("2 builds because of BackgroundBuildDiscarderListener", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{10, 9}); GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().clear(); - GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new SimpleBuildDiscarderStrategy(new LogRotator(null, "1", null, null))); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new SimpleGlobalBuildDiscarderStrategy(new LogRotator(null, "1", null, null))); // apply global config changes periodically - ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); + ExtensionList.lookupSingleton(BackgroundGlobalBuildDiscarder.class).execute(TaskListener.NULL); Assert.assertArrayEquals("2 builds again", p.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{10}); } @@ -89,14 +89,14 @@ public void testJobBuildDiscarder() throws Exception { Assert.assertArrayEquals("job with 3 builds", p2.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{6,5,4,3,2,1}); p2.setBuildDiscarder(new LogRotator(null, "3", null, null)); - GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new SimpleBuildDiscarderStrategy(new LogRotator(null, "4", null, null))); - GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new JobBackgroundBuildDiscarderStrategy()); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new SimpleGlobalBuildDiscarderStrategy(new LogRotator(null, "4", null, null))); + GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().add(new JobGlobalBuildDiscarderStrategy()); { // job 1 with builds more aggressively deleted by global strategy j.buildAndAssertSuccess(p1); j.buildAndAssertSuccess(p1); Assert.assertArrayEquals("job 1 discards down to 5, but global override is for 4", p1.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{9, 8, 7, 6}); - ExtensionList.lookupSingleton(BackgroundBuildDiscarder.class).execute(TaskListener.NULL); + ExtensionList.lookupSingleton(BackgroundGlobalBuildDiscarder.class).execute(TaskListener.NULL); Assert.assertArrayEquals("job 1 discards down to 5, but global override is for 4", p1.getBuilds().stream().mapToInt(Run::getNumber).toArray(), new int[]{9, 8, 7, 6}); } From ca1c79365d28c09b5d1d8d45817305e0abe5937c Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 15 Dec 2019 21:41:37 +0100 Subject: [PATCH 09/12] Add missing license header --- .../model/GlobalBuildDiscarderListener.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderListener.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderListener.java index 377a755b4f6d..9edeb61430f6 100644 --- a/core/src/main/java/jenkins/model/GlobalBuildDiscarderListener.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderListener.java @@ -1,3 +1,26 @@ +/* + * The MIT License + * + * Copyright 2019 Daniel Beck + * + * 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 jenkins.model; import hudson.Extension; From c0e193b33c2bdcb9b0a1d533268ed40311600fed Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 15 Dec 2019 21:47:14 +0100 Subject: [PATCH 10/12] Fix compile error --- .../java/jenkins/model/SimpleGlobalBuildDiscarderStrategy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/jenkins/model/SimpleGlobalBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/SimpleGlobalBuildDiscarderStrategy.java index ac8cc9c788f3..5b4f68ede397 100644 --- a/core/src/main/java/jenkins/model/SimpleGlobalBuildDiscarderStrategy.java +++ b/core/src/main/java/jenkins/model/SimpleGlobalBuildDiscarderStrategy.java @@ -68,7 +68,7 @@ public static class DescriptorImpl extends GlobalBuildDiscarderStrategyDescripto @Nonnull @Override public String getDisplayName() { - return Messages.SimpleBuildDiscarderStrategy_displayName(); + return Messages.SimpleGlobalBuildDiscarderStrategy_displayName(); } } } From 85e49f6cd1c14d592ec232aa7fb2aecf58428486 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 15 Dec 2019 21:47:24 +0100 Subject: [PATCH 11/12] This option no effect --- .../model/JobGlobalBuildDiscarderStrategy/config.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config.properties b/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config.properties index dfc73510afd5..3e19a30f35cd 100644 --- a/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config.properties +++ b/core/src/main/resources/jenkins/model/JobGlobalBuildDiscarderStrategy/config.properties @@ -1,3 +1,3 @@ blurb = Build discarders configured for a job are only run after a build finishes. \ This option runs jobs'' configured build discarders periodically, applying configuration changes even when no new builds are run. \ - This option no effect if there is no build discarder configured for a job. + This option has no effect if there is no build discarder configured for a job. From 9ffeeff43bdc005e85dbff485992e6e7d30c67b2 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Fri, 7 Feb 2020 23:29:50 +0100 Subject: [PATCH 12/12] Do not catch InterruptedException --- .../java/jenkins/model/GlobalBuildDiscarderStrategy.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java index 3ec744280774..124b26ef5ea0 100644 --- a/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java +++ b/core/src/main/java/jenkins/model/GlobalBuildDiscarderStrategy.java @@ -59,14 +59,13 @@ public abstract class GlobalBuildDiscarderStrategy extends AbstractDescribableIm * @throws InterruptedException */ public void apply(Job job) throws IOException, InterruptedException { - job.getBuilds().forEach(run -> { + for (Run run : job.getBuilds()) { try { apply(run); - } catch (IOException|InterruptedException ex) { - // TODO should these actually be caught, or just thrown up to stop applying? + } catch (IOException ex) { LOGGER.log(Level.WARNING, "Failed to delete " + run.getFullDisplayName(), ex); } - }); + } } /**