diff options
author | Ed Leafe <ed@leafe.com> | 2011-01-13 09:58:42 -0600 |
---|---|---|
committer | Ed Leafe <ed@leafe.com> | 2011-01-13 09:58:42 -0600 |
commit | 0002d9ea9690cc82f7fac05881c30bfd9581702b (patch) | |
tree | e10a48180032becd935a927c739dbabc493b7559 | |
parent | 0240e044b281f0c7af0a23b0ab1b3854a6e6b94a (diff) | |
parent | aa20d2c7ce4567b1bab540a1d4c06b6ef5e42571 (diff) | |
download | nova-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-- | Authors | 1 | ||||
-rw-r--r-- | nova/virt/libvirt_conn.py | 23 | ||||
-rw-r--r-- | nova/virt/xenapi/vmops.py | 48 | ||||
-rw-r--r-- | nova/volume/driver.py | 57 |
4 files changed, 105 insertions, 24 deletions
@@ -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 |