HttpError=>VirtualInterface(Unp|P)lugException

With this change set, the top-level vif driver plug/unplug methods trap
HttpError (typically a 400 or 500) and convert it to the standard
VirtualInterfacePlugException/VirtualInterfaceUnplugException from
nova.exception.

This change set also gets rid of the VirtualInterfaceUnplugException in
vif.py and tasks/network.py, replacing their invocations with the
corresponding nova.exception class.

Change-Id: Iad1197218cb8d8a260c00d55c9addd39ac3a6226
This commit is contained in:
Eric Fried
2016-09-02 08:35:20 -05:00
parent 7aa585c69c
commit 7e30cb43ea
4 changed files with 38 additions and 22 deletions

View File

@@ -94,7 +94,7 @@ class TestNetwork(test.TestCase):
# Run method
p_vifs = tf_net.UnplugVifs(self.apt, inst, mock.Mock(), 'host_uuid',
'slot_mgr')
self.assertRaises(tf_net.VirtualInterfaceUnplugException,
self.assertRaises(exception.VirtualInterfaceUnplugException,
p_vifs.execute, self.mock_lpar_wrap)
@mock.patch('nova_powervm.virt.powervm.vif.plug')

View File

@@ -18,6 +18,7 @@ import mock
from nova import exception
from nova import test
from pypowervm import exceptions as pvm_ex
from pypowervm.tests import test_fixtures as pvm_fx
from pypowervm import util as pvm_util
from pypowervm.wrappers import logical_partition as pvm_lpar
@@ -111,6 +112,24 @@ class TestVifFunctions(test.TestCase):
'vif', cna_w_list='cnalist')
slot_mgr.drop_vnet.assert_not_called()
@mock.patch('nova_powervm.virt.powervm.vif._build_vif_driver')
def test_plug_raises(self, mock_vif_drv):
"""HttpError is converted to VirtualInterfacePlugException."""
vif_drv = mock.Mock(plug=mock.Mock(side_effect=pvm_ex.HttpError(
resp=mock.Mock(status='status', reqmethod='method', reqpath='path',
reason='reason'))))
mock_vif_drv.return_value = vif_drv
mock_slot_mgr = mock.Mock()
mock_vif = {'address': 'vifaddr'}
self.assertRaises(exception.VirtualInterfacePlugException,
vif.plug, 'adap', 'huuid', 'inst', mock_vif,
mock_slot_mgr, new_vif='new_vif')
mock_vif_drv.assert_called_once_with('adap', 'huuid', 'inst', mock_vif)
vif_drv.plug.assert_called_once_with(
mock_vif, mock_slot_mgr.build_map.get_vea_slot.return_value,
new_vif='new_vif')
mock_slot_mgr.build_map.get_vea_slot.assert_called_once_with('vifaddr')
@mock.patch('pypowervm.wrappers.network.VSwitch.search')
def test_get_secure_rmc_vswitch(self, mock_search):
# Test no data coming back gets none

View File

@@ -23,7 +23,6 @@ from oslo_log import log as logging
from pypowervm.wrappers import network as pvm_net
from nova_powervm import conf as cfg
from nova_powervm.virt.powervm.i18n import _
from nova_powervm.virt.powervm.i18n import _LE
from nova_powervm.virt.powervm.i18n import _LI
from nova_powervm.virt.powervm.i18n import _LW
@@ -35,14 +34,6 @@ LOG = logging.getLogger(__name__)
CONF = cfg.CONF
class VirtualInterfaceUnplugException(exception.NovaException):
"""Indicates that a VIF unplug failed."""
# TODO(thorst) symmetrical to the exception in base Nova. Evaluate
# moving to Nova core.
msg_fmt = _("Virtual interface unplug failed")
class UnplugVifs(pvm_task.PowerVMTask):
"""The task to unplug Virtual Network Interfaces from a VM."""
@@ -77,7 +68,7 @@ class UnplugVifs(pvm_task.PowerVMTask):
'The reason reported by the system is: %(reason)s'),
{'inst': self.instance.name, 'reason': reason},
instance=self.instance)
raise VirtualInterfaceUnplugException()
raise exception.VirtualInterfaceUnplugException(reason=reason)
# Get all the current Client Network Adapters (CNA) on the VM itself.
cna_w_list = vm.get_cnas(self.adapter, self.instance)

View File

@@ -25,6 +25,7 @@ from nova import utils
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_utils import importutils
from pypowervm import exceptions as pvm_ex
from pypowervm.tasks import cna as pvm_cna
from pypowervm.tasks import partition as pvm_par
from pypowervm.tasks import sriov as sriovtask
@@ -54,13 +55,6 @@ VIF_MAPPING = {'pvm_sea': 'nova_powervm.virt.powervm.vif.PvmSeaVifDriver',
CONF = cfg.CONF
class VirtualInterfaceUnplugException(exception.NovaException):
"""Indicates that a VIF unplug failed."""
# TODO(thorst) symmetrical to the exception in base Nova. Evaluate
# moving to Nova core.
msg_fmt = _("Virtual interface unplug failed")
def _build_vif_driver(adapter, host_uuid, instance, vif):
"""Returns the appropriate VIF Driver for the given VIF.
@@ -110,7 +104,14 @@ def plug(adapter, host_uuid, instance, vif, slot_mgr, new_vif=True):
slot_num = slot_mgr.build_map.get_vea_slot(vif['address'])
# Invoke the plug
vnet_w = vif_drv.plug(vif, slot_num, new_vif=new_vif)
try:
vnet_w = vif_drv.plug(vif, slot_num, new_vif=new_vif)
except pvm_ex.HttpError as he:
# Log the message constructed by HttpError
LOG.exception(he.args[0])
raise exception.VirtualInterfacePlugException()
# Other exceptions are (hopefully) custom VirtualInterfacePlugException
# generated lower in the call stack.
# If the slot number hadn't been provided initially, save it for the
# next rebuild
@@ -134,7 +135,13 @@ def unplug(adapter, host_uuid, instance, vif, slot_mgr, cna_w_list=None):
allows for an improvement in operation speed.
"""
vif_drv = _build_vif_driver(adapter, host_uuid, instance, vif)
vnet_w = vif_drv.unplug(vif, cna_w_list=cna_w_list)
try:
vnet_w = vif_drv.unplug(vif, cna_w_list=cna_w_list)
except pvm_ex.HttpError as he:
# Log the message constructed by HttpError
LOG.exception(he.args[0])
raise exception.VirtualInterfaceUnplugException(reason=he.args[0])
if vnet_w:
slot_mgr.drop_vnet(vnet_w)
@@ -274,8 +281,7 @@ class PvmVifDriver(object):
LOG.error(_LE('Unable to unplug VIF with mac %(mac)s for instance '
'%(inst)s.'), {'mac': vif['address'],
'inst': self.instance.name})
LOG.exception(e)
raise VirtualInterfaceUnplugException()
raise exception.VirtualInterfaceUnplugException(reason=e.args[0])
return cna_w
def _find_cna_for_vif(self, cna_w_list, vif):