cinder/cinder/volume/drivers/san/hp/hp_lefthand_iscsi.py

155 lines
5.6 KiB
Python

# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
# 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.
#
"""
Volume driver for HP LeftHand Storage array.
This driver requires 11.5 or greater firmware on the LeftHand array, using
the 1.0 or greater version of the hplefthandclient.
You will need to install the python hplefthandclient.
sudo pip install hplefthandclient
Set the following in the cinder.conf file to enable the
LeftHand Channel Driver along with the required flags:
volume_driver=cinder.volume.drivers.san.hp.hp_lefthand_iscsi.
HPLeftHandISCSIDriver
It also requires the setting of hplefthand_api_url, hplefthand_username,
hplefthand_password for credentials to talk to the REST service on the
LeftHand array.
"""
from cinder import exception
from cinder.i18n import _LE, _LI
from cinder.openstack.common import log as logging
from cinder.volume import driver
from cinder.volume.drivers.san.hp import hp_lefthand_cliq_proxy as cliq_proxy
from cinder.volume.drivers.san.hp import hp_lefthand_rest_proxy as rest_proxy
LOG = logging.getLogger(__name__)
MIN_CLIENT_VERSION = '1.0.3'
class HPLeftHandISCSIDriver(driver.VolumeDriver):
"""Executes commands relating to HP/LeftHand SAN ISCSI volumes.
Version history:
1.0.0 - Initial driver
1.0.1 - Added support for retype
1.0.2 - Added support for volume migrate
1.0.3 - Fix for no handler for logger during tests
1.0.4 - Removing locks bug #1395953
"""
VERSION = "1.0.4"
def __init__(self, *args, **kwargs):
super(HPLeftHandISCSIDriver, self).__init__(*args, **kwargs)
self.proxy = None
self.args = args
self.kwargs = kwargs
def _create_proxy(self, *args, **kwargs):
try:
proxy = rest_proxy.HPLeftHandRESTProxy(*args, **kwargs)
except exception.NotFound:
proxy = cliq_proxy.HPLeftHandCLIQProxy(*args, **kwargs)
return proxy
def check_for_setup_error(self):
self.proxy.check_for_setup_error()
def do_setup(self, context):
self.proxy = self._create_proxy(*self.args, **self.kwargs)
LOG.info(_LI("HPLeftHand driver %(driver_ver)s, "
"proxy %(proxy_ver)s") % {
"driver_ver": self.VERSION,
"proxy_ver": self.proxy.get_version_string()})
if isinstance(self.proxy, cliq_proxy.HPLeftHandCLIQProxy):
self.proxy.do_setup(context)
else:
# Check minimum client version for REST proxy
client_version = rest_proxy.hplefthandclient.version
if (client_version < MIN_CLIENT_VERSION):
ex_msg = (_LE("Invalid hplefthandclient version found ("
"%(found)s). Version %(minimum)s or greater "
"required.")
% {'found': client_version,
'minimum': MIN_CLIENT_VERSION})
LOG.error(ex_msg)
raise exception.InvalidInput(reason=ex_msg)
def create_volume(self, volume):
"""Creates a volume."""
return self.proxy.create_volume(volume)
def extend_volume(self, volume, new_size):
"""Extend the size of an existing volume."""
self.proxy.extend_volume(volume, new_size)
def create_volume_from_snapshot(self, volume, snapshot):
"""Creates a volume from a snapshot."""
return self.proxy.create_volume_from_snapshot(volume, snapshot)
def create_snapshot(self, snapshot):
"""Creates a snapshot."""
self.proxy.create_snapshot(snapshot)
def delete_volume(self, volume):
"""Deletes a volume."""
self.proxy.delete_volume(volume)
def delete_snapshot(self, snapshot):
"""Deletes a snapshot."""
self.proxy.delete_snapshot(snapshot)
def initialize_connection(self, volume, connector):
"""Assigns the volume to a server."""
return self.proxy.initialize_connection(volume, connector)
def terminate_connection(self, volume, connector, **kwargs):
"""Unassign the volume from the host."""
self.proxy.terminate_connection(volume, connector)
def get_volume_stats(self, refresh=False):
data = self.proxy.get_volume_stats(refresh)
data['driver_version'] = self.VERSION
return data
def create_cloned_volume(self, volume, src_vref):
return self.proxy.create_cloned_volume(volume, src_vref)
def create_export(self, context, volume):
return self.proxy.create_export(context, volume)
def ensure_export(self, context, volume):
return self.proxy.ensure_export(context, volume)
def remove_export(self, context, volume):
return self.proxy.remove_export(context, volume)
def retype(self, context, volume, new_type, diff, host):
"""Convert the volume to be of the new type."""
return self.proxy.retype(context, volume, new_type, diff, host)
def migrate_volume(self, ctxt, volume, host):
"""Migrate directly if source and dest are managed by same storage."""
return self.proxy.migrate_volume(ctxt, volume, host)