summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Leafe <ed@leafe.com>2011-01-13 09:58:42 -0600
committerEd Leafe <ed@leafe.com>2011-01-13 09:58:42 -0600
commit0002d9ea9690cc82f7fac05881c30bfd9581702b (patch)
treee10a48180032becd935a927c739dbabc493b7559
parent0240e044b281f0c7af0a23b0ab1b3854a6e6b94a (diff)
parentaa20d2c7ce4567b1bab540a1d4c06b6ef5e42571 (diff)
downloadnova-0002d9ea9690cc82f7fac05881c30bfd9581702b.tar.gz
nova-0002d9ea9690cc82f7fac05881c30bfd9581702b.tar.xz
nova-0002d9ea9690cc82f7fac05881c30bfd9581702b.zip
Replaced home-grown Diffie-Hellman implementation with the M2Crypto version supplied by Soren
-rw-r--r--Authors1
-rw-r--r--nova/virt/libvirt_conn.py23
-rw-r--r--nova/virt/xenapi/vmops.py48
-rw-r--r--nova/volume/driver.py57
4 files changed, 105 insertions, 24 deletions
diff --git a/Authors b/Authors
index 56344957e..0c49f76a2 100644
--- a/Authors
+++ b/Authors
@@ -21,6 +21,7 @@ Jesse Andrews <anotherjesse@gmail.com>
Joe Heck <heckj@mac.com>
Joel Moore <joelbm24@gmail.com>
Jonathan Bryce <jbryce@jbryce.com>
+Josh Durgin <joshd@hq.newdream.net>
Josh Kearney <josh.kearney@rackspace.com>
Joshua McKenty <jmckenty@gmail.com>
Justin Santa Barbara <justin@fathomdb.com>
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index 655c55fa1..bd863b3a2 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -243,11 +243,24 @@ class LibvirtConnection(object):
def attach_volume(self, instance_name, device_path, mountpoint):
virt_dom = self._conn.lookupByName(instance_name)
mount_device = mountpoint.rpartition("/")[2]
- xml = """<disk type='block'>
- <driver name='qemu' type='raw'/>
- <source dev='%s'/>
- <target dev='%s' bus='virtio'/>
- </disk>""" % (device_path, mount_device)
+ if device_path.startswith('/dev/'):
+ xml = """<disk type='block'>
+ <driver name='qemu' type='raw'/>
+ <source dev='%s'/>
+ <target dev='%s' bus='virtio'/>
+ </disk>""" % (device_path, mount_device)
+ elif ':' in device_path:
+ (protocol, name) = device_path.split(':')
+ xml = """<disk type='network'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='%s' name='%s'/>
+ <target dev='%s' bus='virtio'/>
+ </disk>""" % (protocol,
+ name,
+ mount_device)
+ else:
+ raise exception.Invalid(_("Invalid device path %s") % device_path)
+
virt_dom.attachDevice(xml)
def _get_disk_xml(self, xml, device):
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 99583bee1..23de6d8b6 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -20,6 +20,7 @@ Management class for VM-related functions (spawn, reboot, etc).
"""
import json
+import M2Crypto
import os
import random
import subprocess
@@ -310,13 +311,13 @@ class VMOps(object):
"""suspend the specified instance"""
vm = self._get_vm_opaque_ref(instance)
task = self._session.call_xenapi('Async.VM.suspend', vm)
- self._wait_with_callback(task, callback)
+ self._wait_with_callback(instance.id, task, callback)
def resume(self, instance, callback):
"""resume the specified instance"""
vm = self._get_vm_opaque_ref(instance)
task = self._session.call_xenapi('Async.VM.resume', vm, False, True)
- self._wait_with_callback(task, callback)
+ self._wait_with_callback(instance.id, task, callback)
def get_info(self, instance):
"""Return data about VM instance"""
@@ -524,7 +525,6 @@ class VMOps(object):
self.write_to_param_xenstore(instance_or_vm, {})
########################################################################
-
def _runproc(cmd):
pipe = subprocess.PIPE
return subprocess.Popen([cmd], shell=True, stdin=pipe, stdout=pipe,
@@ -539,19 +539,10 @@ class SimpleDH(object):
the openssl binary be installed on the system on which this is run,
as it uses that to handle the encryption and decryption. If openssl
is not available, a RuntimeError will be raised.
-
- Please note that nova already uses the M2Crypto library for most
- cryptographic functions, and that it includes a Diffie-Hellman
- implementation. However, that is a much more complex implementation,
- and is not compatible with the DH algorithm that the agent uses. Hence
- the need for this 'simple' version.
"""
def __init__(self, prime=None, base=None, secret=None):
"""You can specify the values for prime and base if you wish;
- otherwise, reasonable default values will be used. You may also
- specify the integer value for 'secret', but this should only be
- done while testing when you need reproducible values. Otherwise,
- any security benefits are lost.
+ otherwise, reasonable default values will be used.
"""
if prime is None:
self._prime = 162259276829213363391578010288127
@@ -561,20 +552,39 @@ class SimpleDH(object):
self._base = 5
else:
self._base = base
- if secret is None:
- self._secret = random.randint(5000, 15000)
- else:
- self._secret = secret
self._shared = self._public = None
+ self._dh = M2Crypto.DH.set_params(
+ self.dec_to_mpi(self._prime),
+ self.dec_to_mpi(self._base))
+ self._dh.gen_key()
+ self._public = self.mpi_to_dec(self._dh.pub)
+
def get_public(self):
- self._public = (self._base ** self._secret) % self._prime
return self._public
def compute_shared(self, other):
- self._shared = (other ** self._secret) % self._prime
+ self._shared = self.bin_to_dec(
+ self._dh.compute_key(self.dec_to_mpi(other)))
return self._shared
+ def mpi_to_dec(self, mpi):
+ bn = M2Crypto.m2.mpi_to_bn(mpi)
+ hexval = M2Crypto.m2.bn_to_hex(bn)
+ dec = int(hexval, 16)
+ return dec
+
+ def bin_to_dec(self, binval):
+ bn = M2Crypto.m2.bin_to_bn(binval)
+ hexval = M2Crypto.m2.bn_to_hex(bn)
+ dec = int(hexval, 16)
+ return dec
+
+ def dec_to_mpi(self, dec):
+ bn = M2Crypto.m2.dec_to_bn('%s' % dec)
+ mpi = M2Crypto.m2.bn_to_mpi(bn)
+ return mpi
+
def _run_ssl(self, text, which):
base_cmd = ('cat %(tmpfile)s | openssl enc -aes-128-cbc '
'-a -pass pass:%(shared)s -nosalt %(dec_flag)s')
diff --git a/nova/volume/driver.py b/nova/volume/driver.py
index 6bc925f3e..44bfeaf0c 100644
--- a/nova/volume/driver.py
+++ b/nova/volume/driver.py
@@ -49,6 +49,8 @@ flags.DEFINE_string('iscsi_target_prefix', 'iqn.2010-10.org.openstack:',
'prefix for iscsi volumes')
flags.DEFINE_string('iscsi_ip_prefix', '127.0',
'discover volumes on the ip that starts with this prefix')
+flags.DEFINE_string('rbd_pool', 'rbd',
+ 'the rbd pool in which volumes are stored')
class VolumeDriver(object):
@@ -314,3 +316,58 @@ class FakeISCSIDriver(ISCSIDriver):
"""Execute that simply logs the command."""
LOG.debug(_("FAKE ISCSI: %s"), cmd)
return (None, None)
+
+
+class RBDDriver(VolumeDriver):
+ """Implements RADOS block device (RBD) volume commands"""
+
+ def check_for_setup_error(self):
+ """Returns an error if prerequisites aren't met"""
+ (stdout, stderr) = self._execute("rados lspools")
+ pools = stdout.split("\n")
+ if not FLAGS.rbd_pool in pools:
+ raise exception.Error(_("rbd has no pool %s") %
+ FLAGS.rbd_pool)
+
+ def create_volume(self, volume):
+ """Creates a logical volume."""
+ if int(volume['size']) == 0:
+ size = 100
+ else:
+ size = int(volume['size']) * 1024
+ self._try_execute("rbd --pool %s --size %d create %s" %
+ (FLAGS.rbd_pool,
+ size,
+ volume['name']))
+
+ def delete_volume(self, volume):
+ """Deletes a logical volume."""
+ self._try_execute("rbd --pool %s rm %s" %
+ (FLAGS.rbd_pool,
+ volume['name']))
+
+ def local_path(self, volume):
+ """Returns the path of the rbd volume."""
+ # This is the same as the remote path
+ # since qemu accesses it directly.
+ return self.discover_volume(volume)
+
+ def ensure_export(self, context, volume):
+ """Synchronously recreates an export for a logical volume."""
+ pass
+
+ def create_export(self, context, volume):
+ """Exports the volume"""
+ pass
+
+ def remove_export(self, context, volume):
+ """Removes an export for a logical volume"""
+ pass
+
+ def discover_volume(self, volume):
+ """Discover volume on a remote host"""
+ return "rbd:%s/%s" % (FLAGS.rbd_pool, volume['name'])
+
+ def undiscover_volume(self, volume):
+ """Undiscover volume on a remote host"""
+ pass