Consolidate exceptions and extend NovaException
Consolidate all nova-powervm exception classes into a new module, nova_powervm.virt.powervm.exception, and make sure they all inherit from NovaException. Change-Id: Iec10ed588192be19188e0b4d68df3f1eb73e48a2
This commit is contained in:
@@ -27,6 +27,7 @@ from pypowervm.wrappers import virtual_io_server as pvm_vios
|
|||||||
from nova_powervm.tests.virt.powervm import fixtures as fx
|
from nova_powervm.tests.virt.powervm import fixtures as fx
|
||||||
from nova_powervm.virt.powervm.disk import driver as disk_dvr
|
from nova_powervm.virt.powervm.disk import driver as disk_dvr
|
||||||
from nova_powervm.virt.powervm.disk import localdisk as ld
|
from nova_powervm.virt.powervm.disk import localdisk as ld
|
||||||
|
from nova_powervm.virt.powervm import exception as npvmex
|
||||||
|
|
||||||
|
|
||||||
VOL_GRP_WITH_VIOS = 'fake_volume_group_with_vio_data.txt'
|
VOL_GRP_WITH_VIOS = 'fake_volume_group_with_vio_data.txt'
|
||||||
@@ -268,7 +269,7 @@ class TestLocalDisk(test.TestCase):
|
|||||||
# Not found
|
# Not found
|
||||||
mock_add.reset_mock()
|
mock_add.reset_mock()
|
||||||
self.apt.read.return_value = vios2.entry
|
self.apt.read.return_value = vios2.entry
|
||||||
self.assertRaises(disk_dvr.InstanceDiskMappingFailed,
|
self.assertRaises(npvmex.InstanceDiskMappingFailed,
|
||||||
local.connect_instance_disk_to_mgmt, inst)
|
local.connect_instance_disk_to_mgmt, inst)
|
||||||
self.assertEqual(0, mock_add.call_count)
|
self.assertEqual(0, mock_add.call_count)
|
||||||
|
|
||||||
@@ -276,7 +277,7 @@ class TestLocalDisk(test.TestCase):
|
|||||||
mock_add.reset_mock()
|
mock_add.reset_mock()
|
||||||
self.apt.read.return_value = vios1.entry
|
self.apt.read.return_value = vios1.entry
|
||||||
mock_add.side_effect = Exception("mapping failed")
|
mock_add.side_effect = Exception("mapping failed")
|
||||||
self.assertRaises(disk_dvr.InstanceDiskMappingFailed,
|
self.assertRaises(npvmex.InstanceDiskMappingFailed,
|
||||||
local.connect_instance_disk_to_mgmt, inst)
|
local.connect_instance_disk_to_mgmt, inst)
|
||||||
self.assertEqual(1, mock_add.call_count)
|
self.assertEqual(1, mock_add.call_count)
|
||||||
|
|
||||||
@@ -349,6 +350,6 @@ class TestLocalDiskFindVG(test.TestCase):
|
|||||||
self.flags(volume_group_name='rootvg',
|
self.flags(volume_group_name='rootvg',
|
||||||
volume_group_vios_name='invalid_vios')
|
volume_group_vios_name='invalid_vios')
|
||||||
|
|
||||||
self.assertRaises(ld.VGNotFound, ld.LocalStorage,
|
self.assertRaises(npvmex.VGNotFound, ld.LocalStorage,
|
||||||
{'adapter': self.apt, 'host_uuid': 'host_uuid',
|
{'adapter': self.apt, 'host_uuid': 'host_uuid',
|
||||||
'mp_uuid': 'mp_uuid'})
|
'mp_uuid': 'mp_uuid'})
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ from pypowervm.wrappers import storage as pvm_stg
|
|||||||
from pypowervm.wrappers import virtual_io_server as pvm_vios
|
from pypowervm.wrappers import virtual_io_server as pvm_vios
|
||||||
|
|
||||||
from nova_powervm.tests.virt.powervm import fixtures as fx
|
from nova_powervm.tests.virt.powervm import fixtures as fx
|
||||||
from nova_powervm.virt.powervm.disk import driver
|
|
||||||
from nova_powervm.virt.powervm.disk import ssp
|
from nova_powervm.virt.powervm.disk import ssp
|
||||||
|
from nova_powervm.virt.powervm import exception as npvmex
|
||||||
|
|
||||||
|
|
||||||
SSP = 'fake_ssp.txt'
|
SSP = 'fake_ssp.txt'
|
||||||
@@ -172,7 +172,7 @@ class TestSSPDiskAdapter(test.TestCase):
|
|||||||
def test_init_ClusterNotFoundByName(self):
|
def test_init_ClusterNotFoundByName(self):
|
||||||
"""Empty feed comes back from search - no cluster by that name."""
|
"""Empty feed comes back from search - no cluster by that name."""
|
||||||
self.mock_search.return_value = self._bld_resp(status=204)
|
self.mock_search.return_value = self._bld_resp(status=204)
|
||||||
self.assertRaises(ssp.ClusterNotFoundByName, self._get_ssp_stor)
|
self.assertRaises(npvmex.ClusterNotFoundByName, self._get_ssp_stor)
|
||||||
|
|
||||||
def test_init_TooManyClustersFound(self):
|
def test_init_TooManyClustersFound(self):
|
||||||
"""Search-by-name returns more than one result."""
|
"""Search-by-name returns more than one result."""
|
||||||
@@ -184,13 +184,13 @@ class TestSSPDiskAdapter(test.TestCase):
|
|||||||
pvm_clust.Node.bld(None, 'vios2'))
|
pvm_clust.Node.bld(None, 'vios2'))
|
||||||
self.mock_search.return_value = self._bld_resp(
|
self.mock_search.return_value = self._bld_resp(
|
||||||
entry_or_list=[clust1.entry, clust2.entry])
|
entry_or_list=[clust1.entry, clust2.entry])
|
||||||
self.assertRaises(ssp.TooManyClustersFound, self._get_ssp_stor)
|
self.assertRaises(npvmex.TooManyClustersFound, self._get_ssp_stor)
|
||||||
|
|
||||||
def test_init_NoConfigNoClusterFound(self):
|
def test_init_NoConfigNoClusterFound(self):
|
||||||
"""No cluster name specified in config, no clusters on host."""
|
"""No cluster name specified in config, no clusters on host."""
|
||||||
self.flags(cluster_name='')
|
self.flags(cluster_name='')
|
||||||
self.apt.read.return_value = self._bld_resp(status=204)
|
self.apt.read.return_value = self._bld_resp(status=204)
|
||||||
self.assertRaises(ssp.NoConfigNoClusterFound, self._get_ssp_stor)
|
self.assertRaises(npvmex.NoConfigNoClusterFound, self._get_ssp_stor)
|
||||||
|
|
||||||
def test_init_NoConfigTooManyClusters(self):
|
def test_init_NoConfigTooManyClusters(self):
|
||||||
"""No SSP name specified in config, more than one SSP on host."""
|
"""No SSP name specified in config, more than one SSP on host."""
|
||||||
@@ -203,7 +203,7 @@ class TestSSPDiskAdapter(test.TestCase):
|
|||||||
pvm_clust.Node.bld(None, 'vios2'))
|
pvm_clust.Node.bld(None, 'vios2'))
|
||||||
self.apt.read.return_value = self._bld_resp(
|
self.apt.read.return_value = self._bld_resp(
|
||||||
entry_or_list=[clust1.entry, clust2.entry])
|
entry_or_list=[clust1.entry, clust2.entry])
|
||||||
self.assertRaises(ssp.NoConfigTooManyClusters, self._get_ssp_stor)
|
self.assertRaises(npvmex.NoConfigTooManyClusters, self._get_ssp_stor)
|
||||||
|
|
||||||
def test_refresh_cluster(self):
|
def test_refresh_cluster(self):
|
||||||
"""_refresh_cluster with cached wrapper."""
|
"""_refresh_cluster with cached wrapper."""
|
||||||
@@ -550,7 +550,7 @@ class TestSSPDiskAdapter(test.TestCase):
|
|||||||
# No hits
|
# No hits
|
||||||
mock_add.reset_mock()
|
mock_add.reset_mock()
|
||||||
self.apt.read.side_effect = [rsp3, rsp3]
|
self.apt.read.side_effect = [rsp3, rsp3]
|
||||||
self.assertRaises(driver.InstanceDiskMappingFailed,
|
self.assertRaises(npvmex.InstanceDiskMappingFailed,
|
||||||
ssp_stor.connect_instance_disk_to_mgmt, inst)
|
ssp_stor.connect_instance_disk_to_mgmt, inst)
|
||||||
self.assertEqual(0, mock_add.call_count)
|
self.assertEqual(0, mock_add.call_count)
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from pypowervm.tests.wrappers.util import pvmhttp
|
|||||||
from pypowervm.wrappers import storage as pvm_stor
|
from pypowervm.wrappers import storage as pvm_stor
|
||||||
|
|
||||||
from nova_powervm.tests.virt.powervm import fixtures as fx
|
from nova_powervm.tests.virt.powervm import fixtures as fx
|
||||||
|
from nova_powervm.virt.powervm import exception as npvmex
|
||||||
from nova_powervm.virt.powervm import media as m
|
from nova_powervm.virt.powervm import media as m
|
||||||
|
|
||||||
VOL_GRP_DATA = 'fake_volume_group.txt'
|
VOL_GRP_DATA = 'fake_volume_group.txt'
|
||||||
@@ -136,7 +137,7 @@ class TestConfigDrivePowerVM(test.TestCase):
|
|||||||
def test_validate_opt_vg_fail(self):
|
def test_validate_opt_vg_fail(self):
|
||||||
self.apt.read.side_effect = [self.vio_feed_no_vg,
|
self.apt.read.side_effect = [self.vio_feed_no_vg,
|
||||||
self.vol_grp_novg_resp]
|
self.vol_grp_novg_resp]
|
||||||
self.assertRaises(m.NoMediaRepoVolumeGroupFound,
|
self.assertRaises(npvmex.NoMediaRepoVolumeGroupFound,
|
||||||
m.ConfigDrivePowerVM, self.apt, 'fake_host')
|
m.ConfigDrivePowerVM, self.apt, 'fake_host')
|
||||||
|
|
||||||
@mock.patch('pypowervm.tasks.scsi_mapper.remove_vopt_mapping')
|
@mock.patch('pypowervm.tasks.scsi_mapper.remove_vopt_mapping')
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from pypowervm.tests.wrappers.util import pvmhttp
|
|||||||
from pypowervm.wrappers import logical_partition as pvm_lpar
|
from pypowervm.wrappers import logical_partition as pvm_lpar
|
||||||
|
|
||||||
from nova_powervm.tests.virt.powervm import fixtures as fx
|
from nova_powervm.tests.virt.powervm import fixtures as fx
|
||||||
|
from nova_powervm.virt.powervm import exception as npvmex
|
||||||
from nova_powervm.virt.powervm import mgmt
|
from nova_powervm.virt.powervm import mgmt
|
||||||
|
|
||||||
LPAR_HTTPRESP_FILE = "lpar.txt"
|
LPAR_HTTPRESP_FILE = "lpar.txt"
|
||||||
@@ -77,11 +78,11 @@ class TestMgmt(test.TestCase):
|
|||||||
mapping.backing_storage.udid = udid
|
mapping.backing_storage.udid = udid
|
||||||
# No disks found
|
# No disks found
|
||||||
mock_glob.side_effect = [['path'], []]
|
mock_glob.side_effect = [['path'], []]
|
||||||
self.assertRaises(mgmt.UniqueDiskDiscoveryException,
|
self.assertRaises(npvmex.UniqueDiskDiscoveryException,
|
||||||
mgmt.discover_vscsi_disk, mapping)
|
mgmt.discover_vscsi_disk, mapping)
|
||||||
# Multiple disks found
|
# Multiple disks found
|
||||||
mock_glob.side_effect = [['path'], ['/dev/sde', '/dev/sdf']]
|
mock_glob.side_effect = [['path'], ['/dev/sde', '/dev/sdf']]
|
||||||
self.assertRaises(mgmt.UniqueDiskDiscoveryException,
|
self.assertRaises(npvmex.UniqueDiskDiscoveryException,
|
||||||
mgmt.discover_vscsi_disk, mapping)
|
mgmt.discover_vscsi_disk, mapping)
|
||||||
|
|
||||||
@mock.patch('os.path.realpath')
|
@mock.patch('os.path.realpath')
|
||||||
@@ -126,8 +127,8 @@ class TestMgmt(test.TestCase):
|
|||||||
mock_exec.reset_mock()
|
mock_exec.reset_mock()
|
||||||
mock_stat.reset_mock()
|
mock_stat.reset_mock()
|
||||||
mock_stat.side_effect = (None, None, None)
|
mock_stat.side_effect = (None, None, None)
|
||||||
self.assertRaises(mgmt.DeviceDeletionException, mgmt.remove_block_dev,
|
self.assertRaises(
|
||||||
link)
|
npvmex.DeviceDeletionException, mgmt.remove_block_dev, link)
|
||||||
# stat was called thrice; exec was called once
|
# stat was called thrice; exec was called once
|
||||||
self.assertEqual(3, mock_stat.call_count)
|
self.assertEqual(3, mock_stat.call_count)
|
||||||
self.assertEqual(1, mock_exec.call_count)
|
self.assertEqual(1, mock_exec.call_count)
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
# Copyright 2015 IBM Corp.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
import abc
|
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
|
||||||
class AbstractDiskException(Exception):
|
|
||||||
def __init__(self, **kwds):
|
|
||||||
msg = self.msg_fmt % kwds
|
|
||||||
super(AbstractDiskException, self).__init__(msg)
|
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ import oslo_log.log as logging
|
|||||||
from oslo_utils import units
|
from oslo_utils import units
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from nova.i18n import _, _LW
|
from nova.i18n import _LW
|
||||||
from nova import image
|
from nova import image
|
||||||
import pypowervm.tasks.scsi_mapper as tsk_map
|
import pypowervm.tasks.scsi_mapper as tsk_map
|
||||||
import pypowervm.util as pvm_util
|
import pypowervm.util as pvm_util
|
||||||
import pypowervm.wrappers.virtual_io_server as pvm_vios
|
import pypowervm.wrappers.virtual_io_server as pvm_vios
|
||||||
|
|
||||||
from nova_powervm.virt.powervm import disk
|
from nova_powervm.virt.powervm import exception as npvmex
|
||||||
from nova_powervm.virt.powervm import vm
|
from nova_powervm.virt.powervm import vm
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@@ -39,11 +39,6 @@ class DiskType(object):
|
|||||||
IMAGE = 'image'
|
IMAGE = 'image'
|
||||||
|
|
||||||
|
|
||||||
class InstanceDiskMappingFailed(disk.AbstractDiskException):
|
|
||||||
msg_fmt = _("Failed to map boot disk of instance %(instance_name)s to "
|
|
||||||
"the management partition from any Virtual I/O Server.")
|
|
||||||
|
|
||||||
|
|
||||||
class IterableToFileAdapter(object):
|
class IterableToFileAdapter(object):
|
||||||
"""A degenerate file-like so that an iterable could be read like a file.
|
"""A degenerate file-like so that an iterable could be read like a file.
|
||||||
|
|
||||||
@@ -174,7 +169,7 @@ class DiskAdapter(object):
|
|||||||
"%(vios_name)s: %(exc)s"), msg_args)
|
"%(vios_name)s: %(exc)s"), msg_args)
|
||||||
# Try the next hit, if available.
|
# Try the next hit, if available.
|
||||||
# We either didn't find the boot dev, or failed all attempts to map it.
|
# We either didn't find the boot dev, or failed all attempts to map it.
|
||||||
raise InstanceDiskMappingFailed(**msg_args)
|
raise npvmex.InstanceDiskMappingFailed(**msg_args)
|
||||||
|
|
||||||
def disconnect_disk_from_mgmt(self, vios_uuid, disk_name):
|
def disconnect_disk_from_mgmt(self, vios_uuid, disk_name):
|
||||||
"""Disconnect a disk from the management partition.
|
"""Disconnect a disk from the management partition.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from oslo_config import cfg
|
|||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
from nova import exception as nova_exc
|
from nova import exception as nova_exc
|
||||||
from nova.i18n import _, _LI, _LE
|
from nova.i18n import _LI, _LE
|
||||||
from pypowervm import exceptions as pvm_exc
|
from pypowervm import exceptions as pvm_exc
|
||||||
from pypowervm.tasks import scsi_mapper as tsk_map
|
from pypowervm.tasks import scsi_mapper as tsk_map
|
||||||
from pypowervm.tasks import storage as tsk_stg
|
from pypowervm.tasks import storage as tsk_stg
|
||||||
@@ -28,8 +28,8 @@ from pypowervm.wrappers import managed_system as pvm_ms
|
|||||||
from pypowervm.wrappers import storage as pvm_stg
|
from pypowervm.wrappers import storage as pvm_stg
|
||||||
from pypowervm.wrappers import virtual_io_server as pvm_vios
|
from pypowervm.wrappers import virtual_io_server as pvm_vios
|
||||||
|
|
||||||
import nova_powervm.virt.powervm.disk as disk
|
|
||||||
from nova_powervm.virt.powervm.disk import driver as disk_dvr
|
from nova_powervm.virt.powervm.disk import driver as disk_dvr
|
||||||
|
from nova_powervm.virt.powervm import exception as npvmex
|
||||||
from nova_powervm.virt.powervm import vm
|
from nova_powervm.virt.powervm import vm
|
||||||
|
|
||||||
localdisk_opts = [
|
localdisk_opts = [
|
||||||
@@ -53,11 +53,6 @@ CONF = cfg.CONF
|
|||||||
CONF.register_opts(localdisk_opts)
|
CONF.register_opts(localdisk_opts)
|
||||||
|
|
||||||
|
|
||||||
class VGNotFound(disk.AbstractDiskException):
|
|
||||||
msg_fmt = _("Unable to locate the volume group '%(vg_name)s' for this "
|
|
||||||
"operation.")
|
|
||||||
|
|
||||||
|
|
||||||
class LocalStorage(disk_dvr.DiskAdapter):
|
class LocalStorage(disk_dvr.DiskAdapter):
|
||||||
def __init__(self, connection):
|
def __init__(self, connection):
|
||||||
super(LocalStorage, self).__init__(connection)
|
super(LocalStorage, self).__init__(connection)
|
||||||
@@ -294,7 +289,7 @@ class LocalStorage(disk_dvr.DiskAdapter):
|
|||||||
if name == vol_grp.name:
|
if name == vol_grp.name:
|
||||||
return vios_wrap.uuid, vol_grp.uuid
|
return vios_wrap.uuid, vol_grp.uuid
|
||||||
|
|
||||||
raise VGNotFound(vg_name=name)
|
raise npvmex.VGNotFound(vg_name=name)
|
||||||
|
|
||||||
def _get_vg(self):
|
def _get_vg(self):
|
||||||
vg_rsp = self.adapter.read(
|
vg_rsp = self.adapter.read(
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ import random
|
|||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
import oslo_log.log as logging
|
import oslo_log.log as logging
|
||||||
|
|
||||||
from nova.i18n import _, _LI, _LE
|
from nova.i18n import _LI, _LE
|
||||||
import nova_powervm.virt.powervm.disk as disk
|
|
||||||
from nova_powervm.virt.powervm.disk import driver as disk_drv
|
from nova_powervm.virt.powervm.disk import driver as disk_drv
|
||||||
from nova_powervm.virt.powervm import vm
|
from nova_powervm.virt.powervm import vm
|
||||||
|
|
||||||
@@ -30,6 +29,8 @@ import pypowervm.util as pvm_u
|
|||||||
import pypowervm.wrappers.cluster as pvm_clust
|
import pypowervm.wrappers.cluster as pvm_clust
|
||||||
import pypowervm.wrappers.storage as pvm_stg
|
import pypowervm.wrappers.storage as pvm_stg
|
||||||
|
|
||||||
|
from nova_powervm.virt.powervm import exception as npvmex
|
||||||
|
|
||||||
ssp_opts = [
|
ssp_opts = [
|
||||||
cfg.StrOpt('cluster_name',
|
cfg.StrOpt('cluster_name',
|
||||||
default='',
|
default='',
|
||||||
@@ -44,25 +45,6 @@ CONF = cfg.CONF
|
|||||||
CONF.register_opts(ssp_opts)
|
CONF.register_opts(ssp_opts)
|
||||||
|
|
||||||
|
|
||||||
class ClusterNotFoundByName(disk.AbstractDiskException):
|
|
||||||
msg_fmt = _("Unable to locate the Cluster '%(clust_name)s' for this "
|
|
||||||
"operation.")
|
|
||||||
|
|
||||||
|
|
||||||
class NoConfigNoClusterFound(disk.AbstractDiskException):
|
|
||||||
msg_fmt = _('Unable to locate any Cluster for this operation.')
|
|
||||||
|
|
||||||
|
|
||||||
class TooManyClustersFound(disk.AbstractDiskException):
|
|
||||||
msg_fmt = _("Unexpectedly found %(clust_count)d Clusters "
|
|
||||||
"matching name '%(clust_name)s'.")
|
|
||||||
|
|
||||||
|
|
||||||
class NoConfigTooManyClusters(disk.AbstractDiskException):
|
|
||||||
msg_fmt = _("No cluster_name specified. Refusing to select one of the "
|
|
||||||
"%(clust_count)d Clusters found.")
|
|
||||||
|
|
||||||
|
|
||||||
class SSPDiskAdapter(disk_drv.DiskAdapter):
|
class SSPDiskAdapter(disk_drv.DiskAdapter):
|
||||||
"""Provides a disk adapter for Shared Storage Pools.
|
"""Provides a disk adapter for Shared Storage Pools.
|
||||||
|
|
||||||
@@ -318,19 +300,20 @@ class SSPDiskAdapter(disk_drv.DiskAdapter):
|
|||||||
resp = pvm_clust.Cluster.search(self.adapter, name=clust_name)
|
resp = pvm_clust.Cluster.search(self.adapter, name=clust_name)
|
||||||
wraps = pvm_clust.Cluster.wrap(resp)
|
wraps = pvm_clust.Cluster.wrap(resp)
|
||||||
if len(wraps) == 0:
|
if len(wraps) == 0:
|
||||||
raise ClusterNotFoundByName(clust_name=clust_name)
|
raise npvmex.ClusterNotFoundByName(clust_name=clust_name)
|
||||||
if len(wraps) > 1:
|
if len(wraps) > 1:
|
||||||
raise TooManyClustersFound(clust_count=len(wraps),
|
raise npvmex.TooManyClustersFound(clust_count=len(wraps),
|
||||||
clust_name=clust_name)
|
clust_name=clust_name)
|
||||||
else:
|
else:
|
||||||
# Otherwise, pull the entire feed of Clusters and, if
|
# Otherwise, pull the entire feed of Clusters and, if
|
||||||
# exactly one result, use it.
|
# exactly one result, use it.
|
||||||
resp = self.adapter.read(pvm_clust.Cluster.schema_type)
|
resp = self.adapter.read(pvm_clust.Cluster.schema_type)
|
||||||
wraps = pvm_clust.Cluster.wrap(resp)
|
wraps = pvm_clust.Cluster.wrap(resp)
|
||||||
if len(wraps) == 0:
|
if len(wraps) == 0:
|
||||||
raise NoConfigNoClusterFound()
|
raise npvmex.NoConfigNoClusterFound()
|
||||||
if len(wraps) > 1:
|
if len(wraps) > 1:
|
||||||
raise NoConfigTooManyClusters(clust_count=len(wraps))
|
raise npvmex.NoConfigTooManyClusters(
|
||||||
|
clust_count=len(wraps))
|
||||||
clust_wrap = wraps[0]
|
clust_wrap = wraps[0]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(e.message)
|
LOG.exception(e.message)
|
||||||
|
|||||||
86
nova_powervm/virt/powervm/exception.py
Normal file
86
nova_powervm/virt/powervm/exception.py
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# Copyright 2015 IBM Corp.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""Exceptions specific to the powervm nova driver."""
|
||||||
|
|
||||||
|
import abc
|
||||||
|
from nova import exception as nex
|
||||||
|
from nova.i18n import _
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class AbstractMediaException(nex.NovaException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
|
class AbstractDiskException(nex.NovaException):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NoMediaRepoVolumeGroupFound(AbstractMediaException):
|
||||||
|
msg_fmt = _("Unable to locate the volume group %(vol_grp)s to store the "
|
||||||
|
"virtual optical media within. Unable to create the "
|
||||||
|
"media repository.")
|
||||||
|
|
||||||
|
|
||||||
|
class ManagementPartitionNotFoundException(nex.NovaException):
|
||||||
|
"""Couldn't find exactly one management partition on the system."""
|
||||||
|
msg_fmt = _("Expected to find exactly one management partition; found "
|
||||||
|
"%(count)d.")
|
||||||
|
|
||||||
|
|
||||||
|
class UniqueDiskDiscoveryException(nex.NovaException):
|
||||||
|
"""Expected to discover exactly one disk, but discovered 0 or >1."""
|
||||||
|
msg_fmt = _("Expected to find exactly one disk on the management "
|
||||||
|
"partition at %(path_pattern)s; found %(count)d.")
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceDeletionException(nex.NovaException):
|
||||||
|
"""Expected to delete a disk, but the disk is still present afterward."""
|
||||||
|
msg_fmt = _("Device %(devpath)s is still present on the management "
|
||||||
|
"partition after attempting to delete it.")
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceDiskMappingFailed(AbstractDiskException):
|
||||||
|
msg_fmt = _("Failed to map boot disk of instance %(instance_name)s to "
|
||||||
|
"the management partition from any Virtual I/O Server.")
|
||||||
|
|
||||||
|
|
||||||
|
class VGNotFound(AbstractDiskException):
|
||||||
|
msg_fmt = _("Unable to locate the volume group '%(vg_name)s' for this "
|
||||||
|
"operation.")
|
||||||
|
|
||||||
|
|
||||||
|
class ClusterNotFoundByName(AbstractDiskException):
|
||||||
|
msg_fmt = _("Unable to locate the Cluster '%(clust_name)s' for this "
|
||||||
|
"operation.")
|
||||||
|
|
||||||
|
|
||||||
|
class NoConfigNoClusterFound(AbstractDiskException):
|
||||||
|
msg_fmt = _('Unable to locate any Cluster for this operation.')
|
||||||
|
|
||||||
|
|
||||||
|
class TooManyClustersFound(AbstractDiskException):
|
||||||
|
msg_fmt = _("Unexpectedly found %(clust_count)d Clusters "
|
||||||
|
"matching name '%(clust_name)s'.")
|
||||||
|
|
||||||
|
|
||||||
|
class NoConfigTooManyClusters(AbstractDiskException):
|
||||||
|
msg_fmt = _("No cluster_name specified. Refusing to select one of the "
|
||||||
|
"%(clust_count)d Clusters found.")
|
||||||
@@ -14,10 +14,9 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import abc
|
|
||||||
import copy
|
import copy
|
||||||
from nova.api.metadata import base as instance_metadata
|
from nova.api.metadata import base as instance_metadata
|
||||||
from nova.i18n import _, _LI, _LW
|
from nova.i18n import _LI, _LW
|
||||||
from nova.network import model as network_model
|
from nova.network import model as network_model
|
||||||
from nova.virt import configdrive
|
from nova.virt import configdrive
|
||||||
import os
|
import os
|
||||||
@@ -33,8 +32,7 @@ from pypowervm.wrappers import managed_system as pvm_ms
|
|||||||
from pypowervm.wrappers import storage as pvm_stg
|
from pypowervm.wrappers import storage as pvm_stg
|
||||||
from pypowervm.wrappers import virtual_io_server as pvm_vios
|
from pypowervm.wrappers import virtual_io_server as pvm_vios
|
||||||
|
|
||||||
import six
|
from nova_powervm.virt.powervm import exception as npvmex
|
||||||
|
|
||||||
from nova_powervm.virt.powervm import vm
|
from nova_powervm.virt.powervm import vm
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@@ -42,19 +40,6 @@ LOG = logging.getLogger(__name__)
|
|||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
|
||||||
class AbstractMediaException(Exception):
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
msg = self.msg_fmt % kwargs
|
|
||||||
super(AbstractMediaException, self).__init__(msg)
|
|
||||||
|
|
||||||
|
|
||||||
class NoMediaRepoVolumeGroupFound(AbstractMediaException):
|
|
||||||
msg_fmt = _('Unable to locate the volume group %(vol_grp)s to store the '
|
|
||||||
'virtual optical media within. Unable to create the '
|
|
||||||
'media repository.')
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigDrivePowerVM(object):
|
class ConfigDrivePowerVM(object):
|
||||||
|
|
||||||
_cur_vios_uuid = None
|
_cur_vios_uuid = None
|
||||||
@@ -87,7 +72,7 @@ class ConfigDrivePowerVM(object):
|
|||||||
:param injected_files: A list of file paths that will be injected into
|
:param injected_files: A list of file paths that will be injected into
|
||||||
the ISO.
|
the ISO.
|
||||||
:param network_info: The network_info from the nova spawn method.
|
:param network_info: The network_info from the nova spawn method.
|
||||||
:param admin_password: Optional password to inject for the VM.
|
:param admin_pass: Optional password to inject for the VM.
|
||||||
:return iso_path: The path to the ISO
|
:return iso_path: The path to the ISO
|
||||||
:return file_name: The file name for the ISO
|
:return file_name: The file name for the ISO
|
||||||
"""
|
"""
|
||||||
@@ -242,7 +227,7 @@ class ConfigDrivePowerVM(object):
|
|||||||
# this is user specified, and if it was not found is a proper
|
# this is user specified, and if it was not found is a proper
|
||||||
# exception path.
|
# exception path.
|
||||||
if found_vg is None:
|
if found_vg is None:
|
||||||
raise NoMediaRepoVolumeGroupFound(
|
raise npvmex.NoMediaRepoVolumeGroupFound(
|
||||||
vol_grp=CONF.vopt_media_volume_group)
|
vol_grp=CONF.vopt_media_volume_group)
|
||||||
|
|
||||||
# Ensure that there is a virtual optical media repository within it.
|
# Ensure that there is a virtual optical media repository within it.
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ The PowerVM Nova Compute service runs on the management partition.
|
|||||||
"""
|
"""
|
||||||
import glob
|
import glob
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova.i18n import _, _LI
|
from nova.i18n import _LI
|
||||||
from nova.storage import linuxscsi
|
from nova.storage import linuxscsi
|
||||||
import os
|
import os
|
||||||
from os import path
|
from os import path
|
||||||
@@ -33,19 +33,11 @@ from oslo_log import log as logging
|
|||||||
|
|
||||||
from pypowervm.wrappers import logical_partition as pvm_lpar
|
from pypowervm.wrappers import logical_partition as pvm_lpar
|
||||||
|
|
||||||
|
from nova_powervm.virt.powervm import exception as npvmex
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class UniqueDiskDiscoveryException(Exception):
|
|
||||||
"""Expected to discover exactly one disk, but discovered 0 or >1."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceDeletionException(Exception):
|
|
||||||
"""Expected to delete a disk, but the disk is still present afterward."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def get_mgmt_partition(adapter):
|
def get_mgmt_partition(adapter):
|
||||||
"""Get the LPAR wrapper for this host's management partition.
|
"""Get the LPAR wrapper for this host's management partition.
|
||||||
|
|
||||||
@@ -53,7 +45,7 @@ def get_mgmt_partition(adapter):
|
|||||||
"""
|
"""
|
||||||
wraps = pvm_lpar.LPAR.search(adapter, is_mgmt_partition=True)
|
wraps = pvm_lpar.LPAR.search(adapter, is_mgmt_partition=True)
|
||||||
if len(wraps) != 1:
|
if len(wraps) != 1:
|
||||||
raise Exception(_("Unable to find a single management partition."))
|
raise npvmex.ManagementPartitionNotFoundException(count=len(wraps))
|
||||||
return wraps[0]
|
return wraps[0]
|
||||||
|
|
||||||
|
|
||||||
@@ -97,10 +89,8 @@ def discover_vscsi_disk(mapping):
|
|||||||
dpathpat = '/dev/disk/by-id/*%s' % udid
|
dpathpat = '/dev/disk/by-id/*%s' % udid
|
||||||
disks = glob.glob(dpathpat)
|
disks = glob.glob(dpathpat)
|
||||||
if len(disks) != 1:
|
if len(disks) != 1:
|
||||||
raise UniqueDiskDiscoveryException(
|
raise npvmex.UniqueDiskDiscoveryException(path_pattern=dpathpat,
|
||||||
_("Expected to find exactly one disk on the management partition "
|
count=len(disks))
|
||||||
"at %(path_pattern)s; found %(count)d.") %
|
|
||||||
{'path_pattern': dpathpat, 'count': len(disks)})
|
|
||||||
|
|
||||||
# The by-id path is a symlink. Resolve to the /dev/sdX path
|
# The by-id path is a symlink. Resolve to the /dev/sdX path
|
||||||
dpath = path.realpath(disks[0])
|
dpath = path.realpath(disks[0])
|
||||||
@@ -142,10 +132,7 @@ def remove_block_dev(devpath):
|
|||||||
linuxscsi.echo_scsi_command(delpath, '1')
|
linuxscsi.echo_scsi_command(delpath, '1')
|
||||||
try:
|
try:
|
||||||
os.stat(devpath)
|
os.stat(devpath)
|
||||||
raise DeviceDeletionException(
|
raise npvmex.DeviceDeletionException(devpath=devpath)
|
||||||
_("Device %(devpath)s is still present on the management "
|
|
||||||
"partition after attempting to delete it."),
|
|
||||||
{'devpath': devpath})
|
|
||||||
except OSError:
|
except OSError:
|
||||||
# Device special file is absent, as expected
|
# Device special file is absent, as expected
|
||||||
pass
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user