LxcProvider track resources

The patch introduce a resource tracking in LxcProvider.

blueprint db-resource-track

Change-Id: I4bb0cb9d9af5203a6de147903c944fc883d3bd8f
This commit is contained in:
Ilya Kharin 2013-12-10 00:09:12 +04:00 committed by Gerrit Code Review
parent 44773b14e6
commit 3a60bd6b9b
2 changed files with 119 additions and 64 deletions

View File

@ -96,42 +96,58 @@ class LxcProvider(provider.ProviderFactory):
"""
def __init__(self, deployment, config):
super(LxcProvider, self).__init__(deployment, config)
self.containers = []
def _next_ip(self):
self.ip += 1
return '%s/%d' % (self.ip, self.network.prefixlen)
@utils.log_deploy_wrapper(LOG.info, _("Create containers on host"))
def create_vms(self):
self.host_provider = provider.ProviderFactory.get_provider(
host_provider = provider.ProviderFactory.get_provider(
self.config['host_provider'], self.deployment)
self.network = netaddr.IPNetwork(self.config['start_ip_address'])
self.ip = self.network.ip - 1
config = self.config['container_config']
first = str(uuid.uuid4())
for server in self.host_provider.create_vms():
config.update({'ip': self._next_ip(), 'name': first})
containers = []
for server in host_provider.create_vms():
config = self.config['container_config'].copy()
config['ip'] = self._next_ip()
config['name'] = first
first_container = LxcContainer(server, config)
first_container.prepare_host()
first_container.create(self.config['distribution'])
self.containers.append(first_container)
containers.append(first_container)
self.resources.create({
'server': first_container.server.get_credentials(),
'config': config,
})
for i in range(1, self.config['containers_per_host']):
config.update({'ip': self._next_ip(),
'name': '%s-%d' % (first, i)})
config = self.config['container_config'].copy()
config['ip'] = self._next_ip()
config['name'] = '%s-%d' % (first, i)
container = LxcContainer(server, config)
container.clone(first)
container.start()
self.containers.append(container)
containers.append(container)
self.resources.create({
'server': container.server.get_credentials(),
'config': config,
})
first_container.start()
for container in self.containers:
for container in containers:
container.server.ssh.wait()
return [c.server for c in self.containers]
return [c.server for c in containers]
@utils.log_deploy_wrapper(LOG.info, _("Destroy host(s)"))
def destroy_vms(self):
for c in self.containers:
c.stop()
self.host_provider.destroy_vms()
for resource in self.resources.get_all():
config = resource['info']['config']
server = provider.Server.from_credentials(
resource['info']['server'])
container = LxcContainer(server, config)
container.stop()
container.destroy()
self.resources.delete(resource)
host_provider = provider.ProviderFactory.get_provider(
self.config['host_provider'], self.deployment)
host_provider.destroy_vms()

View File

@ -13,13 +13,16 @@
# License for the specific language governing permissions and limitations
# under the License.
import contextlib
import mock
from rally.openstack.common.fixture import mockpatch
from rally.openstack.common import test
from rally.serverprovider.providers import lxc
MOD_NAME = 'rally.serverprovider.providers.lxc.'
class LxcContainerTestCase(test.BaseTestCase):
def setUp(self):
@ -93,39 +96,10 @@ class LxcContainerTestCase(test.BaseTestCase):
self.assertEqual(expected, self.server.mock_calls)
class FakeContainer(lxc.LxcContainer):
def __init__(self, *args, **kwargs):
super(FakeContainer, self).__init__(*args, **kwargs)
self.status = []
def prepare_host(self, *args):
self.status.append('prepared')
def create(self, *args):
self.status.append('created')
def clone(self, src):
self.status.append('cloned ' + src)
def start(self, *args):
self.status.append('started')
def stop(self, *args):
self.status.append('stopped')
def destroy(self, *args):
self.status.append('destroyed')
def configure(self, *args):
self.status.append('configured')
class LxcProviderTestCase(test.BaseTestCase):
def setUp(self):
super(LxcProviderTestCase, self).setUp()
self.mod = 'rally.serverprovider.providers.lxc.'
self.config = {
'name': 'LxcProvider',
'containers_per_host': 3,
@ -142,29 +116,94 @@ class LxcProviderTestCase(test.BaseTestCase):
self.mock_deployment = mock.MagicMock()
self.provider = lxc.provider.ProviderFactory.get_provider(
self.config, self.mock_deployment)
self.useFixture(mockpatch.PatchObject(self.provider, 'resources'))
def test_create_vms(self):
@mock.patch(MOD_NAME + 'uuid')
@mock.patch('rally.serverprovider.provider.Server')
@mock.patch(MOD_NAME + 'LxcContainer')
@mock.patch(MOD_NAME + 'provider.ProviderFactory.get_provider')
def test_create_vms(self, get_provider, mock_lxc_container, mock_server,
mock_uuid):
def create_config(ip, name):
conf = self.config['container_config'].copy()
conf['ip'] = ip
conf['name'] = name
return conf
mock_uuid.uuid4.return_value = 'fakeuuid'
mock_first_conts = [mock.Mock(), mock.Mock()]
mock_conts = [mock.Mock() for i in range(4)]
mock_lxc_container.side_effect = containers = \
[mock_first_conts[0]] + mock_conts[:2] + \
[mock_first_conts[1]] + mock_conts[2:]
for (i, mock_cont_i) in enumerate(containers):
mock_cont_i.server.get_credentials.return_value = i
s1 = mock.Mock()
s2 = mock.Mock()
provider = mock.Mock()
provider.create_vms = mock.Mock(return_value=[s1, s2])
get_provider = mock.Mock(return_value=provider)
with contextlib.nested(
mock.patch(self.mod + 'provider.Server'),
mock.patch(self.mod + 'LxcContainer', new=FakeContainer),
mock.patch(self.mod + 'provider.ProviderFactory.get_provider',
new=get_provider)):
self.provider.create_vms()
name = self.provider.containers[0].config['name']
s_first = ['prepared', 'created', 'started']
s_clone = ['cloned ' + name, 'started']
statuses = [c.status for c in self.provider.containers]
self.assertEqual(6, len(statuses))
self.assertEqual(([s_first] + [s_clone] * 2) * 2, statuses)
get_provider.return_value = provider
expected_ips = ['192.168.0.%d/24' % i for i in range(10, 16)]
ips = [c.config['ip'] for c in self.provider.containers]
self.assertEqual(expected_ips, ips)
self.provider.create_vms()
configs = [
create_config('192.168.0.10/24', 'fakeuuid'),
create_config('192.168.0.11/24', 'fakeuuid-1'),
create_config('192.168.0.12/24', 'fakeuuid-2'),
create_config('192.168.0.13/24', 'fakeuuid'),
create_config('192.168.0.14/24', 'fakeuuid-1'),
create_config('192.168.0.15/24', 'fakeuuid-2'),
]
mock_lxc_container.assert_has_calls(
[mock.call(*a) for a in zip(3 * [s1] + 3 * [s2], configs)])
for mock_cont_i in mock_first_conts:
mock_cont_i.assert_has_calls([
mock.call.prepare_host(),
mock.call.create('ubuntu'),
mock.call.server.get_credentials(),
mock.call.start(),
mock.call.server.ssh.wait(),
])
for mock_cont_i in mock_conts:
mock_cont_i.assert_has_calls([
mock.call.clone('fakeuuid'),
mock.call.start(),
mock.call.server.get_credentials(),
mock.call.server.ssh.wait(),
])
get_provider.assert_called_once_with(self.config['host_provider'],
self.mock_deployment)
self.provider.resources.create.assert_has_calls(
[mock.call({'config': a[0], 'server': a[1]})
for a in zip(configs, range(6))])
@mock.patch(MOD_NAME + 'provider.ProviderFactory.get_provider')
@mock.patch(MOD_NAME + 'provider.Server')
@mock.patch(MOD_NAME + 'LxcContainer')
def test_destroy_vms(self, mock_lxc_container, mock_server,
mock_get_provider):
mock_lxc_container.return_value = mock_container = mock.Mock()
mock_get_provider.return_value = mock_provider = mock.Mock()
resource = {
'info': {
'config': 'fakeconfig',
'server': 'fakeserver0',
},
}
self.provider.resources.get_all.return_value = [resource]
mock_server.from_credentials.return_value = 'fakeserver1'
self.provider.destroy_vms()
mock_server.from_credentials.assert_called_once_with('fakeserver0')
mock_lxc_container.assert_called_once_with('fakeserver1', 'fakeconfig')
mock_container.assert_has_calls([
mock.call.stop(),
mock.call.destroy(),
])
self.provider.resources.delete.asert_called_once_with(resource)
mock_get_provider.assert_called_once_with(self.config['host_provider'],
self.mock_deployment)
mock_provider.assert_has_calls([
mock.call.destroy_vms(),
])