Ejemplo n.º 1
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
Ejemplo n.º 2
0
 def test_create(self):
     with mock.patch.object(self.dbapi,
                            'create_volume_mapping',
                            autospec=True) as mock_create_volume_mapping:
         mock_create_volume_mapping.return_value = self.fake_volume_mapping
         volume_mapping_dict = dict(self.fake_volume_mapping)
         del volume_mapping_dict['id']
         volume_mapping = objects.VolumeMapping(self.context,
                                                **volume_mapping_dict)
         volume_mapping.create(self.context)
         mock_create_volume_mapping.assert_called_once_with(
             self.context, volume_mapping_dict)
         self.assertEqual(self.context, volume_mapping._context)
Ejemplo n.º 3
0
 def test_create(self):
     with mock.patch.object(
             self.dbapi, 'create_volume_mapping', autospec=True
     ) as mock_create_volume_mapping, mock.patch.object(
             self.dbapi, 'create_volume',
             autospec=True) as mock_create_volume:
         mock_create_volume_mapping.return_value = self.fake_volume_mapping
         mock_create_volume.return_value = self.fake_volume
         volume_mapping_dict = dict(self.fake_volume_mapping)
         volume_dict = dict(self.fake_volume)
         for attr in ('id', 'uuid', 'created_at', 'updated_at'):
             volume_mapping_dict.pop(attr)
             volume_dict.pop(attr)
         volume_mapping = dict(volume_dict)
         volume_mapping.update(volume_mapping_dict)
         volume_mapping.pop('volume_id')
         volume_mapping = objects.VolumeMapping(self.context,
                                                **volume_mapping)
         volume_mapping.create(self.context)
         mock_create_volume_mapping.assert_called_once_with(
             self.context, volume_mapping_dict)
         mock_create_volume.assert_called_once_with(self.context,
                                                    volume_dict)
         self.assertEqual(self.context, volume_mapping._context)
Ejemplo n.º 4
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