Remove profile-related methods from nova.virt.lxd.session

Another red patch, a few less lines of code to maintain.

Change-Id: Ie6d7fbea5ecf5184129dab4614fcfa94a44731ee
This commit is contained in:
Paul Hummer 2016-11-10 11:54:22 -07:00 committed by Paul Hummer
parent bc17707671
commit 42ed04c572
5 changed files with 29 additions and 199 deletions

View File

@ -1459,6 +1459,23 @@ class LXDDriverTest(test.NoDBTestCase):
container.delete.assert_called_once_with(wait=True) container.delete.assert_called_once_with(wait=True)
def test_post_live_migration_at_source(self):
ctx = context.get_admin_context()
instance = fake_instance.fake_instance_obj(ctx, name='test')
network_info = []
profile = mock.Mock()
self.client.profiles.get.return_value = profile
lxd_driver = driver.LXDDriver(None)
lxd_driver.cleanup = mock.Mock()
lxd_driver.init_host(None)
lxd_driver.post_live_migration_at_source(
ctx, instance, network_info)
profile.delete.assert_called_once_with()
lxd_driver.cleanup.assert_called_once_with(ctx, instance, network_info)
class InstanceAttributesTest(test.NoDBTestCase): class InstanceAttributesTest(test.NoDBTestCase):
"""Tests for InstanceAttributes.""" """Tests for InstanceAttributes."""

View File

@ -18,8 +18,6 @@ import mock
import nova.conf import nova.conf
from nova import exception from nova import exception
from nova import test from nova import test
from nova.tests.unit import fake_instance
import pylxd
from pylxd.deprecated import exceptions as lxd_exceptions from pylxd.deprecated import exceptions as lxd_exceptions
from nova.virt.lxd import driver from nova.virt.lxd import driver
@ -38,30 +36,6 @@ class LXDTestLiveMigrate(test.NoDBTestCase):
self.driver.config = mock.MagicMock() self.driver.config = mock.MagicMock()
self.driver.operations = mock.MagicMock() self.driver.operations = mock.MagicMock()
def test_copy_container_profile(self):
"""Verify the correct calls are made
when a host needs to copy a container profile.
"""
self.driver.create_profile = mock.Mock()
self.driver.session = mock.Mock()
mock_instance = fake_instance.fake_instance_obj(self.context)
fake_network_info = []
self.driver._copy_container_profile(mock_instance, fake_network_info)
self.driver.create_profile.assert_called_once_with(
mock_instance, fake_network_info)
@mock.patch.object(driver.LXDDriver, '_copy_container_profile')
def test_pre_live_migration(self, mock_container_profile):
"""Verify that the copy profile methos is called."""
self.driver.pre_live_migration(
mock.sentinel.context, mock.sentinel.instance,
mock.sentinel.block_device_info,
[],
mock.sentinel.disk_info,
mock.sentinel.migrate_data)
@mock.patch.object(driver.LXDDriver, '_container_init') @mock.patch.object(driver.LXDDriver, '_container_init')
def test_live_migration(self, mock_container_init): def test_live_migration(self, mock_container_init):
"""Verify that the correct live migration calls """Verify that the correct live migration calls
@ -89,7 +63,7 @@ class LXDTestLiveMigrate(test.NoDBTestCase):
mock_container_init.side_effect = \ mock_container_init.side_effect = \
lxd_exceptions.APIError(500, 'Fake') lxd_exceptions.APIError(500, 'Fake')
self.assertRaises( self.assertRaises(
pylxd.deprecated.exceptions.APIError, lxd_exceptions.APIError,
self.driver.live_migration, mock.sentinel.context, self.driver.live_migration, mock.sentinel.context,
mock.sentinel.instance, mock.sentinel.dest, mock.sentinel.instance, mock.sentinel.dest,
mock.sentinel.recover_method, mock.sentinel.block_migration, mock.sentinel.recover_method, mock.sentinel.block_migration,

View File

@ -109,56 +109,3 @@ class SessionEventTest(test.NoDBTestCase):
self.session.operation_wait(operation_id, instance)) self.session.operation_wait(operation_id, instance))
self.ml.wait_container_operation.assert_called_with(operation_id, self.ml.wait_container_operation.assert_called_with(operation_id,
200, -1) 200, -1)
@ddt.ddt
class SessionProfileTest(test.NoDBTestCase):
def setUp(self):
super(SessionProfileTest, self).setUp()
"""This is so we can mock out pylxd API calls."""
self.ml = stubs.lxd_mock()
lxd_patcher = mock.patch('pylxd.deprecated.api.API',
mock.Mock(return_value=self.ml))
lxd_patcher.start()
self.addCleanup(lxd_patcher.stop)
self.session = session.LXDAPISession()
@stubs.annotated_data(
('empty', [], []),
('valid', ['test'], ['test']),
)
def test_profile_list(self, tag, side_effect, expected):
self.ml.profile_list.return_value = side_effect
self.assertEqual(expected,
self.session.profile_list())
def test_profile_list_fail(self):
self.ml.profile_list.side_effect = (
lxd_exceptions.APIError('Fake', 500))
self.assertRaises(
exception.NovaException,
self.session.profile_list)
def test_profile_create(self):
instance = stubs._fake_instance()
config = mock.Mock()
self.ml.profile_defined.return_value = True
self.ml.profile_create.return_value = \
(200, fake_api.fake_standard_return())
self.assertEqual((200, fake_api.fake_standard_return()),
self.session.profile_create(config,
instance))
calls = [mock.call.profile_list(),
mock.call.profile_create(config)]
self.assertEqual(calls, self.ml.method_calls)
def test_profile_delete(self):
instance = stubs._fake_instance()
self.ml.profile_defined.return_value = True
self.ml.profile_delete.return_value = \
(200, fake_api.fake_standard_return())
self.assertEqual(None,
self.session.profile_delete(instance))

