diff --git a/theodolite/crd/crd-benchmark.yaml b/theodolite/crd/crd-benchmark.yaml index c901e61360c05b2f1cf2b1767a20f624eb262231..9a728b22d65112376d664c921b2cde9107db674f 100644 --- a/theodolite/crd/crd-benchmark.yaml +++ b/theodolite/crd/crd-benchmark.yaml @@ -26,6 +26,12 @@ spec: 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: "" + rolloutMode: + type: string + default: "default" + enum: + - "no-waiting" + - "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 diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt index d42c2ea3c0ed5394fdcf5b89be0fe0470a15ba62..5ebd9ceeac9048654e16cb85f8113f9145c110b9 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt @@ -37,6 +37,7 @@ private var DEFAULT_THEODOLITE_APP_RESOURCES = "./benchmark-resources" @RegisterForReflection class KubernetesBenchmark : KubernetesResource, Benchmark { lateinit var name: String + lateinit var rolloutMode: RolloutMode lateinit var resourceTypes: List<TypeName> lateinit var loadTypes: List<TypeName> var kafkaConfig: KafkaConfig? = null @@ -59,10 +60,8 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { override fun setupInfrastructure() { this.infrastructure.beforeActions.forEach { it.exec(client = client) } - val kubernetesManager = K8sManager(this.client) - loadKubernetesResources(this.infrastructure.resources) - .map{it.second} - .forEach { kubernetesManager.deploy(it) } + RolloutManager(rolloutMode, this.client) + .rollout(loadKubernetesResources(this.infrastructure.resources).map { it.second }) } override fun teardownInfrastructure() { @@ -124,7 +123,9 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { afterTeardownDelay = afterTeardownDelay, kafkaConfig = if (kafkaConfig != null) hashMapOf("bootstrap.servers" to kafkaConfig.bootstrapServer) else mapOf(), topics = kafkaConfig?.topics ?: listOf(), - client = this.client + client = this.client, + rolloutMode = rolloutMode + ) } diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt index 2b3cf0fa13d894424e6a0546993e2fd9998b8620..dcfdc04478c54e3d24f7b702f1ccedbed33f9ee8 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt @@ -27,6 +27,7 @@ class KubernetesBenchmarkDeployment( private val sutAfterActions: List<Action>, private val loadGenBeforeActions: List<Action>, private val loadGenAfterActions: List<Action>, + private val rolloutMode: RolloutMode, val appResources: List<KubernetesResource>, val loadGenResources: List<KubernetesResource>, private val loadGenerationDelay: Long, @@ -46,19 +47,20 @@ class KubernetesBenchmarkDeployment( * - Deploy the needed resources. */ override fun setup() { + val rolloutManager = RolloutManager(rolloutMode, client) if (this.topics.isNotEmpty()) { val kafkaTopics = this.topics .filter { !it.removeOnly } .map { NewTopic(it.name, it.numPartitions, it.replicationFactor) } kafkaController.createTopics(kafkaTopics) } + sutBeforeActions.forEach { it.exec(client = client) } - appResources.forEach { kubernetesManager.deploy(it) } + rolloutManager.rollout(appResources) logger.info { "Wait ${this.loadGenerationDelay} seconds before starting the load generator." } Thread.sleep(Duration.ofSeconds(this.loadGenerationDelay).toMillis()) loadGenBeforeActions.forEach { it.exec(client = client) } - loadGenResources.forEach { kubernetesManager.deploy(it) } - + rolloutManager.rollout(loadGenResources) } /** diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/RolloutManager.kt b/theodolite/src/main/kotlin/theodolite/benchmark/RolloutManager.kt new file mode 100644 index 0000000000000000000000000000000000000000..fc29fac7692a721ef5f4ae0fbb0b80398a3beedb --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/benchmark/RolloutManager.kt @@ -0,0 +1,42 @@ +package theodolite.benchmark + +import io.fabric8.kubernetes.api.model.KubernetesResource +import io.fabric8.kubernetes.api.model.apps.DaemonSet +import io.fabric8.kubernetes.api.model.apps.Deployment +import io.fabric8.kubernetes.api.model.apps.ReplicaSet +import io.fabric8.kubernetes.api.model.apps.StatefulSet +import io.fabric8.kubernetes.client.NamespacedKubernetesClient +import theodolite.k8s.K8sManager + +private var SLEEP_TIME_MS = 500L + + +class RolloutManager(private val rolloutMode: RolloutMode, private val client: NamespacedKubernetesClient) { + + fun rollout(resources: List<KubernetesResource>) { + println("MODE IS: ${rolloutMode.value}") + resources + .forEach { K8sManager(client).deploy(it) } + + if (rolloutMode == RolloutMode.DEFAULT) { + resources + .forEach { + when (it) { + is Deployment -> waitFor { client.apps().deployments().withName(it.metadata.name).isReady } + is StatefulSet -> waitFor { client.apps().statefulSets().withName(it.metadata.name).isReady } + is DaemonSet -> waitFor { client.apps().daemonSets().withName(it.metadata.name).isReady } + is ReplicaSet -> waitFor { client.apps().replicaSets().withName(it.metadata.name).isReady } + } + } + } + } + + + private fun waitFor(f: () -> Boolean) { + while (!f()) { + Thread.sleep(SLEEP_TIME_MS) + println("wait for resource") + } + } + +} \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/RolloutMode.kt b/theodolite/src/main/kotlin/theodolite/benchmark/RolloutMode.kt new file mode 100644 index 0000000000000000000000000000000000000000..052847c66880cebbb6a1ffa91dce91d87afa325b --- /dev/null +++ b/theodolite/src/main/kotlin/theodolite/benchmark/RolloutMode.kt @@ -0,0 +1,10 @@ +package theodolite.benchmark + +import com.fasterxml.jackson.annotation.JsonValue +import com.fasterxml.jackson.databind.annotation.JsonDeserialize + +@JsonDeserialize +enum class RolloutMode(@JsonValue val value: String) { + NONE("no-waiting"), + DEFAULT("default") +} \ No newline at end of file