¡@

Home 

OpenStack Study: sm.py

OpenStack Index

**** CubicPower OpenStack Study ****

# Copyright 2010 United States Government as represented by the

# Administrator of the National Aeronautics and Space Administration.

# 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

# a copy of the License at

#

# http://www.apache.org/licenses/LICENSE-2.0

#

# 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.

from oslo.config import cfg

from cinder import exception

from cinder.image import glance

from cinder.image import image_utils

from cinder.openstack.common import log as logging

from cinder.volume import driver

from cinder.volume.drivers.xenapi import lib as xenapi_lib

LOG = logging.getLogger(__name__)

xenapi_opts = [

cfg.StrOpt('xenapi_connection_url',

default=None,

help='URL for XenAPI connection'),

cfg.StrOpt('xenapi_connection_username',

default='root',

help='Username for XenAPI connection'),

cfg.StrOpt('xenapi_connection_password',

default=None,

help='Password for XenAPI connection',

secret=True),

cfg.StrOpt('xenapi_sr_base_path',

default='/var/run/sr-mount',

help='Base path to the storage repository'),

]

xenapi_nfs_opts = [

cfg.StrOpt('xenapi_nfs_server',

default=None,

help='NFS server to be used by XenAPINFSDriver'),

cfg.StrOpt('xenapi_nfs_serverpath',

default=None,

help='Path of exported NFS, used by XenAPINFSDriver'),

]

CONF = cfg.CONF

CONF.register_opts(xenapi_opts)

CONF.register_opts(xenapi_nfs_opts)

**** CubicPower OpenStack Study ****

class XenAPINFSDriver(driver.VolumeDriver):

VERSION = "1.0.0"

**** CubicPower OpenStack Study ****

    def __init__(self, *args, **kwargs):

        super(XenAPINFSDriver, self).__init__(*args, **kwargs)

        self.configuration.append_config_values(xenapi_opts)

        self.configuration.append_config_values(xenapi_nfs_opts)

**** CubicPower OpenStack Study ****

    def do_setup(self, context):

        session_factory = xenapi_lib.SessionFactory(

            self.configuration.xenapi_connection_url,

            self.configuration.xenapi_connection_username,

            self.configuration.xenapi_connection_password

        )

        self.nfs_ops = xenapi_lib.NFSBasedVolumeOperations(session_factory)

**** CubicPower OpenStack Study ****

    def create_cloned_volume(self, volume, src_vref):

        raise NotImplementedError()

**** CubicPower OpenStack Study ****

    def create_volume(self, volume):

        volume_details = self.nfs_ops.create_volume(

            self.configuration.xenapi_nfs_server,

            self.configuration.xenapi_nfs_serverpath,

            volume['size'],

            volume['display_name'],

            volume['display_description']

        )

        location = "%(sr_uuid)s/%(vdi_uuid)s" % volume_details

        return dict(provider_location=location)

**** CubicPower OpenStack Study ****

    def create_export(self, context, volume):

        pass

**** CubicPower OpenStack Study ****

    def delete_volume(self, volume):

        sr_uuid, vdi_uuid = volume['provider_location'].split('/')

        self.nfs_ops.delete_volume(

            self.configuration.xenapi_nfs_server,

            self.configuration.xenapi_nfs_serverpath,

            sr_uuid,

            vdi_uuid

        )

**** CubicPower OpenStack Study ****

    def remove_export(self, context, volume):

        pass

**** CubicPower OpenStack Study ****

    def initialize_connection(self, volume, connector):

        sr_uuid, vdi_uuid = volume['provider_location'].split('/')

        return dict(

            driver_volume_type='xensm',

            data=dict(

                name_label=volume['display_name'] or '',

                name_description=volume['display_description'] or '',

                sr_uuid=sr_uuid,

                vdi_uuid=vdi_uuid,

                sr_type='nfs',

                server=self.configuration.xenapi_nfs_server,

                serverpath=self.configuration.xenapi_nfs_serverpath,

                introduce_sr_keys=['sr_type', 'server', 'serverpath']

            )

        )

**** CubicPower OpenStack Study ****

    def terminate_connection(self, volume, connector, **kwargs):

        pass

**** CubicPower OpenStack Study ****

    def check_for_setup_error(self):

        """To override superclass' method."""

**** CubicPower OpenStack Study ****

    def create_volume_from_snapshot(self, volume, snapshot):

        return self._copy_volume(

            snapshot, volume['display_name'], volume['name_description'])

**** CubicPower OpenStack Study ****

    def create_snapshot(self, snapshot):

        volume_id = snapshot['volume_id']

        volume = snapshot['volume']

        return self._copy_volume(

            volume, snapshot['display_name'], snapshot['display_description'])

**** CubicPower OpenStack Study ****

    def _copy_volume(self, volume, target_name, target_desc):

        sr_uuid, vdi_uuid = volume['provider_location'].split('/')

        volume_details = self.nfs_ops.copy_volume(

            self.configuration.xenapi_nfs_server,

            self.configuration.xenapi_nfs_serverpath,

            sr_uuid,

            vdi_uuid,

            target_name,

            target_desc

        )

        location = "%(sr_uuid)s/%(vdi_uuid)s" % volume_details

        return dict(provider_location=location)

**** CubicPower OpenStack Study ****

    def delete_snapshot(self, snapshot):

        self.delete_volume(snapshot)

**** CubicPower OpenStack Study ****

    def ensure_export(self, context, volume):

        pass

**** CubicPower OpenStack Study ****

    def copy_image_to_volume(self, context, volume, image_service, image_id):

        if image_utils.is_xenserver_image(context, image_service, image_id):

            return self._use_glance_plugin_to_copy_image_to_volume(

                context, volume, image_service, image_id)

        return self._use_image_utils_to_pipe_bytes_to_volume(

            context, volume, image_service, image_id)

**** CubicPower OpenStack Study ****

    def _use_image_utils_to_pipe_bytes_to_volume(self, context, volume,

                                                 image_service, image_id):

        sr_uuid, vdi_uuid = volume['provider_location'].split('/')

        with self.nfs_ops.volume_attached_here(CONF.xenapi_nfs_server,

                                               CONF.xenapi_nfs_serverpath,

                                               sr_uuid, vdi_uuid,

                                               False) as device:

            image_utils.fetch_to_raw(context,

                                     image_service,

                                     image_id,

                                     device,

                                     self.configuration.volume_dd_blocksize,

                                     size=volume['size'])

**** CubicPower OpenStack Study ****

    def _use_glance_plugin_to_copy_image_to_volume(self, context, volume,

                                                   image_service, image_id):

        sr_uuid, vdi_uuid = volume['provider_location'].split('/')

        api_servers = glance.get_api_servers()

        glance_server = api_servers.next()

        auth_token = context.auth_token

        overwrite_result = self.nfs_ops.use_glance_plugin_to_overwrite_volume(

            CONF.xenapi_nfs_server,

            CONF.xenapi_nfs_serverpath,

            sr_uuid,

            vdi_uuid,

            glance_server,

            image_id,

            auth_token,

            CONF.xenapi_sr_base_path)

        if overwrite_result is False:

            raise exception.ImageCopyFailure(reason='Overwriting volume '

                                                    'failed.')

        self.nfs_ops.resize_volume(

            CONF.xenapi_nfs_server,

            CONF.xenapi_nfs_serverpath,

            sr_uuid,

            vdi_uuid,

            volume['size'])

**** CubicPower OpenStack Study ****

    def copy_volume_to_image(self, context, volume, image_service, image_meta):

        if image_utils.is_xenserver_format(image_meta):

            return self._use_glance_plugin_to_upload_volume(

                context, volume, image_service, image_meta)

        return self._use_image_utils_to_upload_volume(

            context, volume, image_service, image_meta)

**** CubicPower OpenStack Study ****

    def _use_image_utils_to_upload_volume(self, context, volume, image_service,

                                          image_meta):

        sr_uuid, vdi_uuid = volume['provider_location'].split('/')

        with self.nfs_ops.volume_attached_here(CONF.xenapi_nfs_server,

                                               CONF.xenapi_nfs_serverpath,

                                               sr_uuid, vdi_uuid,

                                               True) as device:

            image_utils.upload_volume(context,

                                      image_service,

                                      image_meta,

                                      device)

**** CubicPower OpenStack Study ****

    def _use_glance_plugin_to_upload_volume(self, context, volume,

                                            image_service, image_meta):

        image_id = image_meta['id']

        sr_uuid, vdi_uuid = volume['provider_location'].split('/')

        api_servers = glance.get_api_servers()

        glance_server = api_servers.next()

        auth_token = context.auth_token

        self.nfs_ops.use_glance_plugin_to_upload_volume(

            CONF.xenapi_nfs_server,

            CONF.xenapi_nfs_serverpath,

            sr_uuid,

            vdi_uuid,

            glance_server,

            image_id,

            auth_token,

            CONF.xenapi_sr_base_path)

**** CubicPower OpenStack Study ****

    def get_volume_stats(self, refresh=False):

        if refresh or not self._stats:

            data = {}

            backend_name = self.configuration.safe_get('volume_backend_name')

            data["volume_backend_name"] = backend_name or 'XenAPINFS',

            data['vendor_name'] = 'Open Source',

            data['driver_version'] = self.VERSION

            data['storage_protocol'] = 'xensm'

            data['total_capacity_gb'] = 'unknown'

            data['free_capacity_gb'] = 'unknown'

            data['reserved_percentage'] = 0

            self._stats = data

        return self._stats

**** CubicPower OpenStack Study ****

    def backup_volume(self, context, backup, backup_service):

        """Create a new backup from an existing volume."""

        raise NotImplementedError()

**** CubicPower OpenStack Study ****

    def restore_backup(self, context, backup, volume, backup_service):

        """Restore an existing backup to a new or existing volume."""

        raise NotImplementedError()