View File

@ -986,7 +986,10 @@ class LXDDriver(driver.ComputeDriver):
fileutils.ensure_tree(instance_dir) fileutils.ensure_tree(instance_dir)
# Step 1 - Setup the profile on the dest host # Step 1 - Setup the profile on the dest host
self._copy_container_profile(instance, network_info) profile_data = self.create_profile(instance, network_info)
self.client.profiles.create(
profile_data['name'], profile_data['config'],
profile_data['devices'])
# Step 2 - Open a websocket on the srct and and # Step 2 - Open a websocket on the srct and and
# generate the container config # generate the container config
@ -1017,7 +1020,10 @@ class LXDDriver(driver.ComputeDriver):
self.firewall_driver.apply_instance_filter( self.firewall_driver.apply_instance_filter(
instance, network_info) instance, network_info)
self._copy_container_profile(instance, network_info) profile_data = self.create_profile(instance, network_info)
self.client.profiles.create(
profile_data['name'], profile_data['config'],
profile_data['devices'])
def live_migration(self, context, instance, dest, def live_migration(self, context, instance, dest,
post_method, recover_method, block_migration=False, post_method, recover_method, block_migration=False,
@ -1037,7 +1043,7 @@ class LXDDriver(driver.ComputeDriver):
self.client.containers.get(instance.name).delete(wait=True) self.client.containers.get(instance.name).delete(wait=True)
def post_live_migration_at_source(self, context, instance, network_info): def post_live_migration_at_source(self, context, instance, network_info):
self.session.profile_delete(instance) self.client.profiles.get(instance.name).delete()
self.cleanup(context, instance, network_info) self.cleanup(context, instance, network_info)
# XXX: rockstar (20 Jul 2016) - nova-lxd does not support # XXX: rockstar (20 Jul 2016) - nova-lxd does not support
@ -1510,7 +1516,7 @@ class LXDDriver(driver.ComputeDriver):
instance=instance) instance=instance)
try: try:
config = {} config = {}
lxd_config = self.session.get_host_config(instance) lxd_config = self.client.host_info['environment']
config.setdefault('root', {'type': 'disk', 'path': '/'}) config.setdefault('root', {'type': 'disk', 'path': '/'})
if str(lxd_config['storage']) in ['btrfs', 'zfs']: if str(lxd_config['storage']) in ['btrfs', 'zfs']:
config['root'].update({'size': '%sGB' % str(instance.root_gb)}) config['root'].update({'size': '%sGB' % str(instance.root_gb)})
@ -1684,7 +1690,7 @@ class LXDDriver(driver.ComputeDriver):
container_url = 'https://%s:8443%s' \ container_url = 'https://%s:8443%s' \
% (CONF.my_ip, container_migrate.get('operation')) % (CONF.my_ip, container_migrate.get('operation'))
lxd_config = self.session.get_host_config(instance) lxd_config = self.client.host_info['environment']
return { return {
'base_image': '', 'base_image': '',
@ -1740,7 +1746,3 @@ class LXDDriver(driver.ComputeDriver):
data, host, instance) data, host, instance)
} }
self.session.container_init(container_config, instance, host) self.session.container_init(container_config, instance, host)
def _copy_container_profile(self, instance, network_info):
container_profile = self.create_profile(instance, network_info)
self.session.profile_create(container_profile, instance)

