cinder/cinder/volume/drivers/huawei/huawei_dorado.py

109 lines
4.1 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2013 Huawei Technologies Co., Ltd.
# Copyright (c) 2012 OpenStack Foundation
# 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 Drivers for Huawei OceanStor Dorado series storage arrays.
"""
import re
from cinder.openstack.common import log as logging
from cinder.volume.drivers.huawei import huawei_t
from cinder.volume.drivers.huawei import ssh_common
LOG = logging.getLogger(__name__)
class HuaweiDoradoISCSIDriver(huawei_t.HuaweiTISCSIDriver):
"""ISCSI driver class for Huawei OceanStor Dorado storage arrays."""
def __init__(self, *args, **kwargs):
super(HuaweiDoradoISCSIDriver, self).__init__(*args, **kwargs)
def do_setup(self, context):
"""Instantiate common class."""
self.common = ssh_common.DoradoCommon(configuration=self.configuration)
self.common.do_setup(context)
self._assert_cli_out = self.common._assert_cli_out
self._assert_cli_operate_out = self.common._assert_cli_operate_out
class HuaweiDoradoFCDriver(huawei_t.HuaweiTFCDriver):
"""FC driver class for Huawei OceanStor Dorado storage arrays."""
def __init__(self, *args, **kwargs):
super(HuaweiDoradoFCDriver, self).__init__(*args, **kwargs)
def do_setup(self, context):
"""Instantiate common class."""
self.common = ssh_common.DoradoCommon(configuration=self.configuration)
self.common.do_setup(context)
self._assert_cli_out = self.common._assert_cli_out
self._assert_cli_operate_out = self.common._assert_cli_operate_out
def _get_host_port_details(self, hostid):
cli_cmd = 'showfcmode'
out = self.common._execute_cli(cli_cmd)
self._assert_cli_out(re.search('FC Port Topology Mode', out),
'_get_tgt_fc_port_wwns',
'Failed to get FC port WWNs.',
cli_cmd, out)
return [line.split()[3] for line in out.split('\r\n')[6:-2]]
def _get_tgt_fc_port_wwns(self, port_details):
return port_details
def initialize_connection(self, volume, connector):
"""Create FC connection between a volume and a host."""
LOG.debug(_('initialize_connection: volume name: %(vol)s '
'host: %(host)s initiator: %(wwn)s')
% {'vol': volume['name'],
'host': connector['host'],
'wwn': connector['wwpns']})
self.common._update_login_info()
# First, add a host if it is not added before.
host_id = self.common.add_host(connector['host'], connector['ip'])
# Then, add free FC ports to the host.
ini_wwns = connector['wwpns']
free_wwns = self._get_connected_free_wwns()
for wwn in free_wwns:
if wwn in ini_wwns:
self._add_fc_port_to_host(host_id, wwn)
fc_port_details = self._get_host_port_details(host_id)
tgt_wwns = self._get_tgt_fc_port_wwns(fc_port_details)
LOG.debug(_('initialize_connection: Target FC ports WWNS: %s')
% tgt_wwns)
# Finally, map the volume to the host.
volume_id = volume['provider_location']
hostlun_id = self.common.map_volume(host_id, volume_id)
properties = {}
properties['target_discovered'] = False
properties['target_wwn'] = tgt_wwns
properties['target_lun'] = int(hostlun_id)
properties['volume_id'] = volume['id']
return {'driver_volume_type': 'fibre_channel',
'data': properties}