From 4ead1f62189c3d338be82d326ba8ac88b2d83469 Mon Sep 17 00:00:00 2001 From: "stu126940@mail.uni-kiel.de" <stu126940@mail.uni-kiel.de> Date: Wed, 24 Nov 2021 18:47:15 +0100 Subject: [PATCH] Add actions to crd schemata and perform them on setup and teardown --- theodolite/crd/crd-benchmark.yaml | 145 +++++++++++++++++- .../examples/operator/example-benchmark.yaml | 16 ++ .../kotlin/theodolite/benchmark/Action.kt | 14 +- .../benchmark/KubernetesBenchmark.kt | 4 + .../KubernetesBenchmarkDeployment.kt | 11 ++ .../kotlin/theodolite/benchmark/Resources.kt | 1 + .../operator/TheodoliteController.kt | 5 +- 7 files changed, 190 insertions(+), 6 deletions(-) diff --git a/theodolite/crd/crd-benchmark.yaml b/theodolite/crd/crd-benchmark.yaml index 60c777c7d..8fc7d08ee 100644 --- a/theodolite/crd/crd-benchmark.yaml +++ b/theodolite/crd/crd-benchmark.yaml @@ -66,14 +66,59 @@ spec: type: string beforeActions: type: array - properties: + default: [] + items: + type: object + properties: + selector: + type: object + properties: + pod: + type: object + properties: + matchLabels: + type: object + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + type: string + exec: + type: object + properties: + command: + type: string + afterActions: + type: array + default: [] + items: + type: object + properties: + selector: + type: object + properties: + pod: + type: object + properties: + matchLabels: + type: object + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + type: string + exec: + type: object + properties: + command: + type: string sut: description: The appResourceSets specifies all Kubernetes resources required to start the sut. A resourceSet can be either a configMap resourceSet or a fileSystem resourceSet. type: object properties: resources: type: array - default: [ ] + default: [] items: type: object oneOf: @@ -104,6 +149,54 @@ spec: type: array items: type: string + beforeActions: + type: array + default: [] + items: + type: object + properties: + selector: + type: object + properties: + pod: + type: object + properties: + matchLabels: + type: object + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + type: string + exec: + type: object + properties: + command: + type: string + afterActions: + type: array + default: [] + items: + type: object + properties: + selector: + type: object + properties: + pod: + type: object + properties: + matchLabels: + type: object + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + type: string + exec: + type: object + properties: + command: + type: string loadGenerator: description: The loadGenResourceSets specifies all Kubernetes resources required to start the load generator. A resourceSet can be either a configMap resourceSet or a fileSystem resourceSet. type: object @@ -141,6 +234,54 @@ spec: type: array items: type: string + beforeActions: + type: array + default: [ ] + items: + type: object + properties: + selector: + type: object + properties: + pod: + type: object + properties: + matchLabels: + type: object + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + type: string + exec: + type: object + properties: + command: + type: string + afterActions: + type: array + default: [] + items: + type: object + properties: + selector: + type: object + properties: + pod: + type: object + properties: + matchLabels: + type: object + additionalProperties: true + x-kubernetes-map-type: "granular" + default: { } + container: + type: string + exec: + type: object + properties: + command: + type: string resourceTypes: description: A list of resource types that can be scaled for this `benchmark` resource. For each resource type the concrete values are defined in the `execution` object. type: array diff --git a/theodolite/examples/operator/example-benchmark.yaml b/theodolite/examples/operator/example-benchmark.yaml index 3452fff9c..87b3d83c1 100644 --- a/theodolite/examples/operator/example-benchmark.yaml +++ b/theodolite/examples/operator/example-benchmark.yaml @@ -9,6 +9,14 @@ spec: name: "example-configmap" files: - "uc1-kstreams-deployment.yaml" + beforeActions: + - selector: + pod: + matchLabels: + app: kafka-client + container: "abc" # optional (if there is only one container or there exists something like a default container) + exec: + command: "kafka-topics.sh --create --topic abc" # or list loadGenerator: resources: - configMap: @@ -16,6 +24,14 @@ spec: files: - uc1-load-generator-service.yaml - uc1-load-generator-deployment.yaml + beforeActions: + - selector: + pod: + matchLabels: + app: kafka-client + container: "abc" # optional (if there is only one container or there exists something like a default container) + exec: + command: "kafka-topics.sh --create --topic abc" # or list resourceTypes: - typeName: "Instances" patchers: diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/Action.kt b/theodolite/src/main/kotlin/theodolite/benchmark/Action.kt index 55add765e..653a71bd9 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/Action.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/Action.kt @@ -1,7 +1,13 @@ package theodolite.benchmark +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import io.quarkus.runtime.annotations.RegisterForReflection +@JsonDeserialize +@RegisterForReflection +@JsonInclude(JsonInclude.Include.NON_NULL) class Action { lateinit var selector: ActionSelector @@ -17,15 +23,19 @@ class Action { } } +@JsonDeserialize +@RegisterForReflection class ActionSelector { lateinit var pod: PodSelector lateinit var container: String } - +@JsonDeserialize +@RegisterForReflection class PodSelector { lateinit var matchLabels: MutableMap<String, String> } - +@JsonDeserialize +@RegisterForReflection class Command { lateinit var command: String } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt index 0b81f8701..c5e0e3846 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt @@ -110,6 +110,10 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { } } return KubernetesBenchmarkDeployment( + sutBeforeActions = sut.beforeActions, + sutAfterActions = sut.beforeActions, + loadGenBeforeActions = loadGenerator.beforeActions, + loadGenAfterActions = loadGenerator.afterActions, appResources = appResources.map { it.second }, loadGenResources = loadGenResources.map { it.second }, loadGenerationDelay = loadGenerationDelay, diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt index 423ac92c6..db90f0e24 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt @@ -23,6 +23,10 @@ private val logger = KotlinLogging.logger {} */ @RegisterForReflection class KubernetesBenchmarkDeployment( + private val sutBeforeActions: List<Action>, + private val sutAfterActions: List<Action>, + private val loadGenBeforeActions: List<Action>, + private val loadGenAfterActions: List<Action>, val appResources: List<KubernetesResource>, val loadGenResources: List<KubernetesResource>, private val loadGenerationDelay: Long, @@ -36,12 +40,17 @@ class KubernetesBenchmarkDeployment( private val LAG_EXPORTER_POD_LABEL_NAME = "app.kubernetes.io/name" private val LAG_EXPORTER_POD_LABEL_VALUE = "kafka-lag-exporter" + + /** * Setup a [KubernetesBenchmark] using the [TopicManager] and the [K8sManager]: * - Create the needed topics. * - Deploy the needed resources. */ override fun setup() { + sutBeforeActions.forEach { it.exec } + loadGenBeforeActions.forEach { it.exec } + val kafkaTopics = this.topics.filter { !it.removeOnly } .map { NewTopic(it.name, it.numPartitions, it.replicationFactor) } kafkaController.createTopics(kafkaTopics) @@ -65,6 +74,8 @@ class KubernetesBenchmarkDeployment( labelName = LAG_EXPORTER_POD_LABEL_NAME, labelValue = LAG_EXPORTER_POD_LABEL_VALUE ) + sutAfterActions.forEach { it.exec } + loadGenAfterActions.forEach { it.exec } logger.info { "Teardown complete. Wait $afterTeardownDelay ms to let everything come down." } Thread.sleep(Duration.ofSeconds(afterTeardownDelay).toMillis()) } diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/Resources.kt b/theodolite/src/main/kotlin/theodolite/benchmark/Resources.kt index 738fb6014..a5a30c4cd 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/Resources.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/Resources.kt @@ -1,5 +1,6 @@ package theodolite.benchmark +import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.annotation.JsonSerialize import io.quarkus.runtime.annotations.RegisterForReflection diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt index 70e30cf84..6933fb163 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt @@ -72,8 +72,8 @@ class TheodoliteController( try { val modifier = ConfigOverrideModifier( execution = execution, - resources = benchmark.loadKubernetesResources(benchmark.sut.resources).map { it.first } - + benchmark.loadKubernetesResources(benchmark.loadGenerator.resources).map { it.first } + resources = benchmark.loadKubernetesResources(benchmark.sut.resources !!).map { it.first } + + benchmark.loadKubernetesResources(benchmark.loadGenerator.resources !!).map { it.first } ) modifier.setAdditionalLabels( labelValue = execution.name, @@ -186,6 +186,7 @@ class TheodoliteController( benchmarkStateHandler.setResourceSetState(resource.spec.name, state) } + // TODO(Should we check, if actions could be performed or not (all pods are up and running...))? private fun checkResource(benchmark: KubernetesBenchmark): BenchmarkStates { return try { val appResources = -- GitLab