Statistics
| Branch: | Tag: | Revision:

root / lib / luxi.py @ 89b70f39

History | View | Annotate | Download (10.8 kB)

1 c2a03789 Iustin Pop
#
2 c2a03789 Iustin Pop
#
3 c2a03789 Iustin Pop
4 c2a03789 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 c2a03789 Iustin Pop
#
6 c2a03789 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 c2a03789 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 c2a03789 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 c2a03789 Iustin Pop
# (at your option) any later version.
10 c2a03789 Iustin Pop
#
11 c2a03789 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 c2a03789 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 c2a03789 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 c2a03789 Iustin Pop
# General Public License for more details.
15 c2a03789 Iustin Pop
#
16 c2a03789 Iustin Pop
# You should have received a copy of the GNU General Public License
17 c2a03789 Iustin Pop
# along with this program; if not, write to the Free Software
18 c2a03789 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 c2a03789 Iustin Pop
# 02110-1301, USA.
20 c2a03789 Iustin Pop
21 c2a03789 Iustin Pop
22 c2a03789 Iustin Pop
"""Module for the unix socket protocol
23 c2a03789 Iustin Pop

24 8d5b316c Iustin Pop
This module implements the local unix socket protocol. You only need
25 c2a03789 Iustin Pop
this module and the opcodes module in the client program in order to
26 c2a03789 Iustin Pop
communicate with the master.
27 c2a03789 Iustin Pop

28 7577196d Guido Trotter
The module is also used by the master daemon.
29 c2a03789 Iustin Pop

30 c2a03789 Iustin Pop
"""
31 c2a03789 Iustin Pop
32 c2a03789 Iustin Pop
import socket
33 c2a03789 Iustin Pop
import collections
34 c2a03789 Iustin Pop
import time
35 03a8dbdc Iustin Pop
import errno
36 c2a03789 Iustin Pop
37 fad50141 Michael Hanselmann
from ganeti import serializer
38 ceab32dd Iustin Pop
from ganeti import constants
39 6797ec29 Iustin Pop
from ganeti import errors
40 c2a03789 Iustin Pop
41 c2a03789 Iustin Pop
42 3d8548c4 Michael Hanselmann
KEY_METHOD = 'method'
43 3d8548c4 Michael Hanselmann
KEY_ARGS = 'args'
44 3d8548c4 Michael Hanselmann
KEY_SUCCESS = "success"
45 3d8548c4 Michael Hanselmann
KEY_RESULT = "result"
46 3d8548c4 Michael Hanselmann
47 0bbe448c Michael Hanselmann
REQ_SUBMIT_JOB = "SubmitJob"
48 2971c913 Iustin Pop
REQ_SUBMIT_MANY_JOBS = "SubmitManyJobs"
49 dfe57c22 Michael Hanselmann
REQ_WAIT_FOR_JOB_CHANGE = "WaitForJobChange"
50 0bbe448c Michael Hanselmann
REQ_CANCEL_JOB = "CancelJob"
51 0bbe448c Michael Hanselmann
REQ_ARCHIVE_JOB = "ArchiveJob"
52 07cd723a Iustin Pop
REQ_AUTOARCHIVE_JOBS = "AutoArchiveJobs"
53 0bbe448c Michael Hanselmann
REQ_QUERY_JOBS = "QueryJobs"
54 ee6c7b94 Michael Hanselmann
REQ_QUERY_INSTANCES = "QueryInstances"
55 02f7fe54 Michael Hanselmann
REQ_QUERY_NODES = "QueryNodes"
56 32f93223 Michael Hanselmann
REQ_QUERY_EXPORTS = "QueryExports"
57 ae5849b5 Michael Hanselmann
REQ_QUERY_CONFIG_VALUES = "QueryConfigValues"
58 66baeccc Iustin Pop
REQ_QUERY_CLUSTER_INFO = "QueryClusterInfo"
59 7699c3af Iustin Pop
REQ_QUERY_TAGS = "QueryTags"
60 3ccafd0e Iustin Pop
REQ_QUEUE_SET_DRAIN_FLAG = "SetDrainFlag"
61 05e50653 Michael Hanselmann
REQ_SET_WATCHER_PAUSE = "SetWatcherPause"
62 c2a03789 Iustin Pop
63 c2a03789 Iustin Pop
DEF_CTMO = 10
64 c2a03789 Iustin Pop
DEF_RWTO = 60
65 c2a03789 Iustin Pop
66 c2a03789 Iustin Pop
67 c2a03789 Iustin Pop
class ProtocolError(Exception):
68 c2a03789 Iustin Pop
  """Denotes an error in the server communication"""
