manila/manila/share/driver.py

168 lines
5.5 KiB
Python

# Copyright 2012 NetApp
# 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.
"""
Drivers for shares.
"""
import time
from manila import exception
from manila.openstack.common import log as logging
from manila import utils
from oslo.config import cfg
LOG = logging.getLogger(__name__)
share_opts = [
# NOTE(rushiagr): Reasonable to define this option at only one place.
cfg.IntOpt('num_shell_tries',
default=3,
help='Number of times to attempt to run flakey shell '
'commands.'),
cfg.IntOpt('reserved_share_percentage',
default=0,
help='The percentage of backend capacity reserved.'),
cfg.StrOpt('share_backend_name',
default=None,
help='The backend name for a given driver implementation.'),
]
CONF = cfg.CONF
CONF.register_opts(share_opts)
class ExecuteMixin(object):
"""Provides an executable functionality to a driver class."""
def __init__(self, *args, **kwargs):
self.db = None
self.configuration = kwargs.get('configuration', None)
if self.configuration:
self.configuration.append_config_values(share_opts)
self.set_execute(kwargs.pop('execute', utils.execute))
def set_execute(self, execute):
self._execute = execute
def _try_execute(self, *command, **kwargs):
# NOTE(vish): Volume commands can partially fail due to timing, but
# running them a second time on failure will usually
# recover nicely.
tries = 0
while True:
try:
self._execute(*command, **kwargs)
return True
except exception.ProcessExecutionError:
tries += 1
if tries >= self.configuration.num_shell_tries:
raise
LOG.exception(_("Recovering from a failed execute. "
"Try number %s"), tries)
time.sleep(tries ** 2)
class ShareDriver(object):
"""Class defines interface of NAS driver."""
def __init__(self, *args, **kwargs):
super(ShareDriver, self).__init__()
self.configuration = kwargs.get('configuration', None)
if self.configuration:
self.configuration.append_config_values(share_opts)
def create_share(self, context, share, share_server=None):
"""Is called to create share."""
raise NotImplementedError()
def create_share_from_snapshot(self, context, share, snapshot,
share_server=None):
"""Is called to create share from snapshot."""
raise NotImplementedError()
def create_snapshot(self, context, snapshot, share_server=None):
"""Is called to create snapshot."""
raise NotImplementedError()
def delete_share(self, context, share, share_server=None):
"""Is called to remove share."""
raise NotImplementedError()
def delete_snapshot(self, context, snapshot, share_server=None):
"""Is called to remove snapshot."""
raise NotImplementedError()
def ensure_share(self, context, share, share_server=None):
"""Invoked to sure that share is exported."""
raise NotImplementedError()
def allow_access(self, context, share, access, share_server=None):
"""Allow access to the share."""
raise NotImplementedError()
def deny_access(self, context, share, access, share_server=None):
"""Deny access to the share."""
raise NotImplementedError()
def check_for_setup_error(self):
"""Check for setup error."""
pass
def do_setup(self, context):
"""Any initialization the share driver does while starting."""
pass
def get_share_stats(self, refresh=False):
"""Get share status.
If 'refresh' is True, run update the stats first.
"""
if refresh:
self._update_share_status()
return self._stats
def get_network_allocations_number(self):
"""Returns number of network allocations for creating VIFs."""
pass
def setup_server(self, network_info, metadata=None):
"""Set up and configures share server with given network parameters."""
pass
def teardown_server(self, server_details, security_services=None):
"""Teardown share server."""
pass
def _update_share_status(self):
"""Retrieve status info from share group."""
LOG.debug("Updating share status")
data = {}
backend_name = self.configuration.safe_get('share_backend_name')
data["share_backend_name"] = backend_name or 'Generic_NFS'
data["vendor_name"] = 'Open Source'
data["driver_version"] = '1.0'
data["storage_protocol"] = None
data['total_capacity_gb'] = 'infinite'
data['free_capacity_gb'] = 'infinite'
data['reserved_percentage'] = 0
data['QoS_support'] = False
self._stats = data