1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-14 11:03:09 +02:00

dockerExecuteOnKubernetes: Make container limits configurable (#1993)

dockerExecuteOnKubernetes: Make container limits configurable
This commit is contained in:
Marcus Holl 2020-09-23 13:08:43 +02:00 committed by GitHub
parent c092ab0c28
commit da147b16ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 212 additions and 5 deletions

View File

@ -24,6 +24,7 @@ import static org.junit.Assert.assertThat
import static org.junit.Assert.assertTrue
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertFalse
import static org.junit.Assert.assertNull
class DockerExecuteOnKubernetesTest extends BasePiperTest {
private ExpectedException exception = ExpectedException.none()
@ -62,6 +63,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
def securityContext
def inheritFrom
def yamlMergeStrategy
Map resources = [:]
List stashList = []
@Before
@ -71,6 +73,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
envList = []
portList = []
containerCommands = []
resources = [:]
bodyExecuted = false
JenkinsUtils.metaClass.static.isPluginActive = { def s -> new PluginMock(s).isActive() }
helper.registerAllowedMethod('sh', [Map.class], { return whichDockerReturnValue })
@ -104,6 +107,7 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
containerCommands.add(container.command)
}
pullImageMap.put(container.image.toString(), container.imagePullPolicy == "Always")
resources.put(container.name, container.resources)
}
body()
})
@ -236,6 +240,164 @@ class DockerExecuteOnKubernetesTest extends BasePiperTest {
assertTrue(bodyExecuted)
}
@Test
void testDockerExecuteOnKubernetesNoResourceLimitsOnEmptyResourcesMap() throws Exception {
nullScript.commonPipelineEnvironment.configuration = [general:
[jenkinsKubernetes: [
resources: [
DEFAULT: [
requests: [
memory: '1Gi',
cpu: '0.25'
],
limits: [
memory: '2Gi',
cpu: '1'
]
],
mavenexecute: [:]
]
]
]]
stepRule.step.dockerExecuteOnKubernetes(script: nullScript,
containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], {
bodyExecuted = true
})
assertNull(resources.mavenexecute)
assertTrue(bodyExecuted)
}
@Test
void testDockerExecuteOnKubernetesWithDefaultResourceLimits() throws Exception {
nullScript.commonPipelineEnvironment.configuration = [general:
[jenkinsKubernetes: [
resources: [DEFAULT: [
requests: [
memory: '1Gi',
cpu: '0.25'
],
limits: [
memory: '2Gi',
cpu: '1'
]
]
]
]]]
stepRule.step.dockerExecuteOnKubernetes(script: nullScript,
containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'], {
bodyExecuted = true
})
assertEquals(requests: [memory: '1Gi',cpu: '0.25'],limits: [memory: '2Gi',cpu: '1'], resources.jnlp)
assertEquals(requests: [memory: '1Gi',cpu: '0.25'],limits: [memory: '2Gi',cpu: '1'], resources.mavenexecute)
assertTrue(bodyExecuted)
}
@Test
void testDockerExecuteOnKubernetesWithSpecificResourcLimitsParametersAreTakingPrecendence() throws Exception {
// the settings here are expected to be overwritten by the parameters provided via signature
nullScript.commonPipelineEnvironment.configuration = [general:
[jenkinsKubernetes: [
resources: [
mavenexecute: [
requests: [
memory: '2Gi',
cpu: '0.75'
],
limits: [
memory: '4Gi',
cpu: '2'
]
]
]
]]]
stepRule.step.dockerExecuteOnKubernetes(script: nullScript,
containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'],
resources: [
mavenexecute: [
requests: [
memory: '8Gi',
cpu: '2'
],
limits: [
memory: '16Gi',
cpu: '4'
]
]
]) {
bodyExecuted = true
}
assertEquals(requests: [memory: '8Gi',cpu: '2'],limits: [memory: '16Gi',cpu: '4'], resources.mavenexecute)
assertTrue(bodyExecuted)
}
@Test
void testDockerExecuteOnKubernetesWithSpecificResourceLimits() throws Exception {
nullScript.commonPipelineEnvironment.configuration = [general:
[jenkinsKubernetes: [
resources: [
DEFAULT: [
requests: [
memory: '1Gi',
cpu: '0.25'
],
limits: [
memory: '2Gi',
cpu: '1'
]
],
mavenexecute: [
requests: [
memory: '2Gi',
cpu: '0.75'
],
limits: [
memory: '4Gi',
cpu: '2'
]
],
jnlp: [
requests: [
memory: '3Gi',
cpu: '0.33'
],
limits: [
memory: '6Gi',
cpu: '3'
]
],
mysidecar: [
requests: [
memory: '10Gi',
cpu: '5.00'
],
limits: [
memory: '20Gi',
cpu: '10'
]
]
]
]
]]
stepRule.step.dockerExecuteOnKubernetes(script: nullScript,
containerMap: ['maven:3.5-jdk-8-alpine': 'mavenexecute'],
sidecarImage: 'ubuntu',
sidecarName: 'mysidecar') {
bodyExecuted = true
}
assertEquals(requests: [memory: '10Gi',cpu: '5.00'],limits: [memory: '20Gi',cpu: '10'], resources.mysidecar)
assertEquals(requests: [memory: '3Gi',cpu: '0.33'],limits: [memory: '6Gi',cpu: '3'], resources.jnlp)
assertEquals(requests: [memory: '2Gi',cpu: '0.75'],limits: [memory: '4Gi',cpu: '2'], resources.mavenexecute)
assertTrue(bodyExecuted)
}
@Test
void testDockerExecuteOnKubernetesUpperCaseContainerName() throws Exception {
stepRule.step.dockerExecuteOnKubernetes(script: nullScript,

View File

@ -33,6 +33,7 @@ import hudson.AbortException
* @parentConfigKey jenkinsKubernetes
*/
'inheritFrom',
'resources',
/**
* Print more detailed information into the log.
* @possibleValues `true`, `false`
@ -158,7 +159,17 @@ import hudson.AbortException
* This flag controls whether the stashing does *not* use the default exclude patterns in addition to the patterns provided in `stashExcludes`.
* @possibleValues `true`, `false`
*/
'stashNoDefaultExcludes'
'stashNoDefaultExcludes',
/**
* A map containing the resources per container. The key is the
* container name. The value is a map defining valid resources.
* An entry with key `DEFAULT` can be used for defining resources
* for all containers which does not have resources specified otherwise.
* Alternate way for providing resources is via `general/jenkinsKubernetes/resources`
* in the project configuration. Providing the resources map as parameter
* to the step call takes precedence.
*/
'resources',
])
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.minus([
'stashIncludes',
@ -367,10 +378,20 @@ private List getContainerList(config) {
def result = []
//allow definition of jnlp image via environment variable JENKINS_JNLP_IMAGE in the Kubernetes landscape or via config as fallback
if (env.JENKINS_JNLP_IMAGE || config.jenkinsKubernetes.jnlpAgent) {
result.push([
name : 'jnlp',
def jnlpContainerName = 'jnlp'
def jnlpSpec = [
name : jnlpContainerName,
image: env.JENKINS_JNLP_IMAGE ?: config.jenkinsKubernetes.jnlpAgent
])
]
def resources = getResources(jnlpContainerName, config)
if(resources) {
jnlpSpec.resources = resources
}
result.push(jnlpSpec)
}
config.containerMap.each { imageName, containerName ->
def containerPullImage = config.containerPullImageFlags?.get(imageName)
@ -414,22 +435,46 @@ private List getContainerList(config) {
}
containerSpec.ports = ports
}
def resources = getResources(containerName.toLowerCase(), config)
if(resources) {
containerSpec.resources = resources
}
result.push(containerSpec)
}
if (config.sidecarImage) {
def sideCarContainerName = config.sidecarName.toLowerCase()
def containerSpec = [
name : config.sidecarName.toLowerCase(),
name : sideCarContainerName,
image : config.sidecarImage,
imagePullPolicy: config.sidecarPullImage ? "Always" : "IfNotPresent",
env : getContainerEnvs(config, config.sidecarImage, config.sidecarEnvVars, config.sidecarWorkspace),
command : []
]
def resources = getResources(sideCarContainerName, config)
if(resources) {
containerSpec.resources = resources
}
result.push(containerSpec)
}
return result
}
private Map getResources(String containerName, Map config) {
Map resources = config.resources
if(resources == null) {
resources = config?.jenkinsKubernetes.resources
}
if(resources == null) {
return null
}
Map res = resources.get(containerName)
if(res == null) {
res = resources.get('DEFAULT')
}
return res
}
/*
* Returns a list of envVar object consisting of set
* environment variables, params (Parametrized Build) and working directory.