Commit 303bc802 authored by Iustin Pop's avatar Iustin Pop
Browse files

Implement support for query only clients in Rapi

This implements the same query=True|False functionality as in
GetClient for, however since the RAPI code is much more
unit-tested (and the unit-test clients are mocked, for the most part,
without support for addresses) we have to do many adaptations in the
Signed-off-by: default avatarIustin Pop <>
Reviewed-by: default avatarAgata Murawska <>
parent 42ab9ac4
......@@ -34,6 +34,7 @@ from ganeti import rapi
from ganeti import http
from ganeti import errors
from ganeti import compat
from ganeti import constants
# Dummy value to detect unchanged parameters
......@@ -382,13 +383,22 @@ class ResourceBase(object):
return bool(self._checkIntVariable("dry-run"))
def GetClient(self):
def GetClient(self, query=False):
"""Wrapper for L{luxi.Client} with HTTP-specific error handling.
@param query: this signifies that the client will only be used for
queries; if the build-time parameter enable-split-queries is
enabled, then the client will be connected to the query socket
instead of the masterd socket
if query and constants.ENABLE_SPLIT_QUERY:
address = constants.QUERY_SOCKET
address = None
# Could be a function, pylint: disable=R0201
return self._client_cls()
return self._client_cls(address=address)
except luxi.NoMasterError, err:
raise http.HttpBadGateway("Can't connect to master daemon: %s" % err)
except luxi.PermissionError:
......@@ -294,7 +294,7 @@ class _LuxiCallRecorder:
return self._called
def __call__(self):
def __call__(self, address=None):
"""Creates an instrumented LUXI client.
The LUXI client will record all method calls (use L{CalledNames} to
......@@ -302,7 +302,8 @@ class _LuxiCallRecorder:
return luxi.Client(transport=compat.partial(_TestLuxiTransport,
def _TestWrapper(fn, *args, **kwargs):
# Copyright (C) 2010 Google Inc.
# Copyright (C) 2010, 2012 Google Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -57,7 +57,7 @@ def _CreateHandler(cls, items, queryargs, body_data, client_cls):
class _FakeClient:
def __init__(self):
def __init__(self, address=None):
self._jobs = []
def GetNextSubmittedJob(self):
......@@ -77,8 +77,8 @@ class _FakeClientFactory:
def GetNextClient(self):
return self._clients.pop(0)
def __call__(self):
cl = self._client_cls()
def __call__(self, address=None):
cl = self._client_cls(address=address)
return cl
......@@ -103,7 +103,7 @@ class TestConstants(unittest.TestCase):
class TestClientConnectError(unittest.TestCase):
def _FailingClient():
def _FailingClient(address=None):
raise luxi.NoMasterError("test")
def test(self):
......@@ -119,6 +119,9 @@ class TestClientConnectError(unittest.TestCase):
class TestJobSubmitError(unittest.TestCase):
class _SubmitErrorClient:
def __init__(self, address=None):
def SubmitJob(ops):
raise errors.JobQueueFull("test")
......@@ -1714,7 +1717,7 @@ class TestSimpleResources(unittest.TestCase):
class TestClusterInfo(unittest.TestCase):
class _ClusterInfoClient:
def __init__(self):
def __init__(self, address=None):
self.cluster_info = None
def QueryClusterInfo(self):
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment