From e552b21b04a7cded33eeb494ee6c4a33c81f148f Mon Sep 17 00:00:00 2001 From: Kui Shi Date: Thu, 2 Oct 2014 08:02:34 +0800 Subject: [PATCH] Add volume option to boot server from volume and run script nova and cinder may set to different disk backend, e.g. nova use local disk for image, and cinder use rbd volume_driver. This patch will add flexibility for user to choose where the vm is booted from. Based on boot_runcommand_delete scenario, add new option for volume: volume_args, which is default to "None". It is a dict option and 'size' parameter is supported now. If volume_args is assigned, this scenario will create a volume_args['size'] size volume, and boot from the new volume, finally run "script". Here is a sample scenario: "VMTasks.boot_runcommand_delete": [ { "args": { "flavor": { "name": "m1.tiny" }, "image": { "name": "cirros" }, "volume_args": { "size": 2 }, "script": "./instance_dd_test.sh", ... Change-Id: I6993c046bcf5a8632b08d46ae380067ffa677f84 --- .../vm/boot-runcommand-delete-with-disk.json | 34 +++++++++++++++++++ .../vm/boot-runcommand-delete-with-disk.yaml | 24 +++++++++++++ rally-scenarios/rally.yaml | 25 ++++++++++++++ rally/benchmark/scenarios/vm/vmtasks.py | 18 +++++++--- tests/benchmark/scenarios/vm/test_vmtasks.py | 9 +++-- 5 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.json create mode 100644 doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.yaml diff --git a/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.json b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.json new file mode 100644 index 0000000000..a6e3dd848b --- /dev/null +++ b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.json @@ -0,0 +1,34 @@ +{ + "VMTasks.boot_runcommand_delete": [ + { + "args": { + "flavor": { + "name": "m1.nano" + }, + "image": { + "name": "cirros-0.3.1-x86_64-uec" + }, + "volume_args": { + "size": 2 + }, + "fixed_network": "private", + "floating_network": "public", + "use_floatingip": true, + "script": "doc/samples/tasks/support/instance_dd_test.sh", + "interpreter": "/bin/sh", + "username": "cirros" + }, + "runner": { + "type": "constant", + "times": 10, + "concurrency": 2 + }, + "context": { + "users": { + "tenants": 3, + "users_per_tenant": 2 + } + } + } + ] +} diff --git a/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.yaml b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.yaml new file mode 100644 index 0000000000..1b17863dca --- /dev/null +++ b/doc/samples/tasks/scenarios/vm/boot-runcommand-delete-with-disk.yaml @@ -0,0 +1,24 @@ +--- + VMTasks.boot_runcommand_delete: + - + args: + flavor: + name: "m1.nano" + image: + name: "cirros-0.3.1-x86_64-uec" + volume_args: + size: 2 + fixed_network: "private" + floating_network: "public" + use_floatingip: true + script: "doc/samples/tasks/support/instance_dd_test.sh" + interpreter: "/bin/sh" + username: "cirros" + runner: + type: "constant" + times: 10 + concurrency: 2 + context: + users: + tenants: 3 + users_per_tenant: 2 diff --git a/rally-scenarios/rally.yaml b/rally-scenarios/rally.yaml index df70d48542..f5b4860131 100644 --- a/rally-scenarios/rally.yaml +++ b/rally-scenarios/rally.yaml @@ -940,6 +940,31 @@ sla: max_failure_percent: 0 + - + args: + flavor: + name: "m1.tiny" + image: + name: "cirros-0.3.2-x86_64-uec" + volume_args: + size: 2 + fixed_network: "private" + floating_network: "public" + use_floatingip: true + script: "/home/jenkins/.rally/extra/instance_dd_test.sh" + interpreter: "/bin/sh" + username: "cirros" + runner: + type: "constant" + times: 2 + concurrency: 2 + context: + users: + tenants: 1 + users_per_tenant: 1 + sla: + max_failure_percent: 0 + - args: flavor: diff --git a/rally/benchmark/scenarios/vm/vmtasks.py b/rally/benchmark/scenarios/vm/vmtasks.py index d8bc33f25c..57ee6576c8 100644 --- a/rally/benchmark/scenarios/vm/vmtasks.py +++ b/rally/benchmark/scenarios/vm/vmtasks.py @@ -16,6 +16,7 @@ import json from rally.benchmark.scenarios import base +from rally.benchmark.scenarios.cinder import utils as cinder_utils from rally.benchmark.scenarios.nova import utils as nova_utils from rally.benchmark.scenarios.vm import utils as vm_utils from rally.benchmark import types as types @@ -24,7 +25,8 @@ from rally import consts from rally import exceptions -class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario): +class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario, + cinder_utils.CinderScenario): def __init__(self, *args, **kwargs): super(VMTasks, self).__init__(*args, **kwargs) @@ -36,22 +38,26 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario): @validation.number("port", minval=1, maxval=65535, nullable=True, integer_only=True) @validation.external_network_exists("floating_network", "use_floatingip") - @validation.required_services(consts.Service.NOVA) + @validation.required_services(consts.Service.NOVA, consts.Service.CINDER) @validation.required_openstack(users=True) - @base.scenario( - context={"cleanup": ["nova"], "keypair": {}, "allow_ssh": {}}) + @base.scenario(context={"cleanup": ["nova", "cinder"], + "keypair": {}, "allow_ssh": {}}) def boot_runcommand_delete(self, image, flavor, script, interpreter, username, + volume_args=None, fixed_network="private", floating_network="public", ip_version=4, port=22, use_floatingip=True, **kwargs): """Boot server, run a script that outputs JSON, delete server. + :param image: glance image name to use for the vm + :param flavor: VM flavor name :param script: script to run on the server, must output JSON mapping metric names to values. See sample script below. :param interpreter: The shell interpreter to use when running script :param username: User to SSH to instance as + :param volume_args: volume args when boot VM from volume :param fixed_network: Network where instance is part of :param floating_network: External network used to get floating ip from :param ip_version: Version of ip protocol to use for connection @@ -66,6 +72,10 @@ class VMTasks(nova_utils.NovaScenario, vm_utils.VMScenario): Example Script in doc/samples/tasks/support/instance_dd_test.sh """ + if volume_args: + volume = self._create_volume(volume_args['size'], imageRef=None) + kwargs['block_device_mapping'] = {'vda': '%s:::1' % volume.id} + server = None floating_ip = None try: diff --git a/tests/benchmark/scenarios/vm/test_vmtasks.py b/tests/benchmark/scenarios/vm/test_vmtasks.py index 837ab4427a..5844c4ee14 100644 --- a/tests/benchmark/scenarios/vm/test_vmtasks.py +++ b/tests/benchmark/scenarios/vm/test_vmtasks.py @@ -37,6 +37,10 @@ class VMTasksTestCase(test.TestCase): scenario._boot_server = mock.MagicMock(return_value=fake_server) + fake_volume = fakes.FakeVolumeManager().create() + fake_volume.id = "volume_id" + scenario._create_volume = mock.MagicMock(return_value=fake_volume) + scenario._generate_random_name = mock.MagicMock(return_value="name") fake_floating_ip = fakes.FakeFloatingIP() @@ -59,14 +63,15 @@ class VMTasksTestCase(test.TestCase): scenario.boot_runcommand_delete( "image_id", "flavour_id", "script_path", "interpreter", fixed_network='private', floating_network='public', - username="username", ip_version=4, + volume_args={'size': 10}, username="username", ip_version=4, port=22, use_floatingip=True, fakearg="f") # Assertions scenario._boot_server.assert_called_once_with( 'name', 'image_id', "flavour_id", key_name="rally_ssh_key", - fakearg="f") + fakearg="f", block_device_mapping={'vda': 'volume_id:::1'}) + scenario._create_volume.assert_called_once_with(10, imageRef=None) scenario._create_floating_ip.assert_called_once_with( fake_floating_ip_pool.name) scenario._associate_floating_ip.assert_called_once_with(