69 c2a03789 Iustin Pop
70 c2a03789 Iustin Pop
71 c2a03789 Iustin Pop
class ConnectionClosedError(ProtocolError):
72 c2a03789 Iustin Pop
  """Connection closed error"""
73 c2a03789 Iustin Pop
74 c2a03789 Iustin Pop
75 c2a03789 Iustin Pop
class TimeoutError(ProtocolError):
76 c2a03789 Iustin Pop
  """Operation timeout error"""
77 c2a03789 Iustin Pop
78 c2a03789 Iustin Pop
79 c2a03789 Iustin Pop
class EncodingError(ProtocolError):
80 c2a03789 Iustin Pop
  """Encoding failure on the sending side"""
81 c2a03789 Iustin Pop
82 c2a03789 Iustin Pop
83 c2a03789 Iustin Pop
class DecodingError(ProtocolError):
84 c2a03789 Iustin Pop
  """Decoding failure on the receiving side"""
85 c2a03789 Iustin Pop
86 c2a03789 Iustin Pop
87 b77acb3e Iustin Pop
class RequestError(ProtocolError):
88 b77acb3e Iustin Pop
  """Error on request
89 b77acb3e Iustin Pop

90 b77acb3e Iustin Pop
  This signifies an error in the request format or request handling,
91 b77acb3e Iustin Pop
  but not (e.g.) an error in starting up an instance.
92 b77acb3e Iustin Pop

93 b77acb3e Iustin Pop
  Some common conditions that can trigger this exception:
94 b77acb3e Iustin Pop
    - job submission failed because the job data was wrong
95 b77acb3e Iustin Pop
    - query failed because required fields were missing
96 b77acb3e Iustin Pop

97 b77acb3e Iustin Pop
  """
98 b77acb3e Iustin Pop
99 3d8548c4 Michael Hanselmann
100 03a8dbdc Iustin Pop
class NoMasterError(ProtocolError):
101 03a8dbdc Iustin Pop
  """The master cannot be reached
102 03a8dbdc Iustin Pop

103 03a8dbdc Iustin Pop
  This means that the master daemon is not running or the socket has
104 03a8dbdc Iustin Pop
  been removed.
105 03a8dbdc Iustin Pop

106 03a8dbdc Iustin Pop
  """
107 03a8dbdc Iustin Pop
108 b77acb3e Iustin Pop
109 c2a03789 Iustin Pop
class Transport:
110 c2a03789 Iustin Pop
  """Low-level transport class.
111 c2a03789 Iustin Pop

112 c2a03789 Iustin Pop
  This is used on the client side.
113 c2a03789 Iustin Pop

114 c2a03789 Iustin Pop
  This could be replace by any other class that provides the same
115 c2a03789 Iustin Pop
  semantics to the Client. This means:
116 c2a03789 Iustin Pop
    - can send messages and receive messages
117 c2a03789 Iustin Pop
    - safe for multithreading
118 c2a03789 Iustin Pop

119 c2a03789 Iustin Pop
  """
120 c2a03789 Iustin Pop
121 c2a03789 Iustin Pop
  def __init__(self, address, timeouts=None, eom=None):
122 c2a03789 Iustin Pop
    """Constructor for the Client class.
123 c2a03789 Iustin Pop

124 c2a03789 Iustin Pop
    Arguments:
125 c2a03789 Iustin Pop
      - address: a valid address the the used transport class
126 c2a03789 Iustin Pop
      - timeout: a list of timeouts, to be used on connect and read/write
127 c2a03789 Iustin Pop
      - eom: an identifier to be used as end-of-message which the
128 c2a03789 Iustin Pop
        upper-layer will guarantee that this identifier will not appear
129 c2a03789 Iustin Pop
        in any message
130 c2a03789 Iustin Pop

131 c2a03789 Iustin Pop
    There are two timeouts used since we might want to wait for a long
132 c2a03789 Iustin Pop
    time for a response, but the connect timeout should be lower.
133 c2a03789 Iustin Pop

134 c2a03789 Iustin Pop
    If not passed, we use a default of 10 and respectively 60 seconds.
135 c2a03789 Iustin Pop

136 c2a03789 Iustin Pop
    Note that on reading data, since the timeout applies to an
137 c2a03789 Iustin Pop
    invidual receive, it might be that the total duration is longer
138 c2a03789 Iustin Pop
    than timeout value passed (we make a hard limit at twice the read
139 c2a03789 Iustin Pop
    timeout).
140 c2a03789 Iustin Pop

141 c2a03789 Iustin Pop
    """
