diff options
-rw-r--r-- | nova/tests/virt/xenapi/test_vm_utils.py | 106 | ||||
-rw-r--r-- | nova/virt/xenapi/vm_utils.py | 61 |
2 files changed, 145 insertions, 22 deletions
diff --git a/nova/tests/virt/xenapi/test_vm_utils.py b/nova/tests/virt/xenapi/test_vm_utils.py index bba704ed9..3e532a1c7 100644 --- a/nova/tests/virt/xenapi/test_vm_utils.py +++ b/nova/tests/virt/xenapi/test_vm_utils.py @@ -172,3 +172,109 @@ class XenAPIGetUUID(test.TestCase): self.assertEquals('2f46f0f5-f14c-ef1b-1fac-9eeca0888a3f', vm_utils.get_this_vm_uuid()) self.mox.VerifyAll() + + +class FakeSession(): + def call_xenapi(self, *args): + pass + + +class FetchVhdImageTestCase(test.TestCase): + def _apply_stubouts(self): + self.mox.StubOutWithMock(vm_utils, '_make_uuid_stack') + self.mox.StubOutWithMock(vm_utils, 'get_sr_path') + self.mox.StubOutWithMock(vm_utils, '_image_uses_bittorrent') + self.mox.StubOutWithMock(vm_utils, '_add_bittorrent_params') + self.mox.StubOutWithMock(vm_utils, '_generate_glance_callback') + self.mox.StubOutWithMock(vm_utils, + '_fetch_using_dom0_plugin_with_retry') + self.mox.StubOutWithMock(vm_utils, 'safe_find_sr') + self.mox.StubOutWithMock(vm_utils, '_scan_sr') + self.mox.StubOutWithMock(vm_utils, '_check_vdi_size') + self.mox.StubOutWithMock(vm_utils, 'destroy_vdi') + + def _common_params_setup(self, uses_bittorrent): + self.context = "context" + self.session = FakeSession() + self.instance = {"uuid": "uuid"} + self.image_id = "image_id" + self.uuid_stack = ["uuid_stack"] + self.sr_path = "sr_path" + self.params = {'image_id': self.image_id, + 'uuid_stack': self.uuid_stack, 'sr_path': self.sr_path} + self.vdis = {'root': {'uuid': 'vdi'}} + + vm_utils._make_uuid_stack().AndReturn(self.uuid_stack) + vm_utils.get_sr_path(self.session).AndReturn(self.sr_path) + vm_utils._image_uses_bittorrent(self.context, + self.instance).AndReturn(uses_bittorrent) + + def test_fetch_vhd_image_works_with_glance(self): + self._apply_stubouts() + self._common_params_setup(False) + + vm_utils._generate_glance_callback(self.context).AndReturn("dummy") + + vm_utils._fetch_using_dom0_plugin_with_retry(self.context, + self.session, self.image_id, "glance", self.params, + callback="dummy").AndReturn(self.vdis) + + vm_utils.safe_find_sr(self.session).AndReturn("sr") + vm_utils._scan_sr(self.session, "sr") + vm_utils._check_vdi_size(self.context, self.session, self.instance, + "vdi") + + self.mox.ReplayAll() + + self.assertEqual("vdi", vm_utils._fetch_vhd_image(self.context, + self.session, self.instance, self.image_id)['root']['uuid']) + + self.mox.VerifyAll() + + def test_fetch_vhd_image_works_with_bittorrent(self): + self._apply_stubouts() + self._common_params_setup(True) + + vm_utils._add_bittorrent_params(self.params) + + vm_utils._fetch_using_dom0_plugin_with_retry(self.context, + self.session, self.image_id, "bittorrent", self.params, + callback=None).AndReturn(self.vdis) + + vm_utils.safe_find_sr(self.session).AndReturn("sr") + vm_utils._scan_sr(self.session, "sr") + vm_utils._check_vdi_size(self.context, self.session, self.instance, + "vdi") + + self.mox.ReplayAll() + + self.assertEqual("vdi", vm_utils._fetch_vhd_image(self.context, + self.session, self.instance, self.image_id)['root']['uuid']) + + self.mox.VerifyAll() + + def test_fetch_vhd_image_cleans_up_vid_on_fail(self): + self._apply_stubouts() + self._common_params_setup(True) + self.mox.StubOutWithMock(self.session, 'call_xenapi') + + vm_utils._add_bittorrent_params(self.params) + + vm_utils._fetch_using_dom0_plugin_with_retry(self.context, + self.session, self.image_id, "bittorrent", self.params, + callback=None).AndReturn(self.vdis) + + vm_utils.safe_find_sr(self.session).AndReturn("sr") + vm_utils._scan_sr(self.session, "sr") + vm_utils._check_vdi_size(self.context, self.session, self.instance, + "vdi").AndRaise(exception.ImageTooLarge) + + self.session.call_xenapi("VDI.get_by_uuid", "vdi").AndReturn("ref") + vm_utils.destroy_vdi(self.session, "ref") + + self.mox.ReplayAll() + + self.assertRaises(exception.ImageTooLarge, vm_utils._fetch_vhd_image, + self.context, self.session, self.instance, self.image_id) + + self.mox.VerifyAll() diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index fb25ccbf4..30cee234a 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -1118,6 +1118,45 @@ def _fetch_vhd_image(context, session, instance, image_id): if _image_uses_bittorrent(context, instance): plugin_name = 'bittorrent' callback = None + _add_bittorrent_params(params) + else: + plugin_name = 'glance' + callback = _generate_glance_callback(context) + + vdis = _fetch_using_dom0_plugin_with_retry( + context, session, image_id, plugin_name, params, + callback=callback) + + sr_ref = safe_find_sr(session) + _scan_sr(session, sr_ref) + + try: + _check_vdi_size(context, session, instance, vdis['root']['uuid']) + except Exception: + with excutils.save_and_reraise_exception(): + for key in vdis: + vdi = vdis[key] + vdi_uuid = vdi['uuid'] + vdi_ref = session.call_xenapi('VDI.get_by_uuid', vdi_uuid) + destroy_vdi(session, vdi_ref) + + return vdis + + +def _generate_glance_callback(context): + glance_api_servers = glance.get_api_servers() + + def pick_glance(params): + g_host, g_port, g_use_ssl = glance_api_servers.next() + params['glance_host'] = g_host + params['glance_port'] = g_port + params['glance_use_ssl'] = g_use_ssl + params['auth_token'] = getattr(context, 'auth_token', None) + + return pick_glance + + +def _add_bittorrent_params(params): params['torrent_base_url'] = CONF.xenapi_torrent_base_url params['torrent_seed_duration'] = CONF.xenapi_torrent_seed_duration params['torrent_seed_chance'] = CONF.xenapi_torrent_seed_chance @@ -1131,28 +1170,6 @@ def _fetch_vhd_image(context, session, instance, image_id): CONF.xenapi_torrent_download_stall_cutoff params['torrent_max_seeder_processes_per_host'] =\ CONF.xenapi_torrent_max_seeder_processes_per_host - else: - plugin_name = 'glance' - glance_api_servers = glance.get_api_servers() - - def pick_glance(params): - g_host, g_port, g_use_ssl = glance_api_servers.next() - params['glance_host'] = g_host - params['glance_port'] = g_port - params['glance_use_ssl'] = g_use_ssl - params['auth_token'] = getattr(context, 'auth_token', None) - - callback = pick_glance - - vdis = _fetch_using_dom0_plugin_with_retry( - context, session, image_id, plugin_name, params, - callback=callback) - - sr_ref = safe_find_sr(session) - _scan_sr(session, sr_ref) - - _check_vdi_size(context, session, instance, vdis['root']['uuid']) - return vdis def _get_vdi_chain_size(session, vdi_uuid): |