From 658032c0cd86154e554c5c5f48fd799df933afbb Mon Sep 17 00:00:00 2001 From: repolevedavaj Date: Tue, 3 Jan 2023 21:35:33 +0100 Subject: [PATCH] Make maxCacheSize optional --- README.md | 10 ++--- .../plugins/jobcacher/CacheManager.java | 23 +++++++--- .../plugins/jobcacher/CacheWrapper.java | 14 +++--- .../plugins/jobcacher/pipeline/CacheStep.java | 43 ++++++++++++------- .../jobcacher/ArbitraryFileCache/config.jelly | 2 +- .../jobcacher/CacheWrapper/config.jelly | 17 +++++--- .../jobcacher/pipeline/CacheStep/config.jelly | 17 +++++--- src/main/webapp/help-maximumCacheSize.html | 2 +- .../ArbitraryFileCacheWrapperTest.java | 3 +- 9 files changed, 83 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 75c68f6..696e9d0 100644 --- a/README.md +++ b/README.md @@ -34,11 +34,11 @@ The storage type can be configured in the global configuration section of Jenkin The following cache configuration options apply to all supported job types. -| Option | Mandatory | Description | -|-----------------|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `maxCacheSize` | yes | The maximum size in megabytes of all configured caches that Jenkins will allow until it deletes all completely and starts the next build from an empty cache. This prevents caches from growing indefinitely with the downside of periodic fresh builds without a cache. | -| `defaultBranch` | no | If the current branch has no cache, it will seed its cache from the specified branch. Leave empty to generate a fresh cache for each branch. | -| `caches` | yes | Defines the caches to use in the job (see below). | +| Option | Mandatory | Description | +|-----------------|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `maxCacheSize` | no | The maximum size in megabytes of all configured caches that Jenkins will allow until it deletes all completely and starts the next build from an empty cache. This prevents caches from growing indefinitely with the downside of periodic fresh builds without a cache. Set to zero or empty to skip checking cache size. | +| `defaultBranch` | no | If the current branch has no cache, it will seed its cache from the specified branch. Leave empty to generate a fresh cache for each branch. | +| `caches` | yes | Defines the caches to use in the job (see below). | ### `ArbitraryFileCache` diff --git a/src/main/java/jenkins/plugins/jobcacher/CacheManager.java b/src/main/java/jenkins/plugins/jobcacher/CacheManager.java index 5b9d6e9..4784203 100644 --- a/src/main/java/jenkins/plugins/jobcacher/CacheManager.java +++ b/src/main/java/jenkins/plugins/jobcacher/CacheManager.java @@ -70,19 +70,16 @@ public static List cache(ItemStorage storage, Run run, Fil /** * Internal method only */ - public static void save(ItemStorage storage, Run run, FilePath workspace, Launcher launcher, TaskListener listener, long maxCacheSize, List caches, List cacheSavers) throws IOException, InterruptedException { + public static void save(ItemStorage storage, Run run, FilePath workspace, Launcher launcher, TaskListener listener, Long maxCacheSize, List caches, List cacheSavers) throws IOException, InterruptedException { ObjectPath cachePath = getCachePath(storage, run); // First calculate size of cache to check if it should just be deleted - long totalSize = 0L; - for (Cache.Saver saver : cacheSavers) { - totalSize += saver.calculateSize(cachePath, run, workspace, launcher, listener); - } + boolean exceedsMaxCacheSize = exceedsMaxCacheSize(cachePath, run, workspace, launcher, listener, maxCacheSize, cacheSavers); // synchronize on the build's parent object as we are going to write to the shared cache synchronized (getLock(run.getParent())) { // If total size is greater than configured maximum, delete all caches to start fresh next build - if (totalSize > maxCacheSize * 1024 * 1024) { + if (exceedsMaxCacheSize) { listener.getLogger().println("Removing job cache as it has grown beyond configured maximum size of " + maxCacheSize + "M. Next build will start with no cache."); @@ -108,4 +105,18 @@ public static void save(ItemStorage storage, Run run, FilePath workspac run.getAction(CacheBuildLastAction.class).addCaches(caches); } } + + private static boolean exceedsMaxCacheSize(ObjectPath cachePath, Run run, FilePath workspace, Launcher launcher, TaskListener listener, Long maxCacheSize, List cacheSavers) throws IOException, InterruptedException { + if (maxCacheSize == null || maxCacheSize == 0) { + return false; + } + + long totalSize = 0L; + for (Cache.Saver saver : cacheSavers) { + totalSize += saver.calculateSize(cachePath, run, workspace, launcher, listener); + } + + return totalSize > maxCacheSize * 1024 * 1024; + } + } diff --git a/src/main/java/jenkins/plugins/jobcacher/CacheWrapper.java b/src/main/java/jenkins/plugins/jobcacher/CacheWrapper.java index aa5a746..1fbc6d9 100644 --- a/src/main/java/jenkins/plugins/jobcacher/CacheWrapper.java +++ b/src/main/java/jenkins/plugins/jobcacher/CacheWrapper.java @@ -54,7 +54,7 @@ */ public class CacheWrapper extends SimpleBuildWrapper { - private long maxCacheSize; + private Long maxCacheSize; private List caches; private String defaultBranch; @@ -62,8 +62,7 @@ public CacheWrapper() { } @DataBoundConstructor - public CacheWrapper(long maxCacheSize, List caches) { - setMaxCacheSize(maxCacheSize); + public CacheWrapper(List caches) { setCaches(caches); } @@ -73,12 +72,13 @@ public ItemStorage getStorage() { } @SuppressWarnings("unused") - public long getMaxCacheSize() { + public Long getMaxCacheSize() { return maxCacheSize; } + @DataBoundSetter @SuppressWarnings("unused") - public void setMaxCacheSize(long maxCacheSize) { + public void setMaxCacheSize(Long maxCacheSize) { this.maxCacheSize = maxCacheSize; } @@ -141,12 +141,12 @@ private static class CacheDisposer extends Disposer { private static final long serialVersionUID = 1L; private final ItemStorage storage; - private final long maxCacheSize; + private final Long maxCacheSize; private final List caches; private final List cacheSavers; @DataBoundConstructor - public CacheDisposer(ItemStorage storage, long maxCacheSize, List caches, List cacheSavers) { + public CacheDisposer(ItemStorage storage, Long maxCacheSize, List caches, List cacheSavers) { this.storage = storage; this.maxCacheSize = maxCacheSize; this.caches = caches; diff --git a/src/main/java/jenkins/plugins/jobcacher/pipeline/CacheStep.java b/src/main/java/jenkins/plugins/jobcacher/pipeline/CacheStep.java index 0e10f83..2d237f4 100644 --- a/src/main/java/jenkins/plugins/jobcacher/pipeline/CacheStep.java +++ b/src/main/java/jenkins/plugins/jobcacher/pipeline/CacheStep.java @@ -42,7 +42,8 @@ import org.kohsuke.stapler.DataBoundSetter; import java.io.IOException; -import java.util.*; +import java.util.Collections; +import java.util.List; /** * Wrapping workflow step that automatically seeds the specified path with the previous run and on exit of the @@ -50,24 +51,21 @@ */ public class CacheStep extends Step { - private final long maxCacheSize; private final List caches; - @DataBoundSetter - public String defaultBranch = null; + private Long maxCacheSize; + + public String defaultBranch; @DataBoundConstructor - public CacheStep(long maxCacheSize, List caches) { + public CacheStep(Long maxCacheSize, List caches) { this.maxCacheSize = maxCacheSize; this.caches = caches; } + @DataBoundSetter @SuppressWarnings("unused") - public long getMaxCacheSize() { - return maxCacheSize; - } - - public List getCaches() { - return caches; + public void setDefaultBranch(String defaultBranch) { + this.defaultBranch = defaultBranch; } @SuppressWarnings("unused") @@ -75,6 +73,21 @@ public String getDefaultBranch() { return defaultBranch; } + @DataBoundSetter + @SuppressWarnings("unused") + public void setMaxCacheSize(Long maxCacheSize) { + this.maxCacheSize = maxCacheSize; + } + + @SuppressWarnings("unused") + public Long getMaxCacheSize() { + return maxCacheSize; + } + + public List getCaches() { + return caches; + } + @Override public StepExecution start(StepContext context) throws Exception { return new ExecutionImpl(context, maxCacheSize, caches, defaultBranch); @@ -84,11 +97,11 @@ public static class ExecutionImpl extends GeneralNonBlockingStepExecution { private static final long serialVersionUID = 1L; - private final long maxCacheSize; + private final Long maxCacheSize; private final List caches; private final String defaultBranch; - protected ExecutionImpl(StepContext context, long maxCacheSize, List caches, String defaultBranch) { + protected ExecutionImpl(StepContext context, Long maxCacheSize, List caches, String defaultBranch) { super(context); this.maxCacheSize = maxCacheSize; @@ -125,11 +138,11 @@ public static class ExecutionCallback extends BodyExecutionCallback { private static final long serialVersionUID = 1L; - private final long maxCacheSize; + private final Long maxCacheSize; private final List caches; private final List cacheSavers; - public ExecutionCallback(long maxCacheSize, List caches, List cacheSavers) { + public ExecutionCallback(Long maxCacheSize, List caches, List cacheSavers) { this.maxCacheSize = maxCacheSize; this.caches = caches; this.cacheSavers = cacheSavers; diff --git a/src/main/resources/jenkins/plugins/jobcacher/ArbitraryFileCache/config.jelly b/src/main/resources/jenkins/plugins/jobcacher/ArbitraryFileCache/config.jelly index 5a8d6ed..4359dec 100644 --- a/src/main/resources/jenkins/plugins/jobcacher/ArbitraryFileCache/config.jelly +++ b/src/main/resources/jenkins/plugins/jobcacher/ArbitraryFileCache/config.jelly @@ -49,7 +49,7 @@ - + diff --git a/src/main/resources/jenkins/plugins/jobcacher/CacheWrapper/config.jelly b/src/main/resources/jenkins/plugins/jobcacher/CacheWrapper/config.jelly index 51c6473..df2c1e3 100644 --- a/src/main/resources/jenkins/plugins/jobcacher/CacheWrapper/config.jelly +++ b/src/main/resources/jenkins/plugins/jobcacher/CacheWrapper/config.jelly @@ -23,9 +23,6 @@ --> - - - - - - + + + + + + + + + diff --git a/src/main/resources/jenkins/plugins/jobcacher/pipeline/CacheStep/config.jelly b/src/main/resources/jenkins/plugins/jobcacher/pipeline/CacheStep/config.jelly index 51c6473..df2c1e3 100644 --- a/src/main/resources/jenkins/plugins/jobcacher/pipeline/CacheStep/config.jelly +++ b/src/main/resources/jenkins/plugins/jobcacher/pipeline/CacheStep/config.jelly @@ -23,9 +23,6 @@ --> - - - - - - + + + + + + + + + diff --git a/src/main/webapp/help-maximumCacheSize.html b/src/main/webapp/help-maximumCacheSize.html index 2dc8e29..665cc2f 100644 --- a/src/main/webapp/help-maximumCacheSize.html +++ b/src/main/webapp/help-maximumCacheSize.html @@ -25,5 +25,5 @@
The maximum size in megabytes of all configured caches that Jenkins will allow until it deletes all completely and starts the next build from an empty cache. This prevents caches from growing indefinitely with the downside of - periodic fresh builds without a cache. + periodic fresh builds without a cache. Set to zero or empty to skip checking cache size.
\ No newline at end of file diff --git a/src/test/java/jenkins/plugins/jobcacher/ArbitraryFileCacheWrapperTest.java b/src/test/java/jenkins/plugins/jobcacher/ArbitraryFileCacheWrapperTest.java index d2c2c45..a45acdb 100644 --- a/src/test/java/jenkins/plugins/jobcacher/ArbitraryFileCacheWrapperTest.java +++ b/src/test/java/jenkins/plugins/jobcacher/ArbitraryFileCacheWrapperTest.java @@ -34,7 +34,8 @@ private FreeStyleProject createProjectWithFullyConfiguredArbitraryFileCache(Stri cache.setUseDefaultExcludes(false); cache.setCacheName("cacheName"); - CacheWrapper cacheWrapper = new CacheWrapper(999, Collections.singletonList(cache)); + CacheWrapper cacheWrapper = new CacheWrapper(Collections.singletonList(cache)); + cacheWrapper.setMaxCacheSize(999L); cacheWrapper.setDefaultBranch("develop"); FreeStyleProject project = jenkins.createProject(FreeStyleProject.class, name);