
The cfg API is now available via the oslo-config library, so switch to it and remove the copied-and-pasted version. Add the 2013.1b3 tarball to tools/pip-requires - this will be changed to 'oslo-config>=2013.1' when oslo-config is published to pypi. This will happen in time for grizzly final. Add dependency_links to setup.py so that oslo-config can be installed from the tarball URL specified in pip-requires. Remove the 'deps = pep8==1.3.3' from tox.ini as it means all the other deps get installed with easy_install which can't install oslo-config from the URL. Retain dummy cfg.py file until keystoneclient middleware has been updated (I18c450174277c8e2d15ed93879da6cd92074c27a). Change-Id: I4815aeb8a9341a31a250e920157f15ee15cfc5bc
215 lines
7.2 KiB
Python
215 lines
7.2 KiB
Python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
|
|
|
# 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 import flags
|
|
from cinder.image import glance
|
|
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'),
|
|
]
|
|
|
|
FLAGS = flags.FLAGS
|
|
FLAGS.register_opts(xenapi_opts)
|
|
FLAGS.register_opts(xenapi_nfs_opts)
|
|
|
|
|
|
class XenAPINFSDriver(driver.VolumeDriver):
|
|
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)
|
|
|
|
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)
|
|
|
|
def create_cloned_volume(self, volume, src_vref):
|
|
raise NotImplementedError()
|
|
|
|
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)
|
|
|
|
def create_export(self, context, volume):
|
|
pass
|
|
|
|
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
|
|
)
|
|
|
|
def remove_export(self, context, volume):
|
|
pass
|
|
|
|
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']
|
|
)
|
|
)
|
|
|
|
def terminate_connection(self, volume, connector, force=False, **kwargs):
|
|
pass
|
|
|
|
def check_for_setup_error(self):
|
|
"""To override superclass' method"""
|
|
|
|
def create_volume_from_snapshot(self, volume, snapshot):
|
|
return self._copy_volume(
|
|
snapshot, volume['display_name'], volume['name_description'])
|
|
|
|
def create_snapshot(self, snapshot):
|
|
volume_id = snapshot['volume_id']
|
|
volume = snapshot['volume']
|
|
return self._copy_volume(
|
|
volume, snapshot['display_name'], snapshot['display_description'])
|
|
|
|
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)
|
|
|
|
def delete_snapshot(self, snapshot):
|
|
self.delete_volume(snapshot)
|
|
|
|
def ensure_export(self, context, volume):
|
|
pass
|
|
|
|
def 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(
|
|
FLAGS.xenapi_nfs_server,
|
|
FLAGS.xenapi_nfs_serverpath,
|
|
sr_uuid,
|
|
vdi_uuid,
|
|
glance_server,
|
|
image_id,
|
|
auth_token,
|
|
FLAGS.xenapi_sr_base_path)
|
|
|
|
if overwrite_result is False:
|
|
raise exception.ImageCopyFailure()
|
|
|
|
self.nfs_ops.resize_volume(
|
|
FLAGS.xenapi_nfs_server,
|
|
FLAGS.xenapi_nfs_serverpath,
|
|
sr_uuid,
|
|
vdi_uuid,
|
|
volume['size'])
|
|
|
|
def copy_volume_to_image(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(
|
|
FLAGS.xenapi_nfs_server,
|
|
FLAGS.xenapi_nfs_serverpath,
|
|
sr_uuid,
|
|
vdi_uuid,
|
|
glance_server,
|
|
image_id,
|
|
auth_token,
|
|
FLAGS.xenapi_sr_base_path)
|
|
|
|
def get_volume_stats(self, refresh=False):
|
|
if refresh or not self._stats:
|
|
self._stats = dict(
|
|
volume_backend_name='XenAPINFS',
|
|
vendor_name='Open Source',
|
|
driver_version='1.0',
|
|
storage_protocol='xensm',
|
|
total_capacity_gb='unknown',
|
|
free_capacity_gb='unknown',
|
|
reserved_percentage=0)
|
|
|
|
return self._stats
|