Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ 5661b908

History | View | Annotate | Download (28.2 kB)

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

24 a8083063 Iustin Pop
"""
25 a8083063 Iustin Pop
26 72737a7f Iustin Pop
# pylint: disable-msg=C0103,R0201,R0904
27 72737a7f Iustin Pop
# C0103: Invalid name, since call_ are not valid
28 72737a7f Iustin Pop
# R0201: Method could be a function, we keep all rpcs instance methods
29 72737a7f Iustin Pop
# as not to change them back and forth between static/instance methods
30 72737a7f Iustin Pop
# if they need to start using instance attributes
31 72737a7f Iustin Pop
# R0904: Too many public methods
32 a8083063 Iustin Pop
33 a8083063 Iustin Pop
import os
34 81010134 Iustin Pop
import socket
35 58b311ca Iustin Pop
import logging
36 12bce260 Michael Hanselmann
import zlib
37 12bce260 Michael Hanselmann
import base64
38 a8083063 Iustin Pop
39 a8083063 Iustin Pop
from ganeti import utils
40 a8083063 Iustin Pop
from ganeti import objects
41 ecfe9491 Michael Hanselmann
from ganeti import http
42 7c28c575 Michael Hanselmann
from ganeti import serializer
43 eafd8762 Michael Hanselmann
from ganeti import constants
44 781de953 Iustin Pop
from ganeti import errors
45 a8083063 Iustin Pop
46 ae88ef45 Michael Hanselmann
import ganeti.http.client
47 ae88ef45 Michael Hanselmann
48 a8083063 Iustin Pop
49 4331f6cd Michael Hanselmann
# Module level variable
50 4331f6cd Michael Hanselmann
_http_manager = None
51 4331f6cd Michael Hanselmann
52 4331f6cd Michael Hanselmann
53 4331f6cd Michael Hanselmann
def Init():
54 4331f6cd Michael Hanselmann
  """Initializes the module-global HTTP client manager.
55 4331f6cd Michael Hanselmann

56 4331f6cd Michael Hanselmann
  Must be called before using any RPC function.
57 4331f6cd Michael Hanselmann

58 4331f6cd Michael Hanselmann
  """
59 4331f6cd Michael Hanselmann
  global _http_manager
60 4331f6cd Michael Hanselmann
61 4331f6cd Michael Hanselmann
  assert not _http_manager, "RPC module initialized more than once"
62 4331f6cd Michael Hanselmann
63 ae88ef45 Michael Hanselmann
  _http_manager = http.client.HttpClientManager()
64 4331f6cd Michael Hanselmann
65 4331f6cd Michael Hanselmann
66 4331f6cd Michael Hanselmann
def Shutdown():
67 4331f6cd Michael Hanselmann
  """Stops the module-global HTTP client manager.
68 4331f6cd Michael Hanselmann

69 4331f6cd Michael Hanselmann
  Must be called before quitting the program.
70 4331f6cd Michael Hanselmann

71 4331f6cd Michael Hanselmann
  """
72 4331f6cd Michael Hanselmann
  global _http_manager
73 4331f6cd Michael Hanselmann
74 4331f6cd Michael Hanselmann
  if _http_manager:
75 4331f6cd Michael Hanselmann
    _http_manager.Shutdown()
76 4331f6cd Michael Hanselmann
    _http_manager = None
77 4331f6cd Michael Hanselmann
78 4331f6cd Michael Hanselmann
79 781de953 Iustin Pop
class RpcResult(object):
80 781de953 Iustin Pop
  """RPC Result class.
81 781de953 Iustin Pop

82 781de953 Iustin Pop
  This class holds an RPC result. It is needed since in multi-node
83 781de953 Iustin Pop
  calls we can't raise an exception just because one one out of many
84 781de953 Iustin Pop
  failed, and therefore we use this class to encapsulate the result.
85 781de953 Iustin Pop

86 ed83f5cc Iustin Pop
  @ivar data: the data payload, for successfull results, or None
87 ed83f5cc Iustin Pop
  @type failed: boolean
88 ed83f5cc Iustin Pop
  @ivar failed: whether the operation failed at RPC level (not
89 ed83f5cc Iustin Pop
      application level on the remote node)
90 ed83f5cc Iustin Pop
  @ivar call: the name of the RPC call
91 ed83f5cc Iustin Pop
  @ivar node: the name of the node to which we made the call
92 ed83f5cc Iustin Pop
  @ivar offline: whether the operation failed because the node was
93 ed83f5cc Iustin Pop
      offline, as opposed to actual failure; offline=True will always
94 ed83f5cc Iustin Pop
      imply failed=True, in order to allow simpler checking if
95 ed83f5cc Iustin Pop
      the user doesn't care about the exact failure mode
96 ed83f5cc Iustin Pop

97 781de953 Iustin Pop
  """
98 ed83f5cc Iustin Pop
  def __init__(self, data=None, failed=False, offline=False,
99 ed83f5cc Iustin Pop
               call=None, node=None):
100 781de953 Iustin Pop
    self.failed = failed
101 ed83f5cc Iustin Pop
    self.offline = offline
102 ed83f5cc Iustin Pop
    self.call = call
103 ed83f5cc Iustin Pop
    self.node = node
104 ed83f5cc Iustin Pop
    if offline:
105 ed83f5cc Iustin Pop
      self.failed = True
106 ed83f5cc Iustin Pop
      self.error = "Node is marked offline"
107 ed83f5cc Iustin Pop
      self.data = None
108 ed83f5cc Iustin Pop
    elif failed:
109 781de953 Iustin Pop
      self.error = data
110 781de953 Iustin Pop
      self.data = None
111 781de953 Iustin Pop
    else:
112 781de953 Iustin Pop
      self.data = data
113 781de953 Iustin Pop
      self.error = None
114 781de953 Iustin Pop
115 781de953 Iustin Pop
  def Raise(self):
116 781de953 Iustin Pop
    """If the result has failed, raise an OpExecError.
117 781de953 Iustin Pop

118 781de953 Iustin Pop
    This is used so that LU code doesn't have to check for each
119 781de953 Iustin Pop
    result, but instead can call this function.
120 781de953 Iustin Pop

121 781de953 Iustin Pop
    """
122 781de953 Iustin Pop
    if self.failed:
123 781de953 Iustin Pop
      raise errors.OpExecError("Call '%s' to node '%s' has failed: %s" %
124 781de953 Iustin Pop
                               (self.call, self.node, self.error))
125 781de953 Iustin Pop
126 781de953 Iustin Pop
127 a8083063 Iustin Pop
class Client:
128 a8083063 Iustin Pop
  """RPC Client class.