142 c2a03789 Iustin Pop
    self.address = address
143 c2a03789 Iustin Pop
    if timeouts is None:
144 c2a03789 Iustin Pop
      self._ctimeout, self._rwtimeout = DEF_CTMO, DEF_RWTO
145 c2a03789 Iustin Pop
    else:
146 c2a03789 Iustin Pop
      self._ctimeout, self._rwtimeout = timeouts
147 c2a03789 Iustin Pop
148 c2a03789 Iustin Pop
    self.socket = None
149 c2a03789 Iustin Pop
    self._buffer = ""
150 c2a03789 Iustin Pop
    self._msgs = collections.deque()
151 c2a03789 Iustin Pop
152 c2a03789 Iustin Pop
    if eom is None:
153 c2a03789 Iustin Pop
      self.eom = '\3'
154 c2a03789 Iustin Pop
    else:
155 c2a03789 Iustin Pop
      self.eom = eom
156 c2a03789 Iustin Pop
157 c2a03789 Iustin Pop
    try:
158 c2a03789 Iustin Pop
      self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
159 c2a03789 Iustin Pop
      self.socket.settimeout(self._ctimeout)
160 c2a03789 Iustin Pop
      try:
161 c2a03789 Iustin Pop
        self.socket.connect(address)
162 c2a03789 Iustin Pop
      except socket.timeout, err:
163 03a8dbdc Iustin Pop
        raise TimeoutError("Connect timed out: %s" % str(err))
164 03a8dbdc Iustin Pop
      except socket.error, err:
165 082c5adb Michael Hanselmann
        if err.args[0] in (errno.ENOENT, errno.ECONNREFUSED):
166 63d96e4c Michael Hanselmann
          raise NoMasterError(address)
167 03a8dbdc Iustin Pop
        raise
168 c2a03789 Iustin Pop
      self.socket.settimeout(self._rwtimeout)
169 03a8dbdc Iustin Pop
    except (socket.error, NoMasterError):
170 c2a03789 Iustin Pop
      if self.socket is not None:
171 c2a03789 Iustin Pop
        self.socket.close()
172 c2a03789 Iustin Pop
      self.socket = None
173 c2a03789 Iustin Pop
      raise
174 c2a03789 Iustin Pop
175 c2a03789 Iustin Pop
  def _CheckSocket(self):
176 c2a03789 Iustin Pop
    """Make sure we are connected.
177 c2a03789 Iustin Pop

178 c2a03789 Iustin Pop
    """
179 c2a03789 Iustin Pop
    if self.socket is None:
180 c2a03789 Iustin Pop
      raise ProtocolError("Connection is closed")
181 c2a03789 Iustin Pop
182 c2a03789 Iustin Pop
  def Send(self, msg):
183 c2a03789 Iustin Pop
    """Send a message.
184 c2a03789 Iustin Pop

185 c2a03789 Iustin Pop
    This just sends a message and doesn't wait for the response.
186 c2a03789 Iustin Pop

187 c2a03789 Iustin Pop
    """
188 c2a03789 Iustin Pop
    if self.eom in msg:
189 c2a03789 Iustin Pop
      raise EncodingError("Message terminator found in payload")
190 c2a03789 Iustin Pop
    self._CheckSocket()
191 c2a03789 Iustin Pop
    try:
192 6096ee13 Michael Hanselmann
      # TODO: sendall is not guaranteed to send everything
193 c2a03789 Iustin Pop
      self.socket.sendall(msg + self.eom)
194 c2a03789 Iustin Pop
    except socket.timeout, err:
195 c2a03789 Iustin Pop
      raise TimeoutError("Sending timeout: %s" % str(err))
196 c2a03789 Iustin Pop
197 c2a03789 Iustin Pop
  def Recv(self):
198 5bbd3f7f Michael Hanselmann
    """Try to receive a message from the socket.
199 c2a03789 Iustin Pop

200 c2a03789 Iustin Pop
    In case we already have messages queued, we just return from the
201 c2a03789 Iustin Pop
    queue. Otherwise, we try to read data with a _rwtimeout network
202 c2a03789 Iustin Pop
    timeout, and making sure we don't go over 2x_rwtimeout as a global
203 c2a03789 Iustin Pop
    limit.
204 c2a03789 Iustin Pop

205 c2a03789 Iustin Pop
    """
