Пример #1
0
 def delete_volume(self, volume):
     volume_id = volume.volume_id
     cinder_api = cinder.CinderAPI(self.context)
     try:
         cinder_api.delete_volume(volume_id)
     except cinder_exception as e:
         raise exception.Invalid(_("Delete Volume failed: %s") % str(e))
Пример #2
0
    def _build_requested_volumes(self, context, mounts):
        # NOTE(hongbin): We assume cinder is the only volume provider here.
        # The logic needs to be re-visited if a second volume provider
        # (i.e. Manila) is introduced.
        cinder_api = cinder.CinderAPI(context)
        requested_volumes = []
        for mount in mounts:
            if mount.get('source'):
                volume = cinder_api.search_volume(mount['source'])
                auto_remove = False
            else:
                volume = cinder_api.create_volume(mount['size'])
                auto_remove = True
            cinder_api.ensure_volume_usable(volume)
            volmapp = objects.VolumeMapping(
                context,
                volume_id=volume.id,
                volume_provider='cinder',
                container_path=mount['destination'],
                user_id=context.user_id,
                project_id=context.project_id,
                auto_remove=auto_remove)
            requested_volumes.append(volmapp)

        return requested_volumes
    def test_unreserve_volume(self, mock_cinderclient):
        mock_volumes = mock.MagicMock()
        mock_cinderclient.return_value = mock.MagicMock(volumes=mock_volumes)

        self.api = cinder_api.CinderAPI(self.context)
        self.api.unreserve_volume('id1')

        mock_cinderclient.assert_called_once_with()
        mock_volumes.unreserve.assert_called_once_with('id1')
    def test_roll_detaching(self, mock_cinderclient):
        mock_volumes = mock.MagicMock()
        mock_cinderclient.return_value = mock.MagicMock(volumes=mock_volumes)

        self.api = cinder_api.CinderAPI(self.context)
        self.api.roll_detaching('id1')

        mock_cinderclient.assert_called_once_with()
        mock_volumes.roll_detaching.assert_called_once_with('id1')
Пример #5
0
 def attach_volume(self, volume):
     cinder_api = cinder.CinderAPI(self.context)
     try:
         return self._do_attach_volume(cinder_api, volume)
     except Exception:
         with excutils.save_and_reraise_exception():
             LOG.exception("Failed to attach volume %(volume_id)s",
                           {'volume_id': volume.volume_id})
             cinder_api.unreserve_volume(volume.volume_id)
    def test_create_volume(self, mock_cinderclient):
        mock_volumes = mock.MagicMock()
        mock_cinderclient.return_value = mock.MagicMock(volumes=mock_volumes)

        volume_size = '5'
        self.api = cinder_api.CinderAPI(self.context)
        self.api.create_volume(volume_size)

        mock_cinderclient.assert_called_once_with()
        mock_volumes.create.assert_called_once_with(volume_size)
    def test_terminate_connection(self, mock_cinderclient):
        mock_volumes = mock.MagicMock()
        mock_cinderclient.return_value = mock.MagicMock(volumes=mock_volumes)

        self.api = cinder_api.CinderAPI(self.context)
        self.api.terminate_connection('id1', 'connector')

        mock_cinderclient.assert_called_once_with()
        mock_volumes.terminate_connection.assert_called_once_with(
            'id1', 'connector')
    def test_initialize_connection_no_rollback(self, mock_cinderclient):
        mock_cinderclient.return_value.volumes.\
            initialize_connection.side_effect = TestingException

        connector = {'host': 'host1'}
        self.api = cinder_api.CinderAPI(self.context)
        self.assertRaises(TestingException, self.api.initialize_connection,
                          'id1', connector)
        self.assertFalse(
            mock_cinderclient.return_value.volumes.terminate_connection.called)
    def test_delete_volume(self, mock_cinderclient):
        mock_volumes = mock.MagicMock()
        mock_cinderclient.return_value = mock.MagicMock(volumes=mock_volumes)

        volume_id = self.id
        self.api = cinder_api.CinderAPI(self.context)
        self.api.delete_volume(volume_id)

        mock_cinderclient.assert_called_once_with()
        mock_volumes.delete.assert_called_once_with(volume_id)
    def test_get(self, mock_cinderclient):
        volume_id = 'volume_id1'
        mock_volumes = mock.MagicMock()
        mock_cinderclient.return_value = mock.MagicMock(volumes=mock_volumes)

        self.api = cinder_api.CinderAPI(self.context)
        self.api.get(volume_id)

        mock_cinderclient.assert_called_once_with()
        mock_volumes.get.assert_called_once_with(volume_id)