129 a8083063 Iustin Pop

130 2f8598a5 Alexander Schreiber
  This class, given a (remote) method name, a list of parameters and a
131 a8083063 Iustin Pop
  list of nodes, will contact (in parallel) all nodes, and return a
132 a8083063 Iustin Pop
  dict of results (key: node name, value: result).
133 a8083063 Iustin Pop

134 a8083063 Iustin Pop
  One current bug is that generic failure is still signalled by
135 a8083063 Iustin Pop
  'False' result, which is not good. This overloading of values can
136 a8083063 Iustin Pop
  cause bugs.
137 a8083063 Iustin Pop

138 a8083063 Iustin Pop
  """
139 160e2921 Iustin Pop
  def __init__(self, procedure, body, port):
140 a8083063 Iustin Pop
    self.procedure = procedure
141 160e2921 Iustin Pop
    self.body = body
142 160e2921 Iustin Pop
    self.port = port
143 ecfe9491 Michael Hanselmann
    self.nc = {}
144 a8083063 Iustin Pop
145 d57ae7f7 Michael Hanselmann
    self._ssl_params = \
146 d57ae7f7 Michael Hanselmann
      http.HttpSslParams(ssl_key_path=constants.SSL_CERT_FILE,
147 d57ae7f7 Michael Hanselmann
                         ssl_cert_path=constants.SSL_CERT_FILE)
148 d57ae7f7 Michael Hanselmann
149 bdf7d8c0 Iustin Pop
  def ConnectList(self, node_list, address_list=None):
150 a8083063 Iustin Pop
    """Add a list of nodes to the target nodes.
151 a8083063 Iustin Pop

152 3ef3c771 Iustin Pop
    @type node_list: list
153 3ef3c771 Iustin Pop
    @param node_list: the list of node names to connect
154 bdf7d8c0 Iustin Pop
    @type address_list: list or None
155 bdf7d8c0 Iustin Pop
    @keyword address_list: either None or a list with node addresses,
156 bdf7d8c0 Iustin Pop
        which must have the same length as the node list
157 3ef3c771 Iustin Pop

158 a8083063 Iustin Pop
    """
159 bdf7d8c0 Iustin Pop
    if address_list is None:
160 bdf7d8c0 Iustin Pop
      address_list = [None for _ in node_list]
161 bdf7d8c0 Iustin Pop
    else:
162 bdf7d8c0 Iustin Pop
      assert len(node_list) == len(address_list), \
163 bdf7d8c0 Iustin Pop
             "Name and address lists should have the same length"
164 bdf7d8c0 Iustin Pop
    for node, address in zip(node_list, address_list):
165 bdf7d8c0 Iustin Pop
      self.ConnectNode(node, address)
166 bdf7d8c0 Iustin Pop
167 bdf7d8c0 Iustin Pop
  def ConnectNode(self, name, address=None):
168 a8083063 Iustin Pop
    """Add a node to the target list.
169 a8083063 Iustin Pop

170 bdf7d8c0 Iustin Pop
    @type name: str
171 bdf7d8c0 Iustin Pop
    @param name: the node name
172 bdf7d8c0 Iustin Pop
    @type address: str
173 bdf7d8c0 Iustin Pop
    @keyword address: the node address, if known
174 bdf7d8c0 Iustin Pop

175 a8083063 Iustin Pop
    """
176 ecfe9491 Michael Hanselmann
    if address is None:
177 ecfe9491 Michael Hanselmann
      address = name
178 ecfe9491 Michael Hanselmann
179 ae88ef45 Michael Hanselmann
    self.nc[name] = \
180 ae88ef45 Michael Hanselmann
      http.client.HttpClientRequest(address, self.port, http.HTTP_PUT,
181 ae88ef45 Michael Hanselmann
                                    "/%s" % self.procedure,
182 ae88ef45 Michael Hanselmann
                                    post_data=self.body,
183 ae88ef45 Michael Hanselmann
                                    ssl_params=self._ssl_params,
184 ae88ef45 Michael Hanselmann
                                    ssl_verify_peer=True)
185 a8083063 Iustin Pop
186 3ef3c771 Iustin Pop
  def GetResults(self):
187 ecfe9491 Michael Hanselmann
    """Call nodes and return results.
188 ecfe9491 Michael Hanselmann

189 ecfe9491 Michael Hanselmann
    @rtype: list
190 ecfe9491 Michael Hanselmann
    @returns: List of RPC results
191 a8083063 Iustin Pop

192 a8083063 Iustin Pop
    """
193 4331f6cd Michael Hanselmann
    assert _http_manager, "RPC module not intialized"
194 4331f6cd Michael Hanselmann
195 4331f6cd Michael Hanselmann
    _http_manager.ExecRequests(self.nc.values())
196 a8083063 Iustin Pop
197 ecfe9491 Michael Hanselmann
    results = {}
198 a8083063 Iustin Pop
199 ecfe9491 Michael Hanselmann
    for name, req in self.nc.iteritems():
200 ae88ef45 Michael Hanselmann
      if req.success and req.resp_status_code == http.HTTP_OK:
201 781de953 Iustin Pop
        results[name] = RpcResult(data=serializer.LoadJson(req.resp_body),
202 781de953 Iustin Pop
                                  node=name, call=self.procedure)
203 ecfe9491 Michael Hanselmann
        continue
204 a8083063 Iustin Pop
205 d57ae7f7 Michael Hanselmann
      # TODO: Better error reporting
206 ecfe9491 Michael Hanselmann
      if req.error:
207 ecfe9491 Michael Hanselmann
        msg = req.error
208 ecfe9491 Michael Hanselmann
      else:
209 ecfe9491 Michael Hanselmann
        msg = req.resp_body
210 ecfe9491 Michael Hanselmann
211 ecfe9491 Michael Hanselmann
      logging.error("RPC error from node %s: %s", name, msg)
212 781de953 Iustin Pop
      results[name] = RpcResult(data=msg, failed=True, node=name,
213 781de953 Iustin Pop
                                call=self.procedure)
214 ecfe9491 Michael Hanselmann
215 ecfe9491 Michael Hanselmann
    return results
216 a8083063 Iustin Pop
217 a8083063 Iustin Pop
218 72737a7f Iustin Pop
class RpcRunner(object):
219 72737a7f Iustin Pop
  """RPC runner class"""
220 a8083063 Iustin Pop
221 72737a7f Iustin Pop
  def __init__(self, cfg):
222 72737a7f Iustin Pop
    """Initialized the rpc runner.