206 c2a03789 Iustin Pop
    self._CheckSocket()
207 c2a03789 Iustin Pop
    etime = time.time() + self._rwtimeout
208 c2a03789 Iustin Pop
    while not self._msgs:
209 c2a03789 Iustin Pop
      if time.time() > etime:
210 c2a03789 Iustin Pop
        raise TimeoutError("Extended receive timeout")
211 6096ee13 Michael Hanselmann
      while True:
212 6096ee13 Michael Hanselmann
        try:
213 6096ee13 Michael Hanselmann
          data = self.socket.recv(4096)
214 6096ee13 Michael Hanselmann
        except socket.error, err:
215 6096ee13 Michael Hanselmann
          if err.args and err.args[0] == errno.EAGAIN:
216 6096ee13 Michael Hanselmann
            continue
217 6096ee13 Michael Hanselmann
          raise
218 6096ee13 Michael Hanselmann
        except socket.timeout, err:
219 6096ee13 Michael Hanselmann
          raise TimeoutError("Receive timeout: %s" % str(err))
220 6096ee13 Michael Hanselmann
        break
221 c2a03789 Iustin Pop
      if not data:
222 c2a03789 Iustin Pop
        raise ConnectionClosedError("Connection closed while reading")
223 c2a03789 Iustin Pop
      new_msgs = (self._buffer + data).split(self.eom)
224 c2a03789 Iustin Pop
      self._buffer = new_msgs.pop()
225 c2a03789 Iustin Pop
      self._msgs.extend(new_msgs)
226 c2a03789 Iustin Pop
    return self._msgs.popleft()
227 c2a03789 Iustin Pop
228 c2a03789 Iustin Pop
  def Call(self, msg):
229 c2a03789 Iustin Pop
    """Send a message and wait for the response.
230 c2a03789 Iustin Pop

231 c2a03789 Iustin Pop
    This is just a wrapper over Send and Recv.
232 c2a03789 Iustin Pop

233 c2a03789 Iustin Pop
    """
234 c2a03789 Iustin Pop
    self.Send(msg)
235 c2a03789 Iustin Pop
    return self.Recv()
236 c2a03789 Iustin Pop
237 c2a03789 Iustin Pop
  def Close(self):
238 c2a03789 Iustin Pop
    """Close the socket"""
239 c2a03789 Iustin Pop
    if self.socket is not None:
240 c2a03789 Iustin Pop
      self.socket.close()
241 c2a03789 Iustin Pop
      self.socket = None
242 c2a03789 Iustin Pop
243 c2a03789 Iustin Pop
244 c2a03789 Iustin Pop
class Client(object):
245 c2a03789 Iustin Pop
  """High-level client implementation.
246 c2a03789 Iustin Pop

247 c2a03789 Iustin Pop
  This uses a backing Transport-like class on top of which it
248 c2a03789 Iustin Pop
  implements data serialization/deserialization.
249 c2a03789 Iustin Pop

250 c2a03789 Iustin Pop
  """
251 ceab32dd Iustin Pop
  def __init__(self, address=None, timeouts=None, transport=Transport):
252 c2a03789 Iustin Pop
    """Constructor for the Client class.
253 c2a03789 Iustin Pop

254 c2a03789 Iustin Pop
    Arguments:
255 c2a03789 Iustin Pop
      - address: a valid address the the used transport class
256 c2a03789 Iustin Pop
      - timeout: a list of timeouts, to be used on connect and read/write
257 c2a03789 Iustin Pop
      - transport: a Transport-like class
258 c2a03789 Iustin Pop

259 c2a03789 Iustin Pop

260 c2a03789 Iustin Pop
    If timeout is not passed, the default timeouts of the transport
261 c2a03789 Iustin Pop
    class are used.
262 c2a03789 Iustin Pop

263 c2a03789 Iustin Pop
    """
264 ceab32dd Iustin Pop
    if address is None:
265 ceab32dd Iustin Pop
      address = constants.MASTER_SOCKET
266 8d5b316c Iustin Pop
    self.address = address
267 8d5b316c Iustin Pop
    self.timeouts = timeouts
268 8d5b316c Iustin Pop
    self.transport_class = transport
269 8d5b316c Iustin Pop
    self.transport = None
270 8d5b316c Iustin Pop
    self._InitTransport()
271 8d5b316c Iustin Pop
272 8d5b316c Iustin Pop
  def _InitTransport(self):
