diff --git a/docs/crd-docu.md b/docs/crd-docu.md index 400e888af53a59353e68440ceb34d32c6a72506f..73d85c951fc2958aee25cde2cdff652034643c1a 100644 --- a/docs/crd-docu.md +++ b/docs/crd-docu.md @@ -51,6 +51,13 @@ Resource Types: <td>object</td> <td>Refer to the Kubernetes API documentation for the fields of the `metadata` field.</td> <td>true</td> + </tr><tr> + <td><b><a href="#benchmarkstatus">status</a></b></td> + <td>object</td> + <td> + <br/> + </td> + <td>false</td> </tr><tr> <td><b><a href="#benchmarkspec">spec</a></b></td> <td>object</td> @@ -62,6 +69,33 @@ Resource Types: </table> +### benchmark.status +<sup><sup>[↩ Parent](#benchmark)</sup></sup> + + + + + +<table> + <thead> + <tr> + <th>Name</th> + <th>Type</th> + <th>Description</th> + <th>Required</th> + </tr> + </thead> + <tbody><tr> + <td><b>resourceSetsState</b></td> + <td>string</td> + <td> + The status of a Benchmark indicates whether all resources are available to start the benchmark or not.<br/> + </td> + <td>false</td> + </tr></tbody> +</table> + + ### benchmark.spec <sup><sup>[↩ Parent](#benchmark)</sup></sup> @@ -92,6 +126,8 @@ Resource Types: <td>string</td> <td> This field exists only for technical reasons and should not be set by the user. The value of the field will be overwritten.<br/> + <br/> + <i>Default</i>: <br/> </td> <td>false</td> </tr><tr> diff --git a/helm/templates/theodolite/benchmark-resources-config-map.yaml b/helm/templates/theodolite/benchmark-resources-config-map.yaml deleted file mode 100644 index 4ec1c1bd9c3b9c05cb77920c20b9b573d413c94a..0000000000000000000000000000000000000000 --- a/helm/templates/theodolite/benchmark-resources-config-map.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- $processedDict := dict -}} -{{- range $path, $bytes := .Files.Glob "benchmark-definitions/**/resources/**" }} -{{- $name := base (dir (dir $path)) }} -{{- if not (hasKey $processedDict $name) -}} -{{ $_ := set $processedDict $name "true" }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: benchmark-resources-{{ $name }} -data: -{{ ($.Files.Glob (printf "benchmark-definitions/%s/resources/*" $name)).AsConfig | indent 2 }} ---- -{{- end }} -{{- end }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: benchmark-resources-custom -data: {} diff --git a/helm/templates/theodolite/benchmarks/benchmark-resources-config-map.yaml b/helm/templates/theodolite/benchmarks/benchmark-resources-config-map.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2dd355141350921d772edb73a1e8e7795600b0d1 --- /dev/null +++ b/helm/templates/theodolite/benchmarks/benchmark-resources-config-map.yaml @@ -0,0 +1,12 @@ +{{- range $configmap, $enabled := .Values.operator.theodoliteBenchmarks.resourceConfigMaps }} +{{- if $enabled -}} +{{- $name := kebabcase $configmap }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: benchmark-resources-{{ $name }} +data: +{{ ($.Files.Glob (printf "benchmark-definitions/%s/resources/*" $name)).AsConfig | indent 2 }} +--- +{{- end }} +{{- end }} diff --git a/helm/templates/theodolite/benchmarks/benchmark.yaml b/helm/templates/theodolite/benchmarks/benchmark.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1c4cb02ea69dbed711b781535127e00e2a24f1d7 --- /dev/null +++ b/helm/templates/theodolite/benchmarks/benchmark.yaml @@ -0,0 +1,7 @@ +{{- range $benchmark, $enabled := .Values.operator.theodoliteBenchmarks.benchmarks }} +{{- if $enabled -}} +{{- $name := kebabcase $benchmark }} +{{ $.Files.Get (printf "benchmark-definitions/%s/%s-benchmark-operator.yaml" $name $name) }} +--- +{{- end }} +{{- end }} diff --git a/helm/templates/theodolite/role.yaml b/helm/templates/theodolite/role.yaml index 0b496f3ef506e56b74acf5b7c8d0f4edc4f2cd96..43ee0e43d6974cd95548df32d6c4b1df8f3e497e 100644 --- a/helm/templates/theodolite/role.yaml +++ b/helm/templates/theodolite/role.yaml @@ -49,6 +49,7 @@ rules: - theodolite.com resources: - benchmarks + - benchmarks/status - executions - executions/status verbs: diff --git a/helm/templates/theodolite/theodolite-operator.yaml b/helm/templates/theodolite/theodolite-operator.yaml index 98e0688f79b0b2ab0a5c9c83f098c7dc545cafc5..c7ced880cbbfbb9795ef59156ea1df7d5b860ec6 100644 --- a/helm/templates/theodolite/theodolite-operator.yaml +++ b/helm/templates/theodolite/theodolite-operator.yaml @@ -26,31 +26,11 @@ spec: value: {{ .Release.Namespace }} - name: MODE value: operator - - name: THEODOLITE_APP_RESOURCES - value: "./benchmark-resources" - name: RESULTS_FOLDER value: "./results" volumeMounts: - name: theodolite-results-volume mountPath: "/deployments/results" - - name: benchmark-resources-uc1-kstreams - mountPath: /deployments/benchmark-resources/uc1-kstreams - - name: benchmark-resources-uc2-kstreams - mountPath: /deployments/benchmark-resources/uc2-kstreams - - name: benchmark-resources-uc3-kstreams - mountPath: /deployments/benchmark-resources/uc3-kstreams - - name: benchmark-resources-uc4-kstreams - mountPath: /deployments/benchmark-resources/uc4-kstreams - - name: benchmark-resources-uc1-flink - mountPath: /deployments/benchmark-resources/uc1-flink - - name: benchmark-resources-uc2-flink - mountPath: /deployments/benchmark-resources/uc2-flink - - name: benchmark-resources-uc3-flink - mountPath: /deployments/benchmark-resources/uc3-flink - - name: benchmark-resources-uc4-flink - mountPath: /deployments/benchmark-resources/uc4-flink - - name: benchmark-resources-custom - mountPath: /deployments/benchmark-resources/custom {{- if .Values.operator.sloChecker.lagTrend.enabled }} - name: lag-trend-slo-checker image: "{{ .Values.operator.sloChecker.lagTrend.image }}:{{ .Values.operator.sloChecker.lagTrend.imageTag }}" @@ -96,42 +76,6 @@ spec: {{- else }} emptyDir: {} {{- end }} - - name: benchmark-resources-uc1-kstreams - configMap: - name: benchmark-resources-uc1-kstreams - optional: true - - name: benchmark-resources-uc2-kstreams - configMap: - name: benchmark-resources-uc2-kstreams - optional: true - - name: benchmark-resources-uc3-kstreams - configMap: - name: benchmark-resources-uc3-kstreams - optional: true - - name: benchmark-resources-uc4-kstreams - configMap: - name: benchmark-resources-uc4-kstreams - optional: true - - name: benchmark-resources-uc1-flink - configMap: - name: benchmark-resources-uc1-flink - optional: true - - name: benchmark-resources-uc2-flink - configMap: - name: benchmark-resources-uc2-flink - optional: true - - name: benchmark-resources-uc3-flink - configMap: - name: benchmark-resources-uc3-flink - optional: true - - name: benchmark-resources-uc4-flink - configMap: - name: benchmark-resources-uc4-flink - optional: true - - name: benchmark-resources-custom - configMap: - name: benchmark-resources-custom - optional: true {{- with .Values.operator.nodeSelector }} nodeSelector: {{ toYaml . | indent 2 }} diff --git a/helm/values.yaml b/helm/values.yaml index 5cdb9ddbd5273ece21d32dbc7e1d2ea757248384..9de0155cf26d26bc20975d8ec6524607ac9a1d43 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -281,6 +281,29 @@ operator: imageTag: stable imagePullPolicy: IfNotPresent + theodoliteBenchmarks: + resourceConfigMaps: + uc1LoadGenerator: true + uc1Kstreams: true + uc1Flink: true + uc2LoadGenerator: true + uc2Kstreams: true + uc2Flink: true + uc3LoadGenerator: true + uc3Kstreams: true + uc3Flink: true + uc4LoadGenerator: true + uc4Kstreams: true + uc4Flink: true + benchmarks: + uc1Kstreams: true + uc1Flink: true + uc2Kstreams: true + uc2Flink: true + uc3Kstreams: true + uc3Flink: true + uc4Kstreams: true + uc4Flink: true serviceAccount: create: true diff --git a/theodolite-benchmarks/definitions/install-configmaps.sh b/theodolite-benchmarks/definitions/install-configmaps.sh index c5c0283f434d7a4c13da0e93a855cef7e112bbb9..841a293bbb77c4960a2532a13a009a42227223d3 100755 --- a/theodolite-benchmarks/definitions/install-configmaps.sh +++ b/theodolite-benchmarks/definitions/install-configmaps.sh @@ -1,17 +1,17 @@ -# flink +# Flink kubectl create configmap benchmark-resources-uc1-flink --from-file uc1-flink/resources kubectl create configmap benchmark-resources-uc2-flink --from-file uc2-flink/resources kubectl create configmap benchmark-resources-uc3-flink --from-file uc3-flink/resources kubectl create configmap benchmark-resources-uc4-flink --from-file uc4-flink/resources -# kafka +# Kafka Streams kubectl create configmap benchmark-resources-uc1-kstreams --from-file uc1-kstreams/resources kubectl create configmap benchmark-resources-uc2-kstreams --from-file uc2-kstreams/resources kubectl create configmap benchmark-resources-uc3-kstreams --from-file uc3-kstreams/resources kubectl create configmap benchmark-resources-uc4-kstreams --from-file uc4-kstreams/resources -# load generator -kubectl create configmap benchmark-resources-uc1-loadgen --from-file uc1-loadGen -kubectl create configmap benchmark-resources-uc2-loadgen --from-file uc2-loadGen -kubectl create configmap benchmark-resources-uc3-loadgen --from-file uc3-loadGen -kubectl create configmap benchmark-resources-uc4-loadgen --from-file uc4-loadGen \ No newline at end of file +# Load Generator +kubectl create configmap benchmark-resources-uc1-load-generator --from-file uc1-load-generator/resources +kubectl create configmap benchmark-resources-uc2-load-generator --from-file uc2-load-generator/resources +kubectl create configmap benchmark-resources-uc3-load-generator --from-file uc3-load-generator/resources +kubectl create configmap benchmark-resources-uc4-load-generator --from-file uc4-load-generator/resources diff --git a/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml index fb985d4574b7c04590c0ebff963acc47b7a8f85e..89bac41ee5c8dcefa628b3cb01052df5a1df9292 100644 --- a/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc1-flink/uc1-flink-benchmark-operator.yaml @@ -18,7 +18,7 @@ spec: loadGenerator: resources: - configMap: - name: "benchmark-resources-uc1-loadgen" + name: "benchmark-resources-uc1-load-generator" files: - "uc1-load-generator-deployment.yaml" - "uc1-load-generator-service.yaml" @@ -26,14 +26,14 @@ spec: - typeName: "Instances" patchers: - type: "ReplicaPatcher" - resource: "uc1-flink/taskmanager-deployment.yaml" + resource: "taskmanager-deployment.yaml" - type: "EnvVarPatcher" - resource: "uc1-flink/jobmanager-deployment.yaml" + resource: "jobmanager-deployment.yaml" properties: container: "jobmanager" variableName: "PARALLELISM" - type: "EnvVarPatcher" # required? - resource: "uc1-flink/taskmanager-deployment.yaml" + resource: "taskmanager-deployment.yaml" properties: container: "taskmanager" variableName: "PARALLELISM" @@ -41,12 +41,12 @@ spec: - typeName: "NumSensors" patchers: - type: "EnvVarPatcher" - resource: "uc1-kstreams/uc1-load-generator-deployment.yaml" + resource: "uc1-load-generator-deployment.yaml" properties: container: "workload-generator" variableName: "NUM_SENSORS" - type: NumSensorsLoadGeneratorReplicaPatcher - resource: "uc1-kstreams/uc1-load-generator-deployment.yaml" + resource: "uc1-load-generator-deployment.yaml" properties: loadGenMaxRecords: "150000" kafkaConfig: diff --git a/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc1-kstreams/uc1-kstreams-benchmark-operator.yaml similarity index 80% rename from theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-operator.yaml rename to theodolite-benchmarks/definitions/uc1-kstreams/uc1-kstreams-benchmark-operator.yaml index 3532e5d8cb869209309111c1654e4126b3dd6d2f..fb5557c2df8b483164d3c1000717db4c7cface81 100644 --- a/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc1-kstreams/uc1-kstreams-benchmark-operator.yaml @@ -15,7 +15,7 @@ spec: loadGenerator: resources: - configMap: - name: "benchmark-resources-uc1-loadgen" + name: "benchmark-resources-uc1-load-generator" files: - "uc1-load-generator-deployment.yaml" - "uc1-load-generator-service.yaml" @@ -23,17 +23,17 @@ spec: - typeName: "Instances" patchers: - type: "ReplicaPatcher" - resource: "uc1-kstreams/uc1-kstreams-deployment.yaml" + resource: "uc1-kstreams-deployment.yaml" loadTypes: - typeName: "NumSensors" patchers: - type: "EnvVarPatcher" - resource: "uc1-kstreams/uc1-load-generator-deployment.yaml" + resource: "uc1-load-generator-deployment.yaml" properties: container: "workload-generator" variableName: "NUM_SENSORS" - type: NumSensorsLoadGeneratorReplicaPatcher - resource: "uc1-kstreams/uc1-load-generator-deployment.yaml" + resource: "uc1-load-generator-deployment.yaml" properties: loadGenMaxRecords: "150000" kafkaConfig: diff --git a/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-standalone.yaml b/theodolite-benchmarks/definitions/uc1-kstreams/uc1-kstreams-benchmark-standalone.yaml similarity index 95% rename from theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-standalone.yaml rename to theodolite-benchmarks/definitions/uc1-kstreams/uc1-kstreams-benchmark-standalone.yaml index 58f6d89d610f4eb8bd5ed34c5ab64850d7570154..5aaf87e724a4e8c728c3c15b998cb927ff57f3d5 100644 --- a/theodolite-benchmarks/definitions/uc1-kstreams/uc1-benchmark-standalone.yaml +++ b/theodolite-benchmarks/definitions/uc1-kstreams/uc1-kstreams-benchmark-standalone.yaml @@ -11,7 +11,7 @@ sut: loadGenerator: resources: - configMap: - name: "benchmark-resources-uc1-loadgen" + name: "benchmark-resources-uc1-load-generator" files: - "uc1-load-generator-deployment.yaml" - "uc1-load-generator-service.yaml" diff --git a/theodolite-benchmarks/definitions/uc1-loadGen/uc1-load-generator-deployment.yaml b/theodolite-benchmarks/definitions/uc1-load-generator/resources/uc1-load-generator-deployment.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc1-loadGen/uc1-load-generator-deployment.yaml rename to theodolite-benchmarks/definitions/uc1-load-generator/resources/uc1-load-generator-deployment.yaml diff --git a/theodolite-benchmarks/definitions/uc1-loadGen/uc1-load-generator-service.yaml b/theodolite-benchmarks/definitions/uc1-load-generator/resources/uc1-load-generator-service.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc1-loadGen/uc1-load-generator-service.yaml rename to theodolite-benchmarks/definitions/uc1-load-generator/resources/uc1-load-generator-service.yaml diff --git a/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml index d87d7575be5525ed78ab6ad2815dcbf66639838f..206fbf9683659fcc074341d7077da04c36909b75 100644 --- a/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc2-flink/uc2-flink-benchmark-operator.yaml @@ -4,21 +4,21 @@ metadata: name: uc2-flink spec: sut: - resources: - - configMap: - name: "benchmark-resources-uc2-flink" - files: - - "flink-configuration-configmap.yaml" - - "taskmanager-deployment.yaml" - - "taskmanager-service.yaml" - - "service-monitor.yaml" - - "jobmanager-service.yaml" - - "jobmanager-deployment.yaml" - #- "jobmanager-rest-service.yaml" + resources: + - configMap: + name: "benchmark-resources-uc2-flink" + files: + - "flink-configuration-configmap.yaml" + - "taskmanager-deployment.yaml" + - "taskmanager-service.yaml" + - "service-monitor.yaml" + - "jobmanager-service.yaml" + - "jobmanager-deployment.yaml" + #- "jobmanager-rest-service.yaml" loadGenerator: resources: - configMap: - name: "benchmark-resources-uc2-loadgen" + name: "benchmark-resources-uc2-load-generator" files: - "uc2-load-generator-deployment.yaml" - "uc2-load-generator-service.yaml" @@ -26,14 +26,14 @@ spec: - typeName: "Instances" patchers: - type: "ReplicaPatcher" - resource: "uc2-flink/taskmanager-deployment.yaml" + resource: "taskmanager-deployment.yaml" - type: "EnvVarPatcher" - resource: "uc2-flink/jobmanager-deployment.yaml" + resource: "jobmanager-deployment.yaml" properties: container: "jobmanager" variableName: "PARALLELISM" - type: "EnvVarPatcher" # required? - resource: "uc2-flink/taskmanager-deployment.yaml" + resource: "taskmanager-deployment.yaml" properties: container: "taskmanager" variableName: "PARALLELISM" @@ -41,12 +41,12 @@ spec: - typeName: "NumSensors" patchers: - type: "EnvVarPatcher" - resource: "uc2-kstreams/uc2-load-generator-deployment.yaml" + resource: "uc2-load-generator-deployment.yaml" properties: container: "workload-generator" variableName: "NUM_SENSORS" - type: NumSensorsLoadGeneratorReplicaPatcher - resource: "uc2-kstreams/uc2-load-generator-deployment.yaml" + resource: "uc2-load-generator-deployment.yaml" properties: loadGenMaxRecords: "150000" kafkaConfig: diff --git a/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc2-kstreams/uc2-kstreams-benchmark-operator.yaml similarity index 65% rename from theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-operator.yaml rename to theodolite-benchmarks/definitions/uc2-kstreams/uc2-kstreams-benchmark-operator.yaml index 302fe6b251415ecc94e09961d7471cdce4fdaa39..0db22fa95f46d1cb484fa1a7730b8b6801dac67c 100644 --- a/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc2-kstreams/uc2-kstreams-benchmark-operator.yaml @@ -4,18 +4,18 @@ metadata: name: uc2-kstreams spec: sut: - resources: - - configMap: - name: "benchmark-resources-uc2-kstreams" - files: - - "uc2-kstreams-deployment.yaml" - - "uc2-kstreams-service.yaml" - - "uc2-jmx-configmap.yaml" - - "uc2-service-monitor.yaml" + resources: + - configMap: + name: "benchmark-resources-uc2-kstreams" + files: + - "uc2-kstreams-deployment.yaml" + - "uc2-kstreams-service.yaml" + - "uc2-jmx-configmap.yaml" + - "uc2-service-monitor.yaml" loadGenerator: resources: - configMap: - name: "benchmark-resources-uc2-loadgen" + name: "benchmark-resources-uc2-load-generator" files: - "uc2-load-generator-deployment.yaml" - "uc2-load-generator-service.yaml" @@ -23,17 +23,17 @@ spec: - typeName: "Instances" patchers: - type: "ReplicaPatcher" - resource: "uc2-kstreams/uc2-kstreams-deployment.yaml" + resource: "uc2-kstreams-deployment.yaml" loadTypes: - typeName: "NumSensors" patchers: - type: "EnvVarPatcher" - resource: "uc2-kstreams/uc2-load-generator-deployment.yaml" + resource: "uc2-load-generator-deployment.yaml" properties: container: "workload-generator" variableName: "NUM_SENSORS" - type: NumSensorsLoadGeneratorReplicaPatcher - resource: "uc2-kstreams/uc2-load-generator-deployment.yaml" + resource: "uc2-load-generator-deployment.yaml" properties: loadGenMaxRecords: "150000" kafkaConfig: diff --git a/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-standalone.yaml b/theodolite-benchmarks/definitions/uc2-kstreams/uc2-kstreams-benchmark-standalone.yaml similarity index 95% rename from theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-standalone.yaml rename to theodolite-benchmarks/definitions/uc2-kstreams/uc2-kstreams-benchmark-standalone.yaml index d70c4669ff485eeb801e6db16f9d333d843d3f51..67376d76bf0a7cc4cd47563a1d8da8dc0aa3b944 100644 --- a/theodolite-benchmarks/definitions/uc2-kstreams/uc2-benchmark-standalone.yaml +++ b/theodolite-benchmarks/definitions/uc2-kstreams/uc2-kstreams-benchmark-standalone.yaml @@ -11,7 +11,7 @@ sut: loadGenerator: resources: - configMap: - name: "benchmark-resources-uc2-loadgen" + name: "benchmark-resources-uc2-load-generator" files: - "uc2-load-generator-deployment.yaml" - "uc2-load-generator-service.yaml" diff --git a/theodolite-benchmarks/definitions/uc2-loadGen/uc2-load-generator-deployment.yaml b/theodolite-benchmarks/definitions/uc2-load-generator/resources/uc2-load-generator-deployment.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc2-loadGen/uc2-load-generator-deployment.yaml rename to theodolite-benchmarks/definitions/uc2-load-generator/resources/uc2-load-generator-deployment.yaml diff --git a/theodolite-benchmarks/definitions/uc2-loadGen/uc2-load-generator-service.yaml b/theodolite-benchmarks/definitions/uc2-load-generator/resources/uc2-load-generator-service.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc2-loadGen/uc2-load-generator-service.yaml rename to theodolite-benchmarks/definitions/uc2-load-generator/resources/uc2-load-generator-service.yaml diff --git a/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml index bd58d7de0b985d7f4a3f5d0a8ea01e1947de5af9..47b64d9890fc0f300ee1bd8e67acbdf7c8c4e4f9 100644 --- a/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc3-flink/uc3-flink-benchmark-operator.yaml @@ -18,7 +18,7 @@ spec: loadGenerator: resources: - configMap: - name: "benchmark-resources-uc3-loadgen" + name: "benchmark-resources-uc3-load-generator" files: - "uc3-load-generator-deployment.yaml" - "uc3-load-generator-service.yaml" @@ -26,14 +26,14 @@ spec: - typeName: "Instances" patchers: - type: "ReplicaPatcher" - resource: "uc3-flink/taskmanager-deployment.yaml" + resource: "taskmanager-deployment.yaml" - type: "EnvVarPatcher" - resource: "uc3-flink/jobmanager-deployment.yaml" + resource: "jobmanager-deployment.yaml" properties: container: "jobmanager" variableName: "PARALLELISM" - type: "EnvVarPatcher" # required? - resource: "uc3-flink/taskmanager-deployment.yaml" + resource: "taskmanager-deployment.yaml" properties: container: "taskmanager" variableName: "PARALLELISM" @@ -41,12 +41,12 @@ spec: - typeName: "NumSensors" patchers: - type: "EnvVarPatcher" - resource: "uc3-kstreams/uc3-load-generator-deployment.yaml" + resource: "uc3-load-generator-deployment.yaml" properties: container: "workload-generator" variableName: "NUM_SENSORS" - type: NumSensorsLoadGeneratorReplicaPatcher - resource: "uc3-kstreams/uc3-load-generator-deployment.yaml" + resource: "uc3-load-generator-deployment.yaml" properties: loadGenMaxRecords: "150000" kafkaConfig: diff --git a/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc3-kstreams/uc3-kstreams-benchmark-operator.yaml similarity index 82% rename from theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-operator.yaml rename to theodolite-benchmarks/definitions/uc3-kstreams/uc3-kstreams-benchmark-operator.yaml index 9151fb14ec77d3ace0cf0fe491c37dd624a335f1..25374ad92a32782857cea5924ea6482060832eac 100644 --- a/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc3-kstreams/uc3-kstreams-benchmark-operator.yaml @@ -15,7 +15,7 @@ spec: loadGenerator: resources: - configMap: - name: "benchmark-resources-uc3-loadgen" + name: "benchmark-resources-uc3-load-generator" files: - "uc3-load-generator-deployment.yaml" - "uc3-load-generator-service.yaml" @@ -23,17 +23,17 @@ spec: - typeName: "Instances" patchers: - type: "ReplicaPatcher" - resource: "uc3-kstreams/uc3-kstreams-deployment.yaml" + resource: "uc3-kstreams-deployment.yaml" loadTypes: - typeName: "NumSensors" patchers: - type: "EnvVarPatcher" - resource: "uc3-kstreams/uc3-load-generator-deployment.yaml" + resource: "uc3-load-generator-deployment.yaml" properties: container: "workload-generator" variableName: "NUM_SENSORS" - type: NumSensorsLoadGeneratorReplicaPatcher - resource: "uc3-kstreams/uc3-load-generator-deployment.yaml" + resource: "uc3-load-generator-deployment.yaml" properties: loadGenMaxRecords: "150000" kafkaConfig: diff --git a/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-standalone.yaml b/theodolite-benchmarks/definitions/uc3-kstreams/uc3-kstreams-benchmark-standalone.yaml similarity index 95% rename from theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-standalone.yaml rename to theodolite-benchmarks/definitions/uc3-kstreams/uc3-kstreams-benchmark-standalone.yaml index 8783a3d5e2efffe723d52d1f260a4914a6e6f578..aa92913d2c992835078174747ea849ce296c3eb1 100644 --- a/theodolite-benchmarks/definitions/uc3-kstreams/uc3-benchmark-standalone.yaml +++ b/theodolite-benchmarks/definitions/uc3-kstreams/uc3-kstreams-benchmark-standalone.yaml @@ -11,7 +11,7 @@ sut: loadGenerator: resources: - configMap: - name: "benchmark-resources-uc3-loadgen" + name: "benchmark-resources-uc3-load-generator" files: - "uc3-load-generator-deployment.yaml" - "uc3-load-generator-service.yaml" diff --git a/theodolite-benchmarks/definitions/uc3-loadGen/uc3-load-generator-deployment.yaml b/theodolite-benchmarks/definitions/uc3-load-generator/resources/uc3-load-generator-deployment.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc3-loadGen/uc3-load-generator-deployment.yaml rename to theodolite-benchmarks/definitions/uc3-load-generator/resources/uc3-load-generator-deployment.yaml diff --git a/theodolite-benchmarks/definitions/uc3-loadGen/uc3-load-generator-service.yaml b/theodolite-benchmarks/definitions/uc3-load-generator/resources/uc3-load-generator-service.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc3-loadGen/uc3-load-generator-service.yaml rename to theodolite-benchmarks/definitions/uc3-load-generator/resources/uc3-load-generator-service.yaml diff --git a/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml index 0ee6a3d9b2879bbb1642cb0c0bfb3984f53b66ac..8a73f5b0f87198def7b152ea52008e3d4a1aa4ee 100644 --- a/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc4-flink/uc4-flink-benchmark-operator.yaml @@ -18,7 +18,7 @@ spec: loadGenerator: resources: - configMap: - name: "benchmark-resources-uc4-loadgen" + name: "benchmark-resources-uc4-load-generator" files: - "uc4-load-generator-deployment.yaml" - "uc4-load-generator-service.yaml" @@ -26,14 +26,14 @@ spec: - typeName: "Instances" patchers: - type: "ReplicaPatcher" - resource: "uc4-flink/taskmanager-deployment.yaml" + resource: "taskmanager-deployment.yaml" - type: "EnvVarPatcher" - resource: "uc4-flink/jobmanager-deployment.yaml" + resource: "jobmanager-deployment.yaml" properties: container: "jobmanager" variableName: "PARALLELISM" - type: "EnvVarPatcher" # required? - resource: "uc4-flink/taskmanager-deployment.yaml" + resource: "taskmanager-deployment.yaml" properties: container: "taskmanager" variableName: "PARALLELISM" @@ -41,12 +41,12 @@ spec: - typeName: "NumNestedGroups" patchers: - type: "EnvVarPatcher" - resource: "uc4-kstreams/uc4-load-generator-deployment.yaml" + resource: "uc4-load-generator-deployment.yaml" properties: container: "workload-generator" variableName: "NUM_NESTED_GROUPS" - type: NumNestedGroupsLoadGeneratorReplicaPatcher - resource: "uc4-kstreams/uc4-load-generator-deployment.yaml" + resource: "uc4-load-generator-deployment.yaml" properties: loadGenMaxRecords: "150000" numSensors: "4.0" diff --git a/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-operator.yaml b/theodolite-benchmarks/definitions/uc4-kstreams/uc4-kstreams-benchmark-operator.yaml similarity index 84% rename from theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-operator.yaml rename to theodolite-benchmarks/definitions/uc4-kstreams/uc4-kstreams-benchmark-operator.yaml index 8cb5638828d545a751f22ce94a52ff8bb6ab7e86..655db2fd4122c9e0e844eed3bfe7c0a878c6d7ec 100644 --- a/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-operator.yaml +++ b/theodolite-benchmarks/definitions/uc4-kstreams/uc4-kstreams-benchmark-operator.yaml @@ -15,7 +15,7 @@ spec: loadGenerator: resources: - configMap: - name: "benchmark-resources-uc4-loadgen" + name: "benchmark-resources-uc4-load-generator" files: - "uc4-load-generator-deployment.yaml" - "uc4-load-generator-service.yaml" @@ -23,17 +23,17 @@ spec: - typeName: "Instances" patchers: - type: "ReplicaPatcher" - resource: "uc4-kstreams/uc4-kstreams-deployment.yaml" + resource: "uc4-kstreams-deployment.yaml" loadTypes: - typeName: "NumNestedGroups" patchers: - type: "EnvVarPatcher" - resource: "uc4-kstreams/uc4-load-generator-deployment.yaml" + resource: "uc4-load-generator-deployment.yaml" properties: container: "workload-generator" variableName: "NUM_SENSORS" - type: NumNestedGroupsLoadGeneratorReplicaPatcher - resource: "uc4-kstreams/uc4-load-generator-deployment.yaml" + resource: "uc4-load-generator-deployment.yaml" properties: loadGenMaxRecords: "150000" numSensors: "4.0" diff --git a/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-standalone.yaml b/theodolite-benchmarks/definitions/uc4-kstreams/uc4-kstreams-benchmark-standalone.yaml similarity index 96% rename from theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-standalone.yaml rename to theodolite-benchmarks/definitions/uc4-kstreams/uc4-kstreams-benchmark-standalone.yaml index 39e65f36d4dbff84f1ae1bab3b76a5c912f4a7d6..5c50b6f95d796941c0b2830549ef825f4a4ff6fb 100644 --- a/theodolite-benchmarks/definitions/uc4-kstreams/uc4-benchmark-standalone.yaml +++ b/theodolite-benchmarks/definitions/uc4-kstreams/uc4-kstreams-benchmark-standalone.yaml @@ -11,7 +11,7 @@ sut: loadGenerator: resources: - configMap: - name: "benchmark-resources-uc4-loadgen" + name: "benchmark-resources-uc4-load-generator" files: - "uc4-load-generator-deployment.yaml" - "uc4-load-generator-service.yaml" diff --git a/theodolite-benchmarks/definitions/uc4-loadGen/uc4-load-generator-deployment.yaml b/theodolite-benchmarks/definitions/uc4-load-generator/resources/uc4-load-generator-deployment.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc4-loadGen/uc4-load-generator-deployment.yaml rename to theodolite-benchmarks/definitions/uc4-load-generator/resources/uc4-load-generator-deployment.yaml diff --git a/theodolite-benchmarks/definitions/uc4-loadGen/uc4-load-generator-service.yaml b/theodolite-benchmarks/definitions/uc4-load-generator/resources/uc4-load-generator-service.yaml similarity index 100% rename from theodolite-benchmarks/definitions/uc4-loadGen/uc4-load-generator-service.yaml rename to theodolite-benchmarks/definitions/uc4-load-generator/resources/uc4-load-generator-service.yaml diff --git a/theodolite/crd/crd-benchmark.yaml b/theodolite/crd/crd-benchmark.yaml index befab6f98c2d376218de49bf88e5a037ec13d525..7ab2e5f3b890a883f68dbbd36805f3791158f256 100644 --- a/theodolite/crd/crd-benchmark.yaml +++ b/theodolite/crd/crd-benchmark.yaml @@ -25,6 +25,7 @@ spec: name: description: This field exists only for technical reasons and should not be set by the user. The value of the field will be overwritten. type: string + default: "" infrastructure: description: (Optional) A list of file names that reference Kubernetes resources that are deployed on the cluster to create the required infrastructure. type: object @@ -235,10 +236,20 @@ spec: description: Determines if this topic should only be deleted after each experiement. For removeOnly topics the name can be a RegEx describing the topic. type: boolean default: false + status: + type: object + properties: + resourceSetsState: + description: The status of a Benchmark indicates whether all resources are available to start the benchmark or not. + type: string additionalPrinterColumns: - name: Age type: date jsonPath: .metadata.creationTimestamp + - name: STATUS + type: string + description: The status of a Benchmark indicates whether all resources are available to start the benchmark or not. + jsonPath: .status.resourceSetsState subresources: status: {} scope: Namespaced \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt b/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt index 1f89549fb4eabb86fa1a766627abe3bf7c1b3cc6..273a13170e77ae9e2f5f09869ebbc5cc06185715 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/ConfigMapResourceSet.kt @@ -23,9 +23,6 @@ class ConfigMapResourceSet: ResourceSet, KubernetesResource { @OptIn(ExperimentalStdlibApi::class) override fun getResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, KubernetesResource>> { val loader = K8sResourceLoaderFromString(client) - - logger.info {"use namespace: ${client.namespace} in configmap resource set" } - var resources: Map<String, String> try { @@ -44,6 +41,10 @@ class ConfigMapResourceSet: ResourceSet, KubernetesResource { if (::files.isInitialized){ resources = resources .filter { files.contains(it.key) } + + if (resources.size != files.size) { + throw DeploymentFailedException("Could not find all specified Kubernetes manifests files") + } } return try { diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt index 5b6f956ec236ac8113a426dc22d0d08a968ca7b9..0b81f8701f92a95662efef6e0d58839c9a2f6f3b 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt @@ -1,5 +1,6 @@ package theodolite.benchmark +import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.client.DefaultKubernetesClient diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt b/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt index 19c0808093f6729978f98940641031d8e425c349..a4fe443e7f304c411792ee06c32592ba3c9e692a 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/ResourceSets.kt @@ -11,19 +11,20 @@ import theodolite.util.DeploymentFailedException @JsonDeserialize @RegisterForReflection -@JsonInclude(JsonInclude.Include.NON_NULL) class ResourceSets: KubernetesResource { @JsonProperty("configMap") - lateinit var configMap: ConfigMapResourceSet + @JsonInclude(JsonInclude.Include.NON_NULL) + var configMap: ConfigMapResourceSet? = null @JsonProperty("fileSystem") - lateinit var fileSystem: FileSystemResourceSet + @JsonInclude(JsonInclude.Include.NON_NULL) + var fileSystem: FileSystemResourceSet? = null fun loadResourceSet(client: NamespacedKubernetesClient): Collection<Pair<String, KubernetesResource>> { - return if (::configMap.isInitialized) { - configMap.getResourceSet(client= client) - } else if (::fileSystem.isInitialized) { - fileSystem.getResourceSet(client= client ) + return if (::configMap != null) { + configMap?.getResourceSet(client= client) !! + } else if (::fileSystem != null) { + fileSystem?.getResourceSet(client= client ) !! } else { throw DeploymentFailedException("could not load resourceSet.") } diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateHandler.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateHandler.kt new file mode 100644 index 0000000000000000000000000000000000000000..adca2a8b7fdb9b3e610f15e57c011679869df14c --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/execution/operator/BenchmarkStateHandler.kt @@ -0,0 +1,28 @@ +package theodolite.execution.operator + +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import theodolite.model.crd.* + +class BenchmarkStateHandler(val client: NamespacedKubernetesClient) : + AbstractStateHandler<BenchmarkCRD, KubernetesBenchmarkList, ExecutionStatus>( + client = client, + crd = BenchmarkCRD::class.java, + crdList = KubernetesBenchmarkList::class.java + ) { + + private fun getBenchmarkResourceState() = { cr: BenchmarkCRD -> cr.status.resourceSetsState } + + fun setResourceSetState(resourceName: String, status: BenchmarkStates): Boolean { + setState(resourceName) { cr -> cr.status.resourceSetsState = status.value; cr } + return blockUntilStateIsSet(resourceName, status.value, getBenchmarkResourceState()) + } + + fun getResourceSetState(resourceName: String): ExecutionStates { + val status = this.getState(resourceName, getBenchmarkResourceState()) + return if (status.isNullOrBlank()) { + ExecutionStates.NO_STATE + } else { + ExecutionStates.values().first { it.value == status } + } + } +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/ClusterSetup.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/ClusterSetup.kt index 6987372f96a6d956378a928011be9b5406590a16..efca98f8bf72024daa0367c6c57574f0644872e4 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/operator/ClusterSetup.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/operator/ClusterSetup.kt @@ -41,7 +41,7 @@ class ClusterSetup( .list() .items .asSequence() - .filter { it.status.executionState == States.RUNNING.value } + .filter { it.status.executionState == ExecutionStates.RUNNING.value } .forEach { execution -> val benchmark = benchmarkCRDClient .inNamespace(client.namespace) @@ -54,7 +54,7 @@ class ClusterSetup( benchmark.spec.name = benchmark.metadata.name Shutdown(execution.spec, benchmark.spec).start() } else { - throw IllegalStateException("Execution with state ${States.RUNNING.value} was found, but no corresponding benchmark. " + + throw IllegalStateException("Execution with state ${ExecutionStates.RUNNING.value} was found, but no corresponding benchmark. " + "Could not initialize cluster.") } } diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt index 1209195ee09cebe382f010f38e955dea1c860cd1..16c4ea98ba614bb3dcdd7d9f486f4e65ae70d380 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt @@ -33,9 +33,9 @@ class ExecutionHandler( logger.info { "Add execution ${execution.metadata.name}" } execution.spec.name = execution.metadata.name when (this.stateHandler.getExecutionState(execution.metadata.name)) { - States.NO_STATE -> this.stateHandler.setExecutionState(execution.spec.name, States.PENDING) - States.RUNNING -> { - this.stateHandler.setExecutionState(execution.spec.name, States.RESTART) + ExecutionStates.NO_STATE -> this.stateHandler.setExecutionState(execution.spec.name, ExecutionStates.PENDING) + ExecutionStates.RUNNING -> { + this.stateHandler.setExecutionState(execution.spec.name, ExecutionStates.RESTART) if (this.controller.isExecutionRunning(execution.spec.name)) { this.controller.stop(restart = true) } @@ -58,15 +58,15 @@ class ExecutionHandler( if (gson.toJson(oldExecution.spec) != gson.toJson(newExecution.spec)) { logger.info { "Receive update event for execution ${oldExecution.metadata.name}" } when (this.stateHandler.getExecutionState(newExecution.metadata.name)) { - States.RUNNING -> { - this.stateHandler.setExecutionState(newExecution.spec.name, States.RESTART) + ExecutionStates.RUNNING -> { + this.stateHandler.setExecutionState(newExecution.spec.name, ExecutionStates.RESTART) if (this.controller.isExecutionRunning(newExecution.spec.name)) { this.controller.stop(restart = true) } } - States.RESTART -> { + ExecutionStates.RESTART -> { } // should this set to pending? - else -> this.stateHandler.setExecutionState(newExecution.spec.name, States.PENDING) + else -> this.stateHandler.setExecutionState(newExecution.spec.name, ExecutionStates.PENDING) } } } @@ -79,7 +79,7 @@ class ExecutionHandler( @Synchronized override fun onDelete(execution: ExecutionCRD, b: Boolean) { logger.info { "Delete execution ${execution.metadata.name}" } - if (execution.status.executionState == States.RUNNING.value + if (execution.status.executionState == ExecutionStates.RUNNING.value && this.controller.isExecutionRunning(execution.metadata.name) ) { this.controller.stop() diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt index bcc86c8f2a9b233fa9a1972a866936e14688ecf8..9f49cf3ee4f9f62e7006dbf6697340e1af152f27 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/operator/ExecutionStateHandler.kt @@ -4,7 +4,7 @@ import io.fabric8.kubernetes.client.NamespacedKubernetesClient import theodolite.model.crd.BenchmarkExecutionList import theodolite.model.crd.ExecutionCRD import theodolite.model.crd.ExecutionStatus -import theodolite.model.crd.States +import theodolite.model.crd.ExecutionStates import java.lang.Thread.sleep import java.time.Duration import java.time.Instant @@ -23,17 +23,17 @@ class ExecutionStateHandler(val client: NamespacedKubernetesClient) : private fun getDurationLambda() = { cr: ExecutionCRD -> cr.status.executionDuration } - fun setExecutionState(resourceName: String, status: States): Boolean { + fun setExecutionState(resourceName: String, status: ExecutionStates): Boolean { setState(resourceName) { cr -> cr.status.executionState = status.value; cr } return blockUntilStateIsSet(resourceName, status.value, getExecutionLambda()) } - fun getExecutionState(resourceName: String): States { + fun getExecutionState(resourceName: String): ExecutionStates { val status = this.getState(resourceName, getExecutionLambda()) return if (status.isNullOrBlank()) { - States.NO_STATE + ExecutionStates.NO_STATE } else { - States.values().first { it.value == status } + ExecutionStates.values().first { it.value == status } } } diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt index 14d13160909817dc43d118173bf3ceee9bb47520..70e30cf84ef40796eb085a0d68eb2e323232fde9 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt @@ -28,7 +28,8 @@ const val CREATED_BY_LABEL_VALUE = "theodolite" class TheodoliteController( private val executionCRDClient: MixedOperation<ExecutionCRD, BenchmarkExecutionList, Resource<ExecutionCRD>>, private val benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>>, - private val executionStateHandler: ExecutionStateHandler + private val executionStateHandler: ExecutionStateHandler, + private val benchmarkStateHandler: BenchmarkStateHandler ) { lateinit var executor: TheodoliteExecutor @@ -40,6 +41,7 @@ class TheodoliteController( sleep(5000) // wait until all states are correctly set while (true) { reconcile() + updateBenchmarkStatus() sleep(2000) } } @@ -47,8 +49,10 @@ class TheodoliteController( private fun reconcile() { do { val execution = getNextExecution() + updateBenchmarkStatus() if (execution != null) { val benchmark = getBenchmarks() + .map { it.spec } .firstOrNull { it.name == execution.benchmark } if (benchmark != null) { runExecution(execution, benchmark) @@ -84,20 +88,20 @@ class TheodoliteController( labelName = CREATED_BY_LABEL_NAME ) - executionStateHandler.setExecutionState(execution.name, States.RUNNING) + executionStateHandler.setExecutionState(execution.name, ExecutionStates.RUNNING) executionStateHandler.startDurationStateTimer(execution.name) executor = TheodoliteExecutor(execution, benchmark) executor.run() when (executionStateHandler.getExecutionState(execution.name)) { - States.RESTART -> runExecution(execution, benchmark) - States.RUNNING -> { - executionStateHandler.setExecutionState(execution.name, States.FINISHED) + ExecutionStates.RESTART -> runExecution(execution, benchmark) + ExecutionStates.RUNNING -> { + executionStateHandler.setExecutionState(execution.name, ExecutionStates.FINISHED) logger.info { "Execution of ${execution.name} is finally stopped." } } else -> { - executionStateHandler.setExecutionState(execution.name, States.FAILURE) - logger.warn { "Unexpected execution state, set state to ${States.FAILURE.value}" } + executionStateHandler.setExecutionState(execution.name, ExecutionStates.FAILURE) + logger.warn { "Unexpected execution state, set state to ${ExecutionStates.FAILURE.value}" } } } } catch (e: Exception) { @@ -108,7 +112,7 @@ class TheodoliteController( message = "An error occurs while executing: ${e.message}") logger.error { "Failure while executing execution ${execution.name} with benchmark ${benchmark.name}." } logger.error { "Problem is: $e" } - executionStateHandler.setExecutionState(execution.name, States.FAILURE) + executionStateHandler.setExecutionState(execution.name, ExecutionStates.FAILURE) } executionStateHandler.stopDurationStateTimer() } @@ -117,7 +121,7 @@ class TheodoliteController( fun stop(restart: Boolean = false) { if (!::executor.isInitialized) return if (restart) { - executionStateHandler.setExecutionState(this.executor.getExecution().name, States.RESTART) + executionStateHandler.setExecutionState(this.executor.getExecution().name, ExecutionStates.RESTART) } this.executor.executor.run.set(false) } @@ -125,30 +129,33 @@ class TheodoliteController( /** * @return all available [BenchmarkCRD]s */ - private fun getBenchmarks(): List<KubernetesBenchmark> { + private fun getBenchmarks(): List<BenchmarkCRD> { return this.benchmarkCRDClient .list() .items .map { it.spec.name = it.metadata.name - it.spec + it } } + /** * Get the [BenchmarkExecution] for the next run. Which [BenchmarkExecution] * is selected for the next execution depends on three points: * * 1. Only executions are considered for which a matching benchmark is available on the cluster - * 2. The Status of the execution must be [States.PENDING] or [States.RESTART] - * 3. Of the remaining [BenchmarkCRD], those with status [States.RESTART] are preferred, + * 2. The Status of the execution must be [ExecutionStates.PENDING] or [ExecutionStates.RESTART] + * 3. Of the remaining [BenchmarkCRD], those with status [ExecutionStates.RESTART] are preferred, * then, if there is more than one, the oldest execution is chosen. * * @return the next execution or null */ private fun getNextExecution(): BenchmarkExecution? { - val comparator = ExecutionStateComparator(States.RESTART) + val comparator = ExecutionStateComparator(ExecutionStates.RESTART) val availableBenchmarkNames = getBenchmarks() + .filter { it.status.resourceSetsState == BenchmarkStates.READY.value } + .map { it.spec } .map { it.name } return executionCRDClient @@ -157,8 +164,8 @@ class TheodoliteController( .asSequence() .map { it.spec.name = it.metadata.name; it } .filter { - it.status.executionState == States.PENDING.value || - it.status.executionState == States.RESTART.value + it.status.executionState == ExecutionStates.PENDING.value || + it.status.executionState == ExecutionStates.RESTART.value } .filter { availableBenchmarkNames.contains(it.spec.benchmark) } .sortedWith(comparator.thenBy { it.metadata.creationTimestamp }) @@ -166,6 +173,35 @@ class TheodoliteController( .firstOrNull() } + private fun updateBenchmarkStatus() { + this.benchmarkCRDClient + .list() + .items + .map { it.spec.name = it.metadata.name; it } + .map { Pair(it, checkResource(it.spec)) } + .forEach { setState(it.first, it.second ) } + } + + private fun setState(resource: BenchmarkCRD, state: BenchmarkStates) { + benchmarkStateHandler.setResourceSetState(resource.spec.name, state) + } + + private fun checkResource(benchmark: KubernetesBenchmark): BenchmarkStates { + return try { + val appResources = + benchmark.loadKubernetesResources(resourceSet = benchmark.sut.resources) + val loadGenResources = + benchmark.loadKubernetesResources(resourceSet = benchmark.sut.resources) + if(appResources.isNotEmpty() && loadGenResources.isNotEmpty()) { + BenchmarkStates.READY + } else { + BenchmarkStates.PENDING + } + } catch (e: Exception) { + BenchmarkStates.PENDING + } + } + fun isExecutionRunning(executionName: String): Boolean { if (!::executor.isInitialized) return false return this.executor.getExecution().name == executionName diff --git a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt index d078b52c4c72d71d4f9f773831ea1a0736be6c99..4850a44fdddba117178e29d3170f44a95df646e7 100644 --- a/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt +++ b/theodolite/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt @@ -33,6 +33,7 @@ class TheodoliteOperator { private val client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(namespace) private lateinit var controller: TheodoliteController private lateinit var executionStateHandler: ExecutionStateHandler + private lateinit var benchmarkStateHandler: BenchmarkStateHandler fun start() { @@ -69,7 +70,9 @@ class TheodoliteOperator { controller = getController( client = client, - executionStateHandler = getExecutionStateHandler(client = client) + executionStateHandler = getExecutionStateHandler(client = client), + benchmarkStateHandler = getBenchmarkStateHandler(client = client) + ) getExecutionEventHandler(controller, client).startAllRegisteredInformers() controller.run() @@ -102,15 +105,24 @@ class TheodoliteOperator { return executionStateHandler } + fun getBenchmarkStateHandler(client: NamespacedKubernetesClient) : BenchmarkStateHandler { + if (!::benchmarkStateHandler.isInitialized) { + this.benchmarkStateHandler = BenchmarkStateHandler(client = client) + } + return benchmarkStateHandler + } + fun getController( client: NamespacedKubernetesClient, - executionStateHandler: ExecutionStateHandler + executionStateHandler: ExecutionStateHandler, + benchmarkStateHandler: BenchmarkStateHandler ): TheodoliteController { if (!::controller.isInitialized) { this.controller = TheodoliteController( benchmarkCRDClient = getBenchmarkClient(client), executionCRDClient = getExecutionClient(client), - executionStateHandler = executionStateHandler + executionStateHandler = executionStateHandler, + benchmarkStateHandler = benchmarkStateHandler ) } return this.controller diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt b/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt index 377708af7b7e1a50ae1e33064b2668c364e0685a..b6468fff523e57b124e144d5b9fef6477973655a 100644 --- a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt +++ b/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkCRD.kt @@ -14,5 +14,6 @@ import theodolite.benchmark.KubernetesBenchmark @Group("theodolite.com") @Kind("benchmark") class BenchmarkCRD( - var spec: KubernetesBenchmark = KubernetesBenchmark() -) : CustomResource<KubernetesBenchmark, Void>(), Namespaced, HasMetadata \ No newline at end of file + var spec: KubernetesBenchmark = KubernetesBenchmark(), + var status: BenchmarkStatus = BenchmarkStatus() +) : CustomResource<KubernetesBenchmark, BenchmarkStatus>(), Namespaced, HasMetadata \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkStates.kt b/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkStates.kt new file mode 100644 index 0000000000000000000000000000000000000000..f52f2c168765ebb8bcc4f390795aa470b968021b --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkStates.kt @@ -0,0 +1,6 @@ +package theodolite.model.crd + +enum class BenchmarkStates(val value: String) { + PENDING("Pending"), + READY("Ready") +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkStatus.kt b/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkStatus.kt new file mode 100644 index 0000000000000000000000000000000000000000..f51cb7a76d015d6ecd900279e68d41baa26e876a --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/model/crd/BenchmarkStatus.kt @@ -0,0 +1,11 @@ +package theodolite.model.crd + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.api.model.Namespaced + +@JsonDeserialize +class BenchmarkStatus: KubernetesResource, Namespaced { + var resourceSetsState = "-" + +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionStates.kt b/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionStates.kt new file mode 100644 index 0000000000000000000000000000000000000000..ad68bf380b18af1a654c201817bb7fc982804c8b --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/model/crd/ExecutionStates.kt @@ -0,0 +1,12 @@ +package theodolite.model.crd + +enum class ExecutionStates(val value: String) { + // Execution states + RUNNING("Running"), + PENDING("Pending"), + FAILURE("Failure"), + FINISHED("Finished"), + RESTART("Restart"), + INTERRUPTED("Interrupted"), + NO_STATE("NoState"), +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/model/crd/States.kt b/theodolite/src/main/kotlin/theodolite/model/crd/States.kt deleted file mode 100644 index 79af297915b6703b209acb0c13913482e54db2be..0000000000000000000000000000000000000000 --- a/theodolite/src/main/kotlin/theodolite/model/crd/States.kt +++ /dev/null @@ -1,11 +0,0 @@ -package theodolite.model.crd - -enum class States(val value: String) { - RUNNING("RUNNING"), - PENDING("PENDING"), - FAILURE("FAILURE"), - FINISHED("FINISHED"), - RESTART("RESTART"), - INTERRUPTED("INTERRUPTED"), - NO_STATE("NoState") -} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/util/ExecutionStateComparator.kt b/theodolite/src/main/kotlin/theodolite/util/ExecutionStateComparator.kt index 66ebe12d6505296682744c10c69f182f07d1a16e..8a6b0e9a49362afa401cf3c1279e7f7f6cddf85d 100644 --- a/theodolite/src/main/kotlin/theodolite/util/ExecutionStateComparator.kt +++ b/theodolite/src/main/kotlin/theodolite/util/ExecutionStateComparator.kt @@ -1,13 +1,13 @@ package theodolite.util import theodolite.model.crd.ExecutionCRD -import theodolite.model.crd.States +import theodolite.model.crd.ExecutionStates -class ExecutionStateComparator(private val preferredState: States): Comparator<ExecutionCRD> { +class ExecutionStateComparator(private val preferredState: ExecutionStates): Comparator<ExecutionCRD> { /** * Simple comparator which can be used to order a list of [ExecutionCRD] such that executions with - * status [States.RESTART] are before all other executions. + * status [ExecutionStates.RESTART] are before all other executions. */ override fun compare(p0: ExecutionCRD, p1: ExecutionCRD): Int { return when { diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt index 73a8b9b54813be51937bc17d873ca67dc5ae8724..7e0532aff36cac2fb1a1c718415315b8f54052c2 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt @@ -2,7 +2,6 @@ package theodolite.execution.operator import com.google.gson.Gson import com.google.gson.GsonBuilder -import io.fabric8.kubernetes.api.model.Service import io.fabric8.kubernetes.client.CustomResourceList import io.fabric8.kubernetes.client.server.mock.KubernetesServer import io.quarkus.test.junit.QuarkusTest @@ -14,6 +13,7 @@ import org.junit.jupiter.api.Test import theodolite.benchmark.BenchmarkExecution import theodolite.benchmark.KubernetesBenchmark import theodolite.model.crd.BenchmarkCRD +import theodolite.model.crd.BenchmarkStates import theodolite.model.crd.ExecutionCRD @QuarkusTest @@ -34,11 +34,13 @@ class ControllerTest { server.before() this.controller = TheodoliteOperator().getController( client = server.client, - executionStateHandler = ExecutionStateHandler(server.client) + executionStateHandler = ExecutionStateHandler(server.client), + benchmarkStateHandler = BenchmarkStateHandler(server.client) ) // benchmark val benchmark1 = BenchmarkCRDummy(name = "Test-Benchmark") + benchmark1.getCR().status.resourceSetsState = BenchmarkStates.READY.value val benchmark2 = BenchmarkCRDummy(name = "Test-Benchmark-123") benchmarkResourceList.items = listOf(benchmark1.getCR(), benchmark2.getCR()) @@ -112,12 +114,12 @@ class ControllerTest { .getDeclaredMethod("getBenchmarks") method.isAccessible = true - val result = method.invoke(controller) as List<KubernetesBenchmark> + val result = method.invoke(controller) as List<BenchmarkCRD> assertEquals(2, result.size) assertEquals( gson.toJson(benchmark), - gson.toJson(result.firstOrNull()) + gson.toJson(result.firstOrNull()?.spec) ) } diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt index 56d46279e8effe1f0b5bf307cd896ebd5b7eb2ee..51347d41b396bf375c14d5580b0f2619ce5b518c 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionCRDummy.kt @@ -3,7 +3,7 @@ package theodolite.execution.operator import theodolite.benchmark.BenchmarkExecution import theodolite.model.crd.ExecutionCRD import theodolite.model.crd.ExecutionStatus -import theodolite.model.crd.States +import theodolite.model.crd.ExecutionStates class ExecutionCRDummy(name: String, benchmark: String) { @@ -51,6 +51,6 @@ class ExecutionCRDummy(name: String, benchmark: String) { execution.configOverrides = mutableListOf() execution.name = executionCR.metadata.name - executionState.executionState = States.PENDING.value + executionState.executionState = ExecutionStates.PENDING.value } } \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt index 6c94d9734b3d5f6d1cb4901d2b3bc9a473d90e79..d8db7ab3b64ce3856984ddbc279ef148aa325e73 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ExecutionEventHandlerTest.kt @@ -11,7 +11,7 @@ import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import theodolite.k8s.K8sManager import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile -import theodolite.model.crd.States +import theodolite.model.crd.ExecutionStates import java.lang.Thread.sleep @@ -36,7 +36,8 @@ class ExecutionEventHandlerTest { val operator = TheodoliteOperator() this.controller = operator.getController( client = server.client, - executionStateHandler = ExecutionStateHandler(client = server.client) + executionStateHandler = ExecutionStateHandler(client = server.client), + benchmarkStateHandler = BenchmarkStateHandler(client = server.client) ) this.factory = operator.getExecutionEventHandler(this.controller, server.client) @@ -81,7 +82,7 @@ class ExecutionEventHandlerTest { factory.startAllRegisteredInformers() sleep(500) assertEquals( - States.PENDING, + ExecutionStates.PENDING, stateHandler.getExecutionState( resourceName = executionName ) @@ -95,12 +96,12 @@ class ExecutionEventHandlerTest { stateHandler .setExecutionState( resourceName = executionName, - status = States.RUNNING + status = ExecutionStates.RUNNING ) factory.startAllRegisteredInformers() sleep(500) assertEquals( - States.RESTART, + ExecutionStates.RESTART, stateHandler.getExecutionState( resourceName = executionName ) @@ -116,7 +117,7 @@ class ExecutionEventHandlerTest { sleep(500) assertEquals( - States.PENDING, + ExecutionStates.PENDING, stateHandler.getExecutionState( resourceName = executionName ) @@ -124,7 +125,7 @@ class ExecutionEventHandlerTest { manager.deploy(executionVersion2) assertEquals( - States.PENDING, + ExecutionStates.PENDING, stateHandler.getExecutionState( resourceName = executionName ) @@ -140,14 +141,14 @@ class ExecutionEventHandlerTest { stateHandler.setExecutionState( resourceName = executionName, - status = States.FINISHED + status = ExecutionStates.FINISHED ) manager.deploy(executionVersion2) sleep(500) assertEquals( - States.PENDING, + ExecutionStates.PENDING, stateHandler.getExecutionState( resourceName = executionName ) @@ -163,14 +164,14 @@ class ExecutionEventHandlerTest { stateHandler.setExecutionState( resourceName = executionName, - status = States.FAILURE + status = ExecutionStates.FAILURE ) manager.deploy(executionVersion2) sleep(500) assertEquals( - States.PENDING, + ExecutionStates.PENDING, stateHandler.getExecutionState( resourceName = executionName ) @@ -187,14 +188,14 @@ class ExecutionEventHandlerTest { stateHandler.setExecutionState( resourceName = executionName, - status = States.RUNNING + status = ExecutionStates.RUNNING ) manager.deploy(executionVersion2) sleep(500) assertEquals( - States.RESTART, + ExecutionStates.RESTART, stateHandler.getExecutionState( resourceName = executionName ) @@ -210,14 +211,14 @@ class ExecutionEventHandlerTest { stateHandler.setExecutionState( resourceName = executionName, - status = States.RESTART + status = ExecutionStates.RESTART ) manager.deploy(executionVersion2) sleep(500) assertEquals( - States.RESTART, + ExecutionStates.RESTART, stateHandler.getExecutionState( resourceName = executionName ) diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt index b435b47fddcb58d6444e1fc31304bd355a9e7783..a54f4ed6db559f8f7f15ae82deecf3fedf8b4abe 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/StateHandlerTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import theodolite.k8s.K8sManager import theodolite.k8s.resourceLoader.K8sResourceLoaderFromFile -import theodolite.model.crd.States +import theodolite.model.crd.ExecutionStates import java.time.Duration class StateHandlerTest { @@ -47,7 +47,7 @@ class StateHandlerTest { @DisplayName("Test empty execution state") fun executionWithoutExecutionStatusTest() { val handler = ExecutionStateHandler(client = server.client) - assertEquals(States.NO_STATE, handler.getExecutionState("example-execution")) + assertEquals(ExecutionStates.NO_STATE, handler.getExecutionState("example-execution")) } @Test @@ -62,8 +62,8 @@ class StateHandlerTest { fun executionStatusTest() { val handler = ExecutionStateHandler(client = server.client) - assertTrue(handler.setExecutionState("example-execution", States.INTERRUPTED)) - assertEquals(States.INTERRUPTED, handler.getExecutionState("example-execution")) + assertTrue(handler.setExecutionState("example-execution", ExecutionStates.INTERRUPTED)) + assertEquals(ExecutionStates.INTERRUPTED, handler.getExecutionState("example-execution")) } @Test diff --git a/theodolite/src/test/kotlin/theodolite/util/ExecutionStateComparatorTest.kt b/theodolite/src/test/kotlin/theodolite/util/ExecutionStateComparatorTest.kt index eec029f3878171eb2fd502bf68f549cfce793f23..7332e53f9e1814f28b8ff37a595b31b0eb931ea7 100644 --- a/theodolite/src/test/kotlin/theodolite/util/ExecutionStateComparatorTest.kt +++ b/theodolite/src/test/kotlin/theodolite/util/ExecutionStateComparatorTest.kt @@ -1,14 +1,10 @@ package theodolite.util import io.quarkus.test.junit.QuarkusTest -import org.junit.Rule -import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import theodolite.execution.operator.ExecutionCRDummy -import theodolite.model.crd.ExecutionCRD -import theodolite.model.crd.States +import theodolite.model.crd.ExecutionStates @QuarkusTest @@ -16,11 +12,11 @@ class ExecutionStateComparatorTest { @Test fun testCompare() { - val comparator = ExecutionStateComparator(States.RESTART) + val comparator = ExecutionStateComparator(ExecutionStates.RESTART) val execution1 = ExecutionCRDummy("dummy1", "default-benchmark") val execution2 = ExecutionCRDummy("dummy2", "default-benchmark") - execution1.getStatus().executionState = States.RESTART.value - execution2.getStatus().executionState = States.PENDING.value + execution1.getStatus().executionState = ExecutionStates.RESTART.value + execution2.getStatus().executionState = ExecutionStates.PENDING.value val list = listOf(execution2.getCR(), execution1.getCR())