diff --git a/src/main/java/com/nirima/jenkins/plugins/docker/DockerCloud.java b/src/main/java/com/nirima/jenkins/plugins/docker/DockerCloud.java
index 73f2d4a85..e88ca4d01 100644
--- a/src/main/java/com/nirima/jenkins/plugins/docker/DockerCloud.java
+++ b/src/main/java/com/nirima/jenkins/plugins/docker/DockerCloud.java
@@ -16,6 +16,7 @@
import com.github.dockerjava.api.command.PushImageCmd;
import com.github.dockerjava.api.command.StartContainerCmd;
import com.github.dockerjava.api.model.AuthConfig;
+import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.api.model.Version;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
@@ -601,21 +602,33 @@ public synchronized void removeTemplate(DockerTemplate t) {
templates.remove(t);
}
}
+
+ /**
+ * @deprecated use countContainersInDocker(String, String) instead
+ * @see DockerCloud#countContainersInDocker(String, String)
+ */
+ @Deprecated
+ public int countContainersInDocker(final String imageName) throws Exception {
+ return countContainersInDocker(imageName, null);
+ }
/**
* Counts the number of instances currently running in Docker that are using
- * the specified image.
+ * the specified image and template.
+ * Returns all containers matching the given filter parameters.
+ *
*
* WARNING: This method can be slow so it should be called sparingly.
*
* @param imageName
- * If null, then all instances belonging to this Jenkins instance
- * are counted. Otherwise, only those started with the specified
- * image are counted.
+ * filter for imageName. If null, no filter is active for imageName.
+ * @param templateName
+ * filter for templateName. If null, no filter is active for templateName.
+ *
* @return The number of containers.
* @throws Exception if anything went wrong.
*/
- public int countContainersInDocker(final String imageName) throws Exception {
+ public int countContainersInDocker(final String imageName, final String templateName) throws Exception {
final Map labelFilter = new HashMap<>();
labelFilter.put(
DockerContainerLabelKeys.JENKINS_INSTANCE_ID,
@@ -623,10 +636,14 @@ public int countContainersInDocker(final String imageName) throws Exception {
if (imageName != null) {
labelFilter.put(DockerContainerLabelKeys.CONTAINER_IMAGE, imageName);
}
- final List> containers;
+ if (templateName != null) {
+ labelFilter.put(DockerContainerLabelKeys.TEMPLATE_NAME, templateName);
+ }
+ final List containers;
try (final DockerClient client = dockerApi.getClient()) {
containers = client.listContainersCmd().withLabelFilter(labelFilter).exec();
}
+
final int count = containers.size();
return count;
}
@@ -636,6 +653,7 @@ public int countContainersInDocker(final String imageName) throws Exception {
*/
private boolean canAddProvisionedAgent(DockerTemplate t) throws Exception {
final String templateImage = t.getImage();
+ final String templateName = t.getName();
final int templateContainerCap = t.instanceCap;
final int cloudContainerCap = getContainerCap();
@@ -643,7 +661,7 @@ private boolean canAddProvisionedAgent(DockerTemplate t) throws Exception {
final boolean haveTemplateContainerCap = templateContainerCap > 0 && templateContainerCap != Integer.MAX_VALUE;
final int estimatedTotalAgents;
if (haveCloudContainerCap) {
- final int totalContainersInCloud = countContainersInDocker(null);
+ final int totalContainersInCloud = countContainersInDocker(null, null);
final int containersInProgress = countContainersInProgress();
estimatedTotalAgents = totalContainersInCloud + containersInProgress;
if (estimatedTotalAgents >= cloudContainerCap) {
@@ -659,7 +677,7 @@ private boolean canAddProvisionedAgent(DockerTemplate t) throws Exception {
}
final int estimatedTemplateAgents;
if (haveTemplateContainerCap) {
- final int totalContainersOfThisTemplateInCloud = countContainersInDocker(templateImage);
+ final int totalContainersOfThisTemplateInCloud = countContainersInDocker(templateImage, templateName);
final int containersInProgress = countContainersInProgress(t);
estimatedTemplateAgents = totalContainersOfThisTemplateInCloud + containersInProgress;
if (estimatedTemplateAgents >= templateContainerCap) {
diff --git a/src/main/resources/com/nirima/jenkins/plugins/docker/DockerTemplate/help-name.html b/src/main/resources/com/nirima/jenkins/plugins/docker/DockerTemplate/help-name.html
index c1fbde80c..64236e40f 100644
--- a/src/main/resources/com/nirima/jenkins/plugins/docker/DockerTemplate/help-name.html
+++ b/src/main/resources/com/nirima/jenkins/plugins/docker/DockerTemplate/help-name.html
@@ -4,4 +4,8 @@
Jenkins will append a unique ID to this name in order to create individual node names.
If blank or just whitespace, a default of "docker" will be used.
+
+ When using the same docker image in multiple docker agent templates, make sure to set an individual name for each template.
+ This is needed for capping by number of container instance by template to work correctly.
+
diff --git a/src/test/java/io/jenkins/docker/connector/DockerComputerConnectorTest.java b/src/test/java/io/jenkins/docker/connector/DockerComputerConnectorTest.java
index 355488dbd..fe41ad2d0 100644
--- a/src/test/java/io/jenkins/docker/connector/DockerComputerConnectorTest.java
+++ b/src/test/java/io/jenkins/docker/connector/DockerComputerConnectorTest.java
@@ -148,7 +148,7 @@ private boolean dockerIsStillBusy() throws Exception {
return true;
}
}
- final int containersInDocker = cloud.countContainersInDocker(null);
+ final int containersInDocker = cloud.countContainersInDocker(null, null);
if (containersInDocker > 0) {
return true;
}