From fe793d41e0526ce272154fc63092b9b59f2d414d Mon Sep 17 00:00:00 2001 From: Ludovico Cavedon Date: Wed, 13 Nov 2024 11:11:00 -0800 Subject: [PATCH] Allow randomizing cloud selection When multiple Docker clouds are defined, the plugin will always create agents from the first available cloud, not allowing to distribute the load on all the clouds that are defined. Possible solutions to this issue are: - Docker Swarm Standalone, which is deprecated - Docker Engine Swarm API, which is not supported by docker-plugin. This changes adds a setting that enables randomizing the order in which Docker clouds are tried when creating a new agent. --- .../docker/DockerGlobalConfiguration.java | 29 +++++++++++++++++++ .../docker/FastNodeProvisionerStrategy.java | 21 +++++++++++--- .../DockerGlobalConfiguration/config.jelly | 10 +++++++ 3 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 src/main/java/io/jenkins/docker/DockerGlobalConfiguration.java create mode 100644 src/main/resources/io/jenkins/docker/DockerGlobalConfiguration/config.jelly diff --git a/src/main/java/io/jenkins/docker/DockerGlobalConfiguration.java b/src/main/java/io/jenkins/docker/DockerGlobalConfiguration.java new file mode 100644 index 000000000..716c4b0db --- /dev/null +++ b/src/main/java/io/jenkins/docker/DockerGlobalConfiguration.java @@ -0,0 +1,29 @@ +package io.jenkins.docker; + +import jenkins.model.GlobalConfiguration; +import org.kohsuke.stapler.DataBoundSetter; +import hudson.Extension; +import hudson.ExtensionList; + +@Extension +public class DockerGlobalConfiguration extends GlobalConfiguration { + public static DockerGlobalConfiguration get() { + return ExtensionList.lookupSingleton(DockerGlobalConfiguration.class); + } + + private boolean randomizeCloudsOrder = false; + + public DockerGlobalConfiguration() { + load(); + } + + public boolean getRandomizeCloudsOrder() { + return randomizeCloudsOrder; + } + + @DataBoundSetter + public void setRandomizeCloudsOrder(boolean value) { + randomizeCloudsOrder = value; + save(); + } +} diff --git a/src/main/java/io/jenkins/docker/FastNodeProvisionerStrategy.java b/src/main/java/io/jenkins/docker/FastNodeProvisionerStrategy.java index 6b4f8a25c..cc159c5f5 100644 --- a/src/main/java/io/jenkins/docker/FastNodeProvisionerStrategy.java +++ b/src/main/java/io/jenkins/docker/FastNodeProvisionerStrategy.java @@ -6,6 +6,7 @@ import static hudson.slaves.NodeProvisioner.StrategyDecision.PROVISIONING_COMPLETED; import static java.util.logging.Level.FINE; import static java.util.logging.Level.FINEST; +import static java.util.logging.Level.WARNING; import com.nirima.jenkins.plugins.docker.DockerCloud; import edu.umd.cs.findbugs.annotations.NonNull; @@ -16,7 +17,9 @@ import hudson.model.queue.QueueListener; import hudson.slaves.Cloud; import hudson.slaves.NodeProvisioner; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.logging.Logger; import jenkins.model.Jenkins; @@ -36,12 +39,22 @@ public StrategyDecision apply(@NonNull NodeProvisioner.StrategyState state) { if (Jenkins.get().isQuietingDown()) { return CONSULT_REMAINING_STRATEGIES; } + ArrayList dockerClouds = new ArrayList(); for (Cloud cloud : Jenkins.get().clouds) { if (cloud instanceof DockerCloud) { - final StrategyDecision decision = applyToCloud(state, (DockerCloud) cloud); - if (decision == PROVISIONING_COMPLETED) { - return decision; - } + dockerClouds.add((DockerCloud) cloud); + } + } + if (DockerGlobalConfiguration.get().getRandomizeCloudsOrder()) { + LOGGER.log(WARNING, "Randomizing cloud order"); + Collections.shuffle(dockerClouds); + } else { + LOGGER.log(WARNING, "Not randomizing cloud order"); + } + for (DockerCloud cloud : dockerClouds) { + final StrategyDecision decision = applyToCloud(state, cloud); + if (decision == PROVISIONING_COMPLETED) { + return decision; } } return CONSULT_REMAINING_STRATEGIES; diff --git a/src/main/resources/io/jenkins/docker/DockerGlobalConfiguration/config.jelly b/src/main/resources/io/jenkins/docker/DockerGlobalConfiguration/config.jelly new file mode 100644 index 000000000..632437f92 --- /dev/null +++ b/src/main/resources/io/jenkins/docker/DockerGlobalConfiguration/config.jelly @@ -0,0 +1,10 @@ + + + + + + + + +