From 945d566c10877aeaf4d75bc26e161ba3a5f9c4b9 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Fri, 27 May 2011 11:10:03 +0900 Subject: compute, virt: support boot-from-volume without ephemeral device and no device This patch implements basic ebs boot support. ephemeral device/no device isn't supported yet. --- nova/virt/driver.py | 2 +- nova/virt/fake.py | 2 +- nova/virt/hyperv.py | 2 +- nova/virt/libvirt.xml.template | 9 ++++++ nova/virt/libvirt_conn.py | 69 +++++++++++++++++++++++++++++++----------- nova/virt/vmwareapi_conn.py | 2 +- nova/virt/xenapi_conn.py | 2 +- 7 files changed, 65 insertions(+), 23 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/driver.py b/nova/virt/driver.py index eb9626d08..773d60855 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -61,7 +61,7 @@ class ComputeDriver(object): """Return a list of InstanceInfo for all registered VMs""" raise NotImplementedError() - def spawn(self, instance, network_info=None): + def spawn(self, instance, network_info=None, block_device_mapping=[]): """Launch a VM for the specified instance""" raise NotImplementedError() diff --git a/nova/virt/fake.py b/nova/virt/fake.py index 5ac376e46..093c0f5d2 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -114,7 +114,7 @@ class FakeConnection(driver.ComputeDriver): info_list.append(self._map_to_instance_info(instance)) return info_list - def spawn(self, instance): + def spawn(self, instance, network_info=None, block_device_mapping=[]): """ Create a new instance/VM/domain on the virtualization platform. diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py index 1142e97a4..216e90016 100644 --- a/nova/virt/hyperv.py +++ b/nova/virt/hyperv.py @@ -139,7 +139,7 @@ class HyperVConnection(driver.ComputeDriver): return instance_infos - def spawn(self, instance): + def spawn(self, instance, network_info=None, block_device_mapping=[]): """ Create a new VM and start it.""" vm = self._lookup(instance.name) if vm is not None: diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index de2497a76..f7d699a15 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -67,11 +67,13 @@ #else + #if not ($getVar('ebs_root', False)) + #end if #if $getVar('local', False) @@ -79,6 +81,13 @@ #end if + #for $vol in $volumes + + + + + + #end for #end if #end if diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index fa918b0a3..3290be603 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -39,6 +39,7 @@ Supports KVM, LXC, QEMU, UML, and XEN. import multiprocessing import os import random +import re import shutil import subprocess import sys @@ -207,6 +208,8 @@ def _get_network_info(instance): network_info.append((network, mapping)) return network_info +def _strip_dev(mount_path): + return re.sub(r'^/dev/', '', mount_path) class LibvirtConnection(driver.ComputeDriver): @@ -619,11 +622,13 @@ class LibvirtConnection(driver.ComputeDriver): # NOTE(ilyaalekseyev): Implementation like in multinics # for xenapi(tr3buchet) @exception.wrap_exception - def spawn(self, instance, network_info=None): - xml = self.to_xml(instance, False, network_info) + def spawn(self, instance, network_info=None, block_device_mapping=[]): + xml = self.to_xml(instance, False, network_info=network_info, + block_device_mapping=block_device_mapping) self.firewall_driver.setup_basic_filtering(instance, network_info) self.firewall_driver.prepare_instance_filter(instance, network_info) - self._create_image(instance, xml, network_info=network_info) + self._create_image(instance, xml, network_info=network_info, + block_device_mapping=block_device_mapping) domain = self._create_new_domain(xml) LOG.debug(_("instance %s: is running"), instance['name']) self.firewall_driver.apply_instance_filter(instance) @@ -805,7 +810,7 @@ class LibvirtConnection(driver.ComputeDriver): # TODO(vish): should we format disk by default? def _create_image(self, inst, libvirt_xml, suffix='', disk_images=None, - network_info=None): + network_info=None, block_device_mapping=[]): if not network_info: network_info = _get_network_info(inst) @@ -868,16 +873,19 @@ class LibvirtConnection(driver.ComputeDriver): size = None root_fname += "_sm" - self._cache_image(fn=self._fetch_image, - target=basepath('disk'), - fname=root_fname, - cow=FLAGS.use_cow_images, - image_id=disk_images['image_id'], - user=user, - project=project, - size=size) + if not self._volume_in_mapping(self.root_mount_device, + block_device_mapping): + self._cache_image(fn=self._fetch_image, + target=basepath('disk'), + fname=root_fname, + cow=FLAGS.use_cow_images, + image_id=disk_images['image_id'], + user=user, + project=project, + size=size) - if inst_type['local_gb']: + if inst_type['local_gb'] and not self._volume_in_mapping( + self.local_mount_device, block_device_mapping): self._cache_image(fn=self._create_local, target=basepath('disk.local'), fname="local_%s" % inst_type['local_gb'], @@ -992,7 +1000,18 @@ class LibvirtConnection(driver.ComputeDriver): return result - def _prepare_xml_info(self, instance, rescue=False, network_info=None): + root_mount_device = 'vda' # FIXME for now. it's hard coded. + local_mount_device = 'vdb' # FIXME for now. it's hard coded. + def _volume_in_mapping(self, mount_device, block_device_mapping): + mount_device_ = _strip_dev(mount_device) + for vol in block_device_mapping: + vol_mount_device = _strip_dev(vol['mount_device']) + if vol_mount_device == mount_device_: + return True + return False + + def _prepare_xml_info(self, instance, rescue=False, network_info=None, + block_device_mapping=[]): # TODO(adiantum) remove network_info creation code # when multinics will be completed if not network_info: @@ -1010,6 +1029,16 @@ class LibvirtConnection(driver.ComputeDriver): else: driver_type = 'raw' + for vol in block_device_mapping: + vol['mount_device'] = _strip_dev(vol['mount_device']) + ebs_root = self._volume_in_mapping(self.root_mount_device, + block_device_mapping) + if self._volume_in_mapping(self.local_mount_device, + block_device_mapping): + local_gb = False + else: + local_gb = inst_type['local_gb'] + xml_info = {'type': FLAGS.libvirt_type, 'name': instance['name'], 'basepath': os.path.join(FLAGS.instances_path, @@ -1017,9 +1046,11 @@ class LibvirtConnection(driver.ComputeDriver): 'memory_kb': inst_type['memory_mb'] * 1024, 'vcpus': inst_type['vcpus'], 'rescue': rescue, - 'local': inst_type['local_gb'], + 'local': local_gb, 'driver_type': driver_type, - 'nics': nics} + 'nics': nics, + 'ebs_root': ebs_root, + 'volumes': block_device_mapping} if FLAGS.vnc_enabled: if FLAGS.libvirt_type != 'lxc': @@ -1034,10 +1065,12 @@ class LibvirtConnection(driver.ComputeDriver): xml_info['disk'] = xml_info['basepath'] + "/disk" return xml_info - def to_xml(self, instance, rescue=False, network_info=None): + def to_xml(self, instance, rescue=False, network_info=None, + block_device_mapping=[]): # TODO(termie): cache? LOG.debug(_('instance %s: starting toXML method'), instance['name']) - xml_info = self._prepare_xml_info(instance, rescue, network_info) + xml_info = self._prepare_xml_info(instance, rescue, network_info, + block_device_mapping) xml = str(Template(self.libvirt_xml, searchList=[xml_info])) LOG.debug(_('instance %s: finished toXML method'), instance['name']) return xml diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index 1c6d2572d..a36b45d80 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -124,7 +124,7 @@ class VMWareESXConnection(driver.ComputeDriver): """List VM instances.""" return self._vmops.list_instances() - def spawn(self, instance): + def spawn(self, instance, network_info=None, block_device_mapping=[]): """Create VM instance.""" self._vmops.spawn(instance) diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 6d828e109..8c5e2201e 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -194,7 +194,7 @@ class XenAPIConnection(driver.ComputeDriver): def list_instances_detail(self): return self._vmops.list_instances_detail() - def spawn(self, instance): + def spawn(self, instance, network_info=None, block_device_mapping=[]): """Create VM instance""" self._vmops.spawn(instance) -- cgit From 25104b5e8570003f82ee1b4d2e5678715cdcc551 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Fri, 27 May 2011 11:11:30 +0900 Subject: unittest: make unit tests happy various fixes to make unit tests pass. --- nova/virt/fake.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'nova/virt') diff --git a/nova/virt/fake.py b/nova/virt/fake.py index 093c0f5d2..498c5ecbb 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -222,6 +222,10 @@ class FakeConnection(driver.ComputeDriver): """ pass + def poll_rescued_instances(self, timeout): + """Poll for rescued instances""" + pass + def migrate_disk_and_power_off(self, instance, dest): """ Transfers the disk of a running instance in multiple phases, turning -- cgit From 249279cd7c70a7306ed28a62939477ef94ecbc91 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Thu, 9 Jun 2011 15:31:10 -0400 Subject: further changes --- nova/virt/vmwareapi/vmware_images.py | 6 ------ 1 file changed, 6 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/vmwareapi/vmware_images.py b/nova/virt/vmwareapi/vmware_images.py index 48edc5384..70adba74f 100644 --- a/nova/virt/vmwareapi/vmware_images.py +++ b/nova/virt/vmwareapi/vmware_images.py @@ -90,8 +90,6 @@ def fetch_image(image, instance, **kwargs): func = _get_glance_image elif FLAGS.image_service == "nova.image.s3.S3ImageService": func = _get_s3_image - elif FLAGS.image_service == "nova.image.local.LocalImageService": - func = _get_local_image else: raise NotImplementedError(_("The Image Service %s is not implemented") % FLAGS.image_service) @@ -105,8 +103,6 @@ def upload_image(image, instance, **kwargs): func = _put_glance_image elif FLAGS.image_service == "nova.image.s3.S3ImageService": func = _put_s3_image - elif FLAGS.image_service == "nova.image.local.LocalImageService": - func = _put_local_image else: raise NotImplementedError(_("The Image Service %s is not implemented") % FLAGS.image_service) @@ -192,8 +188,6 @@ def get_vmdk_size_and_properties(image, instance): size, properties = meta_data["size"], meta_data["properties"] elif FLAGS.image_service == "nova.image.s3.S3ImageService": raise NotImplementedError - elif FLAGS.image_service == "nova.image.local.LocalImageService": - raise NotImplementedError LOG.debug(_("Got image size of %(size)s for the image %(image)s") % locals()) return size, properties -- cgit From 2ee3d49e6c35515b9ef9d78365c3bc0ec9236b4b Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Mon, 13 Jun 2011 11:06:25 -0400 Subject: Update xenapi/vm_utils.py so that it calls find_sr instead of get_sr. Remove the old get_sr function which by default looked for an SR named 'slices'. --- nova/virt/xenapi/vm_utils.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index b9d4346e4..cb4da7fdb 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -329,12 +329,6 @@ class VMHelper(HelperBase): 'snap': template_vdi_uuid} return template_vm_ref, template_vdi_uuids - @classmethod - def get_sr(cls, session, sr_label='slices'): - """Finds the SR named by the given name label and returns - the UUID""" - return session.call_xenapi('SR.get_by_name_label', sr_label)[0] - @classmethod def get_sr_path(cls, session): """Return the path to our storage repository @@ -790,8 +784,7 @@ class VMHelper(HelperBase): @classmethod def scan_default_sr(cls, session): """Looks for the system default SR and triggers a re-scan""" - #FIXME(sirp/mdietz): refactor scan_default_sr in there - sr_ref = cls.get_sr(session) + sr_ref = find_sr(session) session.call_xenapi('SR.scan', sr_ref) -- cgit From c7e8f9ff46758ddbeecd049083bece013301bb59 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 15 Jun 2011 14:47:18 +0900 Subject: block_device_mapping: don't use [] as default argument --- nova/virt/driver.py | 2 +- nova/virt/fake.py | 2 +- nova/virt/hyperv.py | 2 +- nova/virt/libvirt/connection.py | 12 ++++++++---- nova/virt/vmwareapi_conn.py | 2 +- nova/virt/xenapi_conn.py | 2 +- 6 files changed, 13 insertions(+), 9 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/driver.py b/nova/virt/driver.py index 773d60855..6341e81d2 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -61,7 +61,7 @@ class ComputeDriver(object): """Return a list of InstanceInfo for all registered VMs""" raise NotImplementedError() - def spawn(self, instance, network_info=None, block_device_mapping=[]): + def spawn(self, instance, network_info=None, block_device_mapping=None): """Launch a VM for the specified instance""" raise NotImplementedError() diff --git a/nova/virt/fake.py b/nova/virt/fake.py index 498c5ecbb..ab85de2e4 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -114,7 +114,7 @@ class FakeConnection(driver.ComputeDriver): info_list.append(self._map_to_instance_info(instance)) return info_list - def spawn(self, instance, network_info=None, block_device_mapping=[]): + def spawn(self, instance, network_info=None, block_device_mapping=None): """ Create a new instance/VM/domain on the virtualization platform. diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py index 216e90016..23e25e457 100644 --- a/nova/virt/hyperv.py +++ b/nova/virt/hyperv.py @@ -139,7 +139,7 @@ class HyperVConnection(driver.ComputeDriver): return instance_infos - def spawn(self, instance, network_info=None, block_device_mapping=[]): + def spawn(self, instance, network_info=None, block_device_mapping=None): """ Create a new VM and start it.""" vm = self._lookup(instance.name) if vm is not None: diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 0d22d6c41..6300d00a8 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -562,9 +562,10 @@ class LibvirtConnection(driver.ComputeDriver): # NOTE(ilyaalekseyev): Implementation like in multinics # for xenapi(tr3buchet) @exception.wrap_exception - def spawn(self, instance, network_info=None, block_device_mapping=[]): + def spawn(self, instance, network_info=None, block_device_mapping=None): xml = self.to_xml(instance, False, network_info=network_info, block_device_mapping=block_device_mapping) + block_device_mapping = block_device_mapping or [] self.firewall_driver.setup_basic_filtering(instance, network_info) self.firewall_driver.prepare_instance_filter(instance, network_info) self._create_image(instance, xml, network_info=network_info, @@ -750,7 +751,8 @@ class LibvirtConnection(driver.ComputeDriver): # TODO(vish): should we format disk by default? def _create_image(self, inst, libvirt_xml, suffix='', disk_images=None, - network_info=None, block_device_mapping=[]): + network_info=None, block_device_mapping=None): + block_device_mapping = block_device_mapping or [] if not network_info: network_info = netutils.get_network_info(inst) @@ -951,7 +953,8 @@ class LibvirtConnection(driver.ComputeDriver): return False def _prepare_xml_info(self, instance, rescue=False, network_info=None, - block_device_mapping=[]): + block_device_mapping=None): + block_device_mapping = block_device_mapping or [] # TODO(adiantum) remove network_info creation code # when multinics will be completed if not network_info: @@ -1006,7 +1009,8 @@ class LibvirtConnection(driver.ComputeDriver): return xml_info def to_xml(self, instance, rescue=False, network_info=None, - block_device_mapping=[]): + block_device_mapping=None): + block_device_mapping = block_device_mapping or [] # TODO(termie): cache? LOG.debug(_('instance %s: starting toXML method'), instance['name']) xml_info = self._prepare_xml_info(instance, rescue, network_info, diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index a36b45d80..3c6345ec8 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -124,7 +124,7 @@ class VMWareESXConnection(driver.ComputeDriver): """List VM instances.""" return self._vmops.list_instances() - def spawn(self, instance, network_info=None, block_device_mapping=[]): + def spawn(self, instance, network_info=None, block_device_mapping=None): """Create VM instance.""" self._vmops.spawn(instance) diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 8c5e2201e..5fcec1715 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -194,7 +194,7 @@ class XenAPIConnection(driver.ComputeDriver): def list_instances_detail(self): return self._vmops.list_instances_detail() - def spawn(self, instance, network_info=None, block_device_mapping=[]): + def spawn(self, instance, network_info=None, block_device_mapping=None): """Create VM instance""" self._vmops.spawn(instance) -- cgit From f48f35183f6bc30c0e053ea9569f5348799ed451 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Wed, 15 Jun 2011 23:11:03 +0900 Subject: pep8 --- nova/virt/libvirt/connection.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 6300d00a8..a877749e9 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -942,8 +942,9 @@ class LibvirtConnection(driver.ComputeDriver): return result - root_mount_device = 'vda' # FIXME for now. it's hard coded. - local_mount_device = 'vdb' # FIXME for now. it's hard coded. + root_mount_device = 'vda' # FIXME for now. it's hard coded. + local_mount_device = 'vdb' # FIXME for now. it's hard coded. + def _volume_in_mapping(self, mount_device, block_device_mapping): mount_device_ = _strip_dev(mount_device) for vol in block_device_mapping: -- cgit From fb5cc193cfbd9f92ba777bdbcdaae045c982b05a Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Thu, 16 Jun 2011 12:50:55 -0500 Subject: Attempting to retrieve the correct VDI for snapshotting --- nova/virt/xenapi/vm_utils.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 11da221f2..c91a9bab7 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -283,19 +283,16 @@ class VMHelper(HelperBase): @classmethod def get_vdi_for_vm_safely(cls, session, vm_ref): - vdi_refs = VMHelper.lookup_vm_vdis(session, vm_ref) - if vdi_refs is None: - raise Exception(_("No VDIs found for VM %s") % vm_ref) - else: - num_vdis = len(vdi_refs) - if num_vdis != 1: - raise Exception( - _("Unexpected number of VDIs (%(num_vdis)s) found" - " for VM %(vm_ref)s") % locals()) - - vdi_ref = vdi_refs[0] - vdi_rec = session.get_xenapi().VDI.get_record(vdi_ref) - return vdi_ref, vdi_rec + """Retrieves the primary VDI for a VM""" + vbd_refs = session.get_xenapi().VM.get_VBDs(vm_ref) + for vbd in vbd_refs: + vbd_rec = session.get_xenapi().VBD.get_record(vbd) + # Convention dictates the primary VDI will be userdevice 0 + if vbd_rec['userdevice'] == '0': + vdi_rec = session.get_xenapi().VDI.get_record(vbd_rec['VDI']) + return vbd_rec['VDI'], vdi_rec + raise exception.Error(_("No primary VDI found for" + "%(vm_ref)s") % locals()) @classmethod def create_snapshot(cls, session, instance_id, vm_ref, label): -- cgit From 9f62def7b578fc85f85e174a031592a5c4750751 Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Thu, 16 Jun 2011 13:45:55 -0500 Subject: Unit tests pass again --- nova/virt/xenapi/fake.py | 1 + 1 file changed, 1 insertion(+) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py index 113198689..d5ac39473 100644 --- a/nova/virt/xenapi/fake.py +++ b/nova/virt/xenapi/fake.py @@ -146,6 +146,7 @@ def create_vdi(name_label, read_only, sr_ref, sharable): def create_vbd(vm_ref, vdi_ref): vbd_rec = {'VM': vm_ref, 'VDI': vdi_ref, + 'userdevice': '0', 'currently_attached': False} vbd_ref = _create_object('VBD', vbd_rec) after_VBD_create(vbd_ref, vbd_rec) -- cgit From 83df657360fe32315d6a55488de7dccdffa25c90 Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Thu, 16 Jun 2011 13:56:52 -0500 Subject: Added a new test for confirming failure when no primary VDI is present --- nova/virt/xenapi/vm_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index c91a9bab7..7597a0e82 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -879,7 +879,7 @@ def get_vdi_for_vm_safely(session, vm_ref): else: num_vdis = len(vdi_refs) if num_vdis != 1: - raise Exception(_("Unexpected number of VDIs (%(num_vdis)s) found" + raise exception.Exception(_("Unexpected number of VDIs (%(num_vdis)s) found" " for VM %(vm_ref)s") % locals()) vdi_ref = vdi_refs[0] -- cgit From 9ff7bf3c379a3c10ab34c50951cad54659433d65 Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Thu, 16 Jun 2011 22:30:56 +0000 Subject: Remove debugging statement --- nova/virt/xenapi/vmops.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 6b61ca9b5..e638808c3 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -257,7 +257,6 @@ class VMOps(object): LOG.info(_('Updating Agent to %s') % agent_build['version']) ret = self.agent_update(instance, agent_build['url'], agent_build['md5hash']) - LOG.info('Agent Update returned: %s' % ret) def _inject_files(): injected_files = instance.injected_files -- cgit From a6687f56e0ebb23d59fc4b4097b5877f57312a95 Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Thu, 16 Jun 2011 22:31:14 +0000 Subject: We don't check result in caller, so don't set variable to return value --- nova/virt/xenapi/vmops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index e638808c3..c3a8fb70e 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -255,7 +255,7 @@ class VMOps(object): if _cmp_version(version, agent_build['version']) < 0: LOG.info(_('Updating Agent to %s') % agent_build['version']) - ret = self.agent_update(instance, agent_build['url'], + self.agent_update(instance, agent_build['url'], agent_build['md5hash']) def _inject_files(): -- cgit From 716e0f8c9c1ee41551e82154de386dfec653218b Mon Sep 17 00:00:00 2001 From: Johannes Erdfelt Date: Fri, 17 Jun 2011 17:32:45 +0000 Subject: Add some documentation for cmp_version Add test cases for cmp_version --- nova/virt/xenapi/vmops.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index c3a8fb70e..2f4286184 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -47,15 +47,18 @@ LOG = logging.getLogger("nova.virt.xenapi.vmops") FLAGS = flags.FLAGS -def _cmp_version(a, b): +def cmp_version(a, b): + """Compare two version strings (eg 0.0.1.10 > 0.0.1.9)""" a = a.split('.') b = b.split('.') + # Compare each individual portion of both version strings for va, vb in zip(a, b): ret = int(va) - int(vb) if ret: return ret + # Fallback to comparing length last return len(a) - len(b) @@ -253,7 +256,7 @@ class VMOps(object): if not agent_build: return - if _cmp_version(version, agent_build['version']) < 0: + if cmp_version(version, agent_build['version']) < 0: LOG.info(_('Updating Agent to %s') % agent_build['version']) self.agent_update(instance, agent_build['url'], agent_build['md5hash']) -- cgit From c5d23693500448b85c727deac364471743363406 Mon Sep 17 00:00:00 2001 From: "matt.dietz@rackspace.com" <> Date: Fri, 17 Jun 2011 12:33:18 -0500 Subject: Missed a pep8 fix --- nova/virt/xenapi/vm_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nova/virt') diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index 7597a0e82..5d6aa9ba3 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -879,7 +879,8 @@ def get_vdi_for_vm_safely(session, vm_ref): else: num_vdis = len(vdi_refs) if num_vdis != 1: - raise exception.Exception(_("Unexpected number of VDIs (%(num_vdis)s) found" + raise exception.Exception(_("Unexpected number of VDIs" + "(%(num_vdis)s) found" " for VM %(vm_ref)s") % locals()) vdi_ref = vdi_refs[0] -- cgit