From 86b26fbc15dd710ca6bdea13c5823d17df6bdebe Mon Sep 17 00:00:00 2001 From: lorgouil Date: Tue, 16 Jul 2019 15:11:11 +0200 Subject: [PATCH 1/5] Adding a new feature to schedule slaves for termination --- pom.xml | 86 ++++++------ .../compute/JCloudsPreCreationThread.java | 117 +++++++++++++++++ .../compute/JCloudsRetentionStrategy.java | 122 ++++++++++++++---- .../openstack/compute/SlaveOptions.java | 25 +++- .../compute/SlaveOptions/config.jelly | 3 + .../plugins/openstack/PluginTestRule.java | 2 +- .../openstack/compute/JCloudsCloudTest.java | 4 +- .../openstack/compute/SlaveOptionsTest.java | 2 +- 8 files changed, 285 insertions(+), 76 deletions(-) diff --git a/pom.xml b/pom.xml index d31056ac..dd9b9d21 100644 --- a/pom.xml +++ b/pom.xml @@ -7,14 +7,14 @@ openstack-cloud - 2.48-SNAPSHOT + 2.47 hpi OpenStack Cloud Plugin Allows Jenkins to build OpenStack Slaves https://wiki.jenkins-ci.org/display/JENKINS/Openstack+Cloud+Plugin - 2.98 + 2.176.1 2.27 8 1C @@ -30,9 +30,9 @@ - olivergondza - Oliver Gondža - ogondza@gmail.com + olivergondza + Oliver Gondža + ogondza@gmail.com @@ -100,12 +100,6 @@ resource-disposer 0.5 - - org.jenkins-ci.plugins.workflow - workflow-durable-task-step - 2.8 - true - @@ -116,12 +110,12 @@ org.jenkins-ci symbol-annotation - 1.5 + 1.18 org.jenkins-ci.plugins script-security - 1.36 + 1.58 org.apache.ant @@ -138,18 +132,13 @@ plexus-classworlds 2.4.2 - - org.jenkins-ci - symbol-annotation - 1.17 - org.yaml snakeyaml 1.23 - + org.hamcrest hamcrest-core @@ -162,31 +151,6 @@ 1.9.5 test - - org.jenkins-ci.plugins.workflow - workflow-cps - 2.25 - test - - - org.jenkins-ci.plugins.workflow - workflow-support - tests - 2.12 - test - - - org.jenkins-ci.plugins.workflow - workflow-job - 2.9 - test - - - org.jenkins-ci.plugins.workflow - workflow-basic-steps - 2.3 - test - org.jenkins-ci.plugins command-launcher @@ -213,8 +177,35 @@ test test-jar + + org.jenkins-ci.plugins.workflow + workflow-step-api + 2.20 + + + org.jenkins-ci.plugins + structs + 1.18 + + + org.jenkins-ci.plugins.workflow + workflow-job + 2.31 + test + + + org.jenkins-ci.plugins.workflow + workflow-cps + 2.70 + test + + + org.jenkins-ci.plugins.workflow + workflow-support + 3.3 + test + - @@ -233,7 +224,7 @@ - + ${project.artifactId} @@ -242,7 +233,7 @@ scm:git:ssh://github.com/jenkinsci/openstack-cloud-plugin.git scm:git:ssh://git@github.com/jenkinsci/openstack-cloud-plugin.git https://github.com/jenkinsci/openstack-cloud-plugin - HEAD + openstack-cloud-2.47 @@ -258,3 +249,4 @@ + diff --git a/src/main/java/jenkins/plugins/openstack/compute/JCloudsPreCreationThread.java b/src/main/java/jenkins/plugins/openstack/compute/JCloudsPreCreationThread.java index 5dc60f0f..845f1f03 100644 --- a/src/main/java/jenkins/plugins/openstack/compute/JCloudsPreCreationThread.java +++ b/src/main/java/jenkins/plugins/openstack/compute/JCloudsPreCreationThread.java @@ -2,10 +2,12 @@ import java.lang.Math; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import hudson.model.Executor; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -13,6 +15,7 @@ import hudson.Functions; import hudson.model.TaskListener; import hudson.model.AsyncPeriodicWork; +import org.openstack4j.model.compute.Server; /** * Periodically ensure enough slaves are created. @@ -92,6 +95,91 @@ public void execute(TaskListener listener) { } } + /** + * Methods which return the list of VM + */ + public static List getVmList(String templateName, String cloudName){ + List vmList = null; + for (JCloudsCloud cloud : JCloudsCloud.getClouds()) { + if (cloud.getDisplayName().equals(cloudName)){ + vmList = cloud.getTemplate(templateName).getRunningNodes(); + } + } + return vmList; + } + + /** + * Methods which return the name of the oldestVM for a specific template. + */ + public static String getOldestVm(String templateName, String cloudName){ + return getOldestVM(templateName, cloudName).getName(); + } + + + /** + * Methods which return the oldestVM + * return a Server + * return a VM which is not offline/Pending delete in Jenkins + */ + private static Server getOldestVM(String templateName, String cloudName){ + Server oldestVm = null; + long oldestVmTime; + long currentVMTime; + String computerName; + String vmName; + List vmList = getVmList(templateName, cloudName); + List listComputer = JCloudsComputer.getAll(); + if (oldestVm == null){ + oldestVm = vmList.get(0); + } + for (int i = 0; i currentVMTime){ + for (int y = 0; y listComputer = JCloudsComputer.getAll(); + List listExecutors; + //For each computer.. + for (int y=0; y { private transient ReentrantLock checkLock; + private static List listOldestVm = new ArrayList<>(); @DataBoundConstructor public JCloudsRetentionStrategy() { @@ -48,33 +51,108 @@ public long check(JCloudsComputer c) { } private void doCheck(JCloudsComputer c) { - if (c.isPendingDelete()) return; // No need to do it again + if (c.isPendingDelete()) return; if (c.isConnecting()) return; // Do not discard slave while launching for the first time when "idle time" does not make much sense - if (!c.isIdle() || c.getOfflineCause() instanceof OfflineCause.UserCause) return; // Occupied by user initiated activity - final JCloudsSlave node = c.getNode(); - if (node == null) return; // Node is gone already - - final int retentionTime = node.getSlaveOptions().getRetentionTime(); - if (retentionTime <= 0) return; // 0 is handled in JCloudsComputer, negative values needs no handling - final long idleSince = c.getIdleStart(); - final long idleMilliseconds = getNow() - idleSince; - if (idleMilliseconds > TimeUnit.MINUTES.toMillis(retentionTime)) { - if (JCloudsPreCreationThread.isNeededReadyComputer(node.getComputer())) { - LOGGER.info("Keeping " + c .getName() + " to meet minimum requirements"); - return; + boolean oldestSlaveTermination = node.getSlaveOptions().getOldestSlaveTermination(); + String templateName = c.getId().getTemplateName(); + String cloudName = c.getId().getCloudName(); + String oldestVmName = ""; + + //case where the checkbox isn't checked + if (oldestSlaveTermination == false) { + if (!c.isIdle() || c.getOfflineCause() instanceof OfflineCause.UserCause) + return; // Occupied by user initiated activity + + if (node == null) return; // Node is gone already + + final int retentionTime = node.getSlaveOptions().getRetentionTime(); + + if ((retentionTime >= 0)) {// 0 is handled in JCloudsComputer, negative values needs no handling + final long idleSince = c.getIdleStart(); + final long idleMilliseconds = getNow() - idleSince; + if (idleMilliseconds > TimeUnit.MINUTES.toMillis(retentionTime)) { + if (JCloudsPreCreationThread.isNeededReadyComputer(node.getComputer())) { + LOGGER.info("Keeping " + c.getName() + " to meet minimum requirements"); + return; + } + LOGGER.info("Scheduling " + c.getName() + " for termination after " + retentionTime + " minutes as it was idle since " + new Date(idleSince)); + if (LOGGER.isLoggable(Level.FINE)) { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Jenkins.XSTREAM2.toXMLUTF8(node, out); + LOGGER.fine(out.toString("UTF-8")); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Failed to dump node config", e); + } + } + c.setPendingDelete(true); + } + } + } + + + //case where the checkbox is checked + if ((oldestSlaveTermination == true)) { + + + //number of free executors in our VM template + int numOfFreeExec = JCloudsPreCreationThread.getNumOfFreeExec(templateName); + + //number of executor required for our template + int numOfMinExec = c.getNode().getSlaveOptions().getNumExecutors() * node.getSlaveOptions().getInstancesMin(); + + //If oldest VM list is empty + if (listOldestVm.isEmpty()){ + //Find the oldest VM for the template of the current Computer + oldestVmName = JCloudsPreCreationThread.getOldestVm(templateName, cloudName); + //New object + JCloudsPreCreationThread.OldestVM oldestVM = new JCloudsPreCreationThread.OldestVM(templateName, oldestVmName); + //Add the object to the oldest VM list + listOldestVm.add(oldestVM); + } else { + + boolean templateInTheList = false; + for (int i = 0; i numOfMinExec){ + //If the current VM is the oldest + for (int i = 0; i, Serializable { private static final long serialVersionUID = -1L; - private static final SlaveOptions EMPTY = new SlaveOptions(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); + private static final SlaveOptions EMPTY = new SlaveOptions(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, false); // Provisioning attributes private /*final*/ @CheckForNull BootSource bootSource; @@ -75,6 +77,7 @@ public class SlaveOptions implements Describable, Serializable { // Slave attributes private final Integer retentionTime; + private final boolean oldestSlaveTermination; // Replaced by BootSource @Deprecated private transient @CheckForNull String imageId; @@ -143,6 +146,8 @@ public Integer getRetentionTime() { return retentionTime; } + public boolean getOldestSlaveTermination() { return oldestSlaveTermination; } + public SlaveOptions(Builder b) { this( b.bootSource, @@ -160,7 +165,8 @@ public SlaveOptions(Builder b) { b.jvmOptions, b.fsRoot, b.launcherFactory, - b.retentionTime + b.retentionTime, + b.oldestSlaveTermination ); } @@ -181,7 +187,8 @@ public SlaveOptions( String jvmOptions, String fsRoot, LauncherFactory launcherFactory, - Integer retentionTime + Integer retentionTime, + boolean oldestSlaveTermination ) { this.bootSource = bootSource; this.hardwareId = Util.fixEmpty(hardwareId); @@ -199,6 +206,7 @@ public SlaveOptions( this.fsRoot = Util.fixEmpty(fsRoot); this.launcherFactory = launcherFactory; this.retentionTime = retentionTime; + this.oldestSlaveTermination = TRUE.equals(oldestSlaveTermination); } private Object readResolve() { @@ -230,6 +238,7 @@ private Object readResolve() { .fsRoot(_override(this.fsRoot, o.fsRoot)) .launcherFactory(_override(this.launcherFactory, o.launcherFactory)) .retentionTime(_override(this.retentionTime, o.retentionTime)) + .oldestSlaveTermination(_override(this.oldestSlaveTermination, o.oldestSlaveTermination)) .build() ; } @@ -259,6 +268,7 @@ private Object readResolve() { .fsRoot(_erase(this.fsRoot, defaults.fsRoot)) .launcherFactory(_erase(this.launcherFactory, defaults.launcherFactory)) .retentionTime(_erase(this.retentionTime, defaults.retentionTime)) + .oldestSlaveTermination(this.oldestSlaveTermination) .build() ; } @@ -289,6 +299,7 @@ public String toString() { .append("fsRoot", fsRoot) .append("launcherFactory", launcherFactory) .append("retentionTime", retentionTime) + .append("oldestSlaveTermination", oldestSlaveTermination) .toString() ; } @@ -361,6 +372,7 @@ public Builder getBuilder() { .fsRoot(fsRoot) .launcherFactory(launcherFactory) .retentionTime(retentionTime) + .oldestSlaveTermination(oldestSlaveTermination) ; } @@ -394,6 +406,7 @@ public static final class Builder { private @CheckForNull LauncherFactory launcherFactory; private @CheckForNull Integer retentionTime; + private boolean oldestSlaveTermination; public Builder() {} @@ -480,6 +493,12 @@ public Builder() {} this.retentionTime = retentionTime; return this; } + + public @Nonnull Builder oldestSlaveTermination(boolean oldestSlaveTermination) { + this.oldestSlaveTermination = oldestSlaveTermination; + return this; + } + } /** diff --git a/src/main/resources/jenkins/plugins/openstack/compute/SlaveOptions/config.jelly b/src/main/resources/jenkins/plugins/openstack/compute/SlaveOptions/config.jelly index 82913f40..310b2b7d 100644 --- a/src/main/resources/jenkins/plugins/openstack/compute/SlaveOptions/config.jelly +++ b/src/main/resources/jenkins/plugins/openstack/compute/SlaveOptions/config.jelly @@ -63,6 +63,9 @@ + + + diff --git a/src/test/java/jenkins/plugins/openstack/PluginTestRule.java b/src/test/java/jenkins/plugins/openstack/PluginTestRule.java index 7ac8689e..f0ac0fab 100644 --- a/src/test/java/jenkins/plugins/openstack/PluginTestRule.java +++ b/src/test/java/jenkins/plugins/openstack/PluginTestRule.java @@ -114,7 +114,7 @@ public static SlaveOptions dummySlaveOptions() { } return new SlaveOptions( new BootSource.VolumeSnapshot("id"), "hw", "nw1,mw2", "dummyUserDataId", 1, 2, "pool", "sg", "az", 1, null, 10, - "jvmo", "fsRoot", LauncherFactory.JNLP.JNLP, 1 + "jvmo", "fsRoot", LauncherFactory.JNLP.JNLP, 1, false ); } diff --git a/src/test/java/jenkins/plugins/openstack/compute/JCloudsCloudTest.java b/src/test/java/jenkins/plugins/openstack/compute/JCloudsCloudTest.java index d3c829b7..9136320e 100644 --- a/src/test/java/jenkins/plugins/openstack/compute/JCloudsCloudTest.java +++ b/src/test/java/jenkins/plugins/openstack/compute/JCloudsCloudTest.java @@ -151,10 +151,10 @@ public void presentUIDefaults() throws Exception { JCloudsSlaveTemplate template = new JCloudsSlaveTemplate("template", "label", new SlaveOptions( new BootSource.Image("iid"), "hw", "nw", "ud", 1, 0, "public", "sg", "az", 2, "kp", 3, "jvmo", "fsRoot", LauncherFactory.JNLP.JNLP, 4 - )); + , false)); JCloudsCloud cloud = new JCloudsCloud("openstack", "endPointUrl", false,"zone", new SlaveOptions( new BootSource.VolumeSnapshot("vsid"), "HW", "NW", "UD", 6, 4, null, "SG", "AZ", 7, "KP", 8, "JVMO", "FSrOOT", new LauncherFactory.SSH("cid"), 9 - ), Collections.singletonList(template),openstackAuth); + , false), Collections.singletonList(template),openstackAuth); j.jenkins.clouds.add(cloud); JenkinsRule.WebClient wc = j.createWebClient(); diff --git a/src/test/java/jenkins/plugins/openstack/compute/SlaveOptionsTest.java b/src/test/java/jenkins/plugins/openstack/compute/SlaveOptionsTest.java index 310497e5..5c482375 100644 --- a/src/test/java/jenkins/plugins/openstack/compute/SlaveOptionsTest.java +++ b/src/test/java/jenkins/plugins/openstack/compute/SlaveOptionsTest.java @@ -90,7 +90,7 @@ public void emptyStrings() { SlaveOptions nulls = SlaveOptions.empty(); SlaveOptions emptyStrings = new SlaveOptions( null, "", "", "", null, null, "", "", "", null, "", null, "", "", null, null - ); + , false); SlaveOptions emptyBuilt = SlaveOptions.builder() .hardwareId("") .networkId("") From 0d7c7d6bab40754bc0d95cc3e0f71a0498db5feb Mon Sep 17 00:00:00 2001 From: lorgouil Date: Tue, 16 Jul 2019 16:44:18 +0200 Subject: [PATCH 2/5] Adding a new feature to schedule slaves for termination --- pom.xml | 77 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/pom.xml b/pom.xml index dd9b9d21..c5b99e36 100644 --- a/pom.xml +++ b/pom.xml @@ -7,14 +7,14 @@ openstack-cloud - 2.47 + 2.48-SNAPSHOT hpi OpenStack Cloud Plugin Allows Jenkins to build OpenStack Slaves https://wiki.jenkins-ci.org/display/JENKINS/Openstack+Cloud+Plugin - 2.176.1 + 2.98 2.27 8 1C @@ -100,6 +100,12 @@ resource-disposer 0.5 + + org.jenkins-ci.plugins.workflow + workflow-durable-task-step + 2.8 + true + @@ -110,12 +116,12 @@ org.jenkins-ci symbol-annotation - 1.18 + 1.5 org.jenkins-ci.plugins script-security - 1.58 + 1.36 org.apache.ant @@ -132,13 +138,18 @@ plexus-classworlds 2.4.2 + + org.jenkins-ci + symbol-annotation + 1.17 + org.yaml snakeyaml 1.23 - + org.hamcrest hamcrest-core @@ -151,6 +162,31 @@ 1.9.5 test + + org.jenkins-ci.plugins.workflow + workflow-cps + 2.25 + test + + + org.jenkins-ci.plugins.workflow + workflow-support + tests + 2.12 + test + + + org.jenkins-ci.plugins.workflow + workflow-job + 2.9 + test + + + org.jenkins-ci.plugins.workflow + workflow-basic-steps + 2.3 + test + org.jenkins-ci.plugins command-launcher @@ -177,35 +213,8 @@ test test-jar - - org.jenkins-ci.plugins.workflow - workflow-step-api - 2.20 - - - org.jenkins-ci.plugins - structs - 1.18 - - - org.jenkins-ci.plugins.workflow - workflow-job - 2.31 - test - - - org.jenkins-ci.plugins.workflow - workflow-cps - 2.70 - test - - - org.jenkins-ci.plugins.workflow - workflow-support - 3.3 - test - + @@ -233,7 +242,7 @@ scm:git:ssh://github.com/jenkinsci/openstack-cloud-plugin.git scm:git:ssh://git@github.com/jenkinsci/openstack-cloud-plugin.git https://github.com/jenkinsci/openstack-cloud-plugin - openstack-cloud-2.47 + HEAD From e540b1eaf8b41fd65a2b30f7d6b23a499290ccdb Mon Sep 17 00:00:00 2001 From: lorgouil Date: Wed, 17 Jul 2019 10:40:19 +0200 Subject: [PATCH 3/5] Adding a new feature to schedule slaves for termination --- .../compute/JCloudsRetentionStrategy.java | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/main/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategy.java b/src/main/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategy.java index ab857ae9..5b49e5ee 100644 --- a/src/main/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategy.java +++ b/src/main/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategy.java @@ -68,30 +68,28 @@ private void doCheck(JCloudsComputer c) { final int retentionTime = node.getSlaveOptions().getRetentionTime(); - if ((retentionTime >= 0)) {// 0 is handled in JCloudsComputer, negative values needs no handling - final long idleSince = c.getIdleStart(); - final long idleMilliseconds = getNow() - idleSince; - if (idleMilliseconds > TimeUnit.MINUTES.toMillis(retentionTime)) { - if (JCloudsPreCreationThread.isNeededReadyComputer(node.getComputer())) { - LOGGER.info("Keeping " + c.getName() + " to meet minimum requirements"); - return; - } - LOGGER.info("Scheduling " + c.getName() + " for termination after " + retentionTime + " minutes as it was idle since " + new Date(idleSince)); - if (LOGGER.isLoggable(Level.FINE)) { - try { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - Jenkins.XSTREAM2.toXMLUTF8(node, out); - LOGGER.fine(out.toString("UTF-8")); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to dump node config", e); - } + if ((retentionTime <= 0)) return; // 0 is handled in JCloudsComputer, negative values needs no handling + final long idleSince = c.getIdleStart(); + final long idleMilliseconds = getNow() - idleSince; + if (idleMilliseconds > TimeUnit.MINUTES.toMillis(retentionTime)) { + if (JCloudsPreCreationThread.isNeededReadyComputer(node.getComputer())) { + LOGGER.info("Keeping " + c.getName() + " to meet minimum requirements"); + return; + } + LOGGER.info("Scheduling " + c.getName() + " for termination after " + retentionTime + " minutes as it was idle since " + new Date(idleSince)); + if (LOGGER.isLoggable(Level.FINE)) { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + Jenkins.XSTREAM2.toXMLUTF8(node, out); + LOGGER.fine(out.toString("UTF-8")); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Failed to dump node config", e); } - c.setPendingDelete(true); } + c.setPendingDelete(true); } } - //case where the checkbox is checked if ((oldestSlaveTermination == true)) { From 65b897334881626c6dfcaa578904dd7bac0c6dd3 Mon Sep 17 00:00:00 2001 From: lorgouil Date: Wed, 17 Jul 2019 12:41:23 +0200 Subject: [PATCH 4/5] Adding a new feature to schedule slaves for termination --- .../openstack/compute/JCloudsRetentionStrategy.java | 11 +++++------ .../compute/JCloudsRetentionStrategyTest.java | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategy.java b/src/main/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategy.java index 5b49e5ee..ac0c6b95 100644 --- a/src/main/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategy.java +++ b/src/main/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategy.java @@ -55,20 +55,16 @@ private void doCheck(JCloudsComputer c) { if (c.isConnecting()) return; // Do not discard slave while launching for the first time when "idle time" does not make much sense final JCloudsSlave node = c.getNode(); boolean oldestSlaveTermination = node.getSlaveOptions().getOldestSlaveTermination(); - String templateName = c.getId().getTemplateName(); - String cloudName = c.getId().getCloudName(); - String oldestVmName = ""; //case where the checkbox isn't checked if (oldestSlaveTermination == false) { - if (!c.isIdle() || c.getOfflineCause() instanceof OfflineCause.UserCause) - return; // Occupied by user initiated activity + if (!c.isIdle() || c.getOfflineCause() instanceof OfflineCause.UserCause) return; // Occupied by user initiated activity if (node == null) return; // Node is gone already final int retentionTime = node.getSlaveOptions().getRetentionTime(); - if ((retentionTime <= 0)) return; // 0 is handled in JCloudsComputer, negative values needs no handling + if (retentionTime <= 0) return; // 0 is handled in JCloudsComputer, negative values needs no handling final long idleSince = c.getIdleStart(); final long idleMilliseconds = getNow() - idleSince; if (idleMilliseconds > TimeUnit.MINUTES.toMillis(retentionTime)) { @@ -93,6 +89,9 @@ private void doCheck(JCloudsComputer c) { //case where the checkbox is checked if ((oldestSlaveTermination == true)) { + String templateName = c.getId().getTemplateName(); + String cloudName = c.getId().getCloudName(); + String oldestVmName = ""; //number of free executors in our VM template int numOfFreeExec = JCloudsPreCreationThread.getNumOfFreeExec(templateName); diff --git a/src/test/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategyTest.java b/src/test/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategyTest.java index 35f3ec52..b3f84a2f 100644 --- a/src/test/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategyTest.java +++ b/src/test/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategyTest.java @@ -175,7 +175,7 @@ public void doNotRemoveSlaveShortlyAfterConnection() throws Exception { Assume.assumeFalse(Functions.isWindows()); LauncherFactory launcherFactory = new TestCommandLauncherFactory("bash -c \"sleep 70 && java -jar '%s'\""); JCloudsCloud cloud = j.configureSlaveProvisioningWithFloatingIP(j.dummyCloud(j.dummySlaveTemplate( - j.defaultSlaveOptions().getBuilder().retentionTime(1).launcherFactory(launcherFactory).build(), + j.defaultSlaveOptions().getBuilder().retentionTime(1).launcherFactory(launcherFactory).oldestSlaveTermination(false).build(), "label" ))); From e297b2cd4bc334a20bda1acd6d38d0f44e2b6d12 Mon Sep 17 00:00:00 2001 From: lorgouil Date: Wed, 17 Jul 2019 12:43:22 +0200 Subject: [PATCH 5/5] Adding a new feature to schedule slaves for termination --- .../openstack/compute/JCloudsRetentionStrategyTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategyTest.java b/src/test/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategyTest.java index b3f84a2f..0dd400f9 100644 --- a/src/test/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategyTest.java +++ b/src/test/java/jenkins/plugins/openstack/compute/JCloudsRetentionStrategyTest.java @@ -175,7 +175,8 @@ public void doNotRemoveSlaveShortlyAfterConnection() throws Exception { Assume.assumeFalse(Functions.isWindows()); LauncherFactory launcherFactory = new TestCommandLauncherFactory("bash -c \"sleep 70 && java -jar '%s'\""); JCloudsCloud cloud = j.configureSlaveProvisioningWithFloatingIP(j.dummyCloud(j.dummySlaveTemplate( - j.defaultSlaveOptions().getBuilder().retentionTime(1).launcherFactory(launcherFactory).oldestSlaveTermination(false).build(), + j.defaultSlaveOptions().getBuilder().retentionTime(1).launcherFactory(launcherFactory) + .oldestSlaveTermination(false).build(), "label" )));