Cluster driver: Blacklist iSCSI/FC volume drivers

There are critical known issues related to the cluster driver and
passthrough disks.

When an instance is failed over, the instance attached volumes need
to be accessible on the destination host. This will not happen
transparently for such disks, for which reason the instance may
bounce between a few nodes and then end up in error state,
basically defeating the purpose of the cluster driver.

This change ensures that the Hyper-V Cluster driver rejects
iSCSI/FC Cinder volumes, raising an error that describes possible
alternatives.

Closes-Bug: #1749958

Change-Id: I231b51c648e1349fcb8df4cd818b2d2887a55d69
This commit is contained in:
Lucian Petrut 2018-02-16 15:18:46 +02:00
parent f50f40ffc4
commit 937aa55ffa
4 changed files with 105 additions and 0 deletions

View File

@ -16,6 +16,7 @@
from compute_hyperv.nova.cluster import clusterops
from compute_hyperv.nova.cluster import livemigrationops
from compute_hyperv.nova.cluster import volumeops
from compute_hyperv.nova import driver
@ -25,6 +26,7 @@ class HyperVClusterDriver(driver.HyperVDriver):
self._clops = clusterops.ClusterOps()
self._livemigrationops = livemigrationops.ClusterLiveMigrationOps()
self._volumeops = volumeops.ClusterVolumeOps()
self._clops.start_failover_listener_daemon()
self._clops.reclaim_failovered_instances()

View File

@ -0,0 +1,49 @@
# Copyright 2018 Cloudbase Solutions Srl
#
# 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 nova import exception
from oslo_log import log as logging
from compute_hyperv.nova import constants
from compute_hyperv.nova import volumeops
LOG = logging.getLogger(__name__)
class ClusterVolumeOps(volumeops.VolumeOps):
def _load_volume_drivers(self):
self.volume_drivers = {
constants.STORAGE_PROTOCOL_SMBFS: volumeops.SMBFSVolumeDriver()
}
def _get_volume_driver(self, connection_info):
driver_type = connection_info.get('driver_volume_type')
if driver_type in [constants.STORAGE_PROTOCOL_ISCSI,
constants.STORAGE_PROTOCOL_FC]:
err_msg = (
"The Hyper-V Cluster driver does not currently support "
"passthrough disks (e.g. iSCSI/FC disks). The reason is "
"that the volumes need to be available on the destination "
"host side during an unexpected instance failover. In order "
"to leverage your storage backend, you may either use the "
"*standard* Nova Hyper-V driver or use the Cinder SMB volume "
"driver (which may imply deploying CSVs on top of LUNs "
"exposed by your storage backend).")
LOG.error(err_msg)
raise exception.VolumeDriverNotFound(driver_type=driver_type)
return super(ClusterVolumeOps, self)._get_volume_driver(
connection_info)

View File

@ -77,6 +77,10 @@ class VolumeOps(object):
self._vmutils = utilsfactory.get_vmutils()
self._default_root_device = 'vda'
self._load_volume_drivers()
def _load_volume_drivers(self):
self.volume_drivers = {
constants.STORAGE_PROTOCOL_SMBFS: SMBFSVolumeDriver(),
constants.STORAGE_PROTOCOL_ISCSI: ISCSIVolumeDriver(),

View File

@ -0,0 +1,50 @@
# Copyright 2018 Cloudbase Solutions Srl
#
# 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 nova import exception
from compute_hyperv.nova.cluster import volumeops
from compute_hyperv.nova import constants
from compute_hyperv.nova import volumeops as base_volumeops
from compute_hyperv.tests.unit import test_base
class ClusterVolumeOpsTestCase(test_base.HyperVBaseTestCase):
_autospec_classes = [
base_volumeops.cinder.API,
]
def setUp(self):
super(ClusterVolumeOpsTestCase, self).setUp()
self._volumeops = volumeops.ClusterVolumeOps()
def test_loaded_volume_drivers(self):
self.assertEqual(set([constants.STORAGE_PROTOCOL_SMBFS]),
set(self._volumeops.volume_drivers.keys()))
def test_get_blacklisted_volume_driver(self):
conn_info = dict(driver_volume_type=constants.STORAGE_PROTOCOL_ISCSI)
self.assertRaises(
exception.VolumeDriverNotFound,
self._volumeops._get_volume_driver,
conn_info)
def test_get_supported_volume_driver(self):
conn_info = dict(driver_volume_type=constants.STORAGE_PROTOCOL_SMBFS)
drv = self._volumeops._get_volume_driver(conn_info)
self.assertIsInstance(drv, base_volumeops.SMBFSVolumeDriver)