diff --git a/theodolite/crd/crd-benchmark.yaml b/theodolite/crd/crd-benchmark.yaml index 529d1ea427a2867f290f360a7330ccabfaf4305f..394d6cc580f7d70e3c201fcc905129bbb94f45d8 100644 --- a/theodolite/crd/crd-benchmark.yaml +++ b/theodolite/crd/crd-benchmark.yaml @@ -90,6 +90,8 @@ spec: type: array items: type: string + timeout: + type: integer afterActions: type: array default: [] @@ -116,6 +118,8 @@ spec: type: array items: type: string + timeout: + type: integer sut: description: The appResourceSets specifies all Kubernetes resources required to start the sut. A resourceSet can be either a configMap resourceSet or a fileSystem resourceSet. type: object @@ -179,6 +183,8 @@ spec: type: array items: type: string + timeout: + type: integer afterActions: type: array default: [] @@ -205,6 +211,8 @@ spec: type: array items: type: string + timeout: + type: integer loadGenerator: description: The loadGenResourceSets specifies all Kubernetes resources required to start the load generator. A resourceSet can be either a configMap resourceSet or a fileSystem resourceSet. type: object @@ -268,6 +276,8 @@ spec: type: array items: type: string + timeout: + type: integer afterActions: type: array default: [] @@ -294,6 +304,8 @@ spec: type: array items: type: string + timeout: + type: integer resourceTypes: description: A list of resource types that can be scaled for this `benchmark` resource. For each resource type the concrete values are defined in the `execution` object. type: array diff --git a/theodolite/examples/operator/example-benchmark.yaml b/theodolite/examples/operator/example-benchmark.yaml index 945a05b381565904e5b11e013975c9b2a321e9dc..b66852b1d82471b6566de9d6d789ccda67524e49 100644 --- a/theodolite/examples/operator/example-benchmark.yaml +++ b/theodolite/examples/operator/example-benchmark.yaml @@ -22,6 +22,7 @@ spec: app: busybox1 exec: command: ["rm", "test-folder"] + timeout: 90 loadGenerator: resources: - configMap: diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/Action.kt b/theodolite/src/main/kotlin/theodolite/benchmark/Action.kt index 9fff88eeaa813424a40e7351b7f2912c3f1f996a..edbffea368ab7cf4dda03b6663ab9ec3c7a41d3f 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/Action.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/Action.kt @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize import io.fabric8.kubernetes.client.NamespacedKubernetesClient import io.quarkus.runtime.annotations.RegisterForReflection import theodolite.util.ActionCommandFailedException +import theodolite.util.Configuration @JsonDeserialize @RegisterForReflection @@ -19,6 +20,7 @@ class Action { .exec( matchLabels = selector.pod.matchLabels, container = selector.container, + timeout = exec.timeout, command = exec.command ) if(exitCode != 0){ @@ -42,4 +44,5 @@ class PodSelector { @RegisterForReflection class Command { lateinit var command: Array<String> + var timeout: Long = Configuration.TIMEOUT } \ No newline at end of file diff --git a/theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt b/theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt index bceb456c0e83b8ff3453f1cd9d6ddd78b92e437e..55c87074a5ee3ffe03d7def2f03f84734846a270 100644 --- a/theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt +++ b/theodolite/src/main/kotlin/theodolite/benchmark/ActionCommand.kt @@ -6,6 +6,7 @@ import io.fabric8.kubernetes.client.dsl.ExecWatch import mu.KotlinLogging import okhttp3.Response import theodolite.util.ActionCommandFailedException +import theodolite.util.Configuration import java.io.ByteArrayOutputStream import java.time.Duration import java.util.concurrent.CountDownLatch @@ -13,7 +14,6 @@ import java.util.concurrent.TimeUnit import kotlin.properties.Delegates private val logger = KotlinLogging.logger {} -private const val TIMEOUT = 30L class ActionCommand(val client: NamespacedKubernetesClient) { var out: ByteArrayOutputStream = ByteArrayOutputStream() @@ -29,8 +29,12 @@ class ActionCommand(val client: NamespacedKubernetesClient) { * @param command The command to be executed. * @return the exit code of this executed command */ - fun exec(matchLabels: MutableMap<String, String>, command: Array<String>, container: String = ""): Int { - + fun exec( + matchLabels: MutableMap<String, String>, + command: Array<String>, + timeout: Long = Configuration.TIMEOUT, + container: String = "" + ): Int { val exitCode = ExitCode() try { @@ -50,7 +54,7 @@ class ActionCommand(val client: NamespacedKubernetesClient) { .usingListener(MyPodExecListener(execLatch, exitCode)) .exec(*command) - val latchTerminationStatus = execLatch.await(TIMEOUT, TimeUnit.SECONDS); + val latchTerminationStatus = execLatch.await(timeout, TimeUnit.SECONDS); if (!latchTerminationStatus) { throw ActionCommandFailedException("Latch could not terminate within specified time") } diff --git a/theodolite/src/main/kotlin/theodolite/util/Configuration.kt b/theodolite/src/main/kotlin/theodolite/util/Configuration.kt index dac3b943e69bd7e208d318f2a788275f19db11e4..97fffb8c91b6e84e548b840acb5402ea6bf43e56 100644 --- a/theodolite/src/main/kotlin/theodolite/util/Configuration.kt +++ b/theodolite/src/main/kotlin/theodolite/util/Configuration.kt @@ -13,6 +13,11 @@ class Configuration( val NAMESPACE = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE val COMPONENT_NAME = System.getenv("COMPONENT_NAME") ?: DEFAULT_COMPONENT_NAME val EXECUTION_MODE = System.getenv("MODE") ?: ExecutionModes.STANDALONE.value + + /** + * Specifies how long Theodolite should wait (in sec) before aborting the execution of an action command. + */ + const val TIMEOUT: Long = 30L } }