273 8d5b316c Iustin Pop
    """(Re)initialize the transport if needed.
274 8d5b316c Iustin Pop

275 8d5b316c Iustin Pop
    """
276 8d5b316c Iustin Pop
    if self.transport is None:
277 8d5b316c Iustin Pop
      self.transport = self.transport_class(self.address,
278 8d5b316c Iustin Pop
                                            timeouts=self.timeouts)
279 8d5b316c Iustin Pop
280 8d5b316c Iustin Pop
  def _CloseTransport(self):
281 8d5b316c Iustin Pop
    """Close the transport, ignoring errors.
282 8d5b316c Iustin Pop

283 8d5b316c Iustin Pop
    """
284 8d5b316c Iustin Pop
    if self.transport is None:
285 8d5b316c Iustin Pop
      return
286 8d5b316c Iustin Pop
    try:
287 8d5b316c Iustin Pop
      old_transp = self.transport
288 8d5b316c Iustin Pop
      self.transport = None
289 8d5b316c Iustin Pop
      old_transp.Close()
290 7260cfbe Iustin Pop
    except Exception: # pylint: disable-msg=W0703
291 8d5b316c Iustin Pop
      pass
292 c2a03789 Iustin Pop
293 3d8548c4 Michael Hanselmann
  def CallMethod(self, method, args):
294 c2a03789 Iustin Pop
    """Send a generic request and return the response.
295 c2a03789 Iustin Pop

296 c2a03789 Iustin Pop
    """
297 3d8548c4 Michael Hanselmann
    # Build request
298 3d8548c4 Michael Hanselmann
    request = {
299 3d8548c4 Michael Hanselmann
      KEY_METHOD: method,
300 3d8548c4 Michael Hanselmann
      KEY_ARGS: args,
301 3d8548c4 Michael Hanselmann
      }
302 3d8548c4 Michael Hanselmann
303 8d5b316c Iustin Pop
    # Serialize the request
304 8d5b316c Iustin Pop
    send_data = serializer.DumpJson(request, indent=False)
305 8d5b316c Iustin Pop
306 3d8548c4 Michael Hanselmann
    # Send request and wait for response
307 8d5b316c Iustin Pop
    try:
308 8d5b316c Iustin Pop
      self._InitTransport()
309 8d5b316c Iustin Pop
      result = self.transport.Call(send_data)
310 8d5b316c Iustin Pop
    except Exception:
311 8d5b316c Iustin Pop
      self._CloseTransport()
312 8d5b316c Iustin Pop
      raise
313 8d5b316c Iustin Pop
314 8d5b316c Iustin Pop
    # Parse the result
315 c2a03789 Iustin Pop
    try:
316 fad50141 Michael Hanselmann
      data = serializer.LoadJson(result)
317 c2a03789 Iustin Pop
    except Exception, err:
318 c2a03789 Iustin Pop
      raise ProtocolError("Error while deserializing response: %s" % str(err))
319 3d8548c4 Michael Hanselmann
320 3d8548c4 Michael Hanselmann
    # Validate response
321 a14a17fc Iustin Pop
    if (not isinstance(data, dict) or
322 3d8548c4 Michael Hanselmann
        KEY_SUCCESS not in data or
323 3d8548c4 Michael Hanselmann
        KEY_RESULT not in data):
324 a14a17fc Iustin Pop
      raise DecodingError("Invalid response from server: %s" % str(data))
325 3d8548c4 Michael Hanselmann
326 6797ec29 Iustin Pop
    result = data[KEY_RESULT]
327 6797ec29 Iustin Pop
328 3d8548c4 Michael Hanselmann
    if not data[KEY_SUCCESS]:
329 6956e9cd Iustin Pop
      errors.MaybeRaise(result)
330 6797ec29 Iustin Pop
      raise RequestError(result)
331 3d8548c4 Michael Hanselmann
332 6797ec29 Iustin Pop
    return result
333 c2a03789 Iustin Pop
334 3ccafd0e Iustin Pop
  def SetQueueDrainFlag(self, drain_flag):
335 3ccafd0e Iustin Pop
    return self.CallMethod(REQ_QUEUE_SET_DRAIN_FLAG, drain_flag)
336 3ccafd0e Iustin Pop
337 05e50653 Michael Hanselmann
  def SetWatcherPause(self, until):
338 05e50653 Michael Hanselmann
    return self.CallMethod(REQ_SET_WATCHER_PAUSE, [until])
