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:
Bob Ball
2013-08-13 15:07:14 +01:00
parent dcc61f35e7
commit c128dbc74a
7 changed files with 46 additions and 11 deletions

View File

@@ -2194,8 +2194,10 @@
# Options defined in nova.virt.xenapi.driver
#
# URL for connection to XenServer/Xen Cloud Platform. Required
# if compute_driver=xenapi.XenAPIDriver (string value)
# 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 (string value)
#xenapi_connection_url=<None>
# Username for connection to XenServer/Xen Cloud Platform.

View File

@@ -62,7 +62,7 @@ def stubout_session(stubs, cls, product_version=(5, 6, 2),
def stubout_get_this_vm_uuid(stubs):
def f():
def f(session):
vms = [rec['uuid'] for ref, rec
in fake.get_all_records('VM').iteritems()
if rec['is_control_domain']]

View File

@@ -187,7 +187,7 @@ class XenAPIGetUUID(test.TestCase):
self.mox.ReplayAll()
self.assertEquals('2f46f0f5-f14c-ef1b-1fac-9eeca0888a3f',
vm_utils.get_this_vm_uuid())
vm_utils.get_this_vm_uuid(None))
self.mox.VerifyAll()
def test_get_this_vm_uuid_old_kernel_reboot(self):
@@ -204,7 +204,7 @@ class XenAPIGetUUID(test.TestCase):
self.mox.ReplayAll()
self.assertEquals('2f46f0f5-f14c-ef1b-1fac-9eeca0888a3f',
vm_utils.get_this_vm_uuid())
vm_utils.get_this_vm_uuid(None))
self.mox.VerifyAll()
@@ -891,6 +891,7 @@ class GenerateDiskTestCase(stubs.XenAPITestBase):
stubs.stubout_session(self.stubs, fake.SessionBase)
driver = xenapi_conn.XenAPIDriver(False)
self.session = driver._session
self.session.is_local_connection = False
self.vm_ref = fake.create_vm("foo", "Running")
def tearDown(self):

View File

@@ -325,6 +325,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
self.project_id = 'fake'
self.context = context.RequestContext(self.user_id, self.project_id)
self.conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
self.conn._session.is_local_connection = False
fake_image.stub_out_image_service(self.stubs)
set_image_fixtures()
@@ -3653,14 +3654,33 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
class XenAPISessionTestCase(test.TestCase):
def _get_mock_xapisession(self, software_version):
class XcpXapiSession(xenapi_conn.XenAPISession):
class MockXapiSession(xenapi_conn.XenAPISession):
def __init__(_ignore):
"Skip the superclass's dirty init"
def _get_software_version(_ignore):
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):
session = self._get_mock_xapisession({

View File

@@ -66,6 +66,8 @@ LOG = logging.getLogger(__name__)
xenapi_opts = [
cfg.StrOpt('xenapi_connection_url',
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'),
cfg.StrOpt('xenapi_connection_username',
default='root',
@@ -782,6 +784,9 @@ class XenAPISession(object):
def _create_session(self, url):
"""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)
def _unwrap_plugin_exceptions(self, func, *args, **kwargs):

View File

@@ -249,7 +249,7 @@ class ResourcePool(object):
"url": sender_url,
"user": CONF.xenapi_connection_username,
"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,
}

View File

@@ -1878,7 +1878,14 @@ def _get_sys_hypervisor_uuid():
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:
return _get_sys_hypervisor_uuid()
except IOError:
@@ -1893,7 +1900,7 @@ def get_this_vm_uuid():
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):
@@ -2240,7 +2247,7 @@ def ensure_correct_host(session):
"""Ensure we're connected to the host we're running on. This is the
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:
session.call_xenapi('VM.get_by_uuid', this_vm_uuid)