summaryrefslogtreecommitdiffstats
path: root/nova/virt
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@yahoo.com>2010-08-17 17:58:52 -0700
committerVishvananda Ishaya <vishvananda@yahoo.com>2010-08-17 17:58:52 -0700
commitcdcbd516f62290697643eecc56550460bd48ff14 (patch)
tree798d4da90b8025b041a3f2b5efe86f3e33e8ef53 /nova/virt
parent1cd448f907e132c451d6b27c64d16c17b7530952 (diff)
parent018ce9abbfb7047eff1e99379fba098a365e89eb (diff)
downloadnova-cdcbd516f62290697643eecc56550460bd48ff14.tar.gz
nova-cdcbd516f62290697643eecc56550460bd48ff14.tar.xz
nova-cdcbd516f62290697643eecc56550460bd48ff14.zip
merged trunk
Diffstat (limited to 'nova/virt')
-rw-r--r--nova/virt/fake.py19
-rw-r--r--nova/virt/images.py8
-rw-r--r--nova/virt/libvirt_conn.py20
-rw-r--r--nova/virt/xenapi.py39
4 files changed, 44 insertions, 42 deletions
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index d7416d250..f7ee34695 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -24,6 +24,8 @@ This module also documents the semantics of real hypervisor connections.
import logging
+from twisted.internet import defer
+
from nova.compute import power_state
@@ -89,10 +91,13 @@ class FakeConnection(object):
This function should use the data there to guide the creation of
the new instance.
- Once this function successfully completes, the instance should be
+ The work will be done asynchronously. This function returns a
+ Deferred that allows the caller to detect when it is complete.
+
+ Once this successfully completes, the instance should be
running (power_state.RUNNING).
- If this function fails, any partial instance should be completely
+ If this fails, any partial instance should be completely
cleaned up, and the virtualization platform should be in the state
that it was before this call began.
"""
@@ -100,6 +105,7 @@ class FakeConnection(object):
fake_instance = FakeInstance()
self.instances[instance.id] = fake_instance
fake_instance._state = power_state.RUNNING
+ return defer.succeed(None)
def reboot(self, instance):
"""
@@ -107,8 +113,11 @@ class FakeConnection(object):
The given parameter is an instance of nova.compute.service.Instance,
and so the instance is being specified as instance.name.
+
+ The work will be done asynchronously. This function returns a
+ Deferred that allows the caller to detect when it is complete.
"""
- pass
+ return defer.succeed(None)
def destroy(self, instance):
"""
@@ -116,8 +125,12 @@ class FakeConnection(object):
The given parameter is an instance of nova.compute.service.Instance,
and so the instance is being specified as instance.name.
+
+ The work will be done asynchronously. This function returns a
+ Deferred that allows the caller to detect when it is complete.
"""
del self.instances[instance.name]
+ return defer.succeed(None)
def get_info(self, instance_id):
"""
diff --git a/nova/virt/images.py b/nova/virt/images.py
index 1e23c48b9..a3ca72bdd 100644
--- a/nova/virt/images.py
+++ b/nova/virt/images.py
@@ -27,11 +27,11 @@ import urlparse
from nova import flags
from nova import process
-from nova.auth import signer
from nova.auth import manager
+from nova.auth import signer
-FLAGS = flags.FLAGS
+FLAGS = flags.FLAGS
flags.DEFINE_bool('use_s3', True,
'whether to get images from s3 or use local copy')
@@ -43,6 +43,7 @@ def fetch(image, path, user, project):
f = _fetch_local_image
return f(image, path, user, project)
+
def _fetch_s3_image(image, path, user, project):
url = image_url(image)
@@ -66,13 +67,16 @@ def _fetch_s3_image(image, path, user, project):
cmd += ['-o', path]
return process.SharedPool().execute(executable=cmd[0], args=cmd[1:])
+
def _fetch_local_image(image, path, user, project):
source = _image_path('%s/image' % image)
return process.simple_execute('cp %s %s' % (source, path))
+
def _image_path(path):
return os.path.join(FLAGS.images_path, path)
+
def image_url(image):
return "http://%s:%s/_images/%s/image" % (FLAGS.s3_host, FLAGS.s3_port,
image)
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index c00421ab8..c4eb3f272 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -42,6 +42,7 @@ from nova.virt import images
libvirt = None
libxml2 = None
+
FLAGS = flags.FLAGS
flags.DEFINE_string('libvirt_xml_template',
utils.abspath('virt/libvirt.qemu.xml.template'),
@@ -57,7 +58,9 @@ flags.DEFINE_string('libvirt_type',
'Libvirt domain type (valid options are: kvm, qemu, uml)')
flags.DEFINE_string('libvirt_uri',
'',
- 'Override the default libvirt URI (which is dependent on libvirt_type)')
+ 'Override the default libvirt URI (which is dependent'
+ ' on libvirt_type)')
+
def get_connection(read_only):
# These are loaded late so that there's no need to install these
@@ -70,6 +73,7 @@ def get_connection(read_only):
libxml2 = __import__('libxml2')
return LibvirtConnection(read_only)
+
class LibvirtConnection(object):
def __init__(self, read_only):
self.libvirt_uri, template_file = self.get_uri_and_template()
@@ -78,14 +82,12 @@ class LibvirtConnection(object):
self._wrapped_conn = None
self.read_only = read_only
-
@property
def _conn(self):
if not self._wrapped_conn:
self._wrapped_conn = self._connect(self.libvirt_uri, self.read_only)
return self._wrapped_conn
-
def get_uri_and_template(self):
if FLAGS.libvirt_type == 'uml':
uri = FLAGS.libvirt_uri or 'uml:///system'
@@ -95,7 +97,6 @@ class LibvirtConnection(object):
template_file = FLAGS.libvirt_xml_template
return uri, template_file
-
def _connect(self, uri, read_only):
auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_NOECHOPROMPT],
'root',
@@ -106,13 +107,10 @@ class LibvirtConnection(object):
else:
return libvirt.openAuth(uri, auth, 0)
-
-
def list_instances(self):
return [self._conn.lookupByID(x).name()
for x in self._conn.listDomainsID()]
-
def destroy(self, instance):
try:
virt_dom = self._conn.lookupByName(instance.name)
@@ -141,14 +139,12 @@ class LibvirtConnection(object):
timer.start(interval=0.5, now=True)
return d
-
def _cleanup(self, instance):
target = os.path.join(FLAGS.instances_path, instance.name)
logging.info("Deleting instance files at %s", target)
if os.path.exists(target):
shutil.rmtree(target)
-
@defer.inlineCallbacks
@exception.wrap_exception
def reboot(self, instance):
@@ -174,7 +170,6 @@ class LibvirtConnection(object):
timer.start(interval=0.5, now=True)
yield d
-
@defer.inlineCallbacks
@exception.wrap_exception
def spawn(self, instance):
@@ -204,7 +199,6 @@ class LibvirtConnection(object):
timer.start(interval=0.5, now=True)
yield local_d
-
@defer.inlineCallbacks
def _create_image(self, inst, libvirt_xml):
# syntactic nicety
@@ -286,7 +280,6 @@ class LibvirtConnection(object):
'num_cpu': num_cpu,
'cpu_time': cpu_time}
-
def get_disks(self, instance_name):
"""
Note that this function takes an instance name, not an Instance, so
@@ -329,7 +322,6 @@ class LibvirtConnection(object):
return disks
-
def get_interfaces(self, instance_name):
"""
Note that this function takes an instance name, not an Instance, so
@@ -372,7 +364,6 @@ class LibvirtConnection(object):
return interfaces
-
def block_stats(self, instance_name, disk):
"""
Note that this function takes an instance name, not an Instance, so
@@ -381,7 +372,6 @@ class LibvirtConnection(object):
domain = self._conn.lookupByName(instance_name)
return domain.blockStats(disk)
-
def interface_stats(self, instance_name, interface):
"""
Note that this function takes an instance name, not an Instance, so
diff --git a/nova/virt/xenapi.py b/nova/virt/xenapi.py
index 9fe15644f..2f5994983 100644
--- a/nova/virt/xenapi.py
+++ b/nova/virt/xenapi.py
@@ -33,16 +33,29 @@ from nova.virt import images
XenAPI = None
+
FLAGS = flags.FLAGS
flags.DEFINE_string('xenapi_connection_url',
None,
- 'URL for connection to XenServer/Xen Cloud Platform. Required if connection_type=xenapi.')
+ 'URL for connection to XenServer/Xen Cloud Platform.'
+ ' Required if connection_type=xenapi.')
flags.DEFINE_string('xenapi_connection_username',
'root',
- 'Username for connection to XenServer/Xen Cloud Platform. Used only if connection_type=xenapi.')
+ 'Username for connection to XenServer/Xen Cloud Platform.'
+ ' Used only if connection_type=xenapi.')
flags.DEFINE_string('xenapi_connection_password',
None,
- 'Password for connection to XenServer/Xen Cloud Platform. Used only if connection_type=xenapi.')
+ 'Password for connection to XenServer/Xen Cloud Platform.'
+ ' Used only if connection_type=xenapi.')
+
+
+XENAPI_POWER_STATE = {
+ 'Halted' : power_state.SHUTDOWN,
+ 'Running' : power_state.RUNNING,
+ 'Paused' : power_state.PAUSED,
+ 'Suspended': power_state.SHUTDOWN, # FIXME
+ 'Crashed' : power_state.CRASHED
+}
def get_connection(_):
@@ -62,7 +75,6 @@ def get_connection(_):
class XenAPIConnection(object):
-
def __init__(self, url, user, pw):
self._conn = XenAPI.Session(url)
self._conn.login_with_password(user, pw)
@@ -107,7 +119,6 @@ class XenAPIConnection(object):
yield self._create_vif(vm_ref, network_ref, mac_address)
yield self._conn.xenapi.VM.start(vm_ref, False, False)
-
def create_vm(self, instance, kernel, ramdisk):
mem = str(long(instance.datamodel['memory_kb']) * 1024)
vcpus = str(instance.datamodel['vcpus'])
@@ -145,7 +156,6 @@ class XenAPIConnection(object):
logging.debug('Created VM %s as %s.', instance.name, vm_ref)
return vm_ref
-
def create_vbd(self, vm_ref, vdi_ref, userdevice, bootable):
vbd_rec = {}
vbd_rec['VM'] = vm_ref
@@ -166,7 +176,6 @@ class XenAPIConnection(object):
vdi_ref)
return vbd_ref
-
def _create_vif(self, vm_ref, network_ref, mac_address):
vif_rec = {}
vif_rec['device'] = '0'
@@ -184,7 +193,6 @@ class XenAPIConnection(object):
vm_ref, network_ref)
return vif_ref
-
def _find_network_with_bridge(self, bridge):
expr = 'field "bridge" = "%s"' % bridge
networks = self._conn.xenapi.network.get_all_records_where(expr)
@@ -195,7 +203,6 @@ class XenAPIConnection(object):
else:
raise Exception('Found no network for bridge %s' % bridge)
-
def fetch_image(self, image, user, project, use_sr):
"""use_sr: True to put the image as a VDI in an SR, False to place
it on dom0's filesystem. The former is for VM disks, the latter for
@@ -213,7 +220,6 @@ class XenAPIConnection(object):
args['add_partition'] = 'true'
return self._call_plugin('objectstore', fn, args)
-
def reboot(self, instance):
vm = self.lookup(instance.name)
if vm is None:
@@ -231,7 +237,7 @@ class XenAPIConnection(object):
if vm is None:
raise Exception('instance not present %s' % instance_id)
rec = self._conn.xenapi.VM.get_record(vm)
- return {'state': power_state_from_xenapi[rec['power_state']],
+ return {'state': XENAPI_POWER_STATE[rec['power_state']],
'max_mem': long(rec['memory_static_max']) >> 10,
'mem': long(rec['memory_dynamic_max']) >> 10,
'num_cpu': rec['VCPUs_max'],
@@ -247,26 +253,15 @@ class XenAPIConnection(object):
else:
return vms[0]
-
def _call_plugin(self, plugin, fn, args):
return _unwrap_plugin_exceptions(
self._conn.xenapi.host.call_plugin,
self._get_xenapi_host(), plugin, fn, args)
-
def _get_xenapi_host(self):
return self._conn.xenapi.session.get_this_host(self._conn.handle)
-power_state_from_xenapi = {
- 'Halted' : power_state.SHUTDOWN,
- 'Running' : power_state.RUNNING,
- 'Paused' : power_state.PAUSED,
- 'Suspended': power_state.SHUTDOWN, # FIXME
- 'Crashed' : power_state.CRASHED
-}
-
-
def _unwrap_plugin_exceptions(func, *args, **kwargs):
try:
return func(*args, **kwargs)