Merge "rbd: update volume<->image copying"

This commit is contained in:
Jenkins 2013-02-16 10:54:33 +00:00 committed by Gerrit Code Review
commit e708025281
2 changed files with 38 additions and 19 deletions

View File

@ -21,6 +21,7 @@ import tempfile
from cinder import db
from cinder import exception
from cinder.image import image_utils
from cinder.openstack.common import log as logging
from cinder.openstack.common import timeutils
from cinder import test
@ -41,8 +42,8 @@ class RBDTestCase(test.TestCase):
def setUp(self):
super(RBDTestCase, self).setUp()
def fake_execute(*args):
pass
def fake_execute(*args, **kwargs):
return '', ''
self.driver = RBDDriver(execute=fake_execute)
def test_good_locations(self):
@ -91,7 +92,9 @@ class RBDTestCase(test.TestCase):
yield FakeTmp('test')
self.stubs.Set(tempfile, 'NamedTemporaryFile', fake_temp_file)
self.stubs.Set(os.path, 'exists', lambda x: True)
self.driver.copy_image_to_volume(None, {'name': 'test'},
self.stubs.Set(image_utils, 'fetch_to_raw', lambda w, x, y, z: None)
self.driver.copy_image_to_volume(None, {'name': 'test',
'size': 1},
FakeImageService(), None)
def test_copy_image_no_volume_tmp(self):
@ -103,17 +106,8 @@ class RBDTestCase(test.TestCase):
self._copy_image()
class FakeRBDDriver(RBDDriver):
def _clone(self):
pass
def _resize(self):
pass
class ManagedRBDTestCase(DriverTestCase):
driver_name = "cinder.tests.test_rbd.FakeRBDDriver"
driver_name = "cinder.volume.drivers.rbd.RBDDriver"
def setUp(self):
super(ManagedRBDTestCase, self).setUp()
@ -124,7 +118,7 @@ class ManagedRBDTestCase(DriverTestCase):
"""Try to clone a volume from an image, and check the status
afterwards"""
def fake_clone_image(volume, image_location):
pass
return True
def fake_clone_error(volume, image_location):
raise exception.CinderException()

View File

@ -21,8 +21,10 @@ import urllib
from cinder import exception
from cinder import flags
from cinder.image import image_utils
from cinder.openstack.common import cfg
from cinder.openstack.common import log as logging
from cinder import utils
from cinder.volume import driver
@ -222,19 +224,42 @@ class RBDDriver(driver.VolumeDriver):
self._resize(volume)
return True
def _ensure_tmp_exists(self):
if FLAGS.volume_tmp_dir and not os.path.exists(FLAGS.volume_tmp_dir):
os.makedirs(FLAGS.volume_tmp_dir)
def copy_image_to_volume(self, context, volume, image_service, image_id):
# TODO(jdurgin): replace with librbd
# this is a temporary hack, since rewriting this driver
# to use librbd would take too long
if FLAGS.volume_tmp_dir and not os.path.exists(FLAGS.volume_tmp_dir):
os.makedirs(FLAGS.volume_tmp_dir)
self._ensure_tmp_exists()
with tempfile.NamedTemporaryFile(dir=FLAGS.volume_tmp_dir) as tmp:
image_service.download(context, image_id, tmp)
image_utils.fetch_to_raw(context, image_service, image_id,
tmp.name)
# import creates the image, so we must remove it first
self._try_execute('rbd', 'rm',
'--pool', FLAGS.rbd_pool,
volume['name'])
self._try_execute('rbd', 'import',
args = ['rbd', 'import',
'--pool', FLAGS.rbd_pool,
tmp.name, volume['name']]
if self._supports_layering():
args += ['--new-format']
self._try_execute(*args)
self._resize(volume)
def copy_volume_to_image(self, context, volume, image_service, image_meta):
self._ensure_tmp_exists()
tmp_dir = FLAGS.volume_tmp_dir or '/tmp'
tmp_file = os.path.join(tmp_dir,
volume['name'] + '-' + image_meta['id'])
with utils.remove_path_on_error(tmp_file):
self._try_execute('rbd', 'export',
'--pool', FLAGS.rbd_pool,
tmp.name, volume['name'])
volume['name'], tmp_file)
image_utils.upload_volume(context, image_service,
image_meta, tmp_file)
os.unlink(tmp_file)