Change-Id: Id34d8dc40942b4e29324eae17f0e64c78c5e0c49
4.6 KiB
Context as a plugin
So what are contexts doing? These plugins will be executed before scenario iteration starts. For example, a context plugin could create resources (e.g., download 10 images) that will be used by the scenarios. All created objects must be put into the self.context dict, through which they will be available in the scenarios. Let's create a simple context plugin that adds a flavor to the environment before runner start first iteration and deletes it after runner finishes execution of all iterations.
Creation
Inherit a class for your plugin from the base Context class. Then, implement the Context API: the setup() method that creates a flavor and the cleanup() method that deletes it.
from rally.task import context
from rally.common import logging
from rally import consts
from rally.plugins.openstack import osclients
= logging.getLogger(__name__)
LOG
@context.configure(name="create_flavor", order=1000)
class CreateFlavorContext(context.Context):
"""This sample creates a flavor with specified option."""
= {
CONFIG_SCHEMA "type": "object",
"$schema": consts.JSON_SCHEMA,
"additionalProperties": False,
"properties": {
"flavor_name": {
"type": "string",
},"ram": {
"type": "integer",
"minimum": 1
},"vcpus": {
"type": "integer",
"minimum": 1
},"disk": {
"type": "integer",
"minimum": 1
}
}
}
def setup(self):
"""This method is called before the task starts."""
try:
# use rally.osclients to get necessary client instance
= osclients.Clients(self.context["admin"]["credential"]).nova()
nova # and than do what you need with this client
self.context["flavor"] = nova.flavors.create(
# context settings are stored in self.config
=self.config.get("flavor_name", "rally_test_flavor"),
name=self.config.get("ram", 1),
ram=self.config.get("vcpus", 1),
vcpus=self.config.get("disk", 1)).to_dict()
disk"Flavor with id '%s'" % self.context["flavor"]["id"])
LOG.debug(except Exception as e:
= "Can't create flavor: %s" % e.message
msg if logging.is_debug():
LOG.exception(msg)else:
LOG.warning(msg)
def cleanup(self):
"""This method is called after the task finishes."""
try:
= osclients.Clients(self.context["admin"]["credential"]).nova()
nova self.context["flavor"]["id"])
nova.flavors.delete("Flavor '%s' deleted" % self.context["flavor"]["id"])
LOG.debug(except Exception as e:
= "Can't delete flavor: %s" % e.message
msg if logging.is_debug():
LOG.exception(msg)else:
LOG.warning(msg)
Usage
The new plugin can be used by specifying it in context section. Like below:
{
"Dummy.dummy": [
{
"args": {
"sleep": 0.01
},
"runner": {
"type": "constant",
"times": 5,
"concurrency": 1
},
"context": {
"users": {
"tenants": 1,
"users_per_tenant": 1
},
"create_flavor": {
"ram": 1024
}
}
}
]
}