From ffac2aa8162ba5111a01b495d9dd7e43bfda4af4 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Mon, 23 May 2011 14:38:37 -0500 Subject: initial fudging in of swap disk --- nova/virt/xenapi/vm_utils.py | 18 ++++++++++++------ nova/virt/xenapi/vmops.py | 21 +++++++++++++-------- 2 files changed, 25 insertions(+), 14 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 9f6cd608c..c24fc7ba6 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -408,18 +408,24 @@ class VMHelper(HelperBase): kwargs = {'params': pickle.dumps(params)} task = session.async_call_plugin('glance', 'download_vhd', kwargs) - vdi_uuid = session.wait_for_task(task, instance_id) + vdi_uuids = session.wait_for_task(task, instance_id) + primary_vdi_uuid = vdi_uuids.get('primary_vdi_uuid') + swap_vdi_uuid = vdi_uuids.get('swap_vdi_uuid') cls.scan_sr(session, instance_id, sr_ref) # Set the name-label to ease debugging - vdi_ref = session.get_xenapi().VDI.get_by_uuid(vdi_uuid) - name_label = get_name_label_for_image(image) - session.get_xenapi().VDI.set_name_label(vdi_ref, name_label) + primary_vdi_ref = session.get_xenapi().VDI.get_by_uuid(primary_vdi_uuid) + primary_name_label = get_name_label_for_image(image) + session.get_xenapi().VDI.set_name_label(primary_vdi_ref, primary_name_label) - LOG.debug(_("xapi 'download_vhd' returned VDI UUID %(vdi_uuid)s") + LOG.debug(_("xapi 'download_vhd' returned VDI UUID %(primary_vdi_uuid)s") % locals()) - return vdi_uuid + + LOG.debug("=" * 100) + LOG.debug(rimary_vdi_uuid) + LOG.debug(swap_vdi_uuid) + return (primary_vdi_uuid, swap_vdi_uuid) @classmethod def _fetch_image_glance_disk(cls, session, instance_id, image, access, diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 0074444f8..4a01cac29 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -109,20 +109,20 @@ class VMOps(object): user = AuthManager().get_user(instance.user_id) project = AuthManager().get_project(instance.project_id) disk_image_type = VMHelper.determine_disk_image_type(instance) - vdi_uuid = VMHelper.fetch_image(self._session, instance.id, - instance.image_id, user, project, disk_image_type) - return vdi_uuid + (primary_vdi_uuid, swap_vdi_uuid) = VMHelper.fetch_image(self._session, + instance.id, instance.image_id, user, project, disk_image_type) + return (primary_vdi_uuid, swap_vdi_uuid) def spawn(self, instance, network_info=None): - vdi_uuid = self._create_disk(instance) - vm_ref = self._create_vm(instance, vdi_uuid, network_info) + vdi_uuid, swap_uuid = self._create_disk(instance) + vm_ref = self._create_vm(instance, vdi_uuid, swap_uuid, network_info) self._spawn(instance, vm_ref) def spawn_rescue(self, instance): """Spawn a rescue instance.""" self.spawn(instance) - def _create_vm(self, instance, vdi_uuid, network_info=None): + def _create_vm(self, instance, vdi_uuid, swap_vdi_uuid=None, network_info=None): """Create VM instance.""" instance_name = instance.name vm_ref = VMHelper.lookup(self._session, instance_name) @@ -143,18 +143,20 @@ class VMOps(object): # Are we building from a pre-existing disk? vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid) + if swap_vdi_uuid: + swap_vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', swap_vdi_uuid) disk_image_type = VMHelper.determine_disk_image_type(instance) kernel = None if instance.kernel_id: kernel = VMHelper.fetch_image(self._session, instance.id, - instance.kernel_id, user, project, ImageType.KERNEL_RAMDISK) + instance.kernel_id, user, project, ImageType.KERNEL_RAMDISK)[0] ramdisk = None if instance.ramdisk_id: ramdisk = VMHelper.fetch_image(self._session, instance.id, - instance.ramdisk_id, user, project, ImageType.KERNEL_RAMDISK) + instance.ramdisk_id, user, project, ImageType.KERNEL_RAMDISK)[0] use_pv_kernel = VMHelper.determine_is_pv(self._session, instance.id, vdi_ref, disk_image_type, instance.os_type) @@ -163,6 +165,9 @@ class VMOps(object): VMHelper.create_vbd(session=self._session, vm_ref=vm_ref, vdi_ref=vdi_ref, userdevice=0, bootable=True) + if swap_vdi_uuid: + VMHelper.create_vbd(session=self._session, vm_ref=vm_ref, + vdi_ref=swap_vdi_ref, userdevice=0, bootable=False) # TODO(tr3buchet) - check to make sure we have network info, otherwise # create it now. This goes away once nova-multi-nic hits. -- cgit From 94766fac0f5fdb3c7847b1129a8f05948a97f887 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Mon, 23 May 2011 20:42:54 +0000 Subject: cleanup and fixes --- nova/virt/xenapi/vm_utils.py | 18 ++++++++++-------- nova/virt/xenapi/vmops.py | 40 ++++++++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 24 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index c24fc7ba6..f1f7b8249 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -410,7 +410,7 @@ class VMHelper(HelperBase): task = session.async_call_plugin('glance', 'download_vhd', kwargs) vdi_uuids = session.wait_for_task(task, instance_id) primary_vdi_uuid = vdi_uuids.get('primary_vdi_uuid') - swap_vdi_uuid = vdi_uuids.get('swap_vdi_uuid') + swap_vdi_uuid = vdi_uuids.get('swap_vdi_uuid', None) cls.scan_sr(session, instance_id, sr_ref) @@ -419,13 +419,14 @@ class VMHelper(HelperBase): primary_name_label = get_name_label_for_image(image) session.get_xenapi().VDI.set_name_label(primary_vdi_ref, primary_name_label) - LOG.debug(_("xapi 'download_vhd' returned VDI UUID %(primary_vdi_uuid)s") - % locals()) + LOG.debug(_("xapi 'download_vhd' returned VDI UUID " + "%(primary_vdi_uuid)s") % locals()) + if swap_vdi_uuid: + LOG.debug(_("xapi 'download_vhd' returned SWAP VDI UUID " + "%(swap_vdi_uuid)s") % locals()) - LOG.debug("=" * 100) - LOG.debug(rimary_vdi_uuid) - LOG.debug(swap_vdi_uuid) - return (primary_vdi_uuid, swap_vdi_uuid) + LOG.debug("=" * 100) + return vdi_uuids @classmethod def _fetch_image_glance_disk(cls, session, instance_id, image, access, @@ -482,7 +483,8 @@ class VMHelper(HelperBase): LOG.debug(_("Kernel/Ramdisk VDI %s destroyed"), vdi_ref) return filename else: - return session.get_xenapi().VDI.get_uuid(vdi_ref) + vdi_uuid = session.get_xenapi().VDI.get_uuid(vdi_ref) + return {'primary_vdi_uuid': vdi_uuid} @classmethod def determine_disk_image_type(cls, instance): diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 4a01cac29..0c30ad4cb 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -109,20 +109,21 @@ class VMOps(object): user = AuthManager().get_user(instance.user_id) project = AuthManager().get_project(instance.project_id) disk_image_type = VMHelper.determine_disk_image_type(instance) - (primary_vdi_uuid, swap_vdi_uuid) = VMHelper.fetch_image(self._session, - instance.id, instance.image_id, user, project, disk_image_type) - return (primary_vdi_uuid, swap_vdi_uuid) + vdi_uuids = VMHelper.fetch_image(self._session, + instance.id, instance.image_id, user, project, + disk_image_type) + return vdi_uuids def spawn(self, instance, network_info=None): - vdi_uuid, swap_uuid = self._create_disk(instance) - vm_ref = self._create_vm(instance, vdi_uuid, swap_uuid, network_info) + vdi_uuids = self._create_disk(instance) + vm_ref = self._create_vm(instance, vdi_uuids, network_info) self._spawn(instance, vm_ref) def spawn_rescue(self, instance): """Spawn a rescue instance.""" self.spawn(instance) - def _create_vm(self, instance, vdi_uuid, swap_vdi_uuid=None, network_info=None): + def _create_vm(self, instance, vdi_uuids, network_info=None): """Create VM instance.""" instance_name = instance.name vm_ref = VMHelper.lookup(self._session, instance_name) @@ -142,30 +143,37 @@ class VMOps(object): project = AuthManager().get_project(instance.project_id) # Are we building from a pre-existing disk? - vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid) + primary_vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', + vdi_uuids['primary_vdi_uuid']) + swap_vdi_uuid = vdi_uuids.get('swap_vdi_uuid', None) if swap_vdi_uuid: swap_vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', swap_vdi_uuid) + else: + swap_vdi_ref = None disk_image_type = VMHelper.determine_disk_image_type(instance) kernel = None if instance.kernel_id: kernel = VMHelper.fetch_image(self._session, instance.id, - instance.kernel_id, user, project, ImageType.KERNEL_RAMDISK)[0] + instance.kernel_id, user, project, + ImageType.KERNEL_RAMDISK) ramdisk = None if instance.ramdisk_id: ramdisk = VMHelper.fetch_image(self._session, instance.id, - instance.ramdisk_id, user, project, ImageType.KERNEL_RAMDISK)[0] + instance.ramdisk_id, user, project, + ImageType.KERNEL_RAMDISK) - use_pv_kernel = VMHelper.determine_is_pv(self._session, instance.id, - vdi_ref, disk_image_type, instance.os_type) - vm_ref = VMHelper.create_vm(self._session, instance, kernel, ramdisk, - use_pv_kernel) + use_pv_kernel = VMHelper.determine_is_pv(self._session, + instance.id, primary_vdi_ref, disk_image_type, + instance.os_type) + vm_ref = VMHelper.create_vm(self._session, instance, kernel, + ramdisk, use_pv_kernel) VMHelper.create_vbd(session=self._session, vm_ref=vm_ref, - vdi_ref=vdi_ref, userdevice=0, bootable=True) - if swap_vdi_uuid: + vdi_ref=primary_vdi_ref, userdevice=0, bootable=True) + if swap_vdi_ref: VMHelper.create_vbd(session=self._session, vm_ref=vm_ref, vdi_ref=swap_vdi_ref, userdevice=0, bootable=False) @@ -177,7 +185,7 @@ class VMOps(object): # Alter the image before VM start for, e.g. network injection if FLAGS.xenapi_inject_image: VMHelper.preconfigure_instance(self._session, instance, - vdi_ref, network_info) + primary_vdi_ref, network_info) self.create_vifs(vm_ref, network_info) self.inject_network_info(instance, network_info, vm_ref) -- cgit From 42c209d90f491d19b3aabc70f8dafc33b76cf20d Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Mon, 23 May 2011 16:51:28 -0500 Subject: fix tests, have glance plugin return json encoded string of vdi uuids --- nova/virt/xenapi/vm_utils.py | 6 +++++- nova/virt/xenapi/vmops.py | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index f1f7b8249..3d980013a 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -19,6 +19,7 @@ Helper methods for operations related to the management of VM records and their attributes like VDIs, VIFs, as well as their lookup functions. """ +import json import os import pickle import re @@ -408,7 +409,8 @@ class VMHelper(HelperBase): kwargs = {'params': pickle.dumps(params)} task = session.async_call_plugin('glance', 'download_vhd', kwargs) - vdi_uuids = session.wait_for_task(task, instance_id) + result = session.wait_for_task(task, instance_id) + vdi_uuids = json.loads(result) primary_vdi_uuid = vdi_uuids.get('primary_vdi_uuid') swap_vdi_uuid = vdi_uuids.get('swap_vdi_uuid', None) @@ -571,6 +573,8 @@ class VMHelper(HelperBase): args['raw'] = 'true' task = session.async_call_plugin('objectstore', fn, args) uuid = session.wait_for_task(task, instance_id) + if image_type != ImageType.KERNEL_RAMDISK: + return {'primary_vdi_uuid': uuid} return uuid @classmethod diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 0c30ad4cb..0d7ef5fac 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -91,7 +91,7 @@ class VMOps(object): def finish_resize(self, instance, disk_info): vdi_uuid = self.link_disks(instance, disk_info['base_copy'], disk_info['cow']) - vm_ref = self._create_vm(instance, vdi_uuid) + vm_ref = self._create_vm(instance, {'primary_vdi_uuid': vdi_uuid}) self.resize_instance(instance, vdi_uuid) self._spawn(instance, vm_ref) @@ -144,7 +144,7 @@ class VMOps(object): # Are we building from a pre-existing disk? primary_vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', - vdi_uuids['primary_vdi_uuid']) + vdi_uuids.get('primary_vdi_uuid')) swap_vdi_uuid = vdi_uuids.get('swap_vdi_uuid', None) if swap_vdi_uuid: swap_vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', swap_vdi_uuid) -- cgit From 038ce7e16ee7ee1afc86ded260c1aa0d40d1e1ad Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Mon, 23 May 2011 22:52:56 +0000 Subject: swap should use device 1 and rescue use device 2 --- nova/virt/xenapi/vmops.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 0d7ef5fac..6ff8fd6a4 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -175,7 +175,7 @@ class VMOps(object): vdi_ref=primary_vdi_ref, userdevice=0, bootable=True) if swap_vdi_ref: VMHelper.create_vbd(session=self._session, vm_ref=vm_ref, - vdi_ref=swap_vdi_ref, userdevice=0, bootable=False) + vdi_ref=swap_vdi_ref, userdevice=1, bootable=False) # TODO(tr3buchet) - check to make sure we have network info, otherwise # create it now. This goes away once nova-multi-nic hits. @@ -711,7 +711,7 @@ class VMOps(object): vbd_ref = self._session.get_xenapi().VM.get_VBDs(vm_ref)[0] vdi_ref = self._session.get_xenapi().VBD.get_record(vbd_ref)["VDI"] rescue_vbd_ref = VMHelper.create_vbd(self._session, rescue_vm_ref, - vdi_ref, 1, False) + vdi_ref, 2, False) self._session.call_xenapi("Async.VBD.plug", rescue_vbd_ref) -- cgit From 26842cba90bd5637bd6aa185b300102ff257d9f1 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Tue, 24 May 2011 22:39:16 +0000 Subject: move devices back --- nova/virt/xenapi/vmops.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 6ff8fd6a4..6fff1d494 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -175,7 +175,7 @@ class VMOps(object): vdi_ref=primary_vdi_ref, userdevice=0, bootable=True) if swap_vdi_ref: VMHelper.create_vbd(session=self._session, vm_ref=vm_ref, - vdi_ref=swap_vdi_ref, userdevice=1, bootable=False) + vdi_ref=swap_vdi_ref, userdevice=2, bootable=False) # TODO(tr3buchet) - check to make sure we have network info, otherwise # create it now. This goes away once nova-multi-nic hits. @@ -711,7 +711,7 @@ class VMOps(object): vbd_ref = self._session.get_xenapi().VM.get_VBDs(vm_ref)[0] vdi_ref = self._session.get_xenapi().VBD.get_record(vbd_ref)["VDI"] rescue_vbd_ref = VMHelper.create_vbd(self._session, rescue_vm_ref, - vdi_ref, 2, False) + vdi_ref, 1, False) self._session.call_xenapi("Async.VBD.plug", rescue_vbd_ref) -- cgit From 899642030dd60541153ccee810d082816f92dd49 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Thu, 26 May 2011 19:27:27 +0000 Subject: Change the return from glance to be a list of dictionaries describing VDIs Fix the rest of the code to account for this Add a test for swap --- nova/virt/xenapi/fake.py | 5 ++++- nova/virt/xenapi/vm_utils.py | 49 ++++++++++++++++++++++++++--------------- nova/virt/xenapi/vmops.py | 52 ++++++++++++++++++++++++-------------------- 3 files changed, 64 insertions(+), 42 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py index e36ef3288..76988b172 100644 --- a/nova/virt/xenapi/fake.py +++ b/nova/virt/xenapi/fake.py @@ -159,7 +159,10 @@ def after_VBD_create(vbd_ref, vbd_rec): vbd_rec['device'] = '' vm_ref = vbd_rec['VM'] vm_rec = _db_content['VM'][vm_ref] - vm_rec['VBDs'] = [vbd_ref] + if vm_rec.get('VBDs', None): + vm_rec['VBDs'].append(vbd_ref) + else: + vm_rec['VBDs'] = [vbd_ref] vm_name_label = _db_content['VM'][vm_ref]['name_label'] vbd_rec['vm_name_label'] = vm_name_label diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 3d980013a..bee9742a4 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -377,6 +377,9 @@ class VMHelper(HelperBase): xenapi_image_service = ['glance', 'objectstore'] glance_address = 'address for glance services' glance_port = 'port for glance services' + + Returns: A single filename if image_type is KERNEL_RAMDISK + A list of dictionaries that describe VDIs, otherwise """ access = AuthManager().get_access_key(user, project) @@ -391,6 +394,10 @@ class VMHelper(HelperBase): @classmethod def _fetch_image_glance_vhd(cls, session, instance_id, image, access, image_type): + """Tell glance to download an image and put the VHDs into the SR + + Returns: A list of dictionaries that describe VDIs + """ LOG.debug(_("Asking xapi to fetch vhd image %(image)s") % locals()) @@ -410,25 +417,21 @@ class VMHelper(HelperBase): kwargs = {'params': pickle.dumps(params)} task = session.async_call_plugin('glance', 'download_vhd', kwargs) result = session.wait_for_task(task, instance_id) - vdi_uuids = json.loads(result) - primary_vdi_uuid = vdi_uuids.get('primary_vdi_uuid') - swap_vdi_uuid = vdi_uuids.get('swap_vdi_uuid', None) + vdis = json.loads(result) + for vdi in vdis: + LOG.debug(_("xapi 'download_vhd' returned VDI of " + "type '%(vdi_type)s' with UUID '%(vdi_uuid)s'" % vdi)) cls.scan_sr(session, instance_id, sr_ref) + # Pull out the UUID of the first VDI + vdi_uuid = vdis[0]['vdi_uuid'] # Set the name-label to ease debugging - primary_vdi_ref = session.get_xenapi().VDI.get_by_uuid(primary_vdi_uuid) + vdi_ref = session.get_xenapi().VDI.get_by_uuid(vdi_uuid) primary_name_label = get_name_label_for_image(image) - session.get_xenapi().VDI.set_name_label(primary_vdi_ref, primary_name_label) - - LOG.debug(_("xapi 'download_vhd' returned VDI UUID " - "%(primary_vdi_uuid)s") % locals()) - if swap_vdi_uuid: - LOG.debug(_("xapi 'download_vhd' returned SWAP VDI UUID " - "%(swap_vdi_uuid)s") % locals()) + session.get_xenapi().VDI.set_name_label(vdi_ref, primary_name_label) - LOG.debug("=" * 100) - return vdi_uuids + return vdis @classmethod def _fetch_image_glance_disk(cls, session, instance_id, image, access, @@ -440,6 +443,8 @@ class VMHelper(HelperBase): plugin; instead, it streams the disks through domU to the VDI directly. + Returns: A single filename if image_type is KERNEL_RAMDISK + A list of dictionaries that describe VDIs, otherwise """ # FIXME(sirp): Since the Glance plugin seems to be required for the # VHD disk, it may be worth using the plugin for both VHD and RAW and @@ -486,7 +491,7 @@ class VMHelper(HelperBase): return filename else: vdi_uuid = session.get_xenapi().VDI.get_uuid(vdi_ref) - return {'primary_vdi_uuid': vdi_uuid} + return [dict(vdi_type='os', vdi_uuid=vdi_uuid)] @classmethod def determine_disk_image_type(cls, instance): @@ -545,6 +550,11 @@ class VMHelper(HelperBase): @classmethod def _fetch_image_glance(cls, session, instance_id, image, access, image_type): + """Fetch image from glance based on image type. + + Returns: A single filename if image_type is KERNEL_RAMDISK + A list of dictionaries that describe VDIs, otherwise + """ if image_type == ImageType.DISK_VHD: return cls._fetch_image_glance_vhd( session, instance_id, image, access, image_type) @@ -555,6 +565,11 @@ class VMHelper(HelperBase): @classmethod def _fetch_image_objectstore(cls, session, instance_id, image, access, secret, image_type): + """Fetch an image from objectstore. + + Returns: A single filename if image_type is KERNEL_RAMDISK + A list of dictionaries that describe VDIs, otherwise + """ url = images.image_url(image) LOG.debug(_("Asking xapi to fetch %(url)s as %(access)s") % locals()) if image_type == ImageType.KERNEL_RAMDISK: @@ -572,10 +587,10 @@ class VMHelper(HelperBase): if image_type == ImageType.DISK_RAW: args['raw'] = 'true' task = session.async_call_plugin('objectstore', fn, args) - uuid = session.wait_for_task(task, instance_id) + uuid_or_fn = session.wait_for_task(task, instance_id) if image_type != ImageType.KERNEL_RAMDISK: - return {'primary_vdi_uuid': uuid} - return uuid + return [dict(vdi_type='os', vdi_uuid=uuid_or_fn)] + return uuid_or_fn @classmethod def determine_is_pv(cls, session, instance_id, vdi_ref, disk_image_type, diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 2a8d97a9d..02e140dcc 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -91,7 +91,8 @@ class VMOps(object): def finish_resize(self, instance, disk_info): vdi_uuid = self.link_disks(instance, disk_info['base_copy'], disk_info['cow']) - vm_ref = self._create_vm(instance, {'primary_vdi_uuid': vdi_uuid}) + vm_ref = self._create_vm(instance, + [dict(vdi_type='os', vdi_uuid=vdi_uuid)]) self.resize_instance(instance, vdi_uuid) self._spawn(instance, vm_ref) @@ -105,25 +106,25 @@ class VMOps(object): LOG.debug(_("Starting instance %s"), instance.name) self._session.call_xenapi('VM.start', vm_ref, False, False) - def _create_disk(self, instance): + def _create_disks(self, instance): user = AuthManager().get_user(instance.user_id) project = AuthManager().get_project(instance.project_id) disk_image_type = VMHelper.determine_disk_image_type(instance) - vdi_uuids = VMHelper.fetch_image(self._session, + vdis = VMHelper.fetch_image(self._session, instance.id, instance.image_id, user, project, disk_image_type) - return vdi_uuids + return vdis def spawn(self, instance, network_info=None): - vdi_uuids = self._create_disk(instance) - vm_ref = self._create_vm(instance, vdi_uuids, network_info) + vdis = self._create_disks(instance) + vm_ref = self._create_vm(instance, vdis, network_info) self._spawn(instance, vm_ref) def spawn_rescue(self, instance): """Spawn a rescue instance.""" self.spawn(instance) - def _create_vm(self, instance, vdi_uuids, network_info=None): + def _create_vm(self, instance, vdis, network_info=None): """Create VM instance.""" instance_name = instance.name vm_ref = VMHelper.lookup(self._session, instance_name) @@ -142,15 +143,6 @@ class VMOps(object): user = AuthManager().get_user(instance.user_id) project = AuthManager().get_project(instance.project_id) - # Are we building from a pre-existing disk? - primary_vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', - vdi_uuids.get('primary_vdi_uuid')) - swap_vdi_uuid = vdi_uuids.get('swap_vdi_uuid', None) - if swap_vdi_uuid: - swap_vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', swap_vdi_uuid) - else: - swap_vdi_ref = None - disk_image_type = VMHelper.determine_disk_image_type(instance) kernel = None @@ -165,17 +157,29 @@ class VMOps(object): instance.ramdisk_id, user, project, ImageType.KERNEL_RAMDISK) + # Create the VM ref and attach the first disk + first_vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', + vdis[0]['vdi_uuid']) use_pv_kernel = VMHelper.determine_is_pv(self._session, - instance.id, primary_vdi_ref, disk_image_type, + instance.id, first_vdi_ref, disk_image_type, instance.os_type) - vm_ref = VMHelper.create_vm(self._session, instance, kernel, - ramdisk, use_pv_kernel) - + vm_ref = VMHelper.create_vm(self._session, instance, + kernel, ramdisk, use_pv_kernel) VMHelper.create_vbd(session=self._session, vm_ref=vm_ref, - vdi_ref=primary_vdi_ref, userdevice=0, bootable=True) - if swap_vdi_ref: + vdi_ref=first_vdi_ref, userdevice=0, bootable=True) + + # Attach any other disks + # userdevice 1 is reserved for rescue + userdevice = 2 + for vdi in vdis[1:]: + # vdi['vdi_type'] is either 'os' or 'swap', but we don't + # really care what it is right here. + vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', + vdi['vdi_uuid']) VMHelper.create_vbd(session=self._session, vm_ref=vm_ref, - vdi_ref=swap_vdi_ref, userdevice=2, bootable=False) + vdi_ref=vdi_ref, userdevice=userdevice, + bootable=False) + userdevice += 1 # TODO(tr3buchet) - check to make sure we have network info, otherwise # create it now. This goes away once nova-multi-nic hits. @@ -185,7 +189,7 @@ class VMOps(object): # Alter the image before VM start for, e.g. network injection if FLAGS.xenapi_inject_image: VMHelper.preconfigure_instance(self._session, instance, - primary_vdi_ref, network_info) + first_vdi_ref, network_info) self.create_vifs(vm_ref, network_info) self.inject_network_info(instance, network_info, vm_ref) -- cgit From fc27a0ac4f907282a669e2c9f3e128890907f236 Mon Sep 17 00:00:00 2001 From: Chris Behrens Date: Thu, 26 May 2011 20:21:40 +0000 Subject: add a comment when calling glance:download_vhd so it's clear what is returned --- nova/virt/xenapi/vm_utils.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index bee9742a4..06ee8ee9b 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -417,6 +417,10 @@ class VMHelper(HelperBase): kwargs = {'params': pickle.dumps(params)} task = session.async_call_plugin('glance', 'download_vhd', kwargs) result = session.wait_for_task(task, instance_id) + # 'download_vhd' will return a json encoded string containing + # a list of dictionaries describing VDIs. The dictionary will + # contain 'vdi_type' and 'vdi_uuid' keys. 'vdi_type' can be + # 'os' or 'swap' right now. vdis = json.loads(result) for vdi in vdis: LOG.debug(_("xapi 'download_vhd' returned VDI of " -- cgit