From 60064b6719668af5b37d7f21db48dec3469dfe70 Mon Sep 17 00:00:00 2001 From: "stu126940@mail.uni-kiel.de" <stu126940@mail.uni-kiel.de> Date: Mon, 15 Mar 2021 19:10:32 +0100 Subject: [PATCH] Introduce a PatcherFactory and a PatcherDefinitionFactory to make the API more understandable. --- .../benchmark/KubernetesBenchmark.kt | 24 +++--- .../execution/TheodoliteExecutor.kt | 8 +- .../execution/TheodoliteYamlExecutor.kt | 3 + .../patcher/PatcherDefinitionFactory.kt | 21 ++++++ .../theodolite/patcher/PatcherFactory.kt | 28 +++++++ .../theodolite/patcher/PatcherManager.kt | 73 ------------------- .../restriction/LowerBoundRestriction.kt | 3 +- .../kotlin/theodolite/util/LoadDimension.kt | 4 +- .../main/kotlin/theodolite/util/Resource.kt | 4 +- .../main/kotlin/theodolite/util/Results.kt | 2 +- .../theodolite/CompositeStrategyTest.kt | 22 +++--- .../theodolite/ResourceLimitPatcherTest.kt | 22 +++--- .../theodolite/ResourceRequestPatcherTest.kt | 22 +++--- 13 files changed, 109 insertions(+), 127 deletions(-) create mode 100644 theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherDefinitionFactory.kt create mode 100644 theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherFactory.kt delete mode 100644 theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherManager.kt diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt index 1e2d9a2e6..995f35e26 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt @@ -4,7 +4,7 @@ import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.client.DefaultKubernetesClient import mu.KotlinLogging import theodolite.k8s.K8sResourceLoader -import theodolite.patcher.PatcherManager +import theodolite.patcher.PatcherFactory import theodolite.util.* private val logger = KotlinLogging.logger {} @@ -43,20 +43,20 @@ class KubernetesBenchmark : Benchmark { configurationOverrides: List<ConfigurationOverride> ): BenchmarkDeployment { val resources = loadKubernetesResources(this.appResource + this.loadGenResource) - val patcherManager = PatcherManager() + val patcherFactory = PatcherFactory() - // patch res and load - patcherManager.createAndApplyPatcher(res.getType(), this.resourceTypes, resources, res.get()) - patcherManager.createAndApplyPatcher(load.getType(), this.loadTypes, resources, load.get().toString()) + // patch the load dimension + load.getType().map { patcherDefinition -> patcherFactory.createPatcher(patcherDefinition, resources) } + .forEach { patcher -> patcher.patch(load.get().toString()) } - // patch overrides + // patch the resources + res.getType().map { patcherDefinition -> patcherFactory.createPatcher(patcherDefinition, resources) } + .forEach { patcher -> patcher.patch(res.get().toString()) } + + // Patch the given overrides configurationOverrides.forEach { override -> - patcherManager.applyPatcher( - listOf(override.patcher), - resources, - override.value - ) - } + patcherFactory.createPatcher(override.patcher, resources).patch(override.value) } + return KubernetesBenchmarkDeployment( namespace = namespace, diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt index 87388cb61..da569e792 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt @@ -2,6 +2,7 @@ package theodolite.execution import theodolite.benchmark.BenchmarkExecution import theodolite.benchmark.KubernetesBenchmark +import theodolite.patcher.PatcherDefinitionFactory import theodolite.strategies.StrategyFactory import theodolite.strategies.searchstrategy.CompositeStrategy import theodolite.util.Config @@ -21,11 +22,12 @@ class TheodoliteExecutor( val executionDuration = Duration.ofSeconds(config.execution.duration) val executor = BenchmarkExecutorImpl(kubernetesBenchmark, results, executionDuration, config.configOverrides) + val resourcePatcherDefinition = PatcherDefinitionFactory().createPatcherDefinition(config.resources.resourceType, this.kubernetesBenchmark.resourceTypes) + val loadDimensionPatcherDefinition = PatcherDefinitionFactory().createPatcherDefinition(config.load.loadType, this.kubernetesBenchmark.loadTypes) return Config( - loads = config.load.loadValues.map { load -> LoadDimension(load, config.load.loadType) }, - resources = config.resources.resourceValues.map - { resource -> Resource(resource, config.resources.resourceType) }, + loads = config.load.loadValues.map { load -> LoadDimension(load, loadDimensionPatcherDefinition) }, + resources = config.resources.resourceValues.map { resource -> Resource(resource, resourcePatcherDefinition) }, compositeStrategy = CompositeStrategy( benchmarkExecutor = executor, searchStrategy = strategyFactory.createSearchStrategy(executor, config.execution.strategy), diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt index ecc202542..f6c109dac 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt @@ -5,6 +5,8 @@ import mu.KotlinLogging import theodolite.benchmark.BenchmarkExecution import theodolite.benchmark.KubernetesBenchmark import theodolite.util.YamlParser +import kotlin.system.exitProcess + private val logger = KotlinLogging.logger {} @QuarkusMain(name = "TheodoliteYamlExecutor") @@ -23,5 +25,6 @@ object TheodoliteYamlExecutor { val executor = TheodoliteExecutor(benchmarkExecution, benchmark) executor.run() logger.info { "Theodolite finished" } + exitProcess(0) } } diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherDefinitionFactory.kt b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherDefinitionFactory.kt new file mode 100644 index 000000000..0882b8d96 --- /dev/null +++ b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherDefinitionFactory.kt @@ -0,0 +1,21 @@ +package theodolite.patcher + +import theodolite.util.PatcherDefinition +import theodolite.util.TypeName + +class PatcherDefinitionFactory { + fun createPatcherDefinition(requiredType: String, patcherTypes: List<TypeName>) : List<PatcherDefinition> { + return patcherTypes + .filter { type -> type.typeName == requiredType } + .flatMap { type -> type.patchers } + } + + fun getEmptyPatcherDefinition(): PatcherDefinition { + val emptyDef = PatcherDefinition() + emptyDef.type = "" + emptyDef.resource = "" + emptyDef.container = "" + emptyDef.variableName = "" + return emptyDef + } +} \ No newline at end of file diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherFactory.kt b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherFactory.kt new file mode 100644 index 000000000..1a3e56bfe --- /dev/null +++ b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherFactory.kt @@ -0,0 +1,28 @@ +package theodolite.patcher + +import io.fabric8.kubernetes.api.model.KubernetesResource +import theodolite.util.PatcherDefinition + +class PatcherFactory { + fun createPatcher(patcherDefinition: PatcherDefinition, + k8sResources: List<Pair<String, KubernetesResource>>) : Patcher { + val resource = + k8sResources.filter { it.first == patcherDefinition.resource }.map { resource -> resource.second }[0] + return when (patcherDefinition.type) { + "ReplicaPatcher" -> ReplicaPatcher(resource) + "EnvVarPatcher" -> EnvVarPatcher(resource, patcherDefinition.container, patcherDefinition.variableName) + "NodeSelectorPatcher" -> NodeSelectorPatcher(resource, patcherDefinition.variableName) + "ResourceLimitPatcher" -> ResourceLimitPatcher( + resource, + patcherDefinition.container, + patcherDefinition.variableName + ) + "ResourceRequestPatcher" -> ResourceRequestPatcher( + resource, + patcherDefinition.container, + patcherDefinition.variableName + ) + else -> throw IllegalArgumentException("Patcher type ${patcherDefinition.type} not found") + } + } +} \ No newline at end of file diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherManager.kt b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherManager.kt deleted file mode 100644 index 5557eb4b9..000000000 --- a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/PatcherManager.kt +++ /dev/null @@ -1,73 +0,0 @@ -package theodolite.patcher - -import io.fabric8.kubernetes.api.model.KubernetesResource -import theodolite.util.PatcherDefinition -import theodolite.util.TypeName - -class PatcherManager { - private fun createK8sPatcher( - patcherDefinition: PatcherDefinition, - k8sResources: List<Pair<String, KubernetesResource>> - ): Patcher { - val resource = - k8sResources.filter { it.first == patcherDefinition.resource }.map { resource -> resource.second }[0] - return when (patcherDefinition.type) { - "ReplicaPatcher" -> ReplicaPatcher(resource) - "EnvVarPatcher" -> EnvVarPatcher(resource, patcherDefinition.container, patcherDefinition.variableName) - "NodeSelectorPatcher" -> NodeSelectorPatcher(resource, patcherDefinition.variableName) - "ResourceLimitPatcher" -> ResourceLimitPatcher( - resource, - patcherDefinition.container, - patcherDefinition.variableName - ) - "ResourceRequestPatcher" -> ResourceRequestPatcher( - resource, - patcherDefinition.container, - patcherDefinition.variableName - ) - else -> throw IllegalArgumentException("Patcher type ${patcherDefinition.type} not found") - } - } - - private fun getPatcherDef(requiredType: String, patcherTypes: List<TypeName>): List<PatcherDefinition> { - return patcherTypes - .filter { type -> type.typeName == requiredType } - .flatMap { type -> type.patchers } - } - - /** - * This function first creates a patcher definition and - * then patches the list of resources based on this patcher definition - * - * @param type Patcher type, for example "EnvVarPatcher" - * @param patcherTypes List of patcher types definitions, for example for resources and threads - * @param resources List of K8s resources, a patcher takes the resources that are needed - * @param value The value to patch - */ - fun createAndApplyPatcher( - type: String, - patcherTypes: List<TypeName>, - resources: List<Pair<String, KubernetesResource>>, - value: Any - ) { - this.getPatcherDef(type, patcherTypes) - .forEach { patcherDef -> - createK8sPatcher(patcherDef, resources).patch(value) - } - } - - /** - * Patch a resource based on the given patcher definition, a list of resources and a value to patch - * - * @param patcherDefinition The patcher definition - * @param resources List of patcher types definitions, for example for resources and threads - * @param value The value to patch - */ - fun applyPatcher( - patcherDefinition: List<PatcherDefinition>, - resources: List<Pair<String, KubernetesResource>>, - value: Any - ) { - patcherDefinition.forEach { def -> this.createK8sPatcher(def, resources).patch(value) } - } -} diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt index dfd6bc805..2a0cd9c84 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/strategies/restriction/LowerBoundRestriction.kt @@ -1,5 +1,6 @@ package theodolite.strategies.restriction +import theodolite.patcher.PatcherDefinitionFactory import theodolite.util.LoadDimension import theodolite.util.Resource import theodolite.util.Results @@ -13,7 +14,7 @@ import theodolite.util.Results class LowerBoundRestriction(results: Results) : RestrictionStrategy(results) { override fun next(load: LoadDimension, resources: List<Resource>): List<Resource> { val maxLoad: LoadDimension? = this.results.getMaxBenchmarkedLoad(load) - var lowerBound: Resource? = this.results.getMinRequiredInstances(maxLoad, resources[0].getType()) + var lowerBound: Resource? = this.results.getMinRequiredInstances(maxLoad, listOf(PatcherDefinitionFactory().getEmptyPatcherDefinition())) if (lowerBound == null) { lowerBound = resources[0] } diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/util/LoadDimension.kt b/theodolite-quarkus/src/main/kotlin/theodolite/util/LoadDimension.kt index 29d47460b..43cb861b2 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/util/LoadDimension.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/util/LoadDimension.kt @@ -1,11 +1,11 @@ package theodolite.util -data class LoadDimension(private val number: Int, private val type: String) { +data class LoadDimension(private val number: Int, private val type: List<PatcherDefinition>) { fun get(): Int { return this.number } - fun getType(): String { + fun getType(): List<PatcherDefinition> { return this.type } } diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/util/Resource.kt b/theodolite-quarkus/src/main/kotlin/theodolite/util/Resource.kt index cb172e0b8..094e89ebb 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/util/Resource.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/util/Resource.kt @@ -1,11 +1,11 @@ package theodolite.util -data class Resource(private val number: Int, private val type: String) { +data class Resource(private val number: Int, private val type: List<PatcherDefinition>) { fun get(): Int { return this.number } - fun getType(): String { + fun getType(): List<PatcherDefinition> { return this.type } } diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/util/Results.kt b/theodolite-quarkus/src/main/kotlin/theodolite/util/Results.kt index 91bde7179..34fcfc047 100644 --- a/theodolite-quarkus/src/main/kotlin/theodolite/util/Results.kt +++ b/theodolite-quarkus/src/main/kotlin/theodolite/util/Results.kt @@ -11,7 +11,7 @@ class Results { return this.results[experiment] } - fun getMinRequiredInstances(load: LoadDimension?, resourceTyp: String): Resource? { + fun getMinRequiredInstances(load: LoadDimension?, resourceTyp: List<PatcherDefinition>): Resource? { if (this.results.isEmpty()) return Resource(Int.MIN_VALUE, resourceTyp) var requiredInstances: Resource? = Resource(Int.MAX_VALUE, resourceTyp) diff --git a/theodolite-quarkus/src/test/kotlin/theodolite/CompositeStrategyTest.kt b/theodolite-quarkus/src/test/kotlin/theodolite/CompositeStrategyTest.kt index 31eaa40fb..d50541c2e 100644 --- a/theodolite-quarkus/src/test/kotlin/theodolite/CompositeStrategyTest.kt +++ b/theodolite-quarkus/src/test/kotlin/theodolite/CompositeStrategyTest.kt @@ -3,6 +3,7 @@ package theodolite import io.quarkus.test.junit.QuarkusTest import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test +import theodolite.patcher.PatcherDefinitionFactory import theodolite.strategies.restriction.LowerBoundRestriction import theodolite.strategies.searchstrategy.BinarySearch import theodolite.strategies.searchstrategy.CompositeStrategy @@ -25,8 +26,9 @@ class CompositeStrategyTest { arrayOf(false, false, false, false, false, false, true), arrayOf(false, false, false, false, false, false, false) ) - val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, "NumSensors") } - val mockResources: List<Resource> = (0..6).map { number -> Resource(number, "Instances") } + val emptyPatcherDefinition = PatcherDefinitionFactory().getEmptyPatcherDefinition() + val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, listOf(emptyPatcherDefinition)) } + val mockResources: List<Resource> = (0..6).map { number -> Resource(number, listOf(emptyPatcherDefinition)) } val results = Results() val benchmark = TestBenchmark() val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results) @@ -36,7 +38,7 @@ class CompositeStrategyTest { CompositeStrategy(benchmarkExecutor, linearSearch, setOf(lowerBoundRestriction)) val actual: ArrayList<Resource?> = ArrayList() - val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, "Instances") }) + val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, listOf(emptyPatcherDefinition)) }) expected.add(null) for (load in mockLoads) { @@ -57,8 +59,9 @@ class CompositeStrategyTest { arrayOf(false, false, false, false, false, false, true), arrayOf(false, false, false, false, false, false, false) ) - val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, "NumSensors") } - val mockResources: List<Resource> = (0..6).map { number -> Resource(number, "Instances") } + val emptyPatcherDefinition = PatcherDefinitionFactory().getEmptyPatcherDefinition() + val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, listOf(emptyPatcherDefinition)) } + val mockResources: List<Resource> = (0..6).map { number -> Resource(number, listOf(emptyPatcherDefinition)) } val results = Results() val benchmark = TestBenchmark() val benchmarkExecutorImpl = @@ -69,7 +72,7 @@ class CompositeStrategyTest { CompositeStrategy(benchmarkExecutorImpl, binarySearch, setOf(lowerBoundRestriction)) val actual: ArrayList<Resource?> = ArrayList() - val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, "Instances") }) + val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, listOf(emptyPatcherDefinition)) }) expected.add(null) for (load in mockLoads) { @@ -90,8 +93,9 @@ class CompositeStrategyTest { arrayOf(false, false, false, false, false, false, true, true), arrayOf(false, false, false, false, false, false, false, true) ) - val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, "NumSensors") } - val mockResources: List<Resource> = (0..7).map { number -> Resource(number, "Instances") } + val emptyPatcherDefinition = PatcherDefinitionFactory().getEmptyPatcherDefinition() + val mockLoads: List<LoadDimension> = (0..6).map { number -> LoadDimension(number, listOf(emptyPatcherDefinition)) } + val mockResources: List<Resource> = (0..7).map { number -> Resource(number, listOf(emptyPatcherDefinition)) } val results = Results() val benchmark = TestBenchmark() val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results) @@ -102,7 +106,7 @@ class CompositeStrategyTest { val actual: ArrayList<Resource?> = ArrayList() val expected: ArrayList<Resource?> = - ArrayList(listOf(0, 2, 2, 3, 4, 6, 7).map { x -> Resource(x, "Instances") }) + ArrayList(listOf(0, 2, 2, 3, 4, 6, 7).map { x -> Resource(x, listOf(emptyPatcherDefinition)) }) for (load in mockLoads) { actual.add(strategy.findSuitableResource(load, mockResources)) diff --git a/theodolite-quarkus/src/test/kotlin/theodolite/ResourceLimitPatcherTest.kt b/theodolite-quarkus/src/test/kotlin/theodolite/ResourceLimitPatcherTest.kt index 2170a6a54..79d6efe47 100644 --- a/theodolite-quarkus/src/test/kotlin/theodolite/ResourceLimitPatcherTest.kt +++ b/theodolite-quarkus/src/test/kotlin/theodolite/ResourceLimitPatcherTest.kt @@ -6,7 +6,7 @@ import io.quarkus.test.junit.QuarkusTest import io.smallrye.common.constraint.Assert.assertTrue import org.junit.jupiter.api.Test import theodolite.k8s.K8sResourceLoader -import theodolite.patcher.PatcherManager +import theodolite.patcher.PatcherFactory import theodolite.util.PatcherDefinition /** @@ -23,7 +23,7 @@ import theodolite.util.PatcherDefinition class ResourceLimitPatcherTest { val testPath = "./src/main/resources/testYaml/" val loader = K8sResourceLoader(DefaultKubernetesClient().inNamespace("")) - val manager = PatcherManager() + val patcherFactory = PatcherFactory() fun applyTest(fileName: String) { val cpuValue = "50m" @@ -42,16 +42,14 @@ class ResourceLimitPatcherTest { defMEM.container = "uc-application" defMEM.type = "ResourceLimitPatcher" - manager.applyPatcher( - patcherDefinition = listOf(defCPU), - resources = listOf(Pair("cpu-memory-deployment.yaml", k8sResource)), - value = cpuValue - ) - manager.applyPatcher( - patcherDefinition = listOf(defMEM), - resources = listOf(Pair("cpu-memory-deployment.yaml", k8sResource)), - value = memValue - ) + patcherFactory.createPatcher( + patcherDefinition = defCPU, + k8sResources = listOf(Pair("cpu-memory-deployment.yaml", k8sResource)) + ).patch(value = cpuValue) + patcherFactory.createPatcher( + patcherDefinition = defMEM, + k8sResources = listOf(Pair("cpu-memory-deployment.yaml", k8sResource)) + ).patch(value = memValue) k8sResource.spec.template.spec.containers.filter { it.name == defCPU.container } .forEach { diff --git a/theodolite-quarkus/src/test/kotlin/theodolite/ResourceRequestPatcherTest.kt b/theodolite-quarkus/src/test/kotlin/theodolite/ResourceRequestPatcherTest.kt index 108142843..9ca9a83aa 100644 --- a/theodolite-quarkus/src/test/kotlin/theodolite/ResourceRequestPatcherTest.kt +++ b/theodolite-quarkus/src/test/kotlin/theodolite/ResourceRequestPatcherTest.kt @@ -6,7 +6,7 @@ import io.quarkus.test.junit.QuarkusTest import io.smallrye.common.constraint.Assert.assertTrue import org.junit.jupiter.api.Test import theodolite.k8s.K8sResourceLoader -import theodolite.patcher.PatcherManager +import theodolite.patcher.PatcherFactory import theodolite.util.PatcherDefinition /** @@ -23,7 +23,7 @@ import theodolite.util.PatcherDefinition class ResourceRequestPatcherTest { val testPath = "./src/main/resources/testYaml/" val loader = K8sResourceLoader(DefaultKubernetesClient().inNamespace("")) - val manager = PatcherManager() + val patcherFactory = PatcherFactory() fun applyTest(fileName: String) { val cpuValue = "50m" @@ -42,16 +42,14 @@ class ResourceRequestPatcherTest { defMEM.container = "uc-application" defMEM.type = "ResourceRequestPatcher" - manager.applyPatcher( - patcherDefinition = listOf(defCPU), - resources = listOf(Pair("cpu-memory-deployment.yaml", k8sResource)), - value = cpuValue - ) - manager.applyPatcher( - patcherDefinition = listOf(defMEM), - resources = listOf(Pair("cpu-memory-deployment.yaml", k8sResource)), - value = memValue - ) + patcherFactory.createPatcher( + patcherDefinition = defCPU, + k8sResources = listOf(Pair("cpu-memory-deployment.yaml", k8sResource)) + ).patch(value = cpuValue) + patcherFactory.createPatcher( + patcherDefinition = defMEM, + k8sResources = listOf(Pair("cpu-memory-deployment.yaml", k8sResource)) + ).patch(value = memValue) k8sResource.spec.template.spec.containers.filter { it.name == defCPU.container } .forEach { -- GitLab