FakeConnector = {'initiator': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
'wwpns': ['10000090fa0d6754'],
'wwnns': ['10000090fa0d6755'],
- 'host': 'fakehost'}
+ 'host': 'fakehost',
+ 'ip': '10.10.0.1'}
def Fake_sleep(time):
from cinder import test
from cinder import utils
from cinder.volume import configuration as conf
+from cinder.volume.drivers.huawei import huawei_utils
from cinder.volume.drivers.huawei import HuaweiVolumeDriver
from cinder.volume.drivers.huawei import ssh_common
from cinder.volume import volume_types
FAKE_CONNECTOR = {'initiator': 'iqn.1993-08.debian:01:ec2bff7ac3a3',
'wwpns': ['1000000164s45126'],
'wwnns': ['2000666666666565'],
- 'host': 'fakehost'}
+ 'host': 'fakehost',
+ 'ip': '10.10.0.1'}
RESPOOL_A_SIM = {'Size': '10240', 'Valid Size': '5120'}
RESPOOL_B_SIM = {'Size': '10240', 'Valid Size': '10240'}
initiator.setAttribute('TargetIP', '192.168.100.2')
iscsi.appendChild(initiator)
+ os_type = doc.createElement('Host')
+ os_type.setAttribute('OSType', 'Linux')
+ os_type.setAttribute('HostIP', '10.10.0.1')
+ config.appendChild(os_type)
+
tmp_file = open(filename, 'w')
tmp_file.write(doc.toprettyxml(indent=''))
tmp_file.close()
self.assertRaises(exception.InvalidInput,
tmp_driver.create_volume, FAKE_VOLUME)
modify_conf(self.fake_conf_file, 'LUN/LUNType', 'Thick')
+ # Test OSType invalid
+ modify_conf(self.fake_conf_file, 'Host', 'invalid_type',
+ attrib='OSType')
+ tmp_driver = HuaweiVolumeDriver(configuration=self.configuration)
+ self.assertRaises(exception.InvalidInput,
+ tmp_driver.do_setup, None)
+ modify_conf(self.fake_conf_file, 'Host', 'Linux', attrib='OSType')
# Test TargetIP not found
modify_conf(self.fake_conf_file, 'iSCSI/DefaultTargetIP', '')
modify_conf(self.fake_conf_file, 'iSCSI/Initiator', '', attrib='Name')
def _fake_recv2(self, nBytes):
raise socket.timeout()
+
+
+class HuaweiUtilsTestCase(test.TestCase):
+ def __init__(self, *args, **kwargs):
+ super(HuaweiUtilsTestCase, self).__init__(*args, **kwargs)
+
+ def setUp(self):
+ super(HuaweiUtilsTestCase, self).setUp()
+
+ self.tmp_dir = tempfile.mkdtemp()
+ self.fake_conf_file = self.tmp_dir + '/cinder_huawei_conf.xml'
+ create_fake_conf_file(self.fake_conf_file)
+
+ def tearDown(self):
+ if os.path.exists(self.fake_conf_file):
+ os.remove(self.fake_conf_file)
+ shutil.rmtree(self.tmp_dir)
+ super(HuaweiUtilsTestCase, self).tearDown()
+
+ def test_parse_xml_file_ioerror(self):
+ tmp_fonf_file = '/xxx/cinder_huawei_conf.xml'
+ self.assertRaises(IOError, huawei_utils.parse_xml_file, tmp_fonf_file)
+
+ def test_is_xml_item_exist(self):
+ root = huawei_utils.parse_xml_file(self.fake_conf_file)
+ res = huawei_utils.is_xml_item_exist(root, 'Storage/UserName')
+ self.assertTrue(res)
+ res = huawei_utils.is_xml_item_exist(root, 'xxx')
+ self.assertFalse(res)
+ res = huawei_utils.is_xml_item_exist(root, 'LUN/StoragePool', 'Name')
+ self.assertTrue(res)
+ res = huawei_utils.is_xml_item_exist(root, 'LUN/StoragePool', 'xxx')
+ self.assertFalse(res)
+
+ def test_is_xml_item_valid(self):
+ root = huawei_utils.parse_xml_file(self.fake_conf_file)
+ res = huawei_utils.is_xml_item_valid(root, 'LUN/LUNType',
+ ['Thin', 'Thick'])
+ self.assertTrue(res)
+ res = huawei_utils.is_xml_item_valid(root, 'LUN/LUNType', ['test'])
+ self.assertFalse(res)
+ res = huawei_utils.is_xml_item_valid(root, 'Host',
+ ['Linux', 'Windows'], 'OSType')
+ self.assertTrue(res)
+ res = huawei_utils.is_xml_item_valid(root, 'Host', ['test'], 'OSType')
+ self.assertFalse(res)
+
+ def test_get_conf_host_os_type(self):
+ # Default os is Linux
+ res = huawei_utils.get_conf_host_os_type('10.10.10.1',
+ self.fake_conf_file)
+ self.assertEqual(res, '0')
+ modify_conf(self.fake_conf_file, 'Host', 'Windows', 'OSType')
+ res = huawei_utils.get_conf_host_os_type(FAKE_CONNECTOR['ip'],
+ self.fake_conf_file)
+ self.assertEqual(res, '1')
from cinder.volume.drivers.huawei import huawei_dorado
from cinder.volume.drivers.huawei import huawei_hvs
from cinder.volume.drivers.huawei import huawei_t
-from cinder.volume.drivers.huawei import ssh_common
+from cinder.volume.drivers.huawei import huawei_utils
LOG = logging.getLogger(__name__)
def _get_conf_info(self, filename):
"""Get product type and connection protocol from config file."""
- root = ssh_common.parse_xml_file(filename)
+ root = huawei_utils.parse_xml_file(filename)
product = root.findtext('Storage/Product').strip()
protocol = root.findtext('Storage/Protocol').strip()
if (product in self._product.keys() and
self.common._update_login_info()
# First, add a host if it is not added before.
- host_id = self.common.add_host(connector['host'])
+ 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()
def do_setup(self, context):
"""Instantiate common class and log in storage system."""
self.common = HVSCommon(configuration=self.configuration)
- self.common.login()
def check_for_setup_error(self):
"""Check configuration file."""
self.common._check_conf_file()
+ self.common.login()
def create_volume(self, volume):
"""Create a volume."""
from cinder import exception
from cinder.openstack.common import log as logging
from cinder.volume import driver
+from cinder.volume.drivers.huawei import huawei_utils
from cinder.volume.drivers.huawei import ssh_common
self._get_iscsi_params(connector['initiator'])
# First, add a host if not added before.
- host_id = self.common.add_host(connector['host'],
+ host_id = self.common.add_host(connector['host'], connector['ip'],
connector['initiator'])
# Then, add the iSCSI port to the host.
"""
iscsiinfo = {}
- root = ssh_common.parse_xml_file(filename)
+ root = huawei_utils.parse_xml_file(filename)
default_ip = root.findtext('iSCSI/DefaultTargetIP')
if default_ip:
self.common._update_login_info()
# First, add a host if it is not added before.
- host_id = self.common.add_host(connector['host'])
+ 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()
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2013 Huawei Technologies Co., Ltd.
+# Copyright (c) 2012 OpenStack LLC.
+# 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 xml.etree import ElementTree as ET
+
+from cinder import exception
+from cinder.openstack.common import log as logging
+
+LOG = logging.getLogger(__name__)
+
+os_type = {'Linux': '0',
+ 'Windows': '1',
+ 'Solaris': '2',
+ 'HP-UX': '3',
+ 'AIX': '4',
+ 'XenServer': '5',
+ 'Mac OS X': '6',
+ 'VMware ESX': '7'}
+
+
+def parse_xml_file(filepath):
+ """Get root of xml file."""
+ try:
+ tree = ET.parse(filepath)
+ root = tree.getroot()
+ return root
+ except IOError as err:
+ LOG.error(_('parse_xml_file: %s') % err)
+ raise err
+
+
+def get_xml_item(xml_root, item):
+ """Get the given item details.
+
+ :param xml_root: The root of xml tree
+ :param item: The tag need to get
+ :return: A dict contains all the config info of the given item.
+ """
+ items_list = []
+ items = xml_root.findall(item)
+ for item in items:
+ tmp_dict = {'text': None, 'attrib': {}}
+ if item.text:
+ tmp_dict['text'] = item.text.strip()
+ for key, val in item.attrib.items():
+ if val:
+ item.attrib[key] = val.strip()
+ tmp_dict['attrib'] = item.attrib
+ items_list.append(tmp_dict)
+ return items_list
+
+
+def is_xml_item_exist(xml_root, item, attrib_key=None):
+ """Check if the given item exits in xml config file.
+
+ :param xml_root: The root of xml tree
+ :param item: The xml tag to check
+ :param attrib_key: The xml attrib to check
+ :return: True of False
+ """
+ items_list = get_xml_item(xml_root, item)
+ value = []
+ if attrib_key:
+ for tmp_dict in items_list:
+ if tmp_dict['attrib'].get(attrib_key, None):
+ return True
+ else:
+ if items_list and items_list[0]['text']:
+ return True
+ return False
+
+
+def is_xml_item_valid(xml_root, item, valid_list, attrib_key=None):
+ """Check if the given item is valid in xml config file.
+
+ :param xml_root: The root of xml tree
+ :param item: The xml tag to check
+ :param valid_list: The valid item value
+ :param attrib_key: The xml attrib to check
+ :return: True of False
+ """
+ items_list = get_xml_item(xml_root, item)
+ if attrib_key:
+ for tmp_dict in items_list:
+ value = tmp_dict['attrib'].get(attrib_key, None)
+ if value not in valid_list:
+ return False
+ else:
+ value = items_list[0]['text']
+ if value not in valid_list:
+ return False
+
+ return True
+
+
+def get_conf_host_os_type(host_ip, config):
+ """Get host OS type from xml config file.
+
+ :param host_ip: The IP of Nova host
+ :param config: xml config file
+ :return: host OS type
+ """
+ os_conf = {}
+ root = parse_xml_file(config)
+ hosts_list = get_xml_item(root, 'Host')
+ for host in hosts_list:
+ os = host['attrib']['OSType'].strip()
+ ips = [ip.strip() for ip in host['attrib']['HostIP'].split(',')]
+ os_conf[os] = ips
+ host_os = None
+ for k, v in os_conf.items():
+ if host_ip in v:
+ host_os = os_type.get(k, None)
+ if not host_os:
+ host_os = os_type['Linux'] # default os type
+
+ LOG.debug(_('_get_host_os_type: Host %(ip)s OS type is %(os)s.')
+ % {'ip': host_ip, 'os': host_os})
+
+ return host_os
from cinder.openstack.common import log as logging
from cinder import units
from cinder import utils
+from cinder.volume.drivers.huawei import huawei_utils
from cinder.volume import volume_types
self.configuration = configuration
self.cookie = cookielib.CookieJar()
self.url = None
+ self.xml_conf = self.configuration.cinder_huawei_conf_file
def call(self, url=False, data=None, method=None):
"""Send requests to HVS server.
def _assert_data_in_result(self, result, msg):
if "data" not in result:
- msg = _('%s "data" was not in result.') % msg
- LOG.error(msg)
- raise exception.CinderException(msg)
+ err_msg = _('%s "data" was not in result.') % msg
+ LOG.error(err_msg)
+ raise exception.CinderException(err_msg)
def _create_volume(self, lun_param):
url = self.url + "/lun"
result = self.call(url, data, "DELETE")
self._assert_rest_result(result, 'delete lun error')
- def _read_xml(self):
- """Open xml file and parse the content."""
- filename = self.configuration.cinder_huawei_conf_file
- try:
- tree = ET.parse(filename)
- root = tree.getroot()
- except Exception as err:
- LOG.error(_('_read_xml:%s') % err)
- raise err
- return root
-
def _encode_name(self, name):
uuid_str = name.replace("-", "")
vol_uuid = uuid.UUID('urn:uuid:%s' % uuid_str)
return newuuid
def _find_pool_info(self):
- root = self._read_xml()
+ root = huawei_utils.parse_xml_file(self.xml_conf)
pool_name = root.findtext('LUN/StoragePool')
if not pool_name:
err_msg = _("Invalid resource pool: %s") % pool_name
return result['data']['ID']
- def _add_host_into_hostgroup(self, host_name):
+ def _add_host_into_hostgroup(self, host_name, host_ip):
"""Associate host to hostgroup.
If host group doesn't exist, create one.
hostid = self._find_host(host_name)
if hostid is None:
- hostid = self._add_host(host_name)
+ os_type = huawei_utils.get_conf_host_os_type(host_ip,
+ self.xml_conf)
+ hostid = self._add_host(host_name, os_type)
self._associate_host_to_hostgroup(hostgroup_id, hostid)
return hostid, hostgroup_id
def initialize_connection_iscsi(self, volume, connector):
"""Map a volume to a host and return target iSCSI information."""
initiator_name = connector['initiator']
- host_name = connector['host']
volume_name = self._encode_name(volume['id'])
LOG.debug(_('initiator name:%(initiator_name)s, '
'volume name:%(volume)s.')
% {'initiator_name': initiator_name,
'volume': volume_name})
+
(iscsi_iqn, target_ip) = self._get_iscsi_params(connector)
#create host_goup if not exist
- hostid, hostgroup_id = self._add_host_into_hostgroup(host_name)
+ hostid, hostgroup_id = self._add_host_into_hostgroup(connector['host'],
+ connector['ip'])
self._ensure_initiator_added(initiator_name, hostid)
# Mapping lungooup and hostgoup to view
def initialize_connection_fc(self, volume, connector):
wwns = connector['wwpns']
- host_name = connector['host']
volume_name = self._encode_name(volume['id'])
LOG.debug(_('initiator name:%(initiator_name)s, '
% {'initiator_name': wwns,
'volume': volume_name})
- # Create host goup if not exist
- hostid, hostgroup_id = self._add_host_into_hostgroup(host_name)
+ # Create host group if not exist
+ hostid, hostgroup_id = self._add_host_into_hostgroup(connector['host'],
+ connector['ip'])
free_wwns = self._get_connected_free_wwns()
LOG.debug(_("the free wwns %s") % free_wwns)
break
return host_id
- def _add_host(self, hostname):
+ def _add_host(self, hostname, type):
"""Add a new host."""
url = self.url + "/host"
data = json.dumps({"TYPE": "21",
"NAME": hostname,
- "OPERATIONSYSTEM": "0"})
+ "OPERATIONSYSTEM": type})
result = self.call(url, data)
self._assert_rest_result(result, 'Add new host error.')
'PrefetchValue': '0',
'PrefetchTimes': '0'}
- root = self._read_xml()
+ root = huawei_utils.parse_xml_file(self.xml_conf)
luntype = root.findtext('LUN/LUNType')
if luntype:
if luntype.strip() in ['Thick', 'Thin']:
def _get_iscsi_conf(self):
"""Get iSCSI info from config file."""
iscsiinfo = {}
- root = self._read_xml()
+ root = huawei_utils.parse_xml_file(self.xml_conf)
iscsiinfo['DefaultTargetIP'] = \
root.findtext('iSCSI/DefaultTargetIP').strip()
initiator_list = []
def _check_conf_file(self):
"""Check the config file, make sure the essential items are set."""
- root = self._read_xml()
- hvsurl = root.findtext('Storage/HVSURL')
- username = root.findtext('Storage/UserName')
- pwd = root.findtext('Storage/UserPassword')
- pool_node = root.findall('LUN/StoragePool')
-
- if (not hvsurl) or (not username) or (not pwd):
- err_msg = (_('_check_conf_file: Config file invalid. HVSURL,'
- ' UserName and UserPassword must be set.'))
- LOG.error(err_msg)
- raise exception.InvalidInput(reason=err_msg)
+ root = huawei_utils.parse_xml_file(self.xml_conf)
+ check_list = ['Storage/HVSURL', 'Storage/UserName',
+ 'Storage/UserPassword']
+ for item in check_list:
+ if not huawei_utils.is_xml_item_exist(root, item):
+ err_msg = (_('_check_conf_file: Config file invalid. '
+ '%s must be set.') % item)
+ LOG.error(err_msg)
+ raise exception.InvalidInput(reason=err_msg)
- if not pool_node:
- err_msg = (_('_check_conf_file: Config file invalid. '
- 'StoragePool must be set.'))
+ # make sure storage pool is set
+ if not huawei_utils.is_xml_item_exist(root, 'LUN/StoragePool'):
+ err_msg = _('_check_conf_file: Config file invalid. '
+ 'StoragePool must be set.')
LOG.error(err_msg)
raise exception.InvalidInput(reason=err_msg)
+ # make sure host os type valid
+ if huawei_utils.is_xml_item_exist(root, 'Host', 'OSType'):
+ os_list = huawei_utils.os_type.keys()
+ if not huawei_utils.is_xml_item_valid(root, 'Host', os_list,
+ 'OSType'):
+ err_msg = (_('_check_conf_file: Config file invalid. '
+ 'Host OSType invalid.\n'
+ 'The valid values are: %(os_list)s')
+ % {'os_list': os_list})
+ LOG.error(err_msg)
+ raise exception.InvalidInput(reason=err_msg)
+
def _get_iscsi_params(self, connector):
"""Get target iSCSI params, including iqn, IP."""
initiator = connector['initiator']
from cinder.openstack.common import excutils
from cinder.openstack.common import log as logging
from cinder import utils
+from cinder.volume.drivers.huawei import huawei_utils
from cinder.volume import volume_types
VOL_AND_SNAP_NAME_PREFIX = 'OpenStack_'
-def parse_xml_file(filepath):
- """Get root of xml file."""
- try:
- tree = ET.parse(filepath)
- root = tree.getroot()
- return root
- except IOError as err:
- LOG.error(_('parse_xml_file: %s') % err)
- raise err
-
-
def ssh_read(user, channel, cmd, timeout):
"""Get results of CLI commands."""
result = ''
self.hostgroup_id = None
self.ssh_pool = None
self.lock_ip = threading.Lock()
- self.luncopy_list = [] # to storage LUNCopy name
+ self.luncopy_list = [] # to store LUNCopy name
def do_setup(self, context):
"""Check config file."""
def _check_conf_file(self):
"""Check config file, make sure essential items are set."""
- root = parse_xml_file(self.xml_conf)
- IP1 = root.findtext('Storage/ControllerIP0')
- IP2 = root.findtext('Storage/ControllerIP1')
- username = root.findtext('Storage/UserName')
- pwd = root.findtext('Storage/UserPassword')
- pool_node = root.findall('LUN/StoragePool')
-
- if (not IP1 or not IP2) or (not username) or (not pwd):
- err_msg = (_('_check_conf_file: Config file invalid. Controler IP,'
- ' UserName and UserPassword must be set.'))
+ root = huawei_utils.parse_xml_file(self.xml_conf)
+ check_list = ['Storage/ControllerIP0', 'Storage/ControllerIP1',
+ 'Storage/UserName', 'Storage/UserPassword']
+ for item in check_list:
+ if not huawei_utils.is_xml_item_exist(root, item):
+ err_msg = (_('_check_conf_file: Config file invalid. '
+ '%s must be set.') % item)
+ LOG.error(err_msg)
+ raise exception.InvalidInput(reason=err_msg)
+
+ # make sure storage pool is set
+ if not huawei_utils.is_xml_item_exist(root, 'LUN/StoragePool', 'Name'):
+ err_msg = _('_check_conf_file: Config file invalid. '
+ 'StoragePool must be set.')
LOG.error(err_msg)
raise exception.InvalidInput(reason=err_msg)
- for pool in pool_node:
- if pool.attrib['Name']:
- return
- # If pool_node is None or pool.attrib['Name'] is None.
- err_msg = (_('_check_conf_file: Config file invalid. '
- 'StoragePool must be set.'))
- LOG.error(err_msg)
- raise exception.InvalidInput(reason=err_msg)
+ # If setting os type, make sure it valid
+ if huawei_utils.is_xml_item_exist(root, 'Host', 'OSType'):
+ os_list = huawei_utils.os_type.keys()
+ if not huawei_utils.is_xml_item_valid(root, 'Host', os_list,
+ 'OSType'):
+ err_msg = (_('_check_conf_file: Config file invalid. '
+ 'Host OSType is invalid.\n'
+ 'The valid values are: %(os_list)s')
+ % {'os_list': os_list})
+ LOG.error(err_msg)
+ raise exception.InvalidInput(reason=err_msg)
def _get_login_info(self):
"""Get login IP, username and password from config file."""
'PrefetchTimes': '0',
'StoragePool': []}
- root = parse_xml_file(self.xml_conf)
+ root = huawei_utils.parse_xml_file(self.xml_conf)
luntype = root.findtext('LUN/LUNType')
if luntype:
maxpool_id = None
maxpool_size = 0.0
nameindex, sizeindex = ((1, 4) if luntype == 'Thin' else (5, 3))
- pools_dev = sorted(pools_dev, key=lambda x: int(x[sizeindex]))
+ pools_dev = sorted(pools_dev, key=lambda x: float(x[sizeindex]))
while len(pools_dev) > 0:
pool = pools_dev.pop()
if pool[nameindex] in pools_conf:
return hostlun_id
- def add_host(self, host_name, initiator=None):
+ def add_host(self, host_name, host_ip, initiator=None):
"""Create a host and add it to hostgroup."""
# Create an OpenStack hostgroup if not created before.
hostgroup_name = HOST_GROUP_NAME
host_name = HOST_NAME_PREFIX + host_name
host_id = self._get_host_id(host_name, self.hostgroup_id)
if host_id is None:
- self._create_host(host_name, self.hostgroup_id)
+ os_type = huawei_utils.get_conf_host_os_type(host_ip,
+ self.xml_conf)
+ self._create_host(host_name, self.hostgroup_id, os_type)
host_id = self._get_host_id(host_name, self.hostgroup_id)
return host_id
return tmp_line[0]
return None
- def _create_host(self, hostname, hostgroupid):
+ def _create_host(self, hostname, hostgroupid, type):
"""Run CLI command to add host."""
- cli_cmd = ('addhost -group %(groupid)s -n %(hostname)s -t 0'
+ cli_cmd = ('addhost -group %(groupid)s -n %(hostname)s -t %(type)s'
% {'groupid': hostgroupid,
- 'hostname': hostname})
+ 'hostname': hostname,
+ 'type': type})
out = self._execute_cli(cli_cmd)
self._assert_cli_operate_out('_create_host',
def _check_conf_file(self):
"""Check the config file, make sure the key elements are set."""
- root = parse_xml_file(self.xml_conf)
+ root = huawei_utils.parse_xml_file(self.xml_conf)
# Check login infomation
- IP1 = root.findtext('Storage/ControllerIP0')
- IP2 = root.findtext('Storage/ControllerIP1')
- username = root.findtext('Storage/UserName')
- pwd = root.findtext('Storage/UserPassword')
- if (not IP1 and not IP2) or (not username) or (not pwd):
- err_msg = (_('Config file invalid. Controler IP, UserName, '
- 'UserPassword must be specified.'))
- LOG.error(err_msg)
- raise exception.InvalidInput(reason=err_msg)
+ check_list = ['Storage/ControllerIP0', 'Storage/ControllerIP1',
+ 'Storage/UserName', 'Storage/UserPassword']
+ for item in check_list:
+ if not huawei_utils.is_xml_item_exist(root, item):
+ err_msg = (_('_check_conf_file: Config file invalid. '
+ '%s must be set.') % item)
+ LOG.error(err_msg)
+ raise exception.InvalidInput(reason=err_msg)
# Check storage pool
# No need for Dorado2100 G2
self.login_info = self._get_login_info()
self.device_type = self._get_device_type()
if self.device_type == 'Dorado5100':
- pool_node = root.findall('LUN/StoragePool')
- if not pool_node:
+ if not huawei_utils.is_xml_item_exist(root, 'LUN/StoragePool',
+ 'Name'):
err_msg = (_('_check_conf_file: Config file invalid. '
'StoragePool must be specified.'))
LOG.error(err_msg)
raise exception.InvalidInput(reason=err_msg)
+ # If setting os type, make sure it valid
+ if huawei_utils.is_xml_item_exist(root, 'Host', 'OSType'):
+ os_list = huawei_utils.os_type.keys()
+ if not huawei_utils.is_xml_item_valid(root, 'Host', os_list,
+ 'OSType'):
+ err_msg = (_('_check_conf_file: Config file invalid. '
+ 'Host OSType is invalid.\n'
+ 'The valid values are: %(os_list)s')
+ % {'os_list': os_list})
+ LOG.error(err_msg)
+ raise exception.InvalidInput(reason=err_msg)
+
def _get_device_type(self):
"""Run CLI command to get system type."""
cli_cmd = 'showsys'
'WriteType': '1',
'MirrorSwitch': '1'}
- root = parse_xml_file(self.xml_conf)
+ root = huawei_utils.parse_xml_file(self.xml_conf)
luntype = root.findtext('LUN/LUNType')
if luntype: