From 40ef84a8562f7c1217c9742e255b455bec665e1a Mon Sep 17 00:00:00 2001 From: Marcel Becker <stu117960@mail.uni-kiel.de> Date: Tue, 15 Mar 2022 13:51:02 +0100 Subject: [PATCH] Fixed Problems with KubernetesExecutionRunner --- .../rocks/theodolite/kubernetes/Main.kt | 9 ++- .../rocks/theodolite/kubernetes/Shutdown.kt | 7 +- .../execution/ExperimentRunnerImpl.kt | 3 +- .../execution/KubernetesExecutionRunner.kt | 10 +-- .../execution/TheodoliteExecutor.kt | 2 +- .../kubernetes/model/KubernetesBenchmark.kt | 9 --- .../operator/BenchmarkStateChecker.kt | 25 ++++--- .../kubernetes/operator/ClusterSetup.kt | 2 +- .../kubernetes/operator/EventCreator.kt | 8 +-- .../operator/TheodoliteController.kt | 26 ++++++-- .../kubernetes/operator/TheodoliteOperator.kt | 65 +++++++++---------- .../standalone/TheodoliteStandalone.kt | 7 +- .../theodolite/benchmark/ActionCommandTest.kt | 7 +- .../operator/BenchmarkStateCheckerTest.kt | 14 ++-- .../execution/operator/ControllerTest.kt | 7 +- 15 files changed, 105 insertions(+), 96 deletions(-) diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Main.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Main.kt index a8994efa4..7a21b580a 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Main.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Main.kt @@ -1,5 +1,7 @@ package rocks.theodolite.kubernetes +import io.fabric8.kubernetes.client.DefaultKubernetesClient +import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.quarkus.runtime.annotations.QuarkusMain import mu.KotlinLogging import rocks.theodolite.kubernetes.execution.ExecutionModes @@ -19,9 +21,12 @@ object Main { val mode = Configuration.EXECUTION_MODE logger.info { "Start Theodolite with mode $mode" } + val namespace = Configuration.NAMESPACE + val client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(namespace) + when (mode.lowercase()) { - ExecutionModes.STANDALONE.value -> TheodoliteStandalone().start() - ExecutionModes.OPERATOR.value -> TheodoliteOperator().start() + ExecutionModes.STANDALONE.value -> TheodoliteStandalone(client).start() + ExecutionModes.OPERATOR.value -> TheodoliteOperator(client).start() else -> { logger.error { "MODE $mode not found" } exitProcess(1) diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Shutdown.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Shutdown.kt index 28b57ac0c..ce828e2df 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Shutdown.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/Shutdown.kt @@ -1,5 +1,6 @@ package rocks.theodolite.kubernetes +import io.fabric8.kubernetes.client.NamespacedKubernetesClient import mu.KotlinLogging import rocks.theodolite.kubernetes.execution.KubernetesExecutionRunner import rocks.theodolite.kubernetes.model.BenchmarkExecution @@ -13,7 +14,9 @@ private val logger = KotlinLogging.logger {} * @property benchmarkExecution * @property benchmark */ -class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val benchmark: KubernetesBenchmark) { +class Shutdown(private val benchmarkExecution: BenchmarkExecution, + private val benchmark: KubernetesBenchmark, + private val client: NamespacedKubernetesClient) { /** * Run @@ -21,7 +24,7 @@ class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val b */ fun run() { // Build Configuration to teardown - val kubernetesExecutionRunner = KubernetesExecutionRunner(benchmark) + val kubernetesExecutionRunner = KubernetesExecutionRunner(benchmark, this.client) try { logger.info { "Received shutdown signal -> Shutting down" } val deployment = diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/ExperimentRunnerImpl.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/ExperimentRunnerImpl.kt index c5b5de129..a33e9518f 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/ExperimentRunnerImpl.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/ExperimentRunnerImpl.kt @@ -1,5 +1,6 @@ package rocks.theodolite.kubernetes.execution +import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.quarkus.runtime.annotations.RegisterForReflection import mu.KotlinLogging import rocks.theodolite.core.ExperimentRunner @@ -30,7 +31,7 @@ class ExperimentRunnerImpl( private val afterTeardownDelay: Long, private val executionName: String, private val loadPatcherDefinitions: List<PatcherDefinition>, - private val resourcePatcherDefinitions: List<PatcherDefinition> + private val resourcePatcherDefinitions: List<PatcherDefinition>, ) : ExperimentRunner( results ) { diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/KubernetesExecutionRunner.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/KubernetesExecutionRunner.kt index f72940751..493aabdb9 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/KubernetesExecutionRunner.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/KubernetesExecutionRunner.kt @@ -17,12 +17,8 @@ private val logger = KotlinLogging.logger {} private var DEFAULT_NAMESPACE = "default" -class KubernetesExecutionRunner(val kubernetesBenchmark: KubernetesBenchmark) : Benchmark { - - private var namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE - - @Transient - private var client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(namespace) +class KubernetesExecutionRunner(val kubernetesBenchmark: KubernetesBenchmark, + private var client: NamespacedKubernetesClient) : Benchmark { /** * Loads [KubernetesResource]s. @@ -68,7 +64,7 @@ class KubernetesExecutionRunner(val kubernetesBenchmark: KubernetesBenchmark) : loadGenerationDelay: Long, afterTeardownDelay: Long ): BenchmarkDeployment { - logger.info { "Using ${this.namespace} as namespace." } + logger.info { "Using ${this.client.namespace} as namespace." } val appResources = loadKubernetesResources(kubernetesBenchmark.sut.resources) val loadGenResources = loadKubernetesResources(kubernetesBenchmark.loadGenerator.resources) diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/TheodoliteExecutor.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/TheodoliteExecutor.kt index 6178d803c..1dc3d4d52 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/TheodoliteExecutor.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/execution/TheodoliteExecutor.kt @@ -68,7 +68,7 @@ class TheodoliteExecutor( results = results, executionDuration = executionDuration, configurationOverrides = benchmarkExecution.configOverrides, - slos = kubernetesBenchmark.slos, + slos = slos, repetitions = benchmarkExecution.execution.repetitions, executionId = benchmarkExecution.executionId, loadGenerationDelay = benchmarkExecution.execution.loadGenerationDelay, diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/KubernetesBenchmark.kt index d32a42b7b..9498374e1 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/KubernetesBenchmark.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/model/KubernetesBenchmark.kt @@ -36,7 +36,6 @@ class KubernetesBenchmark : KubernetesResource { lateinit var infrastructure: Resources lateinit var sut: Resources lateinit var loadGenerator: Resources - //TODO: maybe add identifier and in BenchmarkCRD maybe manage them /** * The TypeName encapsulates a list of [PatcherDefinition] along with a typeName that specifies for what the [PatcherDefinition] should be used. @@ -74,12 +73,4 @@ class KubernetesBenchmark : KubernetesResource { lateinit var beforeActions: List<Action> lateinit var afterActions: List<Action> } - -/* fun getClient() : NamespacedKubernetesClient { - return this.client - } - - fun getNamespace() : String { - return this.namespace - }*/ } diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt index b91201317..5c9359b7a 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/BenchmarkStateChecker.kt @@ -1,5 +1,6 @@ package rocks.theodolite.kubernetes.operator +import io.fabric8.kubernetes.api.model.KubernetesResource import io.fabric8.kubernetes.api.model.apps.Deployment import io.fabric8.kubernetes.api.model.apps.StatefulSet import io.fabric8.kubernetes.client.NamespacedKubernetesClient @@ -10,6 +11,7 @@ import rocks.theodolite.kubernetes.benchmark.ActionSelector import rocks.theodolite.kubernetes.model.KubernetesBenchmark import rocks.theodolite.kubernetes.resourceSet.ResourceSets import rocks.theodolite.kubernetes.execution.KubernetesExecutionRunner +import rocks.theodolite.kubernetes.k8s.resourceLoader.K8sResourceLoader import rocks.theodolite.kubernetes.model.crd.BenchmarkCRD import rocks.theodolite.kubernetes.model.crd.BenchmarkState import rocks.theodolite.kubernetes.model.crd.KubernetesBenchmarkList @@ -18,7 +20,6 @@ class BenchmarkStateChecker( private val benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>>, private val benchmarkStateHandler: BenchmarkStateHandler, private val client: NamespacedKubernetesClient, - //private val kubernetesExecutionRunnerList: List<KubernetesExecutionRunner> ) { @@ -54,9 +55,9 @@ class BenchmarkStateChecker( * @param benchmark The benchmark to check * @return [BenchmarkStates.READY] iff all resource could be loaded and all actions could be executed, [BenchmarkStates.PENDING] else */ - private fun checkState(kubernetesExecutionRunner: KubernetesExecutionRunner): BenchmarkState { - return if (checkActionCommands(kubernetesExecutionRunner.kubernetesBenchmark) == BenchmarkState.READY - && checkResources(kubernetesExecutionRunner) == BenchmarkState.READY + private fun checkState(benchmark: KubernetesBenchmark): BenchmarkState { + return if (checkActionCommands(benchmark) == BenchmarkState.READY + && checkResources(benchmark) == BenchmarkState.READY ) { BenchmarkState.READY } else { @@ -175,13 +176,12 @@ class BenchmarkStateChecker( * @param benchmark The benchmark to check * @return The state of this benchmark. [BenchmarkState.READY] if all resources could be loaded, else [BenchmarkState.PENDING] */ - fun checkResources(kubernetesExecutionRunner: KubernetesExecutionRunner): BenchmarkState { + fun checkResources(benchmark: KubernetesBenchmark): BenchmarkState { return try { - val benchmark = kubernetesExecutionRunner.kubernetesBenchmark val appResources = - kubernetesExecutionRunner.loadKubernetesResources(resourceSet = benchmark.sut.resources) + loadKubernetesResources(resourceSet = benchmark.sut.resources) val loadGenResources = - kubernetesExecutionRunner.loadKubernetesResources(resourceSet = benchmark.loadGenerator.resources) + loadKubernetesResources(resourceSet = benchmark.loadGenerator.resources) if (appResources.isNotEmpty() && loadGenResources.isNotEmpty()) { BenchmarkState.READY } else { @@ -191,6 +191,15 @@ class BenchmarkStateChecker( BenchmarkState.PENDING } } + + /** + * Loads [KubernetesResource]s. + * It first loads them via the [YamlParserFromFile] to check for their concrete type and afterwards initializes them using + * the [K8sResourceLoader] + */ + private fun loadKubernetesResources(resourceSet: List<ResourceSets>): Collection<Pair<String, KubernetesResource>> { + return resourceSet.flatMap { it.loadResourceSet(this.client) } + } } private fun <K, V> MutableMap<K, V>.containsMatchLabels(matchLabels: MutableMap<V, V>): Boolean { diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ClusterSetup.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ClusterSetup.kt index 34c14114e..db95659f0 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ClusterSetup.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/ClusterSetup.kt @@ -50,7 +50,7 @@ class ClusterSetup( if (benchmark != null) { execution.spec.name = execution.metadata.name benchmark.spec.name = benchmark.metadata.name - Shutdown(execution.spec, benchmark.spec).run() + Shutdown(execution.spec, benchmark.spec, client).run() } else { throw IllegalStateException("Execution with state ${ExecutionState.RUNNING.value} was found, but no corresponding benchmark. " + "Could not initialize cluster.") diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/EventCreator.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/EventCreator.kt index b1a8dc8c3..cb23f8791 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/EventCreator.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/EventCreator.kt @@ -13,7 +13,7 @@ import kotlin.NoSuchElementException private val logger = KotlinLogging.logger {} class EventCreator { - val client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(Configuration.NAMESPACE) + private val client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(Configuration.NAMESPACE) fun createEvent(executionName: String, type: String, message: String, reason: String) { val uuid = UUID.randomUUID().toString() @@ -34,15 +34,15 @@ class EventCreator { event.source = source event.involvedObject = objectRef - client.v1().events().inNamespace(Configuration.NAMESPACE).createOrReplace(event) + this.client.v1().events().inNamespace(Configuration.NAMESPACE).createOrReplace(event) } catch (e: NoSuchElementException) { logger.warn {"Could not create event: type: $type, message: $message, reason: $reason, no corresponding execution found."} } } private fun buildObjectReference(executionName: String): ObjectReference { - val exec = TheodoliteOperator() - .getExecutionClient(client = client) + val exec = TheodoliteOperator(this.client) + .getExecutionClient() .list() .items .first{it.metadata.name == executionName} diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteController.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteController.kt index d3171fec8..8fcb42ca4 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteController.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteController.kt @@ -1,5 +1,7 @@ package rocks.theodolite.kubernetes.operator +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.fabric8.kubernetes.client.dsl.MixedOperation import io.fabric8.kubernetes.client.dsl.Resource import mu.KotlinLogging @@ -10,9 +12,11 @@ import rocks.theodolite.kubernetes.model.crd.KubernetesBenchmarkList import rocks.theodolite.kubernetes.model.KubernetesBenchmark import rocks.theodolite.kubernetes.execution.KubernetesExecutionRunner import rocks.theodolite.kubernetes.execution.TheodoliteExecutor +import rocks.theodolite.kubernetes.k8s.resourceLoader.K8sResourceLoader import rocks.theodolite.kubernetes.model.crd.* import rocks.theodolite.kubernetes.patcher.ConfigOverrideModifier import rocks.theodolite.kubernetes.model.crd.ExecutionStateComparator +import rocks.theodolite.kubernetes.resourceSet.ResourceSets import java.lang.Thread.sleep private val logger = KotlinLogging.logger {} @@ -29,10 +33,12 @@ const val CREATED_BY_LABEL_VALUE = "rocks/theodolite" */ class TheodoliteController( + private val client: NamespacedKubernetesClient, private val executionCRDClient: MixedOperation<ExecutionCRD, BenchmarkExecutionList, Resource<ExecutionCRD>>, private val benchmarkCRDClient: MixedOperation<BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>>, private val executionStateHandler: ExecutionStateHandler, - private val benchmarkStateChecker: BenchmarkStateChecker + private val benchmarkStateChecker: BenchmarkStateChecker, + ) { lateinit var executor: TheodoliteExecutor @@ -71,11 +77,10 @@ class TheodoliteController( */ private fun runExecution(execution: BenchmarkExecution, benchmark: KubernetesBenchmark) { try { - val kubernetesExecutionRunner = KubernetesExecutionRunner(benchmark) val modifier = ConfigOverrideModifier( - execution = execution, - resources = kubernetesExecutionRunner.loadKubernetesResources(benchmark.sut.resources).map { it.first } - + kubernetesExecutionRunner.loadKubernetesResources(benchmark.loadGenerator.resources).map { it.first } + execution = execution, + resources = loadKubernetesResources(benchmark.sut.resources).map { it.first } + + loadKubernetesResources(benchmark.loadGenerator.resources).map { it.first } ) modifier.setAdditionalLabels( labelValue = execution.name, @@ -93,7 +98,7 @@ class TheodoliteController( executionStateHandler.setExecutionState(execution.name, ExecutionState.RUNNING) executionStateHandler.startDurationStateTimer(execution.name) - executor = TheodoliteExecutor(execution, kubernetesExecutionRunner) + executor = TheodoliteExecutor(execution, KubernetesExecutionRunner(benchmark, this.client)) executor.setupAndRunExecution() when (executionStateHandler.getExecutionState(execution.name)) { ExecutionState.RESTART -> runExecution(execution, benchmark) @@ -176,4 +181,13 @@ class TheodoliteController( if (!::executor.isInitialized) return false return this.executor.getExecution().name == executionName } + + /** + * Loads [KubernetesResource]s. + * It first loads them via the [YamlParserFromFile] to check for their concrete type and afterwards initializes them using + * the [K8sResourceLoader] + */ + private fun loadKubernetesResources(resourceSet: List<ResourceSets>): Collection<Pair<String, KubernetesResource>> { + return resourceSet.flatMap { it.loadResourceSet(this.client) } + } } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt index 3a38844a7..83420b55a 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/operator/TheodoliteOperator.kt @@ -1,6 +1,5 @@ package rocks.theodolite.kubernetes.operator -import io.fabric8.kubernetes.client.DefaultKubernetesClient import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.fabric8.kubernetes.client.dsl.MixedOperation import io.fabric8.kubernetes.client.dsl.Resource @@ -14,7 +13,6 @@ import rocks.theodolite.kubernetes.model.crd.KubernetesBenchmarkList import rocks.theodolite.kubernetes.util.Configuration -private const val DEFAULT_NAMESPACE = "default" private const val EXECUTION_SINGULAR = "execution" private const val BENCHMARK_SINGULAR = "benchmark" private const val API_VERSION = "v1" @@ -27,10 +25,7 @@ private val logger = KotlinLogging.logger {} * * **See Also:** [Kubernetes Operator Pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) */ -class TheodoliteOperator { - private val namespace = Configuration.NAMESPACE - - private val client: NamespacedKubernetesClient = DefaultKubernetesClient().inNamespace(namespace) +class TheodoliteOperator(private val client: NamespacedKubernetesClient) { private lateinit var controller: TheodoliteController private lateinit var executionStateHandler: ExecutionStateHandler private lateinit var benchmarkStateHandler: BenchmarkStateHandler @@ -39,7 +34,7 @@ class TheodoliteOperator { fun start() { LeaderElector( - client = client, + client = this.client, name = Configuration.COMPONENT_NAME ) .getLeadership(::startOperator) @@ -49,8 +44,8 @@ class TheodoliteOperator { * Start the operator. */ private fun startOperator() { - logger.info { "Using $namespace as namespace." } - client.use { + logger.info { "Using ${this.client.namespace} as namespace." } + this.client.use { KubernetesDeserializer.registerCustomKind( "$GROUP/$API_VERSION", EXECUTION_SINGULAR, @@ -64,28 +59,26 @@ class TheodoliteOperator { ) ClusterSetup( - executionCRDClient = getExecutionClient(client), - benchmarkCRDClient = getBenchmarkClient(client), - client = client + executionCRDClient = getExecutionClient(), + benchmarkCRDClient = getBenchmarkClient(), + client = this.client ).clearClusterState() controller = getController( - client = client, - executionStateHandler = getExecutionStateHandler(client = client), - benchmarkStateChecker = getBenchmarkStateChecker(client = client) + executionStateHandler = getExecutionStateHandler(), + benchmarkStateChecker = getBenchmarkStateChecker() ) - getExecutionEventHandler(controller, client).startAllRegisteredInformers() + getExecutionEventHandler(controller).startAllRegisteredInformers() controller.run() } } - fun getExecutionEventHandler( + private fun getExecutionEventHandler( controller: TheodoliteController, - client: NamespacedKubernetesClient ): SharedInformerFactory { - val factory = client.informers() - .inNamespace(client.namespace) + val factory = this.client.informers() + .inNamespace(this.client.namespace) factory.sharedIndexInformerForCustomResource( ExecutionCRD::class.java, @@ -93,46 +86,46 @@ class TheodoliteOperator { ).addEventHandler( ExecutionEventHandler( controller = controller, - stateHandler = ExecutionStateHandler(client) + stateHandler = ExecutionStateHandler(this.client) ) ) return factory } - fun getExecutionStateHandler(client: NamespacedKubernetesClient): ExecutionStateHandler { + fun getExecutionStateHandler(): ExecutionStateHandler { if (!::executionStateHandler.isInitialized) { - this.executionStateHandler = ExecutionStateHandler(client = client) + this.executionStateHandler = ExecutionStateHandler(client = this.client) } return executionStateHandler } - fun getBenchmarkStateHandler(client: NamespacedKubernetesClient) : BenchmarkStateHandler { + fun getBenchmarkStateHandler() : BenchmarkStateHandler { if (!::benchmarkStateHandler.isInitialized) { - this.benchmarkStateHandler = BenchmarkStateHandler(client = client) + this.benchmarkStateHandler = BenchmarkStateHandler(client = this.client) } return benchmarkStateHandler } - fun getBenchmarkStateChecker(client: NamespacedKubernetesClient) : BenchmarkStateChecker { + fun getBenchmarkStateChecker() : BenchmarkStateChecker { if (!::benchmarkStateChecker.isInitialized) { this.benchmarkStateChecker = BenchmarkStateChecker( - client = client, - benchmarkStateHandler = getBenchmarkStateHandler(client = client), - benchmarkCRDClient = getBenchmarkClient(client = client)) + client = this.client, + benchmarkStateHandler = getBenchmarkStateHandler(), + benchmarkCRDClient = getBenchmarkClient()) } return benchmarkStateChecker } fun getController( - client: NamespacedKubernetesClient, executionStateHandler: ExecutionStateHandler, benchmarkStateChecker: BenchmarkStateChecker ): TheodoliteController { if (!::controller.isInitialized) { this.controller = TheodoliteController( - benchmarkCRDClient = getBenchmarkClient(client), - executionCRDClient = getExecutionClient(client), + client = this.client, + benchmarkCRDClient = getBenchmarkClient(), + executionCRDClient = getExecutionClient(), executionStateHandler = executionStateHandler, benchmarkStateChecker = benchmarkStateChecker ) @@ -140,21 +133,21 @@ class TheodoliteOperator { return this.controller } - fun getExecutionClient(client: NamespacedKubernetesClient): MixedOperation< + fun getExecutionClient(): MixedOperation< ExecutionCRD, BenchmarkExecutionList, Resource<ExecutionCRD>> { - return client.customResources( + return this.client.customResources( ExecutionCRD::class.java, BenchmarkExecutionList::class.java ) } - fun getBenchmarkClient(client: NamespacedKubernetesClient): MixedOperation< + fun getBenchmarkClient(): MixedOperation< BenchmarkCRD, KubernetesBenchmarkList, Resource<BenchmarkCRD>> { - return client.customResources( + return this.client.customResources( BenchmarkCRD::class.java, KubernetesBenchmarkList::class.java ) diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/standalone/TheodoliteStandalone.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/standalone/TheodoliteStandalone.kt index c6a257ea7..95092edf3 100644 --- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/standalone/TheodoliteStandalone.kt +++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/standalone/TheodoliteStandalone.kt @@ -1,5 +1,6 @@ package rocks.theodolite.kubernetes.standalone +import io.fabric8.kubernetes.client.NamespacedKubernetesClient import mu.KotlinLogging import rocks.theodolite.kubernetes.model.BenchmarkExecution import rocks.theodolite.kubernetes.model.KubernetesBenchmark @@ -31,7 +32,7 @@ private val logger = KotlinLogging.logger {} * * @constructor Create empty Theodolite yaml executor */ -class TheodoliteStandalone { +class TheodoliteStandalone (private val client: NamespacedKubernetesClient) { private val parser = YamlParserFromFile() fun start() { @@ -52,11 +53,11 @@ class TheodoliteStandalone { // Add shutdown hook // Use thread{} with start = false, else the thread will start right away - val shutdown = thread(start = false) { Shutdown(benchmarkExecution, benchmark).run() } + val shutdown = thread(start = false) { Shutdown(benchmarkExecution, benchmark, client).run() } Runtime.getRuntime().addShutdownHook(shutdown) try { - TheodoliteExecutor(benchmarkExecution, KubernetesExecutionRunner(benchmark)).setupAndRunExecution() + TheodoliteExecutor(benchmarkExecution, KubernetesExecutionRunner(benchmark, client)).setupAndRunExecution() } catch (e: EvaluationFailedException) { logger.error { "Evaluation failed with error: ${e.message}" } }catch (e: ExecutionFailedException) { diff --git a/theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt b/theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt index ef80526b3..e88aeb1e3 100644 --- a/theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt +++ b/theodolite/src/test/kotlin/theodolite/benchmark/ActionCommandTest.kt @@ -22,11 +22,10 @@ class ActionCommandTest { @BeforeEach fun setUp() { server.before() - val operator = TheodoliteOperator() + val operator = TheodoliteOperator(server.client) this.controller = operator.getController( - client = server.client, - executionStateHandler = operator.getExecutionStateHandler(client = server.client), - benchmarkStateChecker = operator.getBenchmarkStateChecker(client = server.client) + executionStateHandler = operator.getExecutionStateHandler(), + benchmarkStateChecker = operator.getBenchmarkStateChecker() ) val pod: Pod = PodBuilder().withNewMetadata() diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkStateCheckerTest.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkStateCheckerTest.kt index fcbc577fc..53d8d4b68 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkStateCheckerTest.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/BenchmarkStateCheckerTest.kt @@ -32,17 +32,17 @@ internal class BenchmarkStateCheckerTest { fun setUp() { server.before() serverCrud.before() - val operator = TheodoliteOperator() + val operator = TheodoliteOperator(serverCrud.client) checker = BenchmarkStateChecker( client = server.client, - benchmarkCRDClient = operator.getBenchmarkClient(server.client), - benchmarkStateHandler = operator.getBenchmarkStateHandler(server.client) + benchmarkCRDClient = operator.getBenchmarkClient(), + benchmarkStateHandler = operator.getBenchmarkStateHandler() ) checkerCrud = BenchmarkStateChecker( client = serverCrud.client, - benchmarkCRDClient = operator.getBenchmarkClient(serverCrud.client), - benchmarkStateHandler = operator.getBenchmarkStateHandler(serverCrud.client) + benchmarkCRDClient = operator.getBenchmarkClient(), + benchmarkStateHandler = operator.getBenchmarkStateHandler() ) val pod: Pod = PodBuilder().withNewMetadata() @@ -172,8 +172,6 @@ internal class BenchmarkStateCheckerTest { name = "test-benchmark" ) val benchmark = benchmarkCR.getCR().spec - val kubernetesExecutionRunner = KubernetesExecutionRunner(benchmark) - kubernetesExecutionRunner.setClient(serverCrud.client) val resourceSet = KubernetesBenchmark.Resources() resourceSet.resources = listOf(createAndDeployConfigmapResourceSet()) @@ -181,6 +179,6 @@ internal class BenchmarkStateCheckerTest { benchmark.loadGenerator = resourceSet benchmark.sut = resourceSet - assertEquals(BenchmarkState.READY,checkerCrud.checkResources(kubernetesExecutionRunner)) + assertEquals(BenchmarkState.READY,checkerCrud.checkResources(benchmark)) } } \ No newline at end of file diff --git a/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt b/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt index 19cc0cd03..144bf2717 100644 --- a/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt +++ b/theodolite/src/test/kotlin/theodolite/execution/operator/ControllerTest.kt @@ -35,11 +35,10 @@ class ControllerTest { @BeforeEach fun setUp() { server.before() - val operator = TheodoliteOperator() + val operator = TheodoliteOperator(server.client) this.controller = operator.getController( - client = server.client, - executionStateHandler = operator.getExecutionStateHandler(client = server.client), - benchmarkStateChecker = operator.getBenchmarkStateChecker(client = server.client) + executionStateHandler = operator.getExecutionStateHandler(), + benchmarkStateChecker = operator.getBenchmarkStateChecker() ) // benchmark -- GitLab