223 a8083063 Iustin Pop

224 72737a7f Iustin Pop
    @type cfg:  C{config.ConfigWriter}
225 72737a7f Iustin Pop
    @param cfg: the configuration object that will be used to get data
226 72737a7f Iustin Pop
                about the cluster
227 a8083063 Iustin Pop

228 72737a7f Iustin Pop
    """
229 72737a7f Iustin Pop
    self._cfg = cfg
230 160e2921 Iustin Pop
    self.port = utils.GetNodeDaemonPort()
231 a8083063 Iustin Pop
232 26ba2bd8 Iustin Pop
  def _InstDict(self, instance):
233 26ba2bd8 Iustin Pop
    """Convert the given instance to a dict.
234 26ba2bd8 Iustin Pop

235 26ba2bd8 Iustin Pop
    This is done via the instance's ToDict() method and additionally
236 26ba2bd8 Iustin Pop
    we fill the hvparams with the cluster defaults.
237 26ba2bd8 Iustin Pop

238 26ba2bd8 Iustin Pop
    @type instance: L{objects.Instance}
239 26ba2bd8 Iustin Pop
    @param instance: an Instance object
240 26ba2bd8 Iustin Pop
    @rtype: dict
241 26ba2bd8 Iustin Pop
    @return: the instance dict, with the hvparams filled with the
242 26ba2bd8 Iustin Pop
        cluster defaults
243 26ba2bd8 Iustin Pop

244 26ba2bd8 Iustin Pop
    """
245 26ba2bd8 Iustin Pop
    idict = instance.ToDict()
246 5b442704 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
247 5b442704 Iustin Pop
    idict["hvparams"] = cluster.FillHV(instance)
248 5b442704 Iustin Pop
    idict["beparams"] = cluster.FillBE(instance)
249 26ba2bd8 Iustin Pop
    return idict
250 26ba2bd8 Iustin Pop
251 25348212 Iustin Pop
  def _ConnectList(self, client, node_list):
252 25348212 Iustin Pop
    """Helper for computing node addresses.
253 25348212 Iustin Pop

254 25348212 Iustin Pop
    @type client: L{Client}
255 25348212 Iustin Pop
    @param client: a C{Client} instance
256 25348212 Iustin Pop
    @type node_list: list
257 25348212 Iustin Pop
    @param node_list: the node list we should connect
258 25348212 Iustin Pop

259 25348212 Iustin Pop
    """
260 25348212 Iustin Pop
    all_nodes = self._cfg.GetAllNodesInfo()
261 ed83f5cc Iustin Pop
    name_list = []
262 25348212 Iustin Pop
    addr_list = []
263 ed83f5cc Iustin Pop
    skip_dict = {}
264 25348212 Iustin Pop
    for node in node_list:
265 25348212 Iustin Pop
      if node in all_nodes:
266 ed83f5cc Iustin Pop
        if all_nodes[node].offline:
267 ed83f5cc Iustin Pop
          skip_dict[node] = RpcResult(node=node, offline=True)
268 ed83f5cc Iustin Pop
          continue
269 25348212 Iustin Pop
        val = all_nodes[node].primary_ip
270 25348212 Iustin Pop
      else:
271 25348212 Iustin Pop
        val = None
272 25348212 Iustin Pop
      addr_list.append(val)
273 ed83f5cc Iustin Pop
      name_list.append(node)
274 ed83f5cc Iustin Pop
    if name_list:
275 ed83f5cc Iustin Pop
      client.ConnectList(name_list, address_list=addr_list)
276 ed83f5cc Iustin Pop
    return skip_dict
277 25348212 Iustin Pop
278 25348212 Iustin Pop
  def _ConnectNode(self, client, node):
279 25348212 Iustin Pop
    """Helper for computing one node's address.
280 25348212 Iustin Pop

281 25348212 Iustin Pop
    @type client: L{Client}
282 25348212 Iustin Pop
    @param client: a C{Client} instance
283 25348212 Iustin Pop
    @type node: str
284 25348212 Iustin Pop
    @param node: the node we should connect
285 25348212 Iustin Pop

286 25348212 Iustin Pop
    """
287 25348212 Iustin Pop
    node_info = self._cfg.GetNodeInfo(node)
288 25348212 Iustin Pop
    if node_info is not None:
289 ed83f5cc Iustin Pop
      if node_info.offline:
290 ed83f5cc Iustin Pop
        return RpcResult(node=node, offline=True)
291 25348212 Iustin Pop
      addr = node_info.primary_ip
292 25348212 Iustin Pop
    else:
293 25348212 Iustin Pop
      addr = None
294 25348212 Iustin Pop
    client.ConnectNode(node, address=addr)
295 25348212 Iustin Pop
296 ed83f5cc Iustin Pop
  def _MultiNodeCall(self, node_list, procedure, args):
297 160e2921 Iustin Pop
    """Helper for making a multi-node call
298 160e2921 Iustin Pop

299 160e2921 Iustin Pop
    """
300 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
301 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
302 ed83f5cc Iustin Pop
    skip_dict = self._ConnectList(c, node_list)
303 ed83f5cc Iustin Pop
    skip_dict.update(c.GetResults())
304 ed83f5cc Iustin Pop
    return skip_dict
305 9a525d83 Michael Hanselmann
306 9a525d83 Michael Hanselmann
  @classmethod
307 9a525d83 Michael Hanselmann
  def _StaticMultiNodeCall(cls, node_list, procedure, args,
308 9a525d83 Michael Hanselmann
                           address_list=None):
309 160e2921 Iustin Pop
    """Helper for making a multi-node static call
310 160e2921 Iustin Pop

311 160e2921 Iustin Pop
    """
312 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
313 160e2921 Iustin Pop
    c = Client(procedure, body, utils.GetNodeDaemonPort())
314 9a525d83 Michael Hanselmann
    c.ConnectList(node_list, address_list=address_list)
315 9a525d83 Michael Hanselmann
    return c.GetResults()
316 9a525d83 Michael Hanselmann
317 9a525d83 Michael Hanselmann
  def _SingleNodeCall(self, node, procedure, args):
318 160e2921 Iustin Pop
    """Helper for making a single-node call
319 9a525d83 Michael Hanselmann

320 9a525d83 Michael Hanselmann
    """
321 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
322 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
323 ed83f5cc Iustin Pop
    result = self._ConnectNode(c, node)
324 ed83f5cc Iustin Pop
    if result is None:
325 ed83f5cc Iustin Pop
      # we did connect, node is not offline
326 ed83f5cc Iustin Pop
      result = c.GetResults()[node]
327 ed83f5cc Iustin Pop
    return result
328 9a525d83 Michael Hanselmann
329 9a525d83 Michael Hanselmann
  @classmethod
330 9a525d83 Michael Hanselmann
  def _StaticSingleNodeCall(cls, node, procedure, args):
331 160e2921 Iustin Pop
    """Helper for making a single-node static call
332 9a525d83 Michael Hanselmann

333 9a525d83 Michael Hanselmann
    """
334 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
335 160e2921 Iustin Pop
    c = Client(procedure, body, utils.GetNodeDaemonPort())
336 3097c858 Michael Hanselmann
    c.ConnectNode(node)
337 ed83f5cc Iustin Pop
    return c.GetResults()[node]
338 9a525d83 Michael Hanselmann
339 12bce260 Michael Hanselmann
  @staticmethod
340 12bce260 Michael Hanselmann
  def _Compress(data):
341 12bce260 Michael Hanselmann
    """Compresses a string for transport over RPC.
342 12bce260 Michael Hanselmann

343 12bce260 Michael Hanselmann
    Small amounts of data are not compressed.
344 12bce260 Michael Hanselmann

345 12bce260 Michael Hanselmann
    @type data: str
346 12bce260 Michael Hanselmann
    @param data: Data
347 12bce260 Michael Hanselmann
    @rtype: tuple
348 12bce260 Michael Hanselmann
    @return: Encoded data to send
349 12bce260 Michael Hanselmann

350 12bce260 Michael Hanselmann
    """
351 12bce260 Michael Hanselmann
    # Small amounts of data are not compressed
352 12bce260 Michael Hanselmann
    if len(data) < 512:
353 12bce260 Michael Hanselmann
      return (constants.RPC_ENCODING_NONE, data)
354 12bce260 Michael Hanselmann
355 12bce260 Michael Hanselmann
    # Compress with zlib and encode in base64
356 12bce260 Michael Hanselmann
    return (constants.RPC_ENCODING_ZLIB_BASE64,
357 12bce260 Michael Hanselmann
            base64.b64encode(zlib.compress(data, 3)))
358 12bce260 Michael Hanselmann
359 781de953 Iustin Pop
  #
360 781de953 Iustin Pop
  # Begin RPC calls
361 781de953 Iustin Pop
  #
362 781de953 Iustin Pop
363 72737a7f Iustin Pop
  def call_volume_list(self, node_list, vg_name):
364 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
365 a8083063 Iustin Pop

366 72737a7f Iustin Pop
    This is a multi-node call.
367 a8083063 Iustin Pop

368 72737a7f Iustin Pop
    """
369 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "volume_list", [vg_name])
370 a8083063 Iustin Pop
371 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
372 72737a7f Iustin Pop
    """Gets the volume group list.
373 a8083063 Iustin Pop

374 72737a7f Iustin Pop
    This is a multi-node call.
375 a8083063 Iustin Pop

376 72737a7f Iustin Pop
    """
377 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "vg_list", [])
378 a8083063 Iustin Pop
379 72737a7f Iustin Pop
  def call_bridges_exist(self, node, bridges_list):
380 72737a7f Iustin Pop
    """Checks if a node has all the bridges given.
381 a8083063 Iustin Pop

382 72737a7f Iustin Pop
    This method checks if all bridges given in the bridges_list are
383 72737a7f Iustin Pop
    present on the remote node, so that an instance that uses interfaces
384 72737a7f Iustin Pop
    on those bridges can be started.
385 a8083063 Iustin Pop

386 72737a7f Iustin Pop
    This is a single-node call.
387 a8083063 Iustin Pop

388 72737a7f Iustin Pop
    """
389 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
390 a8083063 Iustin Pop
391 72737a7f Iustin Pop
  def call_instance_start(self, node, instance, extra_args):
392 72737a7f Iustin Pop
    """Starts an instance.
393 a8083063 Iustin Pop

394 72737a7f Iustin Pop
    This is a single-node call.
395 a8083063 Iustin Pop

396 72737a7f Iustin Pop
    """
397 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_start",
398 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), extra_args])
399 a8083063 Iustin Pop
400 72737a7f Iustin Pop
  def call_instance_shutdown(self, node, instance):
401 72737a7f Iustin Pop
    """Stops an instance.
402 a8083063 Iustin Pop

403 72737a7f Iustin Pop
    This is a single-node call.
404 2a10865c Iustin Pop

405 72737a7f Iustin Pop
    """
406 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_shutdown",
407 9a525d83 Michael Hanselmann
                                [self._InstDict(instance)])
408 2a10865c Iustin Pop
409 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
410 72737a7f Iustin Pop
    """Migrate an instance.
411 2a10865c Iustin Pop

412 72737a7f Iustin Pop
    This is a single-node call.
413 2a10865c Iustin Pop

414 72737a7f Iustin Pop
    @type node: string
415 72737a7f Iustin Pop
    @param node: the node on which the instance is currently running
416 72737a7f Iustin Pop
    @type instance: C{objects.Instance}
417 72737a7f Iustin Pop
    @param instance: the instance definition
418 72737a7f Iustin Pop
    @type target: string
419 72737a7f Iustin Pop
    @param target: the target node name
420 72737a7f Iustin Pop
    @type live: boolean
421 72737a7f Iustin Pop
    @param live: whether the migration should be done live or not (the
422 72737a7f Iustin Pop
        interpretation of this parameter is left to the hypervisor)
423 007a2f3e Alexander Schreiber

424 72737a7f Iustin Pop
    """
425 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_migrate",
426 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), target, live])
427 007a2f3e Alexander Schreiber
428 72737a7f Iustin Pop
  def call_instance_reboot(self, node, instance, reboot_type, extra_args):
429 72737a7f Iustin Pop
    """Reboots an instance.
430 007a2f3e Alexander Schreiber

431 72737a7f Iustin Pop
    This is a single-node call.
432 a8083063 Iustin Pop

433 72737a7f Iustin Pop
    """
434 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_reboot",
435 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), reboot_type,
436 9a525d83 Michael Hanselmann
                                 extra_args])
437 a8083063 Iustin Pop
438 d15a9ad3 Guido Trotter
  def call_instance_os_add(self, node, inst):
439 72737a7f Iustin Pop
    """Installs an OS on the given instance.
440 a8083063 Iustin Pop

441 72737a7f Iustin Pop
    This is a single-node call.
442 decd5f45 Iustin Pop

443 72737a7f Iustin Pop
    """
444 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_add",
445 9a525d83 Michael Hanselmann
                                [self._InstDict(inst)])
446 decd5f45 Iustin Pop
447 d15a9ad3 Guido Trotter
  def call_instance_run_rename(self, node, inst, old_name):
448 72737a7f Iustin Pop
    """Run the OS rename script for an instance.
449 decd5f45 Iustin Pop

450 72737a7f Iustin Pop
    This is a single-node call.
451 a8083063 Iustin Pop

452 72737a7f Iustin Pop
    """
453 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_run_rename",
454 9a525d83 Michael Hanselmann
                                [self._InstDict(inst), old_name])
455 a8083063 Iustin Pop
456 72737a7f Iustin Pop
  def call_instance_info(self, node, instance, hname):
457 72737a7f Iustin Pop
    """Returns information about a single instance.
458 a8083063 Iustin Pop

459 72737a7f Iustin Pop
    This is a single-node call.
460 a8083063 Iustin Pop

461 9a525d83 Michael Hanselmann
    @type node: list
462 9a525d83 Michael Hanselmann
    @param node: the list of nodes to query
463 72737a7f Iustin Pop
    @type instance: string
464 72737a7f Iustin Pop
    @param instance: the instance name
465 72737a7f Iustin Pop
    @type hname: string
466 72737a7f Iustin Pop
    @param hname: the hypervisor type of the instance
467 a8083063 Iustin Pop

468 72737a7f Iustin Pop
    """
469 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_info", [instance, hname])
470 e69d05fd Iustin Pop
471 72737a7f Iustin Pop
  def call_all_instances_info(self, node_list, hypervisor_list):
472 72737a7f Iustin Pop
    """Returns information about all instances on the given nodes.
473 a8083063 Iustin Pop

474 72737a7f Iustin Pop
    This is a multi-node call.
475 a8083063 Iustin Pop

476 72737a7f Iustin Pop
    @type node_list: list
477 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
478 72737a7f Iustin Pop
    @type hypervisor_list: list
479 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
480 a8083063 Iustin Pop

481 72737a7f Iustin Pop
    """
482 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "all_instances_info",
483 9a525d83 Michael Hanselmann
                               [hypervisor_list])
484 e69d05fd Iustin Pop
485 72737a7f Iustin Pop
  def call_instance_list(self, node_list, hypervisor_list):
486 72737a7f Iustin Pop
    """Returns the list of running instances on a given node.
487 a8083063 Iustin Pop

488 72737a7f Iustin Pop
    This is a multi-node call.
489 a8083063 Iustin Pop

490 72737a7f Iustin Pop
    @type node_list: list
491 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
492 72737a7f Iustin Pop
    @type hypervisor_list: list
493 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
494 16abfbc2 Alexander Schreiber

495 72737a7f Iustin Pop
    """
496 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "instance_list", [hypervisor_list])
497 16abfbc2 Alexander Schreiber
498 72737a7f Iustin Pop
  def call_node_tcp_ping(self, node, source, target, port, timeout,
499 72737a7f Iustin Pop
                         live_port_needed):
500 72737a7f Iustin Pop
    """Do a TcpPing on the remote node
501 a8083063 Iustin Pop

502 72737a7f Iustin Pop
    This is a single-node call.
503 caad16e2 Iustin Pop

504 72737a7f Iustin Pop
    """
505 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_tcp_ping",
506 9a525d83 Michael Hanselmann
                                [source, target, port, timeout,
507 72737a7f Iustin Pop
                                 live_port_needed])
508 a8083063 Iustin Pop
509 caad16e2 Iustin Pop
  def call_node_has_ip_address(self, node, address):
510 caad16e2 Iustin Pop
    """Checks if a node has the given IP address.
511 caad16e2 Iustin Pop

512 caad16e2 Iustin Pop
    This is a single-node call.
513 caad16e2 Iustin Pop

514 caad16e2 Iustin Pop
    """
515 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_has_ip_address", [address])
516 a8083063 Iustin Pop
517 72737a7f Iustin Pop
  def call_node_info(self, node_list, vg_name, hypervisor_type):
518 72737a7f Iustin Pop
    """Return node information.
519 e69d05fd Iustin Pop

520 72737a7f Iustin Pop
    This will return memory information and volume group size and free
521 72737a7f Iustin Pop
    space.
522 a8083063 Iustin Pop

523 72737a7f Iustin Pop
    This is a multi-node call.
524 a8083063 Iustin Pop

525 72737a7f Iustin Pop
    @type node_list: list
526 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
527 c41eea6e Iustin Pop
    @type vg_name: C{string}
528 c41eea6e Iustin Pop
    @param vg_name: the name of the volume group to ask for disk space
529 72737a7f Iustin Pop
        information
530 72737a7f Iustin Pop
    @type hypervisor_type: C{str}
531 72737a7f Iustin Pop
    @param hypervisor_type: the name of the hypervisor to ask for
532 72737a7f Iustin Pop
        memory information
533 a8083063 Iustin Pop

534 72737a7f Iustin Pop
    """
535 9a525d83 Michael Hanselmann
    retux = self._MultiNodeCall(node_list, "node_info",
536 9a525d83 Michael Hanselmann
                                [vg_name, hypervisor_type])
537 a8083063 Iustin Pop
538 781de953 Iustin Pop
    for result in retux.itervalues():
539 781de953 Iustin Pop
      if result.failed or not isinstance(result.data, dict):
540 781de953 Iustin Pop
        result.data = {}
541 781de953 Iustin Pop
542 781de953 Iustin Pop
      utils.CheckDict(result.data, {
543 781de953 Iustin Pop
        'memory_total' : '-',
544 781de953 Iustin Pop
        'memory_dom0' : '-',
545 781de953 Iustin Pop
        'memory_free' : '-',
546 781de953 Iustin Pop
        'vg_size' : 'node_unreachable',
547 781de953 Iustin Pop
        'vg_free' : '-',
548 781de953 Iustin Pop
        }, "call_node_info")
549 72737a7f Iustin Pop
    return retux
550 a8083063 Iustin Pop
551 72737a7f Iustin Pop
  def call_node_add(self, node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
552 72737a7f Iustin Pop
    """Add a node to the cluster.
553 a8083063 Iustin Pop

554 72737a7f Iustin Pop
    This is a single-node call.
555 a8083063 Iustin Pop

556 72737a7f Iustin Pop
    """
557 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_add",
558 9a525d83 Michael Hanselmann
                                [dsa, dsapub, rsa, rsapub, ssh, sshpub])
559 a8083063 Iustin Pop
560 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
561 72737a7f Iustin Pop
    """Request verification of given parameters.
562 a8083063 Iustin Pop

563 72737a7f Iustin Pop
    This is a multi-node call.
564 a8083063 Iustin Pop

565 72737a7f Iustin Pop
    """
566 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
567 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
568 a8083063 Iustin Pop
569 9a525d83 Michael Hanselmann
  @classmethod
570 9a525d83 Michael Hanselmann
  def call_node_start_master(cls, node, start_daemons):
571 72737a7f Iustin Pop
    """Tells a node to activate itself as a master.
572 a8083063 Iustin Pop

573 72737a7f Iustin Pop
    This is a single-node call.
574 a8083063 Iustin Pop

575 72737a7f Iustin Pop
    """
576 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_start_master",
577 9a525d83 Michael Hanselmann
                                     [start_daemons])
578 a8083063 Iustin Pop
579 9a525d83 Michael Hanselmann
  @classmethod
580 9a525d83 Michael Hanselmann
  def call_node_stop_master(cls, node, stop_daemons):
581 72737a7f Iustin Pop
    """Tells a node to demote itself from master status.
582 a8083063 Iustin Pop

583 72737a7f Iustin Pop
    This is a single-node call.
584 4e071d3b Iustin Pop

585 72737a7f Iustin Pop
    """
586 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_stop_master", [stop_daemons])
587 4e071d3b Iustin Pop
588 9a525d83 Michael Hanselmann
  @classmethod
589 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
590 72737a7f Iustin Pop
    """Query master info.
591 4e071d3b Iustin Pop

592 72737a7f Iustin Pop
    This is a multi-node call.
593 a8083063 Iustin Pop

594 72737a7f Iustin Pop
    """
595 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
596 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
597 a8083063 Iustin Pop
598 72737a7f Iustin Pop
  def call_version(self, node_list):
599 72737a7f Iustin Pop
    """Query node version.
600 a8083063 Iustin Pop

601 72737a7f Iustin Pop
    This is a multi-node call.
602 a8083063 Iustin Pop

603 72737a7f Iustin Pop
    """
604 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "version", [])
605 a8083063 Iustin Pop
606 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
607 72737a7f Iustin Pop
    """Request creation of a given block device.
608 a8083063 Iustin Pop

609 72737a7f Iustin Pop
    This is a single-node call.
610 a8083063 Iustin Pop

611 72737a7f Iustin Pop
    """
612 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_create",
613 9a525d83 Michael Hanselmann
                                [bdev.ToDict(), size, owner, on_primary, info])
614 a8083063 Iustin Pop
615 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
616 72737a7f Iustin Pop
    """Request removal of a given block device.
617 a8083063 Iustin Pop

618 72737a7f Iustin Pop
    This is a single-node call.
619 f3e513ad Iustin Pop

620 72737a7f Iustin Pop
    """
621 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
622 f3e513ad Iustin Pop
623 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
624 72737a7f Iustin Pop
    """Request rename of the given block devices.
625 f3e513ad Iustin Pop

626 72737a7f Iustin Pop
    This is a single-node call.
627 a8083063 Iustin Pop

628 72737a7f Iustin Pop
    """
629 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_rename",
630 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
631 a8083063 Iustin Pop
632 72737a7f Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary):
633 72737a7f Iustin Pop
    """Request assembling of a given block device.
634 a8083063 Iustin Pop

635 72737a7f Iustin Pop
    This is a single-node call.
636 a8083063 Iustin Pop

637 72737a7f Iustin Pop
    """
638 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
639 9a525d83 Michael Hanselmann
                                [disk.ToDict(), owner, on_primary])
640 a8083063 Iustin Pop
641 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
642 72737a7f Iustin Pop
    """Request shutdown of a given block device.
643 a8083063 Iustin Pop

644 72737a7f Iustin Pop
    This is a single-node call.
645 a8083063 Iustin Pop

646 72737a7f Iustin Pop
    """
647 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
648 a8083063 Iustin Pop
649 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
650 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
651 a8083063 Iustin Pop

652 72737a7f Iustin Pop
    This is a single-node call.
653 a8083063 Iustin Pop

654 72737a7f Iustin Pop
    """
655 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
656 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
657 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
658 a8083063 Iustin Pop
659 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
660 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
661 a8083063 Iustin Pop

662 72737a7f Iustin Pop
    This is a single-node call.
663 a8083063 Iustin Pop

664 72737a7f Iustin Pop
    """
665 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
666 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
667 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
668 a8083063 Iustin Pop
669 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
670 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
671 a8083063 Iustin Pop

672 72737a7f Iustin Pop
    This is a single-node call.
673 a8083063 Iustin Pop

674 72737a7f Iustin Pop
    """
675 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_getmirrorstatus",
676 9a525d83 Michael Hanselmann
                                [dsk.ToDict() for dsk in disks])
677 a8083063 Iustin Pop
678 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
679 72737a7f Iustin Pop
    """Request identification of a given block device.
680 72737a7f Iustin Pop

681 72737a7f Iustin Pop
    This is a single-node call.
682 a8083063 Iustin Pop

683 72737a7f Iustin Pop
    """
684 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
685 d61cbe76 Iustin Pop
686 72737a7f Iustin Pop
  def call_blockdev_close(self, node, disks):
687 72737a7f Iustin Pop
    """Closes the given block devices.
688 d61cbe76 Iustin Pop

689 72737a7f Iustin Pop
    This is a single-node call.
690 d61cbe76 Iustin Pop

691 72737a7f Iustin Pop
    """
692 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_close",
693 9a525d83 Michael Hanselmann
                                [cf.ToDict() for cf in disks])
694 a8083063 Iustin Pop
695 9a525d83 Michael Hanselmann
  @classmethod
696 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
697 72737a7f Iustin Pop
    """Upload a file.
698 72737a7f Iustin Pop

699 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
700 72737a7f Iustin Pop
    approved file list.
701 72737a7f Iustin Pop

702 72737a7f Iustin Pop
    This is a multi-node call.
703 a8083063 Iustin Pop

704 6b294c53 Iustin Pop
    @type node_list: list
705 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
706 6b294c53 Iustin Pop
    @type file_name: str
707 6b294c53 Iustin Pop
    @param file_name: the filename to upload
708 6b294c53 Iustin Pop
    @type address_list: list or None
709 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
710 6b294c53 Iustin Pop
        to optimize the RPC speed
711 6b294c53 Iustin Pop

712 72737a7f Iustin Pop
    """
713 12bce260 Michael Hanselmann
    file_contents = utils.ReadFile(file_name)
714 12bce260 Michael Hanselmann
    data = cls._Compress(file_contents)
715 72737a7f Iustin Pop
    st = os.stat(file_name)
716 72737a7f Iustin Pop
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
717 72737a7f Iustin Pop
              st.st_atime, st.st_mtime]
718 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
719 9a525d83 Michael Hanselmann
                                    address_list=address_list)
720 72737a7f Iustin Pop
721 6ddc95ec Michael Hanselmann
  @classmethod
722 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
723 6ddc95ec Michael Hanselmann
    """Write ssconf files.
724 6ddc95ec Michael Hanselmann

725 6ddc95ec Michael Hanselmann
    This is a multi-node call.
726 6ddc95ec Michael Hanselmann

727 6ddc95ec Michael Hanselmann
    """
728 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
729 6ddc95ec Michael Hanselmann
730 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
731 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
732 72737a7f Iustin Pop

733 72737a7f Iustin Pop
    This is a multi-node call.
734 a8083063 Iustin Pop

735 72737a7f Iustin Pop
    """
736 9a525d83 Michael Hanselmann
    result = self._MultiNodeCall(node_list, "os_diagnose", [])
737 9a525d83 Michael Hanselmann
738 fab1e3a4 Iustin Pop
    for node_result in result.values():
739 781de953 Iustin Pop
      if not node_result.failed and node_result.data:
740 781de953 Iustin Pop
        node_result.data = [objects.OS.FromDict(oss)
741 781de953 Iustin Pop
                            for oss in node_result.data]
742 781de953 Iustin Pop
    return result
743 a8083063 Iustin Pop
744 72737a7f Iustin Pop
  def call_os_get(self, node, name):
745 72737a7f Iustin Pop
    """Returns an OS definition.
746 a8083063 Iustin Pop

747 72737a7f Iustin Pop
    This is a single-node call.
748 a8083063 Iustin Pop

749 72737a7f Iustin Pop
    """
750 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
751 781de953 Iustin Pop
    if not result.failed and isinstance(result.data, dict):
752 781de953 Iustin Pop
      result.data = objects.OS.FromDict(result.data)
753 781de953 Iustin Pop
    return result
754 a8083063 Iustin Pop
755 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
756 72737a7f Iustin Pop
    """Call the hooks runner.
757 a8083063 Iustin Pop

758 72737a7f Iustin Pop
    Args:
759 72737a7f Iustin Pop
      - op: the OpCode instance
760 72737a7f Iustin Pop
      - env: a dictionary with the environment
761 a8083063 Iustin Pop

762 72737a7f Iustin Pop
    This is a multi-node call.
763 a8083063 Iustin Pop

764 72737a7f Iustin Pop
    """
765 72737a7f Iustin Pop
    params = [hpath, phase, env]
766 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
767 a8083063 Iustin Pop
768 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
769 72737a7f Iustin Pop
    """Call an iallocator on a remote node
770 8d528b7c Iustin Pop

771 72737a7f Iustin Pop
    Args:
772 72737a7f Iustin Pop
      - name: the iallocator name
773 72737a7f Iustin Pop
      - input: the json-encoded input string
774 8d528b7c Iustin Pop

775 72737a7f Iustin Pop
    This is a single-node call.
776 8d528b7c Iustin Pop

777 72737a7f Iustin Pop
    """
778 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
779 8d528b7c Iustin Pop
780 72737a7f Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount):
781 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
782 4c8ba8b3 Iustin Pop

783 72737a7f Iustin Pop
    This is a single-node call.
784 4c8ba8b3 Iustin Pop

785 72737a7f Iustin Pop
    """
786 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
787 9a525d83 Michael Hanselmann
                                [cf_bdev.ToDict(), amount])
788 4c8ba8b3 Iustin Pop
789 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
790 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
791 a8083063 Iustin Pop

792 72737a7f Iustin Pop
    This is a single-node call.
793 a8083063 Iustin Pop

794 72737a7f Iustin Pop
    """
795 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
796 a8083063 Iustin Pop
797 72737a7f Iustin Pop
  def call_snapshot_export(self, node, snap_bdev, dest_node, instance,
798 74c47259 Iustin Pop
                           cluster_name, idx):
799 72737a7f Iustin Pop
    """Request the export of a given snapshot.
800 a8083063 Iustin Pop

801 72737a7f Iustin Pop
    This is a single-node call.
802 a8083063 Iustin Pop

803 72737a7f Iustin Pop
    """
804 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "snapshot_export",
805 9a525d83 Michael Hanselmann
                                [snap_bdev.ToDict(), dest_node,
806 9a525d83 Michael Hanselmann
                                 self._InstDict(instance), cluster_name, idx])
807 a8083063 Iustin Pop
808 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
809 72737a7f Iustin Pop
    """Request the completion of an export operation.
810 a8083063 Iustin Pop

811 72737a7f Iustin Pop
    This writes the export config file, etc.
812 a8083063 Iustin Pop

813 72737a7f Iustin Pop
    This is a single-node call.
814 a8083063 Iustin Pop

815 72737a7f Iustin Pop
    """
816 72737a7f Iustin Pop
    flat_disks = []
817 72737a7f Iustin Pop
    for disk in snap_disks:
818 72737a7f Iustin Pop
      flat_disks.append(disk.ToDict())
819 9a525d83 Michael Hanselmann
820 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
821 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
822 a8083063 Iustin Pop
823 72737a7f Iustin Pop
  def call_export_info(self, node, path):
824 72737a7f Iustin Pop
    """Queries the export information in a given path.
825 a8083063 Iustin Pop

826 72737a7f Iustin Pop
    This is a single-node call.
827 a8083063 Iustin Pop

828 72737a7f Iustin Pop
    """
829 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "export_info", [path])
830 781de953 Iustin Pop
    if not result.failed and result.data:
831 781de953 Iustin Pop
      result.data = objects.SerializableConfigParser.Loads(str(result.data))
832 781de953 Iustin Pop
    return result
833 a8083063 Iustin Pop
834 6c0af70e Guido Trotter
  def call_instance_os_import(self, node, inst, src_node, src_images,
835 6c0af70e Guido Trotter
                              cluster_name):
836 72737a7f Iustin Pop
    """Request the import of a backup into an instance.
837 a8083063 Iustin Pop

838 72737a7f Iustin Pop
    This is a single-node call.
839 a8083063 Iustin Pop

840 72737a7f Iustin Pop
    """
841 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_import",
842 9a525d83 Michael Hanselmann
                                [self._InstDict(inst), src_node, src_images,
843 9a525d83 Michael Hanselmann
                                 cluster_name])
844 a8083063 Iustin Pop
845 72737a7f Iustin Pop
  def call_export_list(self, node_list):
846 72737a7f Iustin Pop
    """Gets the stored exports list.
847 a8083063 Iustin Pop

848 72737a7f Iustin Pop
    This is a multi-node call.
849 a8083063 Iustin Pop

850 72737a7f Iustin Pop
    """
851 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
852 a8083063 Iustin Pop
853 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
854 72737a7f Iustin Pop
    """Requests removal of a given export.
855 a8083063 Iustin Pop

856 72737a7f Iustin Pop
    This is a single-node call.
857 a8083063 Iustin Pop

858 72737a7f Iustin Pop
    """
859 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
860 a8083063 Iustin Pop
861 9a525d83 Michael Hanselmann
  @classmethod
862 9a525d83 Michael Hanselmann
  def call_node_leave_cluster(cls, node):
863 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
864 a8083063 Iustin Pop

865 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
866 72737a7f Iustin Pop
    dir.
867 a8083063 Iustin Pop

868 72737a7f Iustin Pop
    This is a single-node call.
869 a8083063 Iustin Pop

870 72737a7f Iustin Pop
    """
871 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_leave_cluster", [])
872 dcb93971 Michael Hanselmann
873 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
874 72737a7f Iustin Pop
    """Gets all volumes on node(s).
875 dcb93971 Michael Hanselmann

876 72737a7f Iustin Pop
    This is a multi-node call.
877 dcb93971 Michael Hanselmann

878 72737a7f Iustin Pop
    """
879 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
880 06009e27 Iustin Pop
881 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
882 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
883 56aa9fd5 Iustin Pop

884 56aa9fd5 Iustin Pop
    This is a single-node call.
885 56aa9fd5 Iustin Pop

886 56aa9fd5 Iustin Pop
    """
887 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
888 56aa9fd5 Iustin Pop
889 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
890 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
891 06009e27 Iustin Pop

892 72737a7f Iustin Pop
    This is a multi-node call.
893 06009e27 Iustin Pop

894 72737a7f Iustin Pop
    """
895 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "test_delay", [duration])
896 5e04ed8b Manuel Franceschini
897 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
898 72737a7f Iustin Pop
    """Create the given file storage directory.
899 5e04ed8b Manuel Franceschini

900 72737a7f Iustin Pop
    This is a single-node call.
901 5e04ed8b Manuel Franceschini

902 72737a7f Iustin Pop
    """
903 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
904 9a525d83 Michael Hanselmann
                                [file_storage_dir])
905 5e04ed8b Manuel Franceschini
906 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
907 72737a7f Iustin Pop
    """Remove the given file storage directory.
908 5e04ed8b Manuel Franceschini

909 72737a7f Iustin Pop
    This is a single-node call.
910 5e04ed8b Manuel Franceschini

911 72737a7f Iustin Pop
    """
912 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
913 9a525d83 Michael Hanselmann
                                [file_storage_dir])
914 5e04ed8b Manuel Franceschini
915 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
916 72737a7f Iustin Pop
                                   new_file_storage_dir):
917 72737a7f Iustin Pop
    """Rename file storage directory.
918 5e04ed8b Manuel Franceschini

919 72737a7f Iustin Pop
    This is a single-node call.
920 5e04ed8b Manuel Franceschini

921 72737a7f Iustin Pop
    """
922 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
923 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
924 ca52cdeb Michael Hanselmann
925 9a525d83 Michael Hanselmann
  @classmethod
926 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
927 72737a7f Iustin Pop
    """Update job queue.
928 ca52cdeb Michael Hanselmann

929 72737a7f Iustin Pop
    This is a multi-node call.
930 ca52cdeb Michael Hanselmann

931 72737a7f Iustin Pop
    """
932 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
933 12bce260 Michael Hanselmann
                                    [file_name, cls._Compress(content)],
934 9a525d83 Michael Hanselmann
                                    address_list=address_list)
935 ca52cdeb Michael Hanselmann
936 9a525d83 Michael Hanselmann
  @classmethod
937 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
938 72737a7f Iustin Pop
    """Purge job queue.
939 ca52cdeb Michael Hanselmann

940 72737a7f Iustin Pop
    This is a single-node call.
941 ca52cdeb Michael Hanselmann

942 72737a7f Iustin Pop
    """
943 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
944 af5ebcb1 Michael Hanselmann
945 9a525d83 Michael Hanselmann
  @classmethod
946 9a525d83 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, old, new):
947 72737a7f Iustin Pop
    """Rename a job queue file.
948 af5ebcb1 Michael Hanselmann

949 72737a7f Iustin Pop
    This is a multi-node call.
950 af5ebcb1 Michael Hanselmann

951 72737a7f Iustin Pop
    """
952 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", [old, new],
953 9a525d83 Michael Hanselmann
                                    address_list=address_list)
954 6217e295 Iustin Pop
955 9a525d83 Michael Hanselmann
  @classmethod
956 9a525d83 Michael Hanselmann
  def call_jobqueue_set_drain(cls, node_list, drain_flag):
957 5d672980 Iustin Pop
    """Set the drain flag on the queue.
958 5d672980 Iustin Pop

959 5d672980 Iustin Pop
    This is a multi-node call.
960 5d672980 Iustin Pop

961 5d672980 Iustin Pop
    @type node_list: list
962 5d672980 Iustin Pop
    @param node_list: the list of nodes to query
963 5d672980 Iustin Pop
    @type drain_flag: bool
964 5d672980 Iustin Pop
    @param drain_flag: if True, will set the drain flag, otherwise reset it.
965 5d672980 Iustin Pop

966 5d672980 Iustin Pop
    """
967 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_set_drain",
968 9a525d83 Michael Hanselmann
                                    [drain_flag])
969 5d672980 Iustin Pop
970 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
971 6217e295 Iustin Pop
    """Validate the hypervisor params.
972 6217e295 Iustin Pop

973 6217e295 Iustin Pop
    This is a multi-node call.
974 6217e295 Iustin Pop

975 6217e295 Iustin Pop
    @type node_list: list
976 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
977 6217e295 Iustin Pop
    @type hvname: string
978 6217e295 Iustin Pop
    @param hvname: the hypervisor name
979 6217e295 Iustin Pop
    @type hvparams: dict
980 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
981 6217e295 Iustin Pop

982 6217e295 Iustin Pop
    """
983 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
984 6217e295 Iustin Pop
    hv_full = cluster.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
985 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
986 9a525d83 Michael Hanselmann
                               [hvname, hv_full])