image_service.download(context, image_id, image_file)
+def fetch_verify_image(context, image_service, image_id, dest,
+ user_id=None, project_id=None):
+ fetch(context, image_service, image_id, dest,
+ None, None)
+
+ with fileutils.remove_path_on_error(dest):
+ data = qemu_img_info(dest)
+ fmt = data.file_format
+ if fmt is None:
+ raise exception.ImageUnacceptable(
+ reason=_("'qemu-img info' parsing failed."),
+ image_id=image_id)
+
+ backing_file = data.backing_file
+ if backing_file is not None:
+ raise exception.ImageUnacceptable(
+ image_id=image_id,
+ reason=_("fmt=%(fmt)s backed by:"
+ "%(backing_file)s") % locals())
+
+
def fetch_to_raw(context, image_service,
image_id, dest,
user_id=None, project_id=None):
# vim: tabstop=4 shiftwidth=4 softtabstop=4
-# Copyright 2013 Wenhao Xu
+# Copyright (c) 2013 Zelin.io
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# License for the specific language governing permissions and limitations
# under the License.
+
+import contextlib
+import os
+import tempfile
+
from cinder import exception
+from cinder.image import image_utils
from cinder import test
from cinder.volume.drivers.sheepdog import SheepdogDriver
+
COLLIE_NODE_INFO = """
0 107287605248 3623897354 3%
Total 107287605248 3623897354 3% 54760833024
"""
-class SheepdogTestCase(test.TestCase):
+class FakeImageService:
+ def download(self, context, image_id, path):
+ pass
+
+class SheepdogTestCase(test.TestCase):
def setUp(self):
super(SheepdogTestCase, self).setUp()
self.driver = SheepdogDriver()
return COLLIE_CLUSTER_INFO_0_6, ''
self.stubs.Set(self.driver, '_execute', fake_stats)
self.driver.check_for_setup_error()
+
+ def test_copy_image_to_volume(self):
+ @contextlib.contextmanager
+ def fake_temp_file(dir):
+ class FakeTmp:
+ def __init__(self, name):
+ self.name = name
+ yield FakeTmp('test')
+
+ def fake_try_execute(obj, *command, **kwargs):
+ return True
+
+ self.stubs.Set(tempfile, 'NamedTemporaryFile', fake_temp_file)
+ self.stubs.Set(os.path, 'exists', lambda x: True)
+ self.stubs.Set(image_utils, 'fetch_verify_image',
+ lambda w, x, y, z: None)
+ self.stubs.Set(image_utils, 'convert_image',
+ lambda x, y, z: None)
+ self.stubs.Set(SheepdogDriver, '_try_execute', fake_try_execute)
+ self.driver.copy_image_to_volume(None, {'name': 'test',
+ 'size': 1},
+ FakeImageService(), None)
# Copyright 2012 OpenStack LLC
+# Copyright (c) 2013 Zelin.io
+# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
SheepDog Volume Driver.
"""
+import os
import re
+import tempfile
from oslo.config import cfg
from cinder import exception
+from cinder.image import image_utils
from cinder.openstack.common import log as logging
from cinder.volume import driver
LOG = logging.getLogger(__name__)
+CONF = cfg.CONF
+CONF.import_opt("image_conversion_dir", "cinder.image.image_utils")
+
class SheepdogDriver(driver.VolumeDriver):
"""Executes commands relating to Sheepdog Volumes"""
def delete_volume(self, volume):
"""Deletes a logical volume"""
- self._try_execute('collie', 'vdi', 'delete', volume['name'])
+ self._delete(volume)
+
+ def _ensure_dir_exists(self, tmp_dir):
+ if tmp_dir and not os.path.exists(tmp_dir):
+ os.makedirs(tmp_dir)
+
+ def _resize(self, volume):
+ size = int(volume['size']) * (1024 ** 3)
+ self._try_execute('collie', 'vdi', 'resize',
+ volume['name'], size)
+
+ def _delete(self, volume):
+ self._try_execute('collie', 'vdi', 'delete',
+ volume['name'])
+
+ def copy_image_to_volume(self, context, volume, image_service, image_id):
+ # use the image_conversion_dir as a temporary place to save the image
+ conversion_dir = CONF.image_conversion_dir
+ self._ensure_dir_exists(conversion_dir)
+ with tempfile.NamedTemporaryFile(dir=conversion_dir) as tmp:
+ # (wenhao): we don't need to convert to raw for sheepdog.
+ image_utils.fetch_verify_image(context, image_service,
+ image_id, tmp.name)
+
+ # remove the image created by import before this function.
+ # see volume/drivers/manager.py:_create_volume
+ self._delete(volume)
+ # convert and store into sheepdog
+ image_utils.convert_image(tmp, 'sheepdog:%s' % volume['name'],
+ 'raw')
+ self._resize(volume)
def create_snapshot(self, snapshot):
"""Creates a sheepdog snapshot"""