XenAPI Use os-xenapi lib for nova
XenServer has released os-xenapi lib on pypi, this patch is to use os-xenapi in nova project. In this patch, we only change the usage of XenAPI to os-xenapi and fix unit tests. In the next patch, we will delete those unused files. Partially-Implements: blueprint add-os-xenapi-library Depends-On: Ic327135b893a77672fd42af919f47f181e932773 Change-Id: I424dfcd507c4b7fbeea5245cc1c234dec01d5781
This commit is contained in:
parent
8e3e9f6d2d
commit
062065ca9e
@ -14,12 +14,12 @@
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
from os_xenapi import client
|
||||
import six
|
||||
|
||||
from nova import context
|
||||
from nova import test
|
||||
from nova.tests.unit.virt.xenapi import stubs
|
||||
from nova.virt.xenapi import client
|
||||
from nova.virt.xenapi import driver as xenapi_conn
|
||||
from nova.virt.xenapi import fake
|
||||
from nova.virt.xenapi.image import bittorrent
|
||||
|
@ -18,7 +18,7 @@ import time
|
||||
|
||||
import mock
|
||||
from mox3 import mox
|
||||
from oslo_log import log as logging
|
||||
from os_xenapi.client import XenAPI
|
||||
|
||||
from nova.compute import utils as compute_utils
|
||||
from nova import context
|
||||
@ -93,9 +93,7 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
||||
@mock.patch.object(random, 'shuffle')
|
||||
@mock.patch.object(time, 'sleep')
|
||||
@mock.patch.object(compute_utils, 'add_instance_fault_from_exc')
|
||||
@mock.patch.object(logging.getLogger('nova.virt.xenapi.client.session'),
|
||||
'debug')
|
||||
def test_download_image_retry(self, mock_log_debug, mock_fault, mock_sleep,
|
||||
def test_download_image_retry(self, mock_fault, mock_sleep,
|
||||
mock_shuffle, mock_make_uuid_stack):
|
||||
params = self._get_download_params()
|
||||
self.flags(num_retries=2, group='glance')
|
||||
@ -107,16 +105,6 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
||||
mock.call('glance.py', 'download_vhd2',
|
||||
endpoint='http://10.0.0.1:9293',
|
||||
**params)]
|
||||
log_calls = [mock.call(mock.ANY,
|
||||
{'callback_result': 'http://10.0.1.1:9292',
|
||||
'attempts': 3, 'attempt': 1,
|
||||
'fn': 'download_vhd2',
|
||||
'plugin': 'glance.py'}),
|
||||
mock.call(mock.ANY,
|
||||
{'callback_result': 'http://10.0.0.1:9293',
|
||||
'attempts': 3, 'attempt': 2,
|
||||
'fn': 'download_vhd2',
|
||||
'plugin': 'glance.py'})]
|
||||
|
||||
glance_api_servers = ['10.0.1.1:9292',
|
||||
'http://10.0.0.1:9293']
|
||||
@ -132,7 +120,6 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
||||
self.instance, 'fake_image_uuid')
|
||||
|
||||
mock_call_plugin_serialized.assert_has_calls(calls)
|
||||
mock_log_debug.assert_has_calls(log_calls, any_order=True)
|
||||
|
||||
self.assertEqual(1, mock_fault.call_count)
|
||||
|
||||
@ -197,21 +184,21 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
||||
self.session.call_plugin_serialized('glance.py', 'upload_vhd2',
|
||||
**params).AndRaise(error)
|
||||
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
||||
error, (fake.Failure,
|
||||
error, (XenAPI.Failure,
|
||||
error,
|
||||
mox.IgnoreArg()))
|
||||
time.sleep(0.5)
|
||||
self.session.call_plugin_serialized('glance.py', 'upload_vhd2',
|
||||
**params).AndRaise(error)
|
||||
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
||||
error, (fake.Failure,
|
||||
error, (XenAPI.Failure,
|
||||
error,
|
||||
mox.IgnoreArg()))
|
||||
time.sleep(1)
|
||||
self.session.call_plugin_serialized('glance.py', 'upload_vhd2',
|
||||
**params).AndRaise(error)
|
||||
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
||||
error, (fake.Failure,
|
||||
error, (XenAPI.Failure,
|
||||
error,
|
||||
mox.IgnoreArg()))
|
||||
self.mox.ReplayAll()
|
||||
@ -234,7 +221,7 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
||||
self.session.call_plugin_serialized('glance.py', 'upload_vhd2',
|
||||
**params).AndRaise(error)
|
||||
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
||||
error, (fake.Failure,
|
||||
error, (XenAPI.Failure,
|
||||
error,
|
||||
mox.IgnoreArg()))
|
||||
time.sleep(0.5)
|
||||
@ -244,7 +231,7 @@ class TestGlanceStore(stubs.XenAPITestBaseNoDB):
|
||||
self.session.call_plugin_serialized('glance.py', 'upload_vhd2',
|
||||
**params).AndRaise(error)
|
||||
compute_utils.add_instance_fault_from_exc(self.context, self.instance,
|
||||
error, (fake.Failure,
|
||||
error, (XenAPI.Failure,
|
||||
error,
|
||||
mox.IgnoreArg()))
|
||||
time.sleep(1)
|
||||
|
@ -17,11 +17,11 @@ import contextlib
|
||||
import tarfile
|
||||
|
||||
import eventlet
|
||||
from os_xenapi.client import session as xenapi_session
|
||||
import six
|
||||
|
||||
from nova.image import glance
|
||||
from nova import test
|
||||
from nova.virt.xenapi.client import session as xenapi_session
|
||||
from nova.virt.xenapi.image import vdi_through_dev
|
||||
|
||||
|
||||
|
@ -19,12 +19,13 @@ import sys
|
||||
|
||||
import fixtures
|
||||
import mock
|
||||
from os_xenapi.client import session
|
||||
from os_xenapi.client import XenAPI
|
||||
from oslo_serialization import jsonutils
|
||||
import six
|
||||
|
||||
from nova import test
|
||||
import nova.tests.unit.image.fake
|
||||
from nova.virt.xenapi.client import session
|
||||
from nova.virt.xenapi import fake
|
||||
from nova.virt.xenapi import vm_utils
|
||||
from nova.virt.xenapi import vmops
|
||||
@ -121,7 +122,7 @@ def stubout_fetch_disk_image(stubs, raise_failure=False):
|
||||
def _fake_fetch_disk_image(context, session, instance, name_label, image,
|
||||
image_type):
|
||||
if raise_failure:
|
||||
raise fake.Failure("Test Exception raised by "
|
||||
raise XenAPI.Failure("Test Exception raised by "
|
||||
"fake fetch_image_glance_disk")
|
||||
elif image_type == vm_utils.ImageType.KERNEL:
|
||||
filename = "kernel"
|
||||
@ -140,7 +141,7 @@ def stubout_create_vm(stubs):
|
||||
"""Simulates a failure in create_vm."""
|
||||
|
||||
def f(*args):
|
||||
raise fake.Failure("Test Exception raised by fake create_vm")
|
||||
raise XenAPI.Failure("Test Exception raised by fake create_vm")
|
||||
stubs.Set(vm_utils, 'create_vm', f)
|
||||
|
||||
|
||||
@ -148,7 +149,7 @@ def stubout_attach_disks(stubs):
|
||||
"""Simulates a failure in _attach_disks."""
|
||||
|
||||
def f(*args):
|
||||
raise fake.Failure("Test Exception raised by fake _attach_disks")
|
||||
raise XenAPI.Failure("Test Exception raised by fake _attach_disks")
|
||||
stubs.Set(vmops.VMOps, '_attach_disks', f)
|
||||
|
||||
|
||||
@ -187,7 +188,7 @@ class FakeSessionForVMTests(fake.SessionBase):
|
||||
def VM_start(self, _1, ref, _2, _3):
|
||||
vm = fake.get_record('VM', ref)
|
||||
if vm['power_state'] != 'Halted':
|
||||
raise fake.Failure(['VM_BAD_POWER_STATE', ref, 'Halted',
|
||||
raise XenAPI.Failure(['VM_BAD_POWER_STATE', ref, 'Halted',
|
||||
vm['power_state']])
|
||||
vm['power_state'] = 'Running'
|
||||
vm['is_a_template'] = False
|
||||
@ -302,7 +303,7 @@ class FakeSessionForVolumeTests(fake.SessionBase):
|
||||
if rec['uuid'] == uuid:
|
||||
valid_vdi = True
|
||||
if not valid_vdi:
|
||||
raise fake.Failure([['INVALID_VDI', 'session', self._session]])
|
||||
raise XenAPI.Failure([['INVALID_VDI', 'session', self._session]])
|
||||
|
||||
|
||||
class FakeSessionForVolumeFailedTests(FakeSessionForVolumeTests):
|
||||
@ -310,7 +311,7 @@ class FakeSessionForVolumeFailedTests(FakeSessionForVolumeTests):
|
||||
def VDI_introduce(self, _1, uuid, _2, _3, _4, _5,
|
||||
_6, _7, _8, _9, _10, _11):
|
||||
# This is for testing failure
|
||||
raise fake.Failure([['INVALID_VDI', 'session', self._session]])
|
||||
raise XenAPI.Failure([['INVALID_VDI', 'session', self._session]])
|
||||
|
||||
def PBD_unplug(self, _1, ref):
|
||||
rec = fake.get_record('PBD', ref)
|
||||
@ -367,14 +368,14 @@ def stub_out_migration_methods(stubs):
|
||||
class FakeSessionForFailedMigrateTests(FakeSessionForVMTests):
|
||||
def VM_assert_can_migrate(self, session, vmref, migrate_data,
|
||||
live, vdi_map, vif_map, options):
|
||||
raise fake.Failure("XenAPI VM.assert_can_migrate failed")
|
||||
raise XenAPI.Failure("XenAPI VM.assert_can_migrate failed")
|
||||
|
||||
def host_migrate_receive(self, session, hostref, networkref, options):
|
||||
raise fake.Failure("XenAPI host.migrate_receive failed")
|
||||
raise XenAPI.Failure("XenAPI host.migrate_receive failed")
|
||||
|
||||
def VM_migrate_send(self, session, vmref, migrate_data, islive, vdi_map,
|
||||
vif_map, options):
|
||||
raise fake.Failure("XenAPI VM.migrate_send failed")
|
||||
raise XenAPI.Failure("XenAPI VM.migrate_send failed")
|
||||
|
||||
|
||||
def get_fake_session(error=None):
|
||||
|
@ -18,11 +18,11 @@ import time
|
||||
import uuid
|
||||
|
||||
import mock
|
||||
from os_xenapi.client import XenAPI
|
||||
|
||||
from nova import exception
|
||||
from nova import test
|
||||
from nova.virt.xenapi import agent
|
||||
from nova.virt.xenapi import fake as xenapi_fake
|
||||
|
||||
|
||||
def _get_fake_instance(**kwargs):
|
||||
@ -369,7 +369,7 @@ class CallAgentTestCase(AgentTestCaseBase):
|
||||
def _call_agent_setup(self, session, mock_uuid,
|
||||
returncode='0', success_codes=None,
|
||||
exception=None):
|
||||
session.XenAPI.Failure = xenapi_fake.Failure
|
||||
session.XenAPI.Failure = XenAPI.Failure
|
||||
instance = {"uuid": "fake"}
|
||||
|
||||
session.VM.get_domid.return_value = "42"
|
||||
@ -402,7 +402,7 @@ class CallAgentTestCase(AgentTestCaseBase):
|
||||
session = mock.Mock()
|
||||
self.assertRaises(exception.AgentTimeout, self._call_agent_setup,
|
||||
session, mock_uuid,
|
||||
exception=xenapi_fake.Failure(["TIMEOUT:fake"]))
|
||||
exception=XenAPI.Failure(["TIMEOUT:fake"]))
|
||||
self._assert_agent_called(session, mock_uuid)
|
||||
|
||||
def test_call_agent_fails_with_not_implemented(self, mock_uuid):
|
||||
@ -410,14 +410,14 @@ class CallAgentTestCase(AgentTestCaseBase):
|
||||
self.assertRaises(exception.AgentNotImplemented,
|
||||
self._call_agent_setup,
|
||||
session, mock_uuid,
|
||||
exception=xenapi_fake.Failure(["NOT IMPLEMENTED:"]))
|
||||
exception=XenAPI.Failure(["NOT IMPLEMENTED:"]))
|
||||
self._assert_agent_called(session, mock_uuid)
|
||||
|
||||
def test_call_agent_fails_with_other_error(self, mock_uuid):
|
||||
session = mock.Mock()
|
||||
self.assertRaises(exception.AgentError, self._call_agent_setup,
|
||||
session, mock_uuid,
|
||||
exception=xenapi_fake.Failure(["asdf"]))
|
||||
exception=XenAPI.Failure(["asdf"]))
|
||||
self._assert_agent_called(session, mock_uuid)
|
||||
|
||||
def test_call_agent_fails_with_returned_error(self, mock_uuid):
|
||||
|
@ -22,6 +22,7 @@ except ImportError:
|
||||
|
||||
from eventlet import greenthread
|
||||
import mock
|
||||
from os_xenapi.client import session as xenapi_session
|
||||
|
||||
from nova.compute import power_state
|
||||
from nova.compute import task_states
|
||||
@ -38,7 +39,6 @@ from nova.tests import uuidsentinel as uuids
|
||||
from nova import utils
|
||||
from nova.virt import fake
|
||||
from nova.virt.xenapi import agent as xenapi_agent
|
||||
from nova.virt.xenapi.client import session as xenapi_session
|
||||
from nova.virt.xenapi import fake as xenapi_fake
|
||||
from nova.virt.xenapi import vm_utils
|
||||
from nova.virt.xenapi import vmops
|
||||
|
@ -24,6 +24,8 @@ import re
|
||||
|
||||
import mock
|
||||
from mox3 import mox
|
||||
from os_xenapi.client import session as xenapi_session
|
||||
from os_xenapi.client import XenAPI
|
||||
from oslo_concurrency import lockutils
|
||||
from oslo_config import fixture as config_fixture
|
||||
from oslo_log import log as logging
|
||||
@ -62,7 +64,6 @@ from nova.tests.unit.virt.xenapi import stubs
|
||||
from nova.tests import uuidsentinel as uuids
|
||||
from nova.virt import fake
|
||||
from nova.virt.xenapi import agent
|
||||
from nova.virt.xenapi.client import session as xenapi_session
|
||||
from nova.virt.xenapi import driver as xenapi_conn
|
||||
from nova.virt.xenapi import fake as xenapi_fake
|
||||
from nova.virt.xenapi import host
|
||||
@ -841,7 +842,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
|
||||
vdi_recs_start = self._list_vdis()
|
||||
start_vms = self._list_vms()
|
||||
stubs.stubout_fetch_disk_image(self.stubs, raise_failure=True)
|
||||
self.assertRaises(xenapi_fake.Failure, self._test_spawn,
|
||||
self.assertRaises(XenAPI.Failure, self._test_spawn,
|
||||
IMAGE_MACHINE, IMAGE_KERNEL, IMAGE_RAMDISK)
|
||||
# No additional VDI should be found.
|
||||
vdi_recs_end = self._list_vdis()
|
||||
@ -858,7 +859,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
|
||||
vdi_recs_start = self._list_vdis()
|
||||
start_vms = self._list_vms()
|
||||
stubs.stubout_create_vm(self.stubs)
|
||||
self.assertRaises(xenapi_fake.Failure, self._test_spawn,
|
||||
self.assertRaises(XenAPI.Failure, self._test_spawn,
|
||||
IMAGE_MACHINE, IMAGE_KERNEL, IMAGE_RAMDISK)
|
||||
# No additional VDI should be found.
|
||||
vdi_recs_end = self._list_vdis()
|
||||
@ -875,7 +876,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
|
||||
stubs.stubout_attach_disks(self.stubs)
|
||||
vdi_recs_start = self._list_vdis()
|
||||
start_vms = self._list_vms()
|
||||
self.assertRaises(xenapi_fake.Failure, self._test_spawn,
|
||||
self.assertRaises(XenAPI.Failure, self._test_spawn,
|
||||
IMAGE_MACHINE, IMAGE_KERNEL, IMAGE_RAMDISK)
|
||||
# No additional VDI should be found.
|
||||
vdi_recs_end = self._list_vdis()
|
||||
@ -1219,7 +1220,7 @@ iface eth0 inet6 static
|
||||
|
||||
def fake_agent_call(self, method, args):
|
||||
if failure:
|
||||
raise xenapi_fake.Failure([failure])
|
||||
raise XenAPI.Failure([failure])
|
||||
else:
|
||||
return value
|
||||
|
||||
@ -1398,7 +1399,7 @@ iface eth0 inet6 static
|
||||
instance = self._create_instance(spawn=False)
|
||||
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
||||
xenapi_fake.create_vm(instance['name'], 'Unknown')
|
||||
self.assertRaises(xenapi_fake.Failure, conn.reboot, self.context,
|
||||
self.assertRaises(XenAPI.Failure, conn.reboot, self.context,
|
||||
instance, None, "SOFT")
|
||||
|
||||
def test_reboot_rescued(self):
|
||||
@ -1492,34 +1493,6 @@ iface eth0 inet6 static
|
||||
expected_name)
|
||||
self.assertEqual(inst_uuid, fake_inst['uuid'])
|
||||
|
||||
def test_session_virtapi(self):
|
||||
was = {'called': False}
|
||||
|
||||
def fake_aggregate_get_by_host(self, *args, **kwargs):
|
||||
was['called'] = True
|
||||
raise test.TestingException()
|
||||
self.stub_out("nova.db.aggregate_get_by_host",
|
||||
fake_aggregate_get_by_host)
|
||||
|
||||
self.stubs.Set(self.conn._session, "is_slave", True)
|
||||
|
||||
self.assertRaises(test.TestingException,
|
||||
self.conn._session._get_host_uuid)
|
||||
self.assertTrue(was['called'])
|
||||
|
||||
def test_session_handles_aggregate_metadata(self):
|
||||
def fake_aggregate_get(context, host, key):
|
||||
agg = copy.copy(test_aggregate.fake_aggregate)
|
||||
agg['metadetails'][CONF.host] = 'this_should_be_metadata'
|
||||
return [agg]
|
||||
self.stub_out('nova.db.aggregate_get_by_host',
|
||||
fake_aggregate_get)
|
||||
|
||||
self.stubs.Set(self.conn._session, "is_slave", True)
|
||||
|
||||
self.assertEqual('this_should_be_metadata',
|
||||
self.conn._session._get_host_uuid())
|
||||
|
||||
def test_per_instance_usage_running(self):
|
||||
instance = self._create_instance(spawn=True)
|
||||
flavor = objects.Flavor.get_by_id(self.context, 3)
|
||||
@ -4018,151 +3991,6 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBaseNoDB):
|
||||
self.assertTrue(self.called_fake_get_vm_opaque_ref)
|
||||
|
||||
|
||||
class XenAPISessionTestCase(test.NoDBTestCase):
|
||||
def _get_mock_xapisession(self, software_version):
|
||||
class MockXapiSession(xenapi_session.XenAPISession):
|
||||
def __init__(_ignore):
|
||||
"Skip the superclass's dirty init"
|
||||
|
||||
def _get_software_version(_ignore):
|
||||
return software_version
|
||||
|
||||
return MockXapiSession()
|
||||
|
||||
def test_local_session(self):
|
||||
session = self._get_mock_xapisession({})
|
||||
session.is_local_connection = True
|
||||
session.XenAPI = self.mox.CreateMockAnything()
|
||||
session.XenAPI.xapi_local().AndReturn("local_connection")
|
||||
|
||||
self.mox.ReplayAll()
|
||||
self.assertEqual("local_connection",
|
||||
session._create_session("unix://local"))
|
||||
|
||||
def test_remote_session(self):
|
||||
session = self._get_mock_xapisession({})
|
||||
session.is_local_connection = False
|
||||
session.XenAPI = self.mox.CreateMockAnything()
|
||||
session.XenAPI.Session("url").AndReturn("remote_connection")
|
||||
|
||||
self.mox.ReplayAll()
|
||||
self.assertEqual("remote_connection", session._create_session("url"))
|
||||
|
||||
def test_get_product_version_product_brand_does_not_fail(self):
|
||||
session = self._get_mock_xapisession({
|
||||
'build_number': '0',
|
||||
'date': '2012-08-03',
|
||||
'hostname': 'komainu',
|
||||
'linux': '3.2.0-27-generic',
|
||||
'network_backend': 'bridge',
|
||||
'platform_name': 'XCP_Kronos',
|
||||
'platform_version': '1.6.0',
|
||||
'xapi': '1.3',
|
||||
'xen': '4.1.2',
|
||||
'xencenter_max': '1.10',
|
||||
'xencenter_min': '1.10'
|
||||
})
|
||||
|
||||
self.assertEqual(
|
||||
((1, 6, 0), None),
|
||||
session._get_product_version_and_brand()
|
||||
)
|
||||
|
||||
def test_get_product_version_product_brand_xs_6(self):
|
||||
session = self._get_mock_xapisession({
|
||||
'product_brand': 'XenServer',
|
||||
'product_version': '6.0.50',
|
||||
'platform_version': '0.0.1'
|
||||
})
|
||||
|
||||
self.assertEqual(
|
||||
((6, 0, 50), 'XenServer'),
|
||||
session._get_product_version_and_brand()
|
||||
)
|
||||
|
||||
def test_verify_plugin_version_same(self):
|
||||
session = self._get_mock_xapisession({})
|
||||
|
||||
session.PLUGIN_REQUIRED_VERSION = '2.4'
|
||||
|
||||
self.mox.StubOutWithMock(session, 'call_plugin_serialized')
|
||||
session.call_plugin_serialized('nova_plugin_version.py', 'get_version',
|
||||
).AndReturn("2.4")
|
||||
|
||||
self.mox.ReplayAll()
|
||||
session._verify_plugin_version()
|
||||
|
||||
def test_verify_plugin_version_compatible(self):
|
||||
session = self._get_mock_xapisession({})
|
||||
session.XenAPI = xenapi_fake.FakeXenAPI()
|
||||
|
||||
session.PLUGIN_REQUIRED_VERSION = '2.4'
|
||||
|
||||
self.mox.StubOutWithMock(session, 'call_plugin_serialized')
|
||||
session.call_plugin_serialized('nova_plugin_version.py', 'get_version',
|
||||
).AndReturn("2.5")
|
||||
|
||||
self.mox.ReplayAll()
|
||||
session._verify_plugin_version()
|
||||
|
||||
def test_verify_plugin_version_python_extensions(self):
|
||||
"""Validate that 2.0 is equivalent to 1.8."""
|
||||
session = self._get_mock_xapisession({})
|
||||
session.XenAPI = xenapi_fake.FakeXenAPI()
|
||||
|
||||
session.PLUGIN_REQUIRED_VERSION = '2.0'
|
||||
|
||||
with mock.patch.object(session, 'call_plugin_serialized',
|
||||
return_value='1.8'):
|
||||
session._verify_plugin_version()
|
||||
|
||||
def test_verify_plugin_version_bad_maj(self):
|
||||
session = self._get_mock_xapisession({})
|
||||
session.XenAPI = xenapi_fake.FakeXenAPI()
|
||||
|
||||
session.PLUGIN_REQUIRED_VERSION = '2.4'
|
||||
|
||||
self.mox.StubOutWithMock(session, 'call_plugin_serialized')
|
||||
session.call_plugin_serialized('nova_plugin_version.py', 'get_version',
|
||||
).AndReturn("3.0")
|
||||
|
||||
self.mox.ReplayAll()
|
||||
self.assertRaises(xenapi_fake.Failure, session._verify_plugin_version)
|
||||
|
||||
def test_verify_plugin_version_bad_min(self):
|
||||
session = self._get_mock_xapisession({})
|
||||
session.XenAPI = xenapi_fake.FakeXenAPI()
|
||||
|
||||
session.PLUGIN_REQUIRED_VERSION = '2.4'
|
||||
|
||||
self.mox.StubOutWithMock(session, 'call_plugin_serialized')
|
||||
session.call_plugin_serialized('nova_plugin_version.py', 'get_version',
|
||||
).AndReturn("2.3")
|
||||
|
||||
self.mox.ReplayAll()
|
||||
self.assertRaises(xenapi_fake.Failure, session._verify_plugin_version)
|
||||
|
||||
def test_verify_current_version_matches(self):
|
||||
session = self._get_mock_xapisession({})
|
||||
|
||||
# Import the plugin to extract its version
|
||||
path = os.path.dirname(__file__)
|
||||
rel_path_elem = "../../../../../plugins/xenserver/xenapi/etc/xapi.d/" \
|
||||
"plugins/nova_plugin_version.py"
|
||||
for elem in rel_path_elem.split('/'):
|
||||
path = os.path.join(path, elem)
|
||||
path = os.path.realpath(path)
|
||||
|
||||
plugin_version = None
|
||||
with open(path) as plugin_file:
|
||||
for line in plugin_file:
|
||||
if "PLUGIN_VERSION = " in line:
|
||||
plugin_version = line.strip()[17:].strip('"')
|
||||
|
||||
self.assertEqual(session.PLUGIN_REQUIRED_VERSION,
|
||||
plugin_version)
|
||||
|
||||
|
||||
class XenAPIFakeTestCase(test.NoDBTestCase):
|
||||
def test_query_matches(self):
|
||||
record = {'a': '1', 'b': '2', 'c_d': '3'}
|
||||
|
@ -25,6 +25,7 @@ A driver for XenServer or Xen Cloud Platform.
|
||||
|
||||
import math
|
||||
|
||||
from os_xenapi.client import session
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import units
|
||||
@ -36,7 +37,6 @@ import nova.conf
|
||||
from nova.i18n import _, _LE, _LW
|
||||
from nova import exception
|
||||
from nova.virt import driver
|
||||
from nova.virt.xenapi.client import session
|
||||
from nova.virt.xenapi import host
|
||||
from nova.virt.xenapi import pool
|
||||
from nova.virt.xenapi import vm_utils
|
||||
@ -79,7 +79,8 @@ class XenAPIDriver(driver.ComputeDriver):
|
||||
'connection_password to use '
|
||||
'compute_driver=xenapi.XenAPIDriver'))
|
||||
|
||||
self._session = session.XenAPISession(url, username, password)
|
||||
self._session = session.XenAPISession(url, username, password,
|
||||
originator="nova")
|
||||
self._volumeops = volumeops.VolumeOps(self._session)
|
||||
self._host_state = None
|
||||
self._host = host.Host(self._session, self.virtapi)
|
||||
|
@ -54,6 +54,8 @@ import random
|
||||
from xml.sax import saxutils
|
||||
import zlib
|
||||
|
||||
from os_xenapi.client import session as xenapi_session
|
||||
from os_xenapi.client import XenAPI
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import timeutils
|
||||
@ -63,7 +65,6 @@ import six
|
||||
|
||||
from nova import exception
|
||||
from nova.i18n import _
|
||||
from nova.virt.xenapi.client import session as xenapi_session
|
||||
|
||||
|
||||
_CLASSES = ['host', 'network', 'session', 'pool', 'SR', 'VBD',
|
||||
@ -360,7 +361,7 @@ def _create_sr(table, obj):
|
||||
sr_type = obj[6]
|
||||
# Forces fake to support iscsi only
|
||||
if sr_type != 'iscsi' and sr_type != 'nfs':
|
||||
raise Failure(['SR_UNKNOWN_DRIVER', sr_type])
|
||||
raise XenAPI.Failure(['SR_UNKNOWN_DRIVER', sr_type])
|
||||
host_ref = list(_db_content['host'])[0]
|
||||
sr_ref = _create_object(table, obj[2])
|
||||
if sr_type == 'iscsi':
|
||||
@ -452,7 +453,7 @@ def get_record(table, ref):
|
||||
if ref in _db_content[table]:
|
||||
return _db_content[table].get(ref)
|
||||
else:
|
||||
raise Failure(['HANDLE_INVALID', table, ref])
|
||||
raise XenAPI.Failure(['HANDLE_INVALID', table, ref])
|
||||
|
||||
|
||||
def check_for_session_leaks():
|
||||
@ -511,14 +512,14 @@ class SessionBase(object):
|
||||
def VBD_plug(self, _1, ref):
|
||||
rec = get_record('VBD', ref)
|
||||
if rec['currently_attached']:
|
||||
raise Failure(['DEVICE_ALREADY_ATTACHED', ref])
|
||||
raise XenAPI.Failure(['DEVICE_ALREADY_ATTACHED', ref])
|
||||
rec['currently_attached'] = True
|
||||
rec['device'] = 'fakedev'
|
||||
|
||||
def VBD_unplug(self, _1, ref):
|
||||
rec = get_record('VBD', ref)
|
||||
if not rec['currently_attached']:
|
||||
raise Failure(['DEVICE_ALREADY_DETACHED', ref])
|
||||
raise XenAPI.Failure(['DEVICE_ALREADY_DETACHED', ref])
|
||||
rec['currently_attached'] = False
|
||||
rec['device'] = ''
|
||||
|
||||
@ -527,8 +528,8 @@ class SessionBase(object):
|
||||
if 'other_config' not in db_ref:
|
||||
db_ref['other_config'] = {}
|
||||
if key in db_ref['other_config']:
|
||||
raise Failure(['MAP_DUPLICATE_KEY', 'VBD', 'other_config',
|
||||
vbd_ref, key])
|
||||
raise XenAPI.Failure(
|
||||
['MAP_DUPLICATE_KEY', 'VBD', 'other_config', vbd_ref, key])
|
||||
db_ref['other_config'][key] = value
|
||||
|
||||
def VBD_get_other_config(self, _1, vbd_ref):
|
||||
@ -545,7 +546,7 @@ class SessionBase(object):
|
||||
def PBD_plug(self, _1, pbd_ref):
|
||||
rec = get_record('PBD', pbd_ref)
|
||||
if rec['currently_attached']:
|
||||
raise Failure(['DEVICE_ALREADY_ATTACHED', rec])
|
||||
raise XenAPI.Failure(['DEVICE_ALREADY_ATTACHED', rec])
|
||||
rec['currently_attached'] = True
|
||||
sr_ref = rec['SR']
|
||||
_db_content['SR'][sr_ref]['PBDs'] = [pbd_ref]
|
||||
@ -553,7 +554,7 @@ class SessionBase(object):
|
||||
def PBD_unplug(self, _1, pbd_ref):
|
||||
rec = get_record('PBD', pbd_ref)
|
||||
if not rec['currently_attached']:
|
||||
raise Failure(['DEVICE_ALREADY_DETACHED', rec])
|
||||
raise XenAPI.Failure(['DEVICE_ALREADY_DETACHED', rec])
|
||||
rec['currently_attached'] = False
|
||||
sr_ref = rec['SR']
|
||||
_db_content['SR'][sr_ref]['PBDs'].remove(pbd_ref)
|
||||
@ -625,8 +626,8 @@ class SessionBase(object):
|
||||
if 'other_config' not in db_ref:
|
||||
db_ref['other_config'] = {}
|
||||
if key in db_ref['other_config']:
|
||||
raise Failure(['MAP_DUPLICATE_KEY', 'VDI', 'other_config',
|
||||
vdi_ref, key])
|
||||
raise XenAPI.Failure(
|
||||
['MAP_DUPLICATE_KEY', 'VDI', 'other_config', vdi_ref, key])
|
||||
db_ref['other_config'][key] = value
|
||||
|
||||
def VDI_copy(self, _1, vdi_to_copy_ref, sr_ref):
|
||||
@ -775,12 +776,12 @@ class SessionBase(object):
|
||||
def _plugin_console_get_console_log(self, method, args):
|
||||
dom_id = args["dom_id"]
|
||||
if dom_id == 0:
|
||||
raise Failure('Guest does not have a console')
|
||||
raise XenAPI.Failure('Guest does not have a console')
|
||||
return base64.b64encode(
|
||||
zlib.compress(("dom_id: %s" % dom_id).encode('utf-8')))
|
||||
|
||||
def _plugin_nova_plugin_version_get_version(self, method, args):
|
||||
return pickle.dumps("1.8")
|
||||
def _plugin_dom0_plugin_version_get_version(self, method, args):
|
||||
return pickle.dumps("2.0")
|
||||
|
||||
def _plugin_xenhost_query_gc(self, method, args):
|
||||
return pickle.dumps("False")
|
||||
@ -809,8 +810,8 @@ class SessionBase(object):
|
||||
def _VM_reboot(self, session, vm_ref):
|
||||
db_ref = _db_content['VM'][vm_ref]
|
||||
if db_ref['power_state'] != 'Running':
|
||||
raise Failure(['VM_BAD_POWER_STATE',
|
||||
'fake-opaque-ref', db_ref['power_state'].lower(), 'halted'])
|
||||
raise XenAPI.Failure(['VM_BAD_POWER_STATE', 'fake-opaque-ref',
|
||||
db_ref['power_state'].lower(), 'halted'])
|
||||
db_ref['power_state'] = 'Running'
|
||||
db_ref['domid'] = '%d' % (random.randrange(1, 1 << 16))
|
||||
|
||||
@ -975,7 +976,7 @@ class SessionBase(object):
|
||||
if (field in _db_content[cls][ref]):
|
||||
return _db_content[cls][ref][field]
|
||||
else:
|
||||
raise Failure(['HANDLE_INVALID', cls, ref])
|
||||
raise XenAPI.Failure(['HANDLE_INVALID', cls, ref])
|
||||
|
||||
LOG.debug('Raising NotImplemented')
|
||||
raise NotImplementedError(
|
||||
@ -1038,7 +1039,7 @@ class SessionBase(object):
|
||||
table = name.split('.')[0]
|
||||
ref = params[1]
|
||||
if ref not in _db_content[table]:
|
||||
raise Failure(['HANDLE_INVALID', table, ref])
|
||||
raise XenAPI.Failure(['HANDLE_INVALID', table, ref])
|
||||
|
||||
# Call destroy function (if exists)
|
||||
destroy_func = _destroy_functions.get('destroy_%s' % table.lower())
|
||||
@ -1057,7 +1058,7 @@ class SessionBase(object):
|
||||
result = as_value(result)
|
||||
task['result'] = result
|
||||
task['status'] = 'success'
|
||||
except Failure as exc:
|
||||
except XenAPI.Failure as exc:
|
||||
task['error_info'] = exc.details
|
||||
task['status'] = 'failed'
|
||||
task['finished'] = timeutils.utcnow()
|
||||
@ -1066,7 +1067,8 @@ class SessionBase(object):
|
||||
def _check_session(self, params):
|
||||
if (self._session is None or
|
||||
self._session not in _db_content['session']):
|
||||
raise Failure(['HANDLE_INVALID', 'session', self._session])
|
||||
raise XenAPI.Failure(
|
||||
['HANDLE_INVALID', 'session', self._session])
|
||||
if len(params) == 0 or params[0] != self._session:
|
||||
LOG.debug('Raising NotImplemented')
|
||||
raise NotImplementedError('Call to XenAPI without using .xenapi')
|
||||
@ -1074,8 +1076,8 @@ class SessionBase(object):
|
||||
def _check_arg_count(self, params, expected):
|
||||
actual = len(params)
|
||||
if actual != expected:
|
||||
raise Failure(['MESSAGE_PARAMETER_COUNT_MISMATCH',
|
||||
expected, actual])
|
||||
raise XenAPI.Failure(
|
||||
['MESSAGE_PARAMETER_COUNT_MISMATCH', expected, actual])
|
||||
|
||||
def _get_by_field(self, recs, k, v, return_singleton):
|
||||
result = []
|
||||
@ -1087,14 +1089,14 @@ class SessionBase(object):
|
||||
try:
|
||||
return result[0]
|
||||
except IndexError:
|
||||
raise Failure(['UUID_INVALID', v, result, recs, k])
|
||||
raise XenAPI.Failure(['UUID_INVALID', v, result, recs, k])
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class FakeXenAPI(object):
|
||||
def __init__(self):
|
||||
self.Failure = Failure
|
||||
self.Failure = XenAPI.Failure
|
||||
|
||||
|
||||
# Based upon _Method from xmlrpclib.
|
||||
|
@ -16,6 +16,7 @@
|
||||
import functools
|
||||
import sys
|
||||
|
||||
from os_xenapi.client import exception as xenapi_exception
|
||||
from oslo_log import log as logging
|
||||
import six
|
||||
|
||||
@ -66,7 +67,7 @@ class GlanceStore(object):
|
||||
try:
|
||||
vdis = self._call_glance_plugin(context, instance, session,
|
||||
'download_vhd2', params)
|
||||
except exception.PluginRetriesExceeded:
|
||||
except xenapi_exception.PluginRetriesExceeded:
|
||||
raise exception.CouldNotFetchImage(image_id=image_id)
|
||||
|
||||
return vdis
|
||||
@ -91,5 +92,5 @@ class GlanceStore(object):
|
||||
try:
|
||||
self._call_glance_plugin(context, instance, session,
|
||||
'upload_vhd2', params)
|
||||
except exception.PluginRetriesExceeded:
|
||||
except xenapi_exception.PluginRetriesExceeded:
|
||||
raise exception.CouldNotUploadImage(image_id=image_id)
|
||||
|
@ -58,3 +58,4 @@ os-vif>=1.3.0 # Apache-2.0
|
||||
os-win>=1.1.0 # Apache-2.0
|
||||
castellan>=0.4.0 # Apache-2.0
|
||||
microversion-parse>=0.1.2 # Apache-2.0
|
||||
os-xenapi>=0.1.1 # Apache-2.0
|
||||
|
@ -28,6 +28,7 @@ eventlet.monkey_patch()
|
||||
import os
|
||||
import sys
|
||||
|
||||
from os_xenapi.client import session
|
||||
from oslo_config import cfg
|
||||
|
||||
# If ../nova/__init__.py exists, add ../ to Python search path, so that
|
||||
@ -42,7 +43,6 @@ if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')):
|
||||
import nova.conf
|
||||
from nova import config
|
||||
from nova import utils
|
||||
from nova.virt.xenapi.client import session
|
||||
from nova.virt.xenapi import vm_utils
|
||||
|
||||
destroy_opts = [
|
||||
|
Loading…
Reference in New Issue
Block a user