Add VM Provider factory

To be able to easy extend VM Providers, and use multiple VMProviders
in the same time

So to extend VM provider by your own you have to do couple of simple things

Add new subclass of rally.vmprovider.VMProviderFactory to any modules in
rally.vmprovider.VMProvider.providers.some_module, and implement 4 next methods:

1) upload_image()
2) destroy_image()
3) create_vms()
4) destroy_vms()
This commit is contained in:
Boris Pavlovic 2013-09-01 23:22:32 +04:00
parent 0089a26a13
commit 8629282547
6 changed files with 151 additions and 0 deletions

View File

@ -92,5 +92,9 @@ class NoSuchEngine(NotFoundException):
msg_fmt = _("There is no engine with name `%(engine_name)s`.")
class NoSuchVMProvider(NotFoundException):
msg_fmt = _("There is no vm provider with name `%(vm_provider_name)s`.")
class TaskNotFound(NotFoundException):
msg_fmt = _("Task with uuid=%(uuid)s not found.")

View File

View File

@ -0,0 +1,74 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013: Mirantis Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import abc
from rally import exceptions
from rally import utils
class VMProviderFactory(object):
"""rally.vmprovider.provider.VMProviderFactory is base class for providers
All provider should be added to rally.vmprovider.providers.some_moduule.py
and implement 4 methods:
*) upload_image
*) destroy_image
*) create_vms
*) destroy_vms.
"""
__metaclass__ = abc.ABCMeta
@staticmethod
def get_provider(name, config):
"""Returns instance of vm provider by name."""
for provider in utils.itersubclasses(VMProviderFactory):
if name == provider.__name__:
return provider(config)
raise exceptions.NoSuchVMProvider(vm_provider_name=name)
@staticmethod
def get_available_providers():
"""Returns list of names of available engines."""
return [e.__name__ for e in utils.itersubclasses(VMProviderFactory)]
@abc.abstractmethod
def upload_image(self, image):
"""Upload image that could be used in creating new vms.
:image: Image file
Returns uuid of added image.
"""
pass
@abc.abstractmethod
def destroy_image(self, image_uuid):
"""Destroy image by image_uuid."""
pass
@abc.abstractmethod
def create_vms(self, image_uuid=None, amount=1):
"""Create VMs with chosen image.
:param image_uuid: Indetificator of image
:param amount: amount of required VMs
Returns list of VMs uuids.
"""
pass
@abc.abstractmethod
def destroy_vms(self, vm_uuids):
"""Destroy already created vms by vm_uuids."""
pass

View File

View File

View File

@ -0,0 +1,73 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013: Mirantis Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Test for vm providers."""
from rally import exceptions
from rally import test
from rally.vmprovider import provider as vm_provider
class VMProviderTestCase(test.NoDBTestCase):
def test_get_provider_not_found(self):
self.assertRaises(exceptions.NoSuchVMProvider,
vm_provider.VMProviderFactory.get_provider,
"non_existing", None)
def _create_fake_providers(self):
class ProviderMixIn(object):
def upload_image(self, image):
pass
def destroy_image(self, image_uuid):
pass
def create_vms(self, image_uuid=None, amount=1):
pass
def destroy_vms(self, vm_uuids):
pass
class ProviderA(ProviderMixIn, vm_provider.VMProviderFactory):
def __init__(self, config):
pass
class ProviderB(ProviderMixIn, vm_provider.VMProviderFactory):
def __init__(self, config):
pass
class ProviderC(ProviderB):
def __init__(self, config):
pass
return [ProviderA, ProviderB, ProviderC]
def test_get_provider(self):
for p in self._create_fake_providers():
p_inst = vm_provider.VMProviderFactory.get_provider(p.__name__,
None)
# TODO(boris-42): make it work through assertIsInstance
self.assertEqual(str(type(p_inst)), str(p))
def test_get_all_provider(self):
provider = [p.__name__ for p in self._create_fake_providers()]
real_provider = vm_provider.VMProviderFactory.get_available_providers()
self.assertEqual(sorted(provider), sorted(real_provider))
def test_vm_prvoider_factory_is_abstract(self):
self.assertRaises(TypeError, vm_provider.VMProviderFactory)