104 lines
3.3 KiB
Python
104 lines
3.3 KiB
Python
# 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.
|
|
|
|
import abc
|
|
|
|
from oslo_log import log as logging
|
|
from oslo_utils import importutils
|
|
|
|
from os_brick import exception
|
|
from os_brick.i18n import _
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
CACHE_ENGINE_TO_CACHE_CLASS_MAP = {
|
|
"opencas": 'os_brick.caches.opencas.OpenCASEngine',
|
|
}
|
|
|
|
|
|
class CacheEngineBase(object, metaclass=abc.ABCMeta):
|
|
def __init__(self, **kwargs):
|
|
self._root_helper = kwargs.get('root_helper')
|
|
|
|
@abc.abstractmethod
|
|
def is_engine_ready(self, **kwargs):
|
|
return
|
|
|
|
@abc.abstractmethod
|
|
def attach_volume(self, **kwargs):
|
|
return
|
|
|
|
@abc.abstractmethod
|
|
def detach_volume(self, **kwargs):
|
|
return
|
|
|
|
|
|
class CacheManager():
|
|
"""Cache manager for volumes.
|
|
|
|
This CacheManager uses cache engines to do volume cache.
|
|
"""
|
|
def __init__(self, root_helper, connection_info,
|
|
*args, **kwargs):
|
|
|
|
data = connection_info['data']
|
|
if not data.get('device_path'):
|
|
volume_id = data.get('volume_id') or connection_info.get('serial')
|
|
raise exception.VolumeLocalCacheNotSupported(
|
|
volume_id=volume_id,
|
|
volume_type=connection_info.get('driver_volume_type'))
|
|
|
|
self.ori_device_path = data.get('device_path')
|
|
if not data.get('cacheable'):
|
|
self.cacheable = False
|
|
return
|
|
|
|
self.cacheable = True
|
|
self.root_helper = root_helper
|
|
self.engine_name = kwargs.get('cache_name')
|
|
self.args = args
|
|
self.kwargs = kwargs
|
|
self.kwargs["root_helper"] = root_helper
|
|
self.kwargs["dev_path"] = data.get('device_path')
|
|
self.engine = self._get_engine(self.engine_name, **self.kwargs)
|
|
|
|
def _get_engine(self, engine_name, **kwargs):
|
|
eng_cls_path = CACHE_ENGINE_TO_CACHE_CLASS_MAP.get(engine_name)
|
|
if eng_cls_path:
|
|
engine_cls = importutils.import_class(eng_cls_path)
|
|
eng = engine_cls(**kwargs)
|
|
if eng.is_engine_ready():
|
|
return eng
|
|
|
|
raise exception.Invalid(_("No valid cache engine"))
|
|
|
|
def attach_volume(self):
|
|
"""setup the cache when attaching volume."""
|
|
if not self.cacheable:
|
|
return self.ori_device_path
|
|
|
|
LOG.debug("volume before cached: %s", self.kwargs.get('dev_path'))
|
|
emulated_disk = self.engine.attach_volume(**self.kwargs)
|
|
LOG.debug("volume after cached: %s", emulated_disk)
|
|
return emulated_disk
|
|
|
|
def detach_volume(self):
|
|
"""Release the cache on detaching volume."""
|
|
if not self.cacheable:
|
|
return self.ori_device_path
|
|
|
|
LOG.debug("volume before detach: %s", self.kwargs.get('dev_path'))
|
|
ori_disk = self.engine.detach_volume(**self.kwargs)
|
|
LOG.debug("volume after detach: %s", ori_disk)
|
|
return ori_disk
|