Пример #11
0
    def test_attach(self, mock_cinderclient):
        mock_volumes = mock.MagicMock()
        mock_cinderclient.return_value = mock.MagicMock(volumes=mock_volumes)

        self.api = cinder_api.CinderAPI(self.context)
        self.api.attach('id1', 'point', 'host')

        mock_cinderclient.assert_called_once_with()
        mock_volumes.attach.assert_called_once_with(
            volume='id1', mountpoint='point', host_name='host',
            instance_uuid=None)
    def test_detach_multiattach(self, mock_cinderclient):
        attachment = {'host_name': CONF.host, 'attachment_id': 'fakeid'}

        mock_volumes = mock.MagicMock()
        mock_cinderclient.return_value = mock.MagicMock(volumes=mock_volumes)
        mock_cinderclient.return_value.volumes.get.return_value = \
            FakeVolume('id1', attachments=[attachment], multiattach=True)

        self.api = cinder_api.CinderAPI(self.context)
        self.api.detach('id1')

        mock_cinderclient.assert_called_with()
        mock_volumes.detach.assert_called_once_with('id1', 'fakeid')
    def test_initialize_connection_exception_no_code(self, mock_cinderclient,
                                                     mock_log):
        mock_cinderclient.return_value.volumes. \
            initialize_connection.side_effect = (
                cinder_exception.ClientException(500, "500"))
        mock_cinderclient.return_value.volumes. \
            terminate_connection.side_effect = (TestingException)

        connector = {'host': 'fakehost1'}
        self.api = cinder_api.CinderAPI(self.context)
        self.assertRaises(cinder_exception.ClientException,
                          self.api.initialize_connection, 'id1', connector)
        self.assertIsNone(mock_log.error.call_args_list[1][0][1]['code'])
    def test_initialize_connection_rollback(self, mock_cinderclient):
        mock_cinderclient.return_value.volumes.\
            initialize_connection.side_effect = (
                cinder_exception.ClientException(500, "500"))

        connector = {'host': 'host1'}
        self.api = cinder_api.CinderAPI(self.context)
        ex = self.assertRaises(cinder_exception.ClientException,
                               self.api.initialize_connection, 'id1',
                               connector)
        self.assertEqual(500, ex.code)
        mock_cinderclient.return_value.volumes.\
            terminate_connection.assert_called_once_with('id1', connector)
Пример #15
0
    def is_volume_deleted(self, context, volmap):
        try:
            volume = cinder_api.CinderAPI(context).search_volume(
                volmap.cinder_volume_id)
            is_deleted = False
            # Cinder volume error states: 'error', 'error_deleting',
            # 'error_backing-up', 'error_restoring', 'error_extending',
            # all of which start with 'error'
            is_error = True if 'error' in volume.status else False
        except exception.VolumeNotFound:
            is_deleted = True
            is_error = False

        return is_deleted, is_error
    def test_initialize_connection(self, mock_cinderclient):
        connection_info = {'foo': 'bar'}
        mock_cinderclient.return_value.volumes. \
            initialize_connection.return_value = connection_info

        volume_id = 'fake_vid'
        connector = {'host': 'fakehost1'}
        self.api = cinder_api.CinderAPI(self.context)
        actual = self.api.initialize_connection(volume_id, connector)

        expected = connection_info
        self.assertEqual(expected, actual)

        mock_cinderclient.return_value.volumes. \
            initialize_connection.assert_called_once_with(volume_id, connector)
Пример #17
0
    def test_detach(self, mock_cinderclient):
        attachment = {'server_id': 'fake_server', 'attachment_id': 'fakeid'}

        mock_volumes = mock.MagicMock()
        mock_cinderclient.return_value = mock.MagicMock(volumes=mock_volumes)
        mock_cinderclient.return_value.volumes.get.return_value = \
            FakeVolume('id1', attachments=[attachment])
        volume = mock.MagicMock()
        volume.volume_id = 'id1'

        self.api = cinder_api.CinderAPI(self.context)
        self.api.detach(volume)

        mock_cinderclient.assert_called_with()
        mock_volumes.detach.assert_called_once_with('id1', None)
