diff --git a/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DeploymentPropertiesResolver.java b/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DeploymentPropertiesResolver.java index 0293a924..55817083 100644 --- a/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DeploymentPropertiesResolver.java +++ b/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/DeploymentPropertiesResolver.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Optional; import java.util.Properties; +import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -147,6 +148,14 @@ List getVolumes(Map kubernetesDeployerProperties) { return volumes; } + private String deducePropertyValue(Map deployerProps, String propNameSansPrefix, Supplier defaultValue) { + String propName = this.propertyPrefix + propNameSansPrefix; + String propValue = PropertyParserUtils.getDeploymentPropertyValue(deployerProps, propName); + if (!StringUtils.hasText(propValue)) { + propValue = defaultValue.get(); + } + return propValue; + } /** * Get the resource limits for the deployment request. A Pod can define its maximum needed resources by setting the @@ -159,33 +168,19 @@ List getVolumes(Map kubernetesDeployerProperties) { * @return the resource limits to use */ Map deduceResourceLimits(Map kubernetesDeployerProperties) { - String memory = PropertyParserUtils.getDeploymentPropertyValue(kubernetesDeployerProperties, - this.propertyPrefix + ".limits.memory"); - - if (!StringUtils.hasText(memory)) { - memory = properties.getLimits().getMemory(); - } + String memory = deducePropertyValue(kubernetesDeployerProperties, ".limits.memory", () -> properties.getLimits().getMemory()); - String cpu = PropertyParserUtils.getDeploymentPropertyValue(kubernetesDeployerProperties, - this.propertyPrefix + ".limits.cpu"); + String cpu = deducePropertyValue(kubernetesDeployerProperties, ".limits.cpu", () -> properties.getLimits().getCpu()); - if (!StringUtils.hasText(cpu)) { - cpu = properties.getLimits().getCpu(); - } + String ephemeralStorage = deducePropertyValue(kubernetesDeployerProperties, ".limits.ephemeral-storage", () -> properties.getLimits().getEphemeralStorage()); - String gpuVendor = PropertyParserUtils.getDeploymentPropertyValue(kubernetesDeployerProperties, - this.propertyPrefix + ".limits.gpuVendor"); + String hugePages2Mi = deducePropertyValue(kubernetesDeployerProperties, ".limits.hugepages-2Mi", () -> properties.getLimits().getHugepages2Mi()); - if (!StringUtils.hasText(gpuVendor)) { - gpuVendor = properties.getLimits().getGpuVendor(); - } + String hugePages1Gi = deducePropertyValue(kubernetesDeployerProperties, ".limits.hugepages-1Gi", () -> properties.getLimits().getHugepages1Gi()); - String gpuCount = PropertyParserUtils.getDeploymentPropertyValue(kubernetesDeployerProperties, - this.propertyPrefix + ".limits.gpuCount"); + String gpuVendor = deducePropertyValue(kubernetesDeployerProperties, ".limits.gpuVendor", () -> properties.getLimits().getGpuVendor()); - if (!StringUtils.hasText(gpuCount)) { - gpuCount = properties.getLimits().getGpuCount(); - } + String gpuCount = deducePropertyValue(kubernetesDeployerProperties, ".limits.gpuCount", () -> properties.getLimits().getGpuCount()); Map limits = new HashMap(); @@ -197,10 +192,25 @@ Map deduceResourceLimits(Map kubernetesDeploye limits.put("cpu", new Quantity(cpu)); } + if(StringUtils.hasText(ephemeralStorage)) { + limits.put("ephemeral-storage", new Quantity(ephemeralStorage)); + } + + if(StringUtils.hasText(hugePages2Mi)) { + limits.put("hugepages-2Mi", new Quantity(hugePages2Mi)); + } + + if(StringUtils.hasText(hugePages1Gi)) { + limits.put("hugepages-1Gi", new Quantity(hugePages1Gi)); + } + if (StringUtils.hasText(gpuVendor) && StringUtils.hasText(gpuCount)) { limits.put(gpuVendor + "/gpu", new Quantity(gpuCount)); } + if(logger.isDebugEnabled()) { + logger.debug("limits:" + limits); + } return limits; } @@ -240,22 +250,19 @@ ImagePullPolicy deduceImagePullPolicy(Map kubernetesDeployerProp * @return the resource requests to use */ Map deduceResourceRequests(Map kubernetesDeployerProperties) { - String memOverride = PropertyParserUtils.getDeploymentPropertyValue(kubernetesDeployerProperties, - this.propertyPrefix + ".requests.memory"); + String memOverride = deducePropertyValue(kubernetesDeployerProperties, ".requests.memory", () -> properties.getRequests().getMemory()); - if (memOverride == null) { - memOverride = properties.getRequests().getMemory(); - } + String cpuOverride = deducePropertyValue(kubernetesDeployerProperties, ".requests.cpu", () -> properties.getRequests().getCpu()); + String ephemeralStorage = deducePropertyValue(kubernetesDeployerProperties, ".requests.ephemeral-storage", () -> properties.getLimits().getEphemeralStorage()); - String cpuOverride = PropertyParserUtils.getDeploymentPropertyValue(kubernetesDeployerProperties, - this.propertyPrefix + ".requests.cpu"); + String hugePages2Mi = deducePropertyValue(kubernetesDeployerProperties, ".requests.hugepages-2Mi", () -> properties.getLimits().getHugepages2Mi()); - if (cpuOverride == null) { - cpuOverride = properties.getRequests().getCpu(); - } + String hugePages1Gi = deducePropertyValue(kubernetesDeployerProperties, ".requests.hugepages-1Gi", () -> properties.getLimits().getHugepages1Gi()); - logger.debug("Using requests - cpu: " + cpuOverride + " mem: " + memOverride); + if(logger.isDebugEnabled()) { + logger.debug("Using requests - cpu: " + cpuOverride + " mem: " + memOverride + " ephemeral-storage:" + ephemeralStorage + " hugepages-2Mi:" + hugePages2Mi + " hugepages-1Gi:" + hugePages1Gi); + } Map requests = new HashMap(); @@ -267,6 +274,21 @@ Map deduceResourceRequests(Map kubernetesDeplo requests.put("cpu", new Quantity(cpuOverride)); } + if(StringUtils.hasText(ephemeralStorage)) { + requests.put("ephemeral-storage", new Quantity(ephemeralStorage)); + } + + if(StringUtils.hasText(hugePages2Mi)) { + requests.put("hugepages-2Mi", new Quantity(hugePages2Mi)); + } + + if(StringUtils.hasText(hugePages1Gi)) { + requests.put("hugepages-1Gi", new Quantity(hugePages1Gi)); + } + + if(logger.isDebugEnabled()) { + logger.debug("requests:" + requests); + } return requests; } diff --git a/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesDeployerProperties.java b/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesDeployerProperties.java index 73703585..aa4ff59f 100755 --- a/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesDeployerProperties.java +++ b/spring-cloud-deployer-kubernetes/src/main/java/org/springframework/cloud/deployer/spi/kubernetes/KubernetesDeployerProperties.java @@ -90,6 +90,20 @@ public static class LimitsResources { */ private String memory; + /** + * Container resource ephemeral-storage limit. + */ + private String ephemeralStorage; + + /** + * Container resource hugepages-2Mi limit. + */ + private String hugepages2Mi; + + /** + * Container resource hugepages-1Gi limit. + */ + private String hugepages1Gi; /** * Container GPU vendor name for limit */ @@ -113,9 +127,12 @@ public LimitsResources() { * Use the default constructor and set() methods instead. */ @Deprecated - public LimitsResources(String cpu, String memory) { + public LimitsResources(String cpu, String memory, String ephemeralStorage, String hugepages2Mi, String hugepages1Gi) { this.cpu = cpu; this.memory = memory; + this.ephemeralStorage = ephemeralStorage; + this.hugepages2Mi = hugepages2Mi; + this.hugepages1Gi = hugepages1Gi; } public String getCpu() { @@ -134,6 +151,30 @@ public void setMemory(String memory) { this.memory = memory; } + public String getEphemeralStorage() { + return ephemeralStorage; + } + + public void setEphemeralStorage(String ephemeralStorage) { + this.ephemeralStorage = ephemeralStorage; + } + + public String getHugepages2Mi() { + return hugepages2Mi; + } + + public void setHugepages2Mi(String hugepages2Mi) { + this.hugepages2Mi = hugepages2Mi; + } + + public String getHugepages1Gi() { + return hugepages1Gi; + } + + public void setHugepages1Gi(String hugepages1Gi) { + this.hugepages1Gi = hugepages1Gi; + } + public String getGpuVendor() { return gpuVendor; } @@ -157,21 +198,39 @@ public void setGpuCount(String gpuCount) { public static class RequestsResources { /** - * Container request limit. + * Container cpu request. */ private String cpu; /** - * Container memory limit. + * Container memory request. */ private String memory; + /** + * Container resource ephemeral-storage request. + */ + private String ephemeralStorage; + + /** + * Container resource hugepages-2Mi request. + */ + private String hugepages2Mi; + + /** + * Container resource hugepages-1Gi request. + */ + private String hugepages1Gi; + public RequestsResources() { } - public RequestsResources(String cpu, String memory) { + public RequestsResources(String cpu, String memory, String ephemeralStorage, String hugepages2Mi, String hugepages1Gi) { this.cpu = cpu; this.memory = memory; + this.ephemeralStorage = ephemeralStorage; + this.hugepages2Mi = hugepages2Mi; + this.hugepages1Gi = hugepages1Gi; } public String getCpu() { @@ -189,6 +248,30 @@ public String getMemory() { public void setMemory(String memory) { this.memory = memory; } + + public String getEphemeralStorage() { + return ephemeralStorage; + } + + public void setEphemeralStorage(String ephemeralStorage) { + this.ephemeralStorage = ephemeralStorage; + } + + public String getHugepages2Mi() { + return hugepages2Mi; + } + + public void setHugepages2Mi(String hugepages2Mi) { + this.hugepages2Mi = hugepages2Mi; + } + + public String getHugepages1Gi() { + return hugepages1Gi; + } + + public void setHugepages1Gi(String hugepages1Gi) { + this.hugepages1Gi = hugepages1Gi; + } } public static class StatefulSet { diff --git a/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/RunAbstractKubernetesDeployerTests.java b/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/RunAbstractKubernetesDeployerTests.java index 8406b7c5..57e5d44f 100755 --- a/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/RunAbstractKubernetesDeployerTests.java +++ b/spring-cloud-deployer-kubernetes/src/test/java/org/springframework/cloud/deployer/spi/kubernetes/RunAbstractKubernetesDeployerTests.java @@ -170,4 +170,52 @@ public void requestMemory_deploymentProperty_usesDeploymentProperty() { Map requests = this.deploymentPropertiesResolver.deduceResourceRequests(deploymentRequest.getDeploymentProperties()); assertThat(requests.get("memory")).isEqualTo(new Quantity("256Mi")); } + + @Test + public void requestEphemeralStorage_deploymentProperty_usesDeploymentProperty() { + kubernetesDeployerProperties.getRequests().setEphemeralStorage("2Gi"); + deploymentProperties.put("spring.cloud.deployer.kubernetes.requests.ephemeral-storage", "2Gi"); + Map requests = this.deploymentPropertiesResolver.deduceResourceRequests(deploymentRequest.getDeploymentProperties()); + assertThat(requests.get("ephemeral-storage")).isEqualTo(new Quantity("2Gi")); + } + + @Test + public void limitEphemeralStorage_deploymentProperty_usesDeploymentProperty() { + kubernetesDeployerProperties.getLimits().setEphemeralStorage("2Gi"); + deploymentProperties.put("spring.cloud.deployer.kubernetes.limits.ephemeral-storage", "2Gi"); + Map limits = this.deploymentPropertiesResolver.deduceResourceLimits(deploymentRequest.getDeploymentProperties()); + assertThat(limits.get("ephemeral-storage")).isEqualTo(new Quantity("2Gi")); + } + + @Test + public void requestHugepages1Gi_deploymentProperty_usesDeploymentProperty() { + kubernetesDeployerProperties.getRequests().setHugepages1Gi("4"); + deploymentProperties.put("spring.cloud.deployer.kubernetes.requests.hugepages-1Gi", "4"); + Map requests = this.deploymentPropertiesResolver.deduceResourceRequests(deploymentRequest.getDeploymentProperties()); + assertThat(requests.get("hugepages-1Gi")).isEqualTo(new Quantity("4")); + } + + @Test + public void limitHugepages1Gi_deploymentProperty_usesDeploymentProperty() { + kubernetesDeployerProperties.getLimits().setHugepages1Gi("4"); + deploymentProperties.put("spring.cloud.deployer.kubernetes.limits.hugepages-1Gi", "4"); + Map limits = this.deploymentPropertiesResolver.deduceResourceLimits(deploymentRequest.getDeploymentProperties()); + assertThat(limits.get("hugepages-1Gi")).isEqualTo(new Quantity("4")); + } + + @Test + public void requestHugepages2Mi_deploymentProperty_usesDeploymentProperty() { + kubernetesDeployerProperties.getRequests().setHugepages2Mi("40"); + deploymentProperties.put("spring.cloud.deployer.kubernetes.requests.hugepages-2Mi", "40"); + Map requests = this.deploymentPropertiesResolver.deduceResourceRequests(deploymentRequest.getDeploymentProperties()); + assertThat(requests.get("hugepages-2Mi")).isEqualTo(new Quantity("40")); + } + + @Test + public void limitHugepages2Mi_deploymentProperty_usesDeploymentProperty() { + kubernetesDeployerProperties.getLimits().setHugepages2Mi("40"); + deploymentProperties.put("spring.cloud.deployer.kubernetes.limits.hugepages-2Mi", "40"); + Map limits = this.deploymentPropertiesResolver.deduceResourceLimits(deploymentRequest.getDeploymentProperties()); + assertThat(limits.get("hugepages-2Mi")).isEqualTo(new Quantity("40")); + } }