Merge "Move vbd plug/unplug into session object"
This commit is contained in:
commit
cb380e8172
|
@ -16,6 +16,7 @@
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from nova.tests.virt.xenapi import stubs
|
from nova.tests.virt.xenapi import stubs
|
||||||
|
from nova import utils
|
||||||
from nova.virt.xenapi.client import objects
|
from nova.virt.xenapi.client import objects
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,3 +90,31 @@ class ObjectsTestCase(stubs.XenAPITestBaseNoDB):
|
||||||
pool = objects.Pool(self.session)
|
pool = objects.Pool(self.session)
|
||||||
pool.get_X("ref")
|
pool.get_X("ref")
|
||||||
self.session.call_xenapi.assert_called_once_with("pool.get_X", "ref")
|
self.session.call_xenapi.assert_called_once_with("pool.get_X", "ref")
|
||||||
|
|
||||||
|
|
||||||
|
class VBDTestCase(stubs.XenAPITestBaseNoDB):
|
||||||
|
def setUp(self):
|
||||||
|
super(VBDTestCase, self).setUp()
|
||||||
|
self.session = mock.Mock()
|
||||||
|
self.session.VBD = objects.VBD(self.session)
|
||||||
|
|
||||||
|
def test_plug(self):
|
||||||
|
self.session.VBD.plug("vbd_ref", "vm_ref")
|
||||||
|
self.session.call_xenapi.assert_called_once_with("VBD.plug", "vbd_ref")
|
||||||
|
|
||||||
|
@mock.patch.object(utils, 'synchronized')
|
||||||
|
def test_vbd_plug_check_synchronized(self, mock_synchronized):
|
||||||
|
session = mock.Mock()
|
||||||
|
self.session.VBD.plug("vbd_ref", "vm_ref")
|
||||||
|
mock_synchronized.assert_called_once_with("xenapi-vbd-vm_ref")
|
||||||
|
|
||||||
|
def test_unplug(self):
|
||||||
|
self.session.VBD.unplug("vbd_ref", "vm_ref")
|
||||||
|
self.session.call_xenapi.assert_called_once_with("VBD.unplug",
|
||||||
|
"vbd_ref")
|
||||||
|
|
||||||
|
@mock.patch.object(utils, 'synchronized')
|
||||||
|
def test_vbd_plug_check_synchronized(self, mock_synchronized):
|
||||||
|
session = mock.Mock()
|
||||||
|
self.session.VBD.unplug("vbd_ref", "vm_ref")
|
||||||
|
mock_synchronized.assert_called_once_with("xenapi-vbd-vm_ref")
|
||||||
|
|
|
@ -887,7 +887,7 @@ class CreateVBDTestCase(VMUtilsTestBase):
|
||||||
class UnplugVbdTestCase(VMUtilsTestBase):
|
class UnplugVbdTestCase(VMUtilsTestBase):
|
||||||
@mock.patch.object(greenthread, 'sleep')
|
@mock.patch.object(greenthread, 'sleep')
|
||||||
def test_unplug_vbd_works(self, mock_sleep):
|
def test_unplug_vbd_works(self, mock_sleep):
|
||||||
session = mock.Mock()
|
session = _get_fake_session()
|
||||||
vbd_ref = "vbd_ref"
|
vbd_ref = "vbd_ref"
|
||||||
vm_ref = 'vm_ref'
|
vm_ref = 'vm_ref'
|
||||||
|
|
||||||
|
@ -897,7 +897,7 @@ class UnplugVbdTestCase(VMUtilsTestBase):
|
||||||
self.assertEqual(0, mock_sleep.call_count)
|
self.assertEqual(0, mock_sleep.call_count)
|
||||||
|
|
||||||
def test_unplug_vbd_raises_unexpected_error(self):
|
def test_unplug_vbd_raises_unexpected_error(self):
|
||||||
session = mock.Mock()
|
session = _get_fake_session()
|
||||||
vbd_ref = "vbd_ref"
|
vbd_ref = "vbd_ref"
|
||||||
vm_ref = 'vm_ref'
|
vm_ref = 'vm_ref'
|
||||||
session.call_xenapi.side_effect = test.TestingException()
|
session.call_xenapi.side_effect = test.TestingException()
|
||||||
|
@ -1742,16 +1742,13 @@ class VDIAttachedHere(VMUtilsTestBase):
|
||||||
@mock.patch.object(vm_utils, 'destroy_vbd')
|
@mock.patch.object(vm_utils, 'destroy_vbd')
|
||||||
@mock.patch.object(vm_utils, '_get_this_vm_ref')
|
@mock.patch.object(vm_utils, '_get_this_vm_ref')
|
||||||
@mock.patch.object(vm_utils, 'create_vbd')
|
@mock.patch.object(vm_utils, 'create_vbd')
|
||||||
@mock.patch.object(volume_utils, 'vbd_plug')
|
|
||||||
@mock.patch.object(vm_utils, '_remap_vbd_dev')
|
@mock.patch.object(vm_utils, '_remap_vbd_dev')
|
||||||
@mock.patch.object(vm_utils, '_wait_for_device')
|
@mock.patch.object(vm_utils, '_wait_for_device')
|
||||||
@mock.patch.object(utils, 'execute')
|
@mock.patch.object(utils, 'execute')
|
||||||
@mock.patch.object(vm_utils, 'unplug_vbd')
|
def test_sync_called(self, mock_execute, mock_wait_for_device,
|
||||||
def test_sync_called(self, mock_unplug_vbd, mock_execute,
|
mock_remap_vbd_dev, mock_create_vbd,
|
||||||
mock_wait_for_device, mock_remap_vbd_dev,
|
|
||||||
mock_vbd_plug, mock_create_vbd,
|
|
||||||
mock_get_this_vm_ref, mock_destroy_vbd):
|
mock_get_this_vm_ref, mock_destroy_vbd):
|
||||||
session = mock.Mock()
|
session = _get_fake_session()
|
||||||
with vm_utils.vdi_attached_here(session, 'vdi_ref'):
|
with vm_utils.vdi_attached_here(session, 'vdi_ref'):
|
||||||
pass
|
pass
|
||||||
mock_execute.assert_called_with('sync', run_as_root=True)
|
mock_execute.assert_called_with('sync', run_as_root=True)
|
||||||
|
|
|
@ -18,34 +18,9 @@ import mock
|
||||||
from eventlet import greenthread
|
from eventlet import greenthread
|
||||||
|
|
||||||
from nova.tests.virt.xenapi import stubs
|
from nova.tests.virt.xenapi import stubs
|
||||||
from nova import utils
|
|
||||||
from nova.virt.xenapi import volume_utils
|
from nova.virt.xenapi import volume_utils
|
||||||
|
|
||||||
|
|
||||||
class CallXenAPIHelpersTestCase(stubs.XenAPITestBaseNoDB):
|
|
||||||
def test_vbd_plug(self):
|
|
||||||
session = mock.Mock()
|
|
||||||
volume_utils.vbd_plug(session, "vbd_ref", "vm_ref:123")
|
|
||||||
session.call_xenapi.assert_called_once_with("VBD.plug", "vbd_ref")
|
|
||||||
|
|
||||||
@mock.patch.object(utils, 'synchronized')
|
|
||||||
def test_vbd_plug_check_synchronized(self, mock_synchronized):
|
|
||||||
session = mock.Mock()
|
|
||||||
volume_utils.vbd_plug(session, "vbd_ref", "vm_ref:123")
|
|
||||||
mock_synchronized.assert_called_once_with("xenapi-events-vm_ref:123")
|
|
||||||
|
|
||||||
def test_vbd_unplug(self):
|
|
||||||
session = mock.Mock()
|
|
||||||
volume_utils.vbd_unplug(session, "vbd_ref", "vm_ref:123")
|
|
||||||
session.call_xenapi.assert_called_once_with("VBD.unplug", "vbd_ref")
|
|
||||||
|
|
||||||
@mock.patch.object(utils, 'synchronized')
|
|
||||||
def test_vbd_unplug_check_synchronized(self, mock_synchronized):
|
|
||||||
session = mock.Mock()
|
|
||||||
volume_utils.vbd_unplug(session, "vbd_ref", "vm_ref:123")
|
|
||||||
mock_synchronized.assert_called_once_with("xenapi-events-vm_ref:123")
|
|
||||||
|
|
||||||
|
|
||||||
class SROps(stubs.XenAPITestBaseNoDB):
|
class SROps(stubs.XenAPITestBaseNoDB):
|
||||||
def test_find_sr_valid_uuid(self):
|
def test_find_sr_valid_uuid(self):
|
||||||
self.session = mock.Mock()
|
self.session = mock.Mock()
|
||||||
|
|
|
@ -128,6 +128,7 @@ class VolumeAttachTestCase(test.NoDBTestCase):
|
||||||
self.mox.StubOutWithMock(volumeops.volume_utils, 'introduce_vdi')
|
self.mox.StubOutWithMock(volumeops.volume_utils, 'introduce_vdi')
|
||||||
self.mox.StubOutWithMock(volumeops.vm_utils, 'create_vbd')
|
self.mox.StubOutWithMock(volumeops.vm_utils, 'create_vbd')
|
||||||
self.mox.StubOutWithMock(volumeops.vm_utils, 'is_vm_shutdown')
|
self.mox.StubOutWithMock(volumeops.vm_utils, 'is_vm_shutdown')
|
||||||
|
self.mox.StubOutWithMock(ops._session.VBD, 'plug')
|
||||||
self.mox.StubOutWithMock(ops._session, 'call_xenapi')
|
self.mox.StubOutWithMock(ops._session, 'call_xenapi')
|
||||||
|
|
||||||
instance_name = 'instance_1'
|
instance_name = 'instance_1'
|
||||||
|
@ -159,7 +160,7 @@ class VolumeAttachTestCase(test.NoDBTestCase):
|
||||||
volumeops.vm_utils.is_vm_shutdown(session,
|
volumeops.vm_utils.is_vm_shutdown(session,
|
||||||
vm_ref).AndReturn(not vm_running)
|
vm_ref).AndReturn(not vm_running)
|
||||||
if plugged:
|
if plugged:
|
||||||
ops._session.call_xenapi("VBD.plug", vbd_ref)
|
ops._session.VBD.plug(vbd_ref, vm_ref)
|
||||||
ops._session.call_xenapi("VDI.get_uuid",
|
ops._session.call_xenapi("VDI.get_uuid",
|
||||||
vdi_ref).AndReturn(vdi_uuid)
|
vdi_ref).AndReturn(vdi_uuid)
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from nova import utils
|
||||||
|
|
||||||
|
|
||||||
class XenAPISessionObject(object):
|
class XenAPISessionObject(object):
|
||||||
"""Wrapper to make calling and mocking the session easier
|
"""Wrapper to make calling and mocking the session easier
|
||||||
|
@ -71,6 +73,26 @@ class VBD(XenAPISessionObject):
|
||||||
def __init__(self, session):
|
def __init__(self, session):
|
||||||
super(VBD, self).__init__(session, "VBD")
|
super(VBD, self).__init__(session, "VBD")
|
||||||
|
|
||||||
|
def plug(self, vbd_ref, vm_ref):
|
||||||
|
@utils.synchronized('xenapi-vbd-' + vm_ref)
|
||||||
|
def synchronized_plug():
|
||||||
|
self._call_method("plug", vbd_ref)
|
||||||
|
|
||||||
|
# NOTE(johngarbutt) we need to ensure there is only ever one
|
||||||
|
# VBD.unplug or VBD.plug happening at once per VM
|
||||||
|
# due to a bug in XenServer 6.1 and 6.2
|
||||||
|
synchronized_plug()
|
||||||
|
|
||||||
|
def unplug(self, vbd_ref, vm_ref):
|
||||||
|
@utils.synchronized('xenapi-vbd-' + vm_ref)
|
||||||
|
def synchronized_unplug():
|
||||||
|
self._call_method("unplug", vbd_ref)
|
||||||
|
|
||||||
|
# NOTE(johngarbutt) we need to ensure there is only ever one
|
||||||
|
# VBD.unplug or VBD.plug happening at once per VM
|
||||||
|
# due to a bug in XenServer 6.1 and 6.2
|
||||||
|
synchronized_unplug()
|
||||||
|
|
||||||
|
|
||||||
class VDI(XenAPISessionObject):
|
class VDI(XenAPISessionObject):
|
||||||
"""Virtual disk image."""
|
"""Virtual disk image."""
|
||||||
|
|
|
@ -63,6 +63,7 @@ from nova.openstack.common import jsonutils
|
||||||
from nova.openstack.common import log as logging
|
from nova.openstack.common import log as logging
|
||||||
from nova.openstack.common import timeutils
|
from nova.openstack.common import timeutils
|
||||||
from nova.openstack.common import units
|
from nova.openstack.common import units
|
||||||
|
from nova.virt.xenapi.client import session as xenapi_session
|
||||||
|
|
||||||
|
|
||||||
_CLASSES = ['host', 'network', 'session', 'pool', 'SR', 'VBD',
|
_CLASSES = ['host', 'network', 'session', 'pool', 'SR', 'VBD',
|
||||||
|
@ -472,6 +473,7 @@ class SessionBase(object):
|
||||||
|
|
||||||
def __init__(self, uri):
|
def __init__(self, uri):
|
||||||
self._session = None
|
self._session = None
|
||||||
|
xenapi_session.apply_session_helpers(self)
|
||||||
|
|
||||||
def pool_get_default_SR(self, _1, pool_ref):
|
def pool_get_default_SR(self, _1, pool_ref):
|
||||||
return _db_content['pool'].values()[0]['default-SR']
|
return _db_content['pool'].values()[0]['default-SR']
|
||||||
|
|
|
@ -426,7 +426,7 @@ def unplug_vbd(session, vbd_ref, this_vm_ref):
|
||||||
if num_attempt > 1:
|
if num_attempt > 1:
|
||||||
greenthread.sleep(1)
|
greenthread.sleep(1)
|
||||||
|
|
||||||
volume_utils.vbd_unplug(session, vbd_ref, this_vm_ref)
|
session.VBD.unplug(vbd_ref, this_vm_ref)
|
||||||
return
|
return
|
||||||
except session.XenAPI.Failure as exc:
|
except session.XenAPI.Failure as exc:
|
||||||
err = len(exc.details) > 0 and exc.details[0]
|
err = len(exc.details) > 0 and exc.details[0]
|
||||||
|
@ -2186,7 +2186,7 @@ def vdi_attached_here(session, vdi_ref, read_only=False):
|
||||||
read_only=read_only, bootable=False)
|
read_only=read_only, bootable=False)
|
||||||
try:
|
try:
|
||||||
LOG.debug(_('Plugging VBD %s ... '), vbd_ref)
|
LOG.debug(_('Plugging VBD %s ... '), vbd_ref)
|
||||||
volume_utils.vbd_plug(session, vbd_ref, this_vm_ref)
|
session.VBD.plug(vbd_ref, this_vm_ref)
|
||||||
try:
|
try:
|
||||||
LOG.debug(_('Plugging VBD %s done.'), vbd_ref)
|
LOG.debug(_('Plugging VBD %s done.'), vbd_ref)
|
||||||
orig_dev = session.call_xenapi("VBD.get_device", vbd_ref)
|
orig_dev = session.call_xenapi("VBD.get_device", vbd_ref)
|
||||||
|
|
|
@ -26,7 +26,6 @@ from oslo.config import cfg
|
||||||
|
|
||||||
from nova.openstack.common.gettextutils import _
|
from nova.openstack.common.gettextutils import _
|
||||||
from nova.openstack.common import log as logging
|
from nova.openstack.common import log as logging
|
||||||
from nova import utils
|
|
||||||
|
|
||||||
xenapi_volume_utils_opts = [
|
xenapi_volume_utils_opts = [
|
||||||
cfg.IntOpt('introduce_vdi_retry_wait',
|
cfg.IntOpt('introduce_vdi_retry_wait',
|
||||||
|
@ -312,23 +311,3 @@ def _get_target_port(iscsi_string):
|
||||||
return iscsi_string.split(':')[1]
|
return iscsi_string.split(':')[1]
|
||||||
|
|
||||||
return CONF.xenserver.target_port
|
return CONF.xenserver.target_port
|
||||||
|
|
||||||
|
|
||||||
def vbd_plug(session, vbd_ref, vm_ref):
|
|
||||||
@utils.synchronized('xenapi-events-' + vm_ref)
|
|
||||||
def synchronized_plug():
|
|
||||||
session.call_xenapi("VBD.plug", vbd_ref)
|
|
||||||
|
|
||||||
# NOTE(johngarbutt) we need to ensure there is only ever one VBD.plug
|
|
||||||
# happening at once per VM due to a bug in XenServer 6.1 and 6.2
|
|
||||||
synchronized_plug()
|
|
||||||
|
|
||||||
|
|
||||||
def vbd_unplug(session, vbd_ref, vm_ref):
|
|
||||||
@utils.synchronized('xenapi-events-' + vm_ref)
|
|
||||||
def synchronized_unplug():
|
|
||||||
session.call_xenapi("VBD.unplug", vbd_ref)
|
|
||||||
|
|
||||||
# NOTE(johngarbutt) we need to ensure there is only ever one VBD.unplug
|
|
||||||
# happening at once per VM due to a bug in XenServer 6.1 and 6.2
|
|
||||||
synchronized_unplug()
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ class VolumeOps(object):
|
||||||
|
|
||||||
running = not vm_utils.is_vm_shutdown(self._session, vm_ref)
|
running = not vm_utils.is_vm_shutdown(self._session, vm_ref)
|
||||||
if hotplug and running:
|
if hotplug and running:
|
||||||
volume_utils.vbd_plug(self._session, vbd_ref, vm_ref)
|
self._session.VBD.plug(vbd_ref, vm_ref)
|
||||||
|
|
||||||
vdi_uuid = self._session.call_xenapi("VDI.get_uuid", vdi_ref)
|
vdi_uuid = self._session.call_xenapi("VDI.get_uuid", vdi_ref)
|
||||||
return (sr_uuid, vdi_uuid)
|
return (sr_uuid, vdi_uuid)
|
||||||
|
|
Loading…
Reference in New Issue