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
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# 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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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']]
 | 
			
		||||
 
 | 
			
		||||
@@ -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):
 | 
			
		||||
 
 | 
			
		||||
@@ -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({
 | 
			
		||||
 
 | 
			
		||||
@@ -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):
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user