Skip to content
Snippets Groups Projects
Commit 42497986 authored by Sören Henning's avatar Sören Henning
Browse files

Merge branch 'waitUntilReady' into 'master'

Wait until the resources of the predecessor resourceSet are ready

See merge request !261
parents 13673867 490196e3
No related branches found
No related tags found
1 merge request!261Wait until the resources of the predecessor resourceSet are ready
Pipeline #8433 passed
...@@ -146,6 +146,15 @@ Resource Types: ...@@ -146,6 +146,15 @@ Resource Types:
<i>Default</i>: <br/> <i>Default</i>: <br/>
</td> </td>
<td>false</td> <td>false</td>
</tr><tr>
<td><b>waitForResourcesEnabled</b></td>
<td>boolean</td>
<td>
If true, Theodolite waits to create the resource for the SUT until the infrastructure resources are ready, and analogously, Theodolite waits to create the load-gen resource until the resources of the SUT are ready.<br/>
<br/>
<i>Default</i>: false<br/>
</td>
<td>false</td>
</tr></tbody> </tr></tbody>
</table> </table>
......
...@@ -26,6 +26,10 @@ spec: ...@@ -26,6 +26,10 @@ 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. 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 type: string
default: "" default: ""
waitForResourcesEnabled:
description: If true, Theodolite waits to create the resource for the SUT until the infrastructure resources are ready, and analogously, Theodolite waits to create the load-gen resource until the resources of the SUT are ready.
type: boolean
default: false
infrastructure: infrastructure:
description: (Optional) A list of file names that reference Kubernetes resources that are deployed on the cluster to create the required 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 type: object
......
...@@ -10,6 +10,7 @@ import mu.KotlinLogging ...@@ -10,6 +10,7 @@ import mu.KotlinLogging
import theodolite.k8s.K8sManager import theodolite.k8s.K8sManager
import theodolite.patcher.PatcherFactory import theodolite.patcher.PatcherFactory
import theodolite.util.* import theodolite.util.*
import kotlin.properties.Delegates
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
...@@ -37,6 +38,7 @@ private var DEFAULT_THEODOLITE_APP_RESOURCES = "./benchmark-resources" ...@@ -37,6 +38,7 @@ private var DEFAULT_THEODOLITE_APP_RESOURCES = "./benchmark-resources"
@RegisterForReflection @RegisterForReflection
class KubernetesBenchmark : KubernetesResource, Benchmark { class KubernetesBenchmark : KubernetesResource, Benchmark {
lateinit var name: String lateinit var name: String
var waitForResourcesEnabled = false
lateinit var resourceTypes: List<TypeName> lateinit var resourceTypes: List<TypeName>
lateinit var loadTypes: List<TypeName> lateinit var loadTypes: List<TypeName>
var kafkaConfig: KafkaConfig? = null var kafkaConfig: KafkaConfig? = null
...@@ -64,10 +66,8 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { ...@@ -64,10 +66,8 @@ class KubernetesBenchmark : KubernetesResource, Benchmark {
override fun setupInfrastructure() { override fun setupInfrastructure() {
this.infrastructure.beforeActions.forEach { it.exec(client = client) } this.infrastructure.beforeActions.forEach { it.exec(client = client) }
val kubernetesManager = K8sManager(this.client) RolloutManager(waitForResourcesEnabled, this.client)
loadResources(this.infrastructure.resources) .rollout(loadResources(this.infrastructure.resources).map { it.second })
.map { it.second }
.forEach { kubernetesManager.deploy(it) }
} }
override fun teardownInfrastructure() { override fun teardownInfrastructure() {
...@@ -129,7 +129,9 @@ class KubernetesBenchmark : KubernetesResource, Benchmark { ...@@ -129,7 +129,9 @@ class KubernetesBenchmark : KubernetesResource, Benchmark {
afterTeardownDelay = afterTeardownDelay, afterTeardownDelay = afterTeardownDelay,
kafkaConfig = if (kafkaConfig != null) mapOf("bootstrap.servers" to kafkaConfig.bootstrapServer) else mapOf(), kafkaConfig = if (kafkaConfig != null) mapOf("bootstrap.servers" to kafkaConfig.bootstrapServer) else mapOf(),
topics = kafkaConfig?.topics ?: listOf(), topics = kafkaConfig?.topics ?: listOf(),
client = this.client client = this.client,
rolloutMode = waitForResourcesEnabled
) )
} }
......
...@@ -28,6 +28,7 @@ class KubernetesBenchmarkDeployment( ...@@ -28,6 +28,7 @@ class KubernetesBenchmarkDeployment(
private val sutAfterActions: List<Action>, private val sutAfterActions: List<Action>,
private val loadGenBeforeActions: List<Action>, private val loadGenBeforeActions: List<Action>,
private val loadGenAfterActions: List<Action>, private val loadGenAfterActions: List<Action>,
private val rolloutMode: Boolean,
val appResources: List<HasMetadata>, val appResources: List<HasMetadata>,
val loadGenResources: List<HasMetadata>, val loadGenResources: List<HasMetadata>,
private val loadGenerationDelay: Long, private val loadGenerationDelay: Long,
...@@ -47,19 +48,20 @@ class KubernetesBenchmarkDeployment( ...@@ -47,19 +48,20 @@ class KubernetesBenchmarkDeployment(
* - Deploy the needed resources. * - Deploy the needed resources.
*/ */
override fun setup() { override fun setup() {
val rolloutManager = RolloutManager(rolloutMode, client)
if (this.topics.isNotEmpty()) { if (this.topics.isNotEmpty()) {
val kafkaTopics = this.topics val kafkaTopics = this.topics
.filter { !it.removeOnly } .filter { !it.removeOnly }
.map { NewTopic(it.name, it.numPartitions, it.replicationFactor) } .map { NewTopic(it.name, it.numPartitions, it.replicationFactor) }
kafkaController.createTopics(kafkaTopics) kafkaController.createTopics(kafkaTopics)
} }
sutBeforeActions.forEach { it.exec(client = client) } 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." } logger.info { "Wait ${this.loadGenerationDelay} seconds before starting the load generator." }
Thread.sleep(Duration.ofSeconds(this.loadGenerationDelay).toMillis()) Thread.sleep(Duration.ofSeconds(this.loadGenerationDelay).toMillis())
loadGenBeforeActions.forEach { it.exec(client = client) } loadGenBeforeActions.forEach { it.exec(client = client) }
loadGenResources.forEach { kubernetesManager.deploy(it) } rolloutManager.rollout(loadGenResources)
} }
/** /**
......
package theodolite.benchmark
import io.fabric8.kubernetes.api.model.HasMetadata
import io.fabric8.kubernetes.api.model.Pod
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.api.model.batch.v1.Job
import io.fabric8.kubernetes.client.NamespacedKubernetesClient
import theodolite.k8s.K8sManager
private var SLEEP_TIME_MS = 500L
class RolloutManager(private val blockUntilResourcesReady: Boolean, private val client: NamespacedKubernetesClient) {
fun rollout(resources: List<HasMetadata>) {
resources
.forEach { K8sManager(client).deploy(it) }
if (blockUntilResourcesReady) {
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 }
is Job -> waitFor { client.batch().v1().cronjobs().withName(it.metadata.name).isReady }
}
}
}
}
private fun waitFor(isResourceReady: () -> Boolean) {
while (!isResourceReady()) {
Thread.sleep(SLEEP_TIME_MS)
}
}
}
\ No newline at end of file
...@@ -20,11 +20,12 @@ class BenchmarkCRDummy(name: String) { ...@@ -20,11 +20,12 @@ class BenchmarkCRDummy(name: String) {
kafkaConfig.bootstrapServer = "" kafkaConfig.bootstrapServer = ""
kafkaConfig.topics = emptyList() kafkaConfig.topics = emptyList()
benchmarkCR.spec = benchmark benchmarkCR.spec = benchmark
benchmarkCR.metadata.name = name benchmarkCR.metadata.name = name
benchmarkCR.kind = "Benchmark" benchmarkCR.kind = "Benchmark"
benchmarkCR.apiVersion = "v1" benchmarkCR.apiVersion = "v1"
benchmark.waitForResourcesEnabled = false
benchmark.infrastructure = Resources() benchmark.infrastructure = Resources()
benchmark.sut = Resources() benchmark.sut = Resources()
......
...@@ -3,6 +3,7 @@ kind: benchmark ...@@ -3,6 +3,7 @@ kind: benchmark
metadata: metadata:
name: example-benchmark name: example-benchmark
spec: spec:
waitForResourcesEnabled: false
sut: sut:
resources: resources:
- configMap: - configMap:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment