From 27c11c4bb4e5c54282caf49cba666f45cfc590c2 Mon Sep 17 00:00:00 2001 From: Jay Pipes Date: Wed, 8 Feb 2012 15:51:59 -0500 Subject: [PATCH] Remedies LP Bug #928910 - Use libvirt lookupByName() to check existence Make determining if an instance exists on a host more efficient by adding an instance_exists() method to the base virt driver that can be overridden by drivers that have a more efficient mechanism of looking up an instance by its ID / name. Modifies the _check_instance_already_created method of the compute manager to use this new instance_exists() method. Someone from Citrix should look into how to make the instance_exists() method in the Xen and VMWare virt drivers more efficient than the base "loop over all domains and see if the instance ID exists" method now in the base driver class. Change-Id: Ibf219788f9c104698057367da89300a060945778 --- nova/compute/manager.py | 2 +- nova/virt/driver.py | 15 +++++++++++++++ nova/virt/libvirt/connection.py | 8 ++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 90a6a84ec09..078f5392831 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -440,7 +440,7 @@ def _run_instance(self, context, instance_uuid, def _check_instance_not_already_created(self, context, instance): """Ensure an instance with the same name is not already present.""" - if instance['name'] in self.driver.list_instances(): + if self.driver.instance_exists(instance['name']): raise exception.Error(_("Instance has already been created")) def _check_image_size(self, context, instance): diff --git a/nova/virt/driver.py b/nova/virt/driver.py index 34ce9613b76..ec143d8ca2a 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -114,6 +114,21 @@ def get_info(self, instance_name): # TODO(Vek): Need to pass context in for access to auth_token raise NotImplementedError() + def instance_exists(self, instance_id): + """Checks existence of an instance on the host. + + Returns True if an instance with the supplied ID exists on + the host, False otherwise. + + :note This implementation works for all drivers, but it is + not particularly efficient. Maintainers of the virt drivers are + encouraged to override this method with something more + efficient. + + :param instance_id: The ID / name of the instance to lookup + """ + return instance_id in self.list_instances() + def list_instances(self): """ Return the names of all the instances known to the virtualization diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 0ae8dd1fbe7..9e5f816906b 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -281,6 +281,14 @@ def _connect(uri, read_only): else: return libvirt.openAuth(uri, auth, 0) + def instance_exists(self, instance_id): + """Efficient override of base instance_exists method.""" + try: + _ignored = self._conn.lookupByName(instance_id) + return True + except libvirt.libvirtError: + return False + def list_instances(self): return [self._conn.lookupByID(x).name() for x in self._conn.listDomainsID()