summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/tests/virt/xenapi/test_vm_utils.py106
-rw-r--r--nova/virt/xenapi/vm_utils.py61
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):