339 05e50653 Michael Hanselmann
340 0bbe448c Michael Hanselmann
  def SubmitJob(self, ops):
341 0bbe448c Michael Hanselmann
    ops_state = map(lambda op: op.__getstate__(), ops)
342 0bbe448c Michael Hanselmann
    return self.CallMethod(REQ_SUBMIT_JOB, ops_state)
343 0bbe448c Michael Hanselmann
344 2971c913 Iustin Pop
  def SubmitManyJobs(self, jobs):
345 2971c913 Iustin Pop
    jobs_state = []
346 2971c913 Iustin Pop
    for ops in jobs:
347 2971c913 Iustin Pop
      jobs_state.append([op.__getstate__() for op in ops])
348 2971c913 Iustin Pop
    return self.CallMethod(REQ_SUBMIT_MANY_JOBS, jobs_state)
349 2971c913 Iustin Pop
350 0bbe448c Michael Hanselmann
  def CancelJob(self, job_id):
351 0bbe448c Michael Hanselmann
    return self.CallMethod(REQ_CANCEL_JOB, job_id)
352 0bbe448c Michael Hanselmann
353 0bbe448c Michael Hanselmann
  def ArchiveJob(self, job_id):
354 0bbe448c Michael Hanselmann
    return self.CallMethod(REQ_ARCHIVE_JOB, job_id)
355 0bbe448c Michael Hanselmann
356 07cd723a Iustin Pop
  def AutoArchiveJobs(self, age):
357 f8ad5591 Michael Hanselmann
    timeout = (DEF_RWTO - 1) / 2
358 f8ad5591 Michael Hanselmann
    return self.CallMethod(REQ_AUTOARCHIVE_JOBS, (age, timeout))
359 07cd723a Iustin Pop
360 6c5a7090 Michael Hanselmann
  def WaitForJobChange(self, job_id, fields, prev_job_info, prev_log_serial):
361 5c735209 Iustin Pop
    timeout = (DEF_RWTO - 1) / 2
362 5c735209 Iustin Pop
    while True:
363 5c735209 Iustin Pop
      result = self.CallMethod(REQ_WAIT_FOR_JOB_CHANGE,
364 5c735209 Iustin Pop
                               (job_id, fields, prev_job_info,
365 5c735209 Iustin Pop
                                prev_log_serial, timeout))
366 5c735209 Iustin Pop
      if result != constants.JOB_NOTCHANGED:
367 5c735209 Iustin Pop
        break
368 5c735209 Iustin Pop
    return result
369 dfe57c22 Michael Hanselmann
370 0bbe448c Michael Hanselmann
  def QueryJobs(self, job_ids, fields):
371 0bbe448c Michael Hanselmann
    return self.CallMethod(REQ_QUERY_JOBS, (job_ids, fields))
372 3d8548c4 Michael Hanselmann
373 ec79568d Iustin Pop
  def QueryInstances(self, names, fields, use_locking):
374 ec79568d Iustin Pop
    return self.CallMethod(REQ_QUERY_INSTANCES, (names, fields, use_locking))
375 ee6c7b94 Michael Hanselmann
376 ec79568d Iustin Pop
  def QueryNodes(self, names, fields, use_locking):
377 ec79568d Iustin Pop
    return self.CallMethod(REQ_QUERY_NODES, (names, fields, use_locking))
378 02f7fe54 Michael Hanselmann
379 ec79568d Iustin Pop
  def QueryExports(self, nodes, use_locking):
380 ec79568d Iustin Pop
    return self.CallMethod(REQ_QUERY_EXPORTS, (nodes, use_locking))
381 32f93223 Michael Hanselmann
382 66baeccc Iustin Pop
  def QueryClusterInfo(self):
383 66baeccc Iustin Pop
    return self.CallMethod(REQ_QUERY_CLUSTER_INFO, ())
384 66baeccc Iustin Pop
385 ae5849b5 Michael Hanselmann
  def QueryConfigValues(self, fields):
386 ae5849b5 Michael Hanselmann
    return self.CallMethod(REQ_QUERY_CONFIG_VALUES, fields)
387 ae5849b5 Michael Hanselmann
388 7699c3af Iustin Pop
  def QueryTags(self, kind, name):
389 7699c3af Iustin Pop
    return self.CallMethod(REQ_QUERY_TAGS, (kind, name))
390 7699c3af Iustin Pop
391 3ccafd0e Iustin Pop
392 3d8548c4 Michael Hanselmann
# TODO: class Server(object)