XenAPI: Support local connections
Currently there is no way to connect to XAPI through the unix socket, requiring a URL and credentials. This change allows you to run in dom0 (particularly in xenserver-core environments) and connect to XAPI using the unix domain socket by specifying "unix://local" DocImpact Change-Id: I3d5ace31c9c0411fa711cfdf87383d36f61bfa4a
This commit is contained in:
@@ -2194,8 +2194,10 @@
|
|||||||
# Options defined in nova.virt.xenapi.driver
|
# Options defined in nova.virt.xenapi.driver
|
||||||
#
|
#
|
||||||
|
|
||||||
# URL for connection to XenServer/Xen Cloud Platform. Required
|
# URL for connection to XenServer/Xen Cloud Platform. A
|
||||||
# if compute_driver=xenapi.XenAPIDriver (string value)
|
# special value of unix://local can be used to connect to the
|
||||||
|
# local unix socket. Required if
|
||||||
|
# compute_driver=xenapi.XenAPIDriver (string value)
|
||||||
#xenapi_connection_url=<None>
|
#xenapi_connection_url=<None>
|
||||||
|
|
||||||
# Username for connection to XenServer/Xen Cloud Platform.
|
# Username for connection to XenServer/Xen Cloud Platform.
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ def stubout_session(stubs, cls, product_version=(5, 6, 2),
|
|||||||
|
|
||||||
|
|
||||||
def stubout_get_this_vm_uuid(stubs):
|
def stubout_get_this_vm_uuid(stubs):
|
||||||
def f():
|
def f(session):
|
||||||
vms = [rec['uuid'] for ref, rec
|
vms = [rec['uuid'] for ref, rec
|
||||||
in fake.get_all_records('VM').iteritems()
|
in fake.get_all_records('VM').iteritems()
|
||||||
if rec['is_control_domain']]
|
if rec['is_control_domain']]
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ class XenAPIGetUUID(test.TestCase):
|
|||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
self.assertEquals('2f46f0f5-f14c-ef1b-1fac-9eeca0888a3f',
|
self.assertEquals('2f46f0f5-f14c-ef1b-1fac-9eeca0888a3f',
|
||||||
vm_utils.get_this_vm_uuid())
|
vm_utils.get_this_vm_uuid(None))
|
||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
def test_get_this_vm_uuid_old_kernel_reboot(self):
|
def test_get_this_vm_uuid_old_kernel_reboot(self):
|
||||||
@@ -204,7 +204,7 @@ class XenAPIGetUUID(test.TestCase):
|
|||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
self.assertEquals('2f46f0f5-f14c-ef1b-1fac-9eeca0888a3f',
|
self.assertEquals('2f46f0f5-f14c-ef1b-1fac-9eeca0888a3f',
|
||||||
vm_utils.get_this_vm_uuid())
|
vm_utils.get_this_vm_uuid(None))
|
||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
|
|
||||||
@@ -891,6 +891,7 @@ class GenerateDiskTestCase(stubs.XenAPITestBase):
|
|||||||
stubs.stubout_session(self.stubs, fake.SessionBase)
|
stubs.stubout_session(self.stubs, fake.SessionBase)
|
||||||
driver = xenapi_conn.XenAPIDriver(False)
|
driver = xenapi_conn.XenAPIDriver(False)
|
||||||
self.session = driver._session
|
self.session = driver._session
|
||||||
|
self.session.is_local_connection = False
|
||||||
self.vm_ref = fake.create_vm("foo", "Running")
|
self.vm_ref = fake.create_vm("foo", "Running")
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
|||||||
@@ -325,6 +325,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
|
|||||||
self.project_id = 'fake'
|
self.project_id = 'fake'
|
||||||
self.context = context.RequestContext(self.user_id, self.project_id)
|
self.context = context.RequestContext(self.user_id, self.project_id)
|
||||||
self.conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
self.conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
|
||||||
|
self.conn._session.is_local_connection = False
|
||||||
|
|
||||||
fake_image.stub_out_image_service(self.stubs)
|
fake_image.stub_out_image_service(self.stubs)
|
||||||
set_image_fixtures()
|
set_image_fixtures()
|
||||||
@@ -3653,14 +3654,33 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
|
|||||||
|
|
||||||
class XenAPISessionTestCase(test.TestCase):
|
class XenAPISessionTestCase(test.TestCase):
|
||||||
def _get_mock_xapisession(self, software_version):
|
def _get_mock_xapisession(self, software_version):
|
||||||
class XcpXapiSession(xenapi_conn.XenAPISession):
|
class MockXapiSession(xenapi_conn.XenAPISession):
|
||||||
def __init__(_ignore):
|
def __init__(_ignore):
|
||||||
"Skip the superclass's dirty init"
|
"Skip the superclass's dirty init"
|
||||||
|
|
||||||
def _get_software_version(_ignore):
|
def _get_software_version(_ignore):
|
||||||
return software_version
|
return software_version
|
||||||
|
|
||||||
return XcpXapiSession()
|
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):
|
def test_get_product_version_product_brand_does_not_fail(self):
|
||||||
session = self._get_mock_xapisession({
|
session = self._get_mock_xapisession({
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ LOG = logging.getLogger(__name__)
|
|||||||
xenapi_opts = [
|
xenapi_opts = [
|
||||||
cfg.StrOpt('xenapi_connection_url',
|
cfg.StrOpt('xenapi_connection_url',
|
||||||
help='URL for connection to XenServer/Xen Cloud Platform. '
|
help='URL for connection to XenServer/Xen Cloud Platform. '
|
||||||
|
'A special value of unix://local can be used to connect '
|
||||||
|
'to the local unix socket. '
|
||||||
'Required if compute_driver=xenapi.XenAPIDriver'),
|
'Required if compute_driver=xenapi.XenAPIDriver'),
|
||||||
cfg.StrOpt('xenapi_connection_username',
|
cfg.StrOpt('xenapi_connection_username',
|
||||||
default='root',
|
default='root',
|
||||||
@@ -782,6 +784,9 @@ class XenAPISession(object):
|
|||||||
|
|
||||||
def _create_session(self, url):
|
def _create_session(self, url):
|
||||||
"""Stubout point. This can be replaced with a mock session."""
|
"""Stubout point. This can be replaced with a mock session."""
|
||||||
|
self.is_local_connection = url == "unix://local"
|
||||||
|
if self.is_local_connection:
|
||||||
|
return self.XenAPI.xapi_local()
|
||||||
return self.XenAPI.Session(url)
|
return self.XenAPI.Session(url)
|
||||||
|
|
||||||
def _unwrap_plugin_exceptions(self, func, *args, **kwargs):
|
def _unwrap_plugin_exceptions(self, func, *args, **kwargs):
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ class ResourcePool(object):
|
|||||||
"url": sender_url,
|
"url": sender_url,
|
||||||
"user": CONF.xenapi_connection_username,
|
"user": CONF.xenapi_connection_username,
|
||||||
"passwd": CONF.xenapi_connection_password,
|
"passwd": CONF.xenapi_connection_password,
|
||||||
"compute_uuid": vm_utils.get_this_vm_uuid(),
|
"compute_uuid": vm_utils.get_this_vm_uuid(None),
|
||||||
"xenhost_uuid": self._host_uuid,
|
"xenhost_uuid": self._host_uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1878,7 +1878,14 @@ def _get_sys_hypervisor_uuid():
|
|||||||
return f.readline().strip()
|
return f.readline().strip()
|
||||||
|
|
||||||
|
|
||||||
def get_this_vm_uuid():
|
def get_this_vm_uuid(session):
|
||||||
|
if session and session.is_local_connection:
|
||||||
|
# UUID is the control domain running on this host
|
||||||
|
host_ref = session.get_xenapi_host()
|
||||||
|
vms = session.call_xenapi("VM.get_all_records_where",
|
||||||
|
'field "is_control_domain"="true" and '
|
||||||
|
'field "resident_on"="%s"' % host_ref)
|
||||||
|
return vms[vms.keys()[0]]['uuid']
|
||||||
try:
|
try:
|
||||||
return _get_sys_hypervisor_uuid()
|
return _get_sys_hypervisor_uuid()
|
||||||
except IOError:
|
except IOError:
|
||||||
@@ -1893,7 +1900,7 @@ def get_this_vm_uuid():
|
|||||||
|
|
||||||
|
|
||||||
def _get_this_vm_ref(session):
|
def _get_this_vm_ref(session):
|
||||||
return session.call_xenapi("VM.get_by_uuid", get_this_vm_uuid())
|
return session.call_xenapi("VM.get_by_uuid", get_this_vm_uuid(session))
|
||||||
|
|
||||||
|
|
||||||
def _get_partitions(dev):
|
def _get_partitions(dev):
|
||||||
@@ -2240,7 +2247,7 @@ def ensure_correct_host(session):
|
|||||||
"""Ensure we're connected to the host we're running on. This is the
|
"""Ensure we're connected to the host we're running on. This is the
|
||||||
required configuration for anything that uses vdi_attached_here.
|
required configuration for anything that uses vdi_attached_here.
|
||||||
"""
|
"""
|
||||||
this_vm_uuid = get_this_vm_uuid()
|
this_vm_uuid = get_this_vm_uuid(session)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
session.call_xenapi('VM.get_by_uuid', this_vm_uuid)
|
session.call_xenapi('VM.get_by_uuid', this_vm_uuid)
|
||||||
|
|||||||
Reference in New Issue
Block a user