View File

@ -185,116 +185,6 @@ class LXDAPISession(object):
{'instance': instance.image_ref, 'reason': e}, {'instance': instance.image_ref, 'reason': e},
instance=instance) instance=instance)
#
# Profile methods
#
def profile_list(self):
LOG.debug('profile_list called for instance')
try:
client = self.get_session()
return client.profile_list()
except lxd_exceptions.APIError as ex:
msg = _('Failed to communicate with LXD API: %(reason)s') \
% {'reason': ex}
LOG.error(msg)
raise exception.NovaException(msg)
except Exception as ex:
with excutils.save_and_reraise_exception():
LOG.error(_LE('Error from LXD during profile_list: '
'%(reason)s') % {'reason': ex})
def profile_defined(self, instance_name, instance):
"""Validate if the profile is available on the LXD
host
:param instance: nova instance object
"""
LOG.debug('profile_defined called for instance',
instance=instance)
try:
found = False
if instance_name in self.profile_list():
found = True
return found
except lxd_exceptions.APIError as ex:
if ex.status_code == 404:
return False
else:
msg = _('Failed to communicate with LXD API %(instance)s:'
' %(reason)s') % {'instance': instance.name,
'reason': ex}
raise exception.NovaException(msg)
except Exception as ex:
with excutils.save_and_reraise_exception():
LOG.error(
_LE('Failed to determine profile %(instance)s:'
' %(reason)s'),
{'instance': instance.name, 'reason': ex})
def profile_create(self, config, instance):
"""Create an LXD container profile
:param config: profile dictionary
:param instance: nova instance object
"""
LOG.debug('profile_create called for instance',
instance=instance)
try:
if self.profile_defined(instance.name, instance):
msg = _('Profile already exists %(instance)s') % \
{'instance': instance.name}
raise exception.NovaException(msg)
client = self.get_session()
return client.profile_create(config)
except lxd_exceptions.APIError as ex:
msg = _('Failed to communicate with LXD API %(instance)s:'
' %(reason)s') % {'instance': instance.name,
'reason': ex}
raise exception.NovaException(msg)
except Exception as ex:
with excutils.save_and_reraise_exception():
LOG.error(
_LE('Failed to create profile %(instance)s: %(reason)s'),
{'instance': instance.name, 'reason': ex})
def profile_delete(self, instance):
"""Delete a LXD container profile.
:param instance: nova instance object
"""
LOG.debug('profile_delete called for instance', instance=instance)
try:
if not self.profile_defined(instance.name, instance):
return
client = self.get_session()
return client.profile_delete(instance.name)
except lxd_exceptions.APIError as ex:
msg = _('Failed to communicate with LXD API %(instance)s:'
' %(reason)s') % {'instance': instance.name,
'reason': ex}
raise exception.NovaException(msg)
except Exception as ex:
with excutils.save_and_reraise_exception():
LOG.error(
_LE('Failed to delete profile %(instance)s: %(reason)s'),
{'instance': instance.name, 'reason': ex})
#
# Host Methods
#
def get_host_config(self, instance):
LOG.debug('host_config called for instance', instance=instance)
try:
client = self.get_session()
return client.host_config()['environment']
except lxd_exceptions.APIError as ex:
msg = _('Failed to communicate with LXD %(instance)s:'
' %(reason)s') % {'instance': instance.name,
'ex': ex}
LOG.error(msg)
# #
# Migrate methods # Migrate methods
# #