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
This commit is contained in:
Kui Shi 2014-10-02 08:02:34 +08:00
parent a11b217114
commit e552b21b04
5 changed files with 104 additions and 6 deletions

View File

@ -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
}
}
}
]
}

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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(