Пример #18
0
    def detach_volume(self, volume):
        volume_id = volume.volume_id
        cinder_api = cinder.CinderAPI(self.context)

        try:
            cinder_api.begin_detaching(volume_id)
        except cinder_exception.BadRequest as e:
            raise exception.Invalid(_("Invalid volume: %s") % str(e))

        conn_info = jsonutils.loads(volume.connection_info)
        try:
            self._disconnect_volume(conn_info)
        except Exception:
            with excutils.save_and_reraise_exception():
                LOG.exception('Failed to disconnect volume %(volume_id)s',
                              {'volume_id': volume_id})
                cinder_api.roll_detaching(volume_id)

        cinder_api.terminate_connection(
            volume_id, get_volume_connector_properties())
        cinder_api.detach(volume_id)
Пример #19
0
 def check_multiattach(self, context, volmap):
     ca = cinder_api.CinderAPI(context)
     return ca.get(volmap.cinder_volume_id).multiattach
Пример #20
0
 def get_volume_status(self, context, volmap):
     ca = cinder_api.CinderAPI(context)
     return ca.get(volmap.cinder_volume_id).status
Пример #21
0
 def is_volume_available(self, context, volume):
     ca = cinder_api.CinderAPI(context)
     if 'available' == ca.get(volume.volume_id).status:
         return True
     else:
         return False
Пример #22
0
 def __init__(self, context):
     self.context = context
     self.cinder_api = cinder.CinderAPI(self.context)
Пример #23
0
    def _build_requested_volumes(self, context, volume_spec, volume_mounts,
                                 capsule):
        # NOTE(hongbin): We assume cinder is the only volume provider here.
        # The logic needs to be re-visited if a second volume provider
        # (i.e. Manila) is introduced.
        # NOTE(kevinz): We assume the volume_mounts has been pretreated,
        # there won't occur that volume multiple attach and no untapped
        # volume.
        cinder_api = cinder.CinderAPI(context)
        volume_driver = "cinder"
        requested_volumes = []
        volume_created = []
        try:
            for mount in volume_spec:
                mount_driver = mount[volume_driver]
                auto_remove = False
                if mount_driver.get("volumeID"):
                    uuid = mount_driver.get("volumeID")
                    volume = cinder_api.search_volume(uuid)
                    cinder_api.ensure_volume_usable(volume)
                else:
                    size = mount_driver.get("size")
                    volume = cinder_api.create_volume(size)
                    volume_created.append(volume)
                    if "autoRemove" in mount_driver.keys() \
                            and mount_driver.get("autoRemove", False):
                        auto_remove = True

                mount_destination = None
                container_name = None

                volume_object = objects.Volume(context,
                                               cinder_volume_id=volume.id,
                                               volume_provider=volume_driver,
                                               user_id=context.user_id,
                                               project_id=context.project_id,
                                               auto_remove=auto_remove)
                volume_object.create(context)

                for item in volume_mounts:
                    if item['name'] == mount['name']:
                        mount_destination = item['mountPath']
                        container_name = item['container_name']
                        volmapp = objects.VolumeMapping(
                            context,
                            container_path=mount_destination,
                            user_id=context.user_id,
                            project_id=context.project_id,
                            volume_id=volume_object.id)
                        requested_volumes.append({container_name: volmapp})

                if not mount_destination or not container_name:
                    msg = _("volume mount parameters is invalid.")
                    raise exception.Invalid(msg)
        except Exception as e:
            # if volume search or created failed, will remove all
            # the created volume. The existed volume will remain.
            for volume in volume_created:
                try:
                    cinder_api.delete_volume(volume.id)
                except Exception as exc:
                    LOG.error('Error on deleting volume "%s": %s.', volume.id,
                              six.text_type(exc))

            # Since the container and capsule database model has been created,
            # we need to delete them here due to the volume create failed.
            for container in capsule.containers:
                try:
                    container.destroy(context)
                except Exception as exc:
                    LOG.warning('fail to delete the container %s: %s',
                                container.uuid, exc)

            capsule.destroy(context)

            raise e

        return requested_volumes