diff options
author | Hans Feldt <hans.feldt@ericsson.com> | 2015-06-29 15:27:55 +0200 |
---|---|---|
committer | Hans Feldt <hans.feldt@ericsson.com> | 2015-07-08 07:02:45 +0000 |
commit | d71e101ac1420ed03fa2dbecb76fc8156a16761a (patch) | |
tree | f6d62c25ac79268626a6a5d3d6e2c14b153e5abf | |
parent | 6b667910909b332e78105ccdf17e39e4b286ed39 (diff) |
Add support for action hooks in runner config
pre-start and post-stop intention is to be used to gather
information about the target system.
single-shot and periodic-action intention is to perform
actions on the infrastructure or cloud resources. For example
server live migration or network interface down.
Example of what can be added in the runner section:
pre-start-action:
command: "heat stack-show demo"
periodic-action:
interval: 10
command: "ifconfig vboxnet1"
single-shot-action:
after: 30
command: "nova show goofy.demo"
post-stop-action:
command: "nova list"
pre-start and post-stop data are added into the output file.
periodic and single-shot are not because that would interfere with
the actual sampled data. Besides the intention is not to log statistics
but do things with the infrastructure such as server live migration.
TODO: add sections to the output file, something like pre, data & post
JIRA: YARDSTICK-46
Change-Id: Ia059813fb74733f86368aea9c7a20e5afb71d228
Signed-off-by: Hans Feldt <hans.feldt@ericsson.com>
-rw-r--r-- | samples/ping-ext-stimuli.yaml | 49 | ||||
-rw-r--r-- | yardstick/benchmark/runners/base.py | 75 |
2 files changed, 123 insertions, 1 deletions
diff --git a/samples/ping-ext-stimuli.yaml b/samples/ping-ext-stimuli.yaml new file mode 100644 index 000000000..cfe791567 --- /dev/null +++ b/samples/ping-ext-stimuli.yaml @@ -0,0 +1,49 @@ +--- +# Sample benchmark task config file +# Measure network latency using ping, destination is an external server +# Make sure servers have internet access before running this test. +# For example using virtual MOS do something this on the host: +# sudo iptables -t nat -A POSTROUTING -s 172.16.0.0/24 \! -d 172.16.0.0/24 -j MASQUERADE +# +# This sample demonstrates the use of runner actions - hooks inserted in +# diffrent places of the runner execution. +# + +schema: "yardstick:task:0.1" + +scenarios: +- + type: Ping + host: goofy.demo + target: 8.8.8.8 + runner: + type: Duration + duration: 60 + interval: 1 + pre-start-action: + command: "heat stack-show demo" + periodic-action: + interval: 10 + command: "ifconfig vboxnet1" + single-shot-action: + after: 30 + command: "nova show goofy.demo" + post-stop-action: + command: "nova list" + sla: + max_rtt: 10 + action: monitor + +context: + name: demo + image: cirros-0.3.3 + flavor: m1.tiny + user: cirros + servers: + goofy: + floating_ip: true + networks: + test: + cidr: '10.0.1.0/24' + external_network: "net04_ext" + diff --git a/yardstick/benchmark/runners/base.py b/yardstick/benchmark/runners/base.py index 08117c625..badc33565 100644 --- a/yardstick/benchmark/runners/base.py +++ b/yardstick/benchmark/runners/base.py @@ -8,9 +8,11 @@ ############################################################################## import importlib -import multiprocessing import json import logging +import multiprocessing +import subprocess +import time log = logging.getLogger(__name__) @@ -35,6 +37,27 @@ def _output_serializer_main(filename, queue): outfile.write('\n') +def _single_action(seconds, command, queue): + '''entrypoint for the single action process''' + log.debug("single action, fires after %d seconds (from now)", seconds) + time.sleep(seconds) + log.debug("single action: executing command: '%s'", command) + data = subprocess.check_output(command, shell=True) + log.debug("\n%s" % data) + + +def _periodic_action(interval, command, queue): + '''entrypoint for the periodic action process''' + log.debug("periodic action, fires every: %d seconds", interval) + time_spent = 0 + while True: + time.sleep(interval) + time_spent += interval + log.debug("periodic action, executing command: '%s'", command) + data = subprocess.check_output(command, shell=True) + log.debug("\n%s" % data) + + class Runner(object): queue = None dump_process = None @@ -88,6 +111,10 @@ class Runner(object): '''Terminate all runners (subprocesses)''' log.debug("Terminating all runners") for runner in Runner.runners: + if runner.periodic_action_process: + log.debug("Terminating periodic action process") + runner.periodic_action_process.terminate() + runner.periodic_action_process = None runner.process.terminate() runner.process.join() Runner.release(runner) @@ -95,9 +122,30 @@ class Runner(object): def __init__(self, config, queue): self.context = {} self.config = config + self.periodic_action_process = None self.result_queue = queue Runner.runners.append(self) + def run_pre_start_action(self): + '''run a potentially configured pre-start action''' + if "pre-start-action" in self.config: + command = self.config["pre-start-action"]["command"] + log.debug("pre start action: command: '%s'" % command) + data = subprocess.check_output(command, shell=True) + log.debug("pre-start data: \n%s" % data) + output = "{'pre-start-action-data': %s}" % data + self.result_queue.put(output) + + def run_post_stop_action(self): + '''run a potentially configured post-stop action''' + if "post-stop-action" in self.config: + command = self.config["post-stop-action"]["command"] + log.debug("post stop action: command: '%s'" % command) + data = subprocess.check_output(command, shell=True) + log.debug("post-stop data: \n%s" % data) + output = "{'post-stop-action-data': %s}" % data + self.result_queue.put(output) + def run(self, scenario_type, scenario_args): class_name = base_scenario.Scenario.get(scenario_type) path_split = class_name.split(".") @@ -106,8 +154,33 @@ class Runner(object): cls = getattr(module, path_split[-1]) self.config['object'] = class_name + + self.run_pre_start_action() + + if "single-shot-action" in self.config: + single_action_process = multiprocessing.Process( + target=_single_action, + name="single-shot-action", + args=(self.config["single-shot-action"]["after"], + self.config["single-shot-action"]["command"], + self.result_queue)) + single_action_process.start() + + if "periodic-action" in self.config: + self.periodic_action_process = multiprocessing.Process( + target=_periodic_action, + name="periodic-action", + args=(self.config["periodic-action"]["interval"], + self.config["periodic-action"]["command"], + self.result_queue)) + self.periodic_action_process.start() + self._run_benchmark(cls, "run", scenario_args) def join(self): self.process.join() + if self.periodic_action_process: + self.periodic_action_process.terminate() + self.periodic_action_process = None + self.run_post_stop_action() return self.process.exitcode |