Source code for octavia.volume.drivers.cinder_driver

#    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
#    a copy of the License at
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import time

from cinderclient import exceptions as cinder_exceptions
from oslo_config import cfg
from oslo_log import log as logging
from tenacity import retry
from tenacity import stop_after_attempt

from octavia.common import clients
from octavia.common import constants
from octavia.common import exceptions
from octavia.volume import volume_base

LOG = logging.getLogger(__name__)


[docs] class VolumeManager(volume_base.VolumeBase): '''Volume implementation of virtual machines via cinder.''' def __init__(self): super().__init__() # Must initialize cinder api self._cinder_client = clients.CinderAuth.get_cinder_client( service_name=CONF.cinder.service_name, endpoint=CONF.cinder.endpoint, region=CONF.cinder.region_name, endpoint_type=CONF.cinder.endpoint_type, insecure=CONF.cinder.insecure, cacert=CONF.cinder.ca_certificates_file ) self.manager = self._cinder_client.volumes
[docs] @retry(reraise=True, stop=stop_after_attempt(CONF.cinder.volume_create_max_retries)) def create_volume_from_image(self, image_id): """Create cinder volume :param image_id: ID of amphora image :return volume id """ volume = self.manager.create( size=CONF.cinder.volume_size, volume_type=CONF.cinder.volume_type, availability_zone=CONF.cinder.availability_zone, imageRef=image_id) resource_status = self.manager.get( status = constants.CINDER_STATUS_AVAILABLE start = int(time.time()) while resource_status != status: time.sleep(CONF.cinder.volume_create_retry_interval) instance_volume = self.manager.get( resource_status = instance_volume.status if resource_status == constants.CINDER_STATUS_ERROR: LOG.error('Error creating %s', instance_volume.delete() raise cinder_exceptions.ResourceInErrorState( obj=volume, fault_msg='Cannot create volume') if int(time.time()) - start >= CONF.cinder.volume_create_timeout: LOG.error('Timed out waiting to create cinder volume %s', instance_volume.delete() raise cinder_exceptions.TimeoutException( obj=volume, action=constants.CINDER_ACTION_CREATE_VOLUME) return
[docs] def delete_volume(self, volume_id): """Get glance image from volume :param volume_id: ID of amphora boot volume :return image id """ LOG.debug('Deleting cinder volume %s', volume_id) try: instance_volume = self.manager.get(volume_id) try: instance_volume.delete() LOG.debug("Deleted volume %s", volume_id) except Exception as e: LOG.exception("Error deleting cinder volume %s", volume_id) raise exceptions.VolumeDeleteException() from e except cinder_exceptions.NotFound: LOG.warning("Volume %s not found: assuming already deleted", volume_id)
[docs] def get_image_from_volume(self, volume_id): """Get glance image from volume :param volume_id: ID of amphora boot volume :return image id """ image_id = None LOG.debug('Get glance image for volume %s', volume_id) try: instance_volume = self.manager.get(volume_id) except cinder_exceptions.NotFound as e: LOG.exception("Volume %s not found", volume_id) raise exceptions.VolumeGetException() from e if hasattr(instance_volume, 'volume_image_metadata'): image_id = instance_volume.volume_image_metadata.get("image_id") else: LOG.error("Volume %s has no image metadata", volume_id) image_id = None return image_id