Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ e4335b5b

History | View | Annotate | Download (34.4 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 58b311ca Iustin Pop
import logging
35 12bce260 Michael Hanselmann
import zlib
36 12bce260 Michael Hanselmann
import base64
37 a8083063 Iustin Pop
38 a8083063 Iustin Pop
from ganeti import utils
39 a8083063 Iustin Pop
from ganeti import objects
40 ecfe9491 Michael Hanselmann
from ganeti import http
41 7c28c575 Michael Hanselmann
from ganeti import serializer
42 eafd8762 Michael Hanselmann
from ganeti import constants
43 781de953 Iustin Pop
from ganeti import errors
44 a8083063 Iustin Pop
45 ae88ef45 Michael Hanselmann
import ganeti.http.client
46 ae88ef45 Michael Hanselmann
47 a8083063 Iustin Pop
48 4331f6cd Michael Hanselmann
# Module level variable
49 4331f6cd Michael Hanselmann
_http_manager = None
50 4331f6cd Michael Hanselmann
51 4331f6cd Michael Hanselmann
52 4331f6cd Michael Hanselmann
def Init():
53 4331f6cd Michael Hanselmann
  """Initializes the module-global HTTP client manager.
54 4331f6cd Michael Hanselmann

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

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

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

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

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

85 5bbd3f7f Michael Hanselmann
  @ivar data: the data payload, for successful results, or None
86 ed83f5cc Iustin Pop
  @ivar call: the name of the RPC call
87 ed83f5cc Iustin Pop
  @ivar node: the name of the node to which we made the call
88 ed83f5cc Iustin Pop
  @ivar offline: whether the operation failed because the node was
89 ed83f5cc Iustin Pop
      offline, as opposed to actual failure; offline=True will always
90 ed83f5cc Iustin Pop
      imply failed=True, in order to allow simpler checking if
91 ed83f5cc Iustin Pop
      the user doesn't care about the exact failure mode
92 4c4e4e1e Iustin Pop
  @ivar fail_msg: the error message if the call failed
93 ed83f5cc Iustin Pop

94 781de953 Iustin Pop
  """
95 ed83f5cc Iustin Pop
  def __init__(self, data=None, failed=False, offline=False,
96 ed83f5cc Iustin Pop
               call=None, node=None):
97 ed83f5cc Iustin Pop
    self.offline = offline
98 ed83f5cc Iustin Pop
    self.call = call
99 ed83f5cc Iustin Pop
    self.node = node
100 ed83f5cc Iustin Pop
    if offline:
101 4c4e4e1e Iustin Pop
      self.fail_msg = "Node is marked offline"
102 f2def43a Iustin Pop
      self.data = self.payload = None
103 ed83f5cc Iustin Pop
    elif failed:
104 4c4e4e1e Iustin Pop
      self.fail_msg = self._EnsureErr(data)
105 f2def43a Iustin Pop
      self.data = self.payload = None
106 781de953 Iustin Pop
    else:
107 781de953 Iustin Pop
      self.data = data
108 d3c8b360 Iustin Pop
      if not isinstance(self.data, (tuple, list)):
109 4c4e4e1e Iustin Pop
        self.fail_msg = ("RPC layer error: invalid result type (%s)" %
110 4c4e4e1e Iustin Pop
                         type(self.data))
111 d3c8b360 Iustin Pop
      elif len(data) != 2:
112 4c4e4e1e Iustin Pop
        self.fail_msg = ("RPC layer error: invalid result length (%d), "
113 4c4e4e1e Iustin Pop
                         "expected 2" % len(self.data))
114 d3c8b360 Iustin Pop
      elif not self.data[0]:
115 4c4e4e1e Iustin Pop
        self.fail_msg = self._EnsureErr(self.data[1])
116 f2def43a Iustin Pop
      else:
117 d3c8b360 Iustin Pop
        # finally success
118 4c4e4e1e Iustin Pop
        self.fail_msg = None
119 d3c8b360 Iustin Pop
        self.payload = data[1]
120 d3c8b360 Iustin Pop
121 d3c8b360 Iustin Pop
  @staticmethod
122 d3c8b360 Iustin Pop
  def _EnsureErr(val):
123 d3c8b360 Iustin Pop
    """Helper to ensure we return a 'True' value for error."""
124 d3c8b360 Iustin Pop
    if val:
125 d3c8b360 Iustin Pop
      return val
126 d3c8b360 Iustin Pop
    else:
127 d3c8b360 Iustin Pop
      return "No error information"
128 781de953 Iustin Pop
129 4c4e4e1e Iustin Pop
  def Raise(self, msg, prereq=False):
130 781de953 Iustin Pop
    """If the result has failed, raise an OpExecError.
131 781de953 Iustin Pop

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

135 781de953 Iustin Pop
    """
136 4c4e4e1e Iustin Pop
    if not self.fail_msg:
137 4c4e4e1e Iustin Pop
      return
138 4c4e4e1e Iustin Pop
139 4c4e4e1e Iustin Pop
    if not msg: # one could pass None for default message
140 4c4e4e1e Iustin Pop
      msg = ("Call '%s' to node '%s' has failed: %s" %
141 4c4e4e1e Iustin Pop
             (self.call, self.node, self.fail_msg))
142 4c4e4e1e Iustin Pop
    else:
143 4c4e4e1e Iustin Pop
      msg = "%s: %s" % (msg, self.fail_msg)
144 4c4e4e1e Iustin Pop
    if prereq:
145 4c4e4e1e Iustin Pop
      ec = errors.OpPrereqError
146 4c4e4e1e Iustin Pop
    else:
147 4c4e4e1e Iustin Pop
      ec = errors.OpExecError
148 4c4e4e1e Iustin Pop
    raise ec(msg)
149 781de953 Iustin Pop
150 781de953 Iustin Pop
151 a8083063 Iustin Pop
class Client:
152 a8083063 Iustin Pop
  """RPC Client class.
153 a8083063 Iustin Pop

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

158 5bbd3f7f Michael Hanselmann
  One current bug is that generic failure is still signaled by
159 a8083063 Iustin Pop
  'False' result, which is not good. This overloading of values can
160 a8083063 Iustin Pop
  cause bugs.
161 a8083063 Iustin Pop

162 a8083063 Iustin Pop
  """
163 160e2921 Iustin Pop
  def __init__(self, procedure, body, port):
164 a8083063 Iustin Pop
    self.procedure = procedure
165 160e2921 Iustin Pop
    self.body = body
166 160e2921 Iustin Pop
    self.port = port
167 ecfe9491 Michael Hanselmann
    self.nc = {}
168 a8083063 Iustin Pop
169 d57ae7f7 Michael Hanselmann
    self._ssl_params = \
170 d57ae7f7 Michael Hanselmann
      http.HttpSslParams(ssl_key_path=constants.SSL_CERT_FILE,
171 d57ae7f7 Michael Hanselmann
                         ssl_cert_path=constants.SSL_CERT_FILE)
172 d57ae7f7 Michael Hanselmann
173 bdf7d8c0 Iustin Pop
  def ConnectList(self, node_list, address_list=None):
174 a8083063 Iustin Pop
    """Add a list of nodes to the target nodes.
175 a8083063 Iustin Pop

176 3ef3c771 Iustin Pop
    @type node_list: list
177 3ef3c771 Iustin Pop
    @param node_list: the list of node names to connect
178 bdf7d8c0 Iustin Pop
    @type address_list: list or None
179 bdf7d8c0 Iustin Pop
    @keyword address_list: either None or a list with node addresses,
180 bdf7d8c0 Iustin Pop
        which must have the same length as the node list
181 3ef3c771 Iustin Pop

182 a8083063 Iustin Pop
    """
183 bdf7d8c0 Iustin Pop
    if address_list is None:
184 bdf7d8c0 Iustin Pop
      address_list = [None for _ in node_list]
185 bdf7d8c0 Iustin Pop
    else:
186 bdf7d8c0 Iustin Pop
      assert len(node_list) == len(address_list), \
187 bdf7d8c0 Iustin Pop
             "Name and address lists should have the same length"
188 bdf7d8c0 Iustin Pop
    for node, address in zip(node_list, address_list):
189 bdf7d8c0 Iustin Pop
      self.ConnectNode(node, address)
190 bdf7d8c0 Iustin Pop
191 bdf7d8c0 Iustin Pop
  def ConnectNode(self, name, address=None):
192 a8083063 Iustin Pop
    """Add a node to the target list.
193 a8083063 Iustin Pop

194 bdf7d8c0 Iustin Pop
    @type name: str
195 bdf7d8c0 Iustin Pop
    @param name: the node name
196 bdf7d8c0 Iustin Pop
    @type address: str
197 bdf7d8c0 Iustin Pop
    @keyword address: the node address, if known
198 bdf7d8c0 Iustin Pop

199 a8083063 Iustin Pop
    """
200 ecfe9491 Michael Hanselmann
    if address is None:
201 ecfe9491 Michael Hanselmann
      address = name
202 ecfe9491 Michael Hanselmann
203 ae88ef45 Michael Hanselmann
    self.nc[name] = \
204 ae88ef45 Michael Hanselmann
      http.client.HttpClientRequest(address, self.port, http.HTTP_PUT,
205 ae88ef45 Michael Hanselmann
                                    "/%s" % self.procedure,
206 ae88ef45 Michael Hanselmann
                                    post_data=self.body,
207 ae88ef45 Michael Hanselmann
                                    ssl_params=self._ssl_params,
208 ae88ef45 Michael Hanselmann
                                    ssl_verify_peer=True)
209 a8083063 Iustin Pop
210 3ef3c771 Iustin Pop
  def GetResults(self):
211 ecfe9491 Michael Hanselmann
    """Call nodes and return results.
212 ecfe9491 Michael Hanselmann

213 ecfe9491 Michael Hanselmann
    @rtype: list
214 5fcc718f Iustin Pop
    @return: List of RPC results
215 a8083063 Iustin Pop

216 a8083063 Iustin Pop
    """
217 5bbd3f7f Michael Hanselmann
    assert _http_manager, "RPC module not initialized"
218 4331f6cd Michael Hanselmann
219 4331f6cd Michael Hanselmann
    _http_manager.ExecRequests(self.nc.values())
220 a8083063 Iustin Pop
221 ecfe9491 Michael Hanselmann
    results = {}
222 a8083063 Iustin Pop
223 ecfe9491 Michael Hanselmann
    for name, req in self.nc.iteritems():
224 ae88ef45 Michael Hanselmann
      if req.success and req.resp_status_code == http.HTTP_OK:
225 781de953 Iustin Pop
        results[name] = RpcResult(data=serializer.LoadJson(req.resp_body),
226 781de953 Iustin Pop
                                  node=name, call=self.procedure)
227 ecfe9491 Michael Hanselmann
        continue
228 a8083063 Iustin Pop
229 d57ae7f7 Michael Hanselmann
      # TODO: Better error reporting
230 ecfe9491 Michael Hanselmann
      if req.error:
231 ecfe9491 Michael Hanselmann
        msg = req.error
232 ecfe9491 Michael Hanselmann
      else:
233 ecfe9491 Michael Hanselmann
        msg = req.resp_body
234 ecfe9491 Michael Hanselmann
235 1b8acf70 Iustin Pop
      logging.error("RPC error in %s from node %s: %s",
236 1b8acf70 Iustin Pop
                    self.procedure, name, msg)
237 781de953 Iustin Pop
      results[name] = RpcResult(data=msg, failed=True, node=name,
238 781de953 Iustin Pop
                                call=self.procedure)
239 ecfe9491 Michael Hanselmann
240 ecfe9491 Michael Hanselmann
    return results
241 a8083063 Iustin Pop
242 a8083063 Iustin Pop
243 72737a7f Iustin Pop
class RpcRunner(object):
244 72737a7f Iustin Pop
  """RPC runner class"""
245 a8083063 Iustin Pop
246 72737a7f Iustin Pop
  def __init__(self, cfg):
247 72737a7f Iustin Pop
    """Initialized the rpc runner.
248 a8083063 Iustin Pop

249 72737a7f Iustin Pop
    @type cfg:  C{config.ConfigWriter}
250 72737a7f Iustin Pop
    @param cfg: the configuration object that will be used to get data
251 72737a7f Iustin Pop
                about the cluster
252 a8083063 Iustin Pop

253 72737a7f Iustin Pop
    """
254 72737a7f Iustin Pop
    self._cfg = cfg
255 cd50653c Guido Trotter
    self.port = utils.GetDaemonPort(constants.NODED)
256 a8083063 Iustin Pop
257 0eca8e0c Iustin Pop
  def _InstDict(self, instance, hvp=None, bep=None):
258 26ba2bd8 Iustin Pop
    """Convert the given instance to a dict.
259 26ba2bd8 Iustin Pop

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

263 26ba2bd8 Iustin Pop
    @type instance: L{objects.Instance}
264 26ba2bd8 Iustin Pop
    @param instance: an Instance object
265 0eca8e0c Iustin Pop
    @type hvp: dict or None
266 5bbd3f7f Michael Hanselmann
    @param hvp: a dictionary with overridden hypervisor parameters
267 0eca8e0c Iustin Pop
    @type bep: dict or None
268 5bbd3f7f Michael Hanselmann
    @param bep: a dictionary with overridden backend parameters
269 26ba2bd8 Iustin Pop
    @rtype: dict
270 26ba2bd8 Iustin Pop
    @return: the instance dict, with the hvparams filled with the
271 26ba2bd8 Iustin Pop
        cluster defaults
272 26ba2bd8 Iustin Pop

273 26ba2bd8 Iustin Pop
    """
274 26ba2bd8 Iustin Pop
    idict = instance.ToDict()
275 5b442704 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
276 5b442704 Iustin Pop
    idict["hvparams"] = cluster.FillHV(instance)
277 0eca8e0c Iustin Pop
    if hvp is not None:
278 0eca8e0c Iustin Pop
      idict["hvparams"].update(hvp)
279 5b442704 Iustin Pop
    idict["beparams"] = cluster.FillBE(instance)
280 0eca8e0c Iustin Pop
    if bep is not None:
281 0eca8e0c Iustin Pop
      idict["beparams"].update(bep)
282 b848ce79 Guido Trotter
    for nic in idict["nics"]:
283 b848ce79 Guido Trotter
      nic['nicparams'] = objects.FillDict(
284 b848ce79 Guido Trotter
        cluster.nicparams[constants.PP_DEFAULT],
285 b848ce79 Guido Trotter
        nic['nicparams'])
286 26ba2bd8 Iustin Pop
    return idict
287 26ba2bd8 Iustin Pop
288 84b45587 Iustin Pop
  def _ConnectList(self, client, node_list, call):
289 25348212 Iustin Pop
    """Helper for computing node addresses.
290 25348212 Iustin Pop

291 6af6270a Iustin Pop
    @type client: L{ganeti.rpc.Client}
292 25348212 Iustin Pop
    @param client: a C{Client} instance
293 25348212 Iustin Pop
    @type node_list: list
294 25348212 Iustin Pop
    @param node_list: the node list we should connect
295 84b45587 Iustin Pop
    @type call: string
296 84b45587 Iustin Pop
    @param call: the name of the remote procedure call, for filling in
297 84b45587 Iustin Pop
        correctly any eventual offline nodes' results
298 25348212 Iustin Pop

299 25348212 Iustin Pop
    """
300 25348212 Iustin Pop
    all_nodes = self._cfg.GetAllNodesInfo()
301 ed83f5cc Iustin Pop
    name_list = []
302 25348212 Iustin Pop
    addr_list = []
303 ed83f5cc Iustin Pop
    skip_dict = {}
304 25348212 Iustin Pop
    for node in node_list:
305 25348212 Iustin Pop
      if node in all_nodes:
306 ed83f5cc Iustin Pop
        if all_nodes[node].offline:
307 84b45587 Iustin Pop
          skip_dict[node] = RpcResult(node=node, offline=True, call=call)
308 ed83f5cc Iustin Pop
          continue
309 25348212 Iustin Pop
        val = all_nodes[node].primary_ip
310 25348212 Iustin Pop
      else:
311 25348212 Iustin Pop
        val = None
312 25348212 Iustin Pop
      addr_list.append(val)
313 ed83f5cc Iustin Pop
      name_list.append(node)
314 ed83f5cc Iustin Pop
    if name_list:
315 ed83f5cc Iustin Pop
      client.ConnectList(name_list, address_list=addr_list)
316 ed83f5cc Iustin Pop
    return skip_dict
317 25348212 Iustin Pop
318 84b45587 Iustin Pop
  def _ConnectNode(self, client, node, call):
319 25348212 Iustin Pop
    """Helper for computing one node's address.
320 25348212 Iustin Pop

321 6af6270a Iustin Pop
    @type client: L{ganeti.rpc.Client}
322 25348212 Iustin Pop
    @param client: a C{Client} instance
323 25348212 Iustin Pop
    @type node: str
324 25348212 Iustin Pop
    @param node: the node we should connect
325 84b45587 Iustin Pop
    @type call: string
326 84b45587 Iustin Pop
    @param call: the name of the remote procedure call, for filling in
327 84b45587 Iustin Pop
        correctly any eventual offline nodes' results
328 25348212 Iustin Pop

329 25348212 Iustin Pop
    """
330 25348212 Iustin Pop
    node_info = self._cfg.GetNodeInfo(node)
331 25348212 Iustin Pop
    if node_info is not None:
332 ed83f5cc Iustin Pop
      if node_info.offline:
333 84b45587 Iustin Pop
        return RpcResult(node=node, offline=True, call=call)
334 25348212 Iustin Pop
      addr = node_info.primary_ip
335 25348212 Iustin Pop
    else:
336 25348212 Iustin Pop
      addr = None
337 25348212 Iustin Pop
    client.ConnectNode(node, address=addr)
338 25348212 Iustin Pop
339 ed83f5cc Iustin Pop
  def _MultiNodeCall(self, node_list, procedure, args):
340 160e2921 Iustin Pop
    """Helper for making a multi-node call
341 160e2921 Iustin Pop

342 160e2921 Iustin Pop
    """
343 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
344 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
345 84b45587 Iustin Pop
    skip_dict = self._ConnectList(c, node_list, procedure)
346 ed83f5cc Iustin Pop
    skip_dict.update(c.GetResults())
347 ed83f5cc Iustin Pop
    return skip_dict
348 9a525d83 Michael Hanselmann
349 9a525d83 Michael Hanselmann
  @classmethod
350 9a525d83 Michael Hanselmann
  def _StaticMultiNodeCall(cls, node_list, procedure, args,
351 9a525d83 Michael Hanselmann
                           address_list=None):
352 160e2921 Iustin Pop
    """Helper for making a multi-node static call
353 160e2921 Iustin Pop

354 160e2921 Iustin Pop
    """
355 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
356 cd50653c Guido Trotter
    c = Client(procedure, body, utils.GetDaemonPort(constants.NODED))
357 9a525d83 Michael Hanselmann
    c.ConnectList(node_list, address_list=address_list)
358 9a525d83 Michael Hanselmann
    return c.GetResults()
359 9a525d83 Michael Hanselmann
360 9a525d83 Michael Hanselmann
  def _SingleNodeCall(self, node, procedure, args):
361 160e2921 Iustin Pop
    """Helper for making a single-node call
362 9a525d83 Michael Hanselmann

363 9a525d83 Michael Hanselmann
    """
364 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
365 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
366 84b45587 Iustin Pop
    result = self._ConnectNode(c, node, procedure)
367 ed83f5cc Iustin Pop
    if result is None:
368 ed83f5cc Iustin Pop
      # we did connect, node is not offline
369 ed83f5cc Iustin Pop
      result = c.GetResults()[node]
370 ed83f5cc Iustin Pop
    return result
371 9a525d83 Michael Hanselmann
372 9a525d83 Michael Hanselmann
  @classmethod
373 9a525d83 Michael Hanselmann
  def _StaticSingleNodeCall(cls, node, procedure, args):
374 160e2921 Iustin Pop
    """Helper for making a single-node static call
375 9a525d83 Michael Hanselmann

376 9a525d83 Michael Hanselmann
    """
377 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
378 cd50653c Guido Trotter
    c = Client(procedure, body, utils.GetDaemonPort(constants.NODED))
379 3097c858 Michael Hanselmann
    c.ConnectNode(node)
380 ed83f5cc Iustin Pop
    return c.GetResults()[node]
381 9a525d83 Michael Hanselmann
382 12bce260 Michael Hanselmann
  @staticmethod
383 12bce260 Michael Hanselmann
  def _Compress(data):
384 12bce260 Michael Hanselmann
    """Compresses a string for transport over RPC.
385 12bce260 Michael Hanselmann

386 12bce260 Michael Hanselmann
    Small amounts of data are not compressed.
387 12bce260 Michael Hanselmann

388 12bce260 Michael Hanselmann
    @type data: str
389 12bce260 Michael Hanselmann
    @param data: Data
390 12bce260 Michael Hanselmann
    @rtype: tuple
391 12bce260 Michael Hanselmann
    @return: Encoded data to send
392 12bce260 Michael Hanselmann

393 12bce260 Michael Hanselmann
    """
394 12bce260 Michael Hanselmann
    # Small amounts of data are not compressed
395 12bce260 Michael Hanselmann
    if len(data) < 512:
396 12bce260 Michael Hanselmann
      return (constants.RPC_ENCODING_NONE, data)
397 12bce260 Michael Hanselmann
398 12bce260 Michael Hanselmann
    # Compress with zlib and encode in base64
399 12bce260 Michael Hanselmann
    return (constants.RPC_ENCODING_ZLIB_BASE64,
400 12bce260 Michael Hanselmann
            base64.b64encode(zlib.compress(data, 3)))
401 12bce260 Michael Hanselmann
402 781de953 Iustin Pop
  #
403 781de953 Iustin Pop
  # Begin RPC calls
404 781de953 Iustin Pop
  #
405 781de953 Iustin Pop
406 b2a6ccd4 Iustin Pop
  def call_lv_list(self, node_list, vg_name):
407 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
408 a8083063 Iustin Pop

409 72737a7f Iustin Pop
    This is a multi-node call.
410 a8083063 Iustin Pop

411 72737a7f Iustin Pop
    """
412 b2a6ccd4 Iustin Pop
    return self._MultiNodeCall(node_list, "lv_list", [vg_name])
413 a8083063 Iustin Pop
414 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
415 72737a7f Iustin Pop
    """Gets the volume group list.
416 a8083063 Iustin Pop

417 72737a7f Iustin Pop
    This is a multi-node call.
418 a8083063 Iustin Pop

419 72737a7f Iustin Pop
    """
420 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "vg_list", [])
421 a8083063 Iustin Pop
422 e337de97 Michael Hanselmann
  def call_storage_list(self, node_list, su_name, su_args, name, fields):
423 8979196a Michael Hanselmann
    """Get list of storage units.
424 e337de97 Michael Hanselmann

425 e337de97 Michael Hanselmann
    This is a multi-node call.
426 e337de97 Michael Hanselmann

427 e337de97 Michael Hanselmann
    """
428 e337de97 Michael Hanselmann
    return self._MultiNodeCall(node_list, "storage_list",
429 e337de97 Michael Hanselmann
                               [su_name, su_args, name, fields])
430 e337de97 Michael Hanselmann
431 8979196a Michael Hanselmann
  def call_storage_modify(self, node, su_name, su_args, name, changes):
432 8979196a Michael Hanselmann
    """Modify a storage unit.
433 8979196a Michael Hanselmann

434 8979196a Michael Hanselmann
    This is a single-node call.
435 8979196a Michael Hanselmann

436 8979196a Michael Hanselmann
    """
437 8979196a Michael Hanselmann
    return self._SingleNodeCall(node, "storage_modify",
438 8979196a Michael Hanselmann
                                [su_name, su_args, name, changes])
439 8979196a Michael Hanselmann
440 637b8d7e Michael Hanselmann
  def call_storage_execute(self, node, su_name, su_args, name, op):
441 637b8d7e Michael Hanselmann
    """Executes an operation on a storage unit.
442 637b8d7e Michael Hanselmann

443 637b8d7e Michael Hanselmann
    This is a single-node call.
444 637b8d7e Michael Hanselmann

445 637b8d7e Michael Hanselmann
    """
446 637b8d7e Michael Hanselmann
    return self._SingleNodeCall(node, "storage_execute",
447 637b8d7e Michael Hanselmann
                                [su_name, su_args, name, op])
448 637b8d7e Michael Hanselmann
449 72737a7f Iustin Pop
  def call_bridges_exist(self, node, bridges_list):
450 72737a7f Iustin Pop
    """Checks if a node has all the bridges given.
451 a8083063 Iustin Pop

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

456 72737a7f Iustin Pop
    This is a single-node call.
457 a8083063 Iustin Pop

458 72737a7f Iustin Pop
    """
459 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
460 a8083063 Iustin Pop
461 0eca8e0c Iustin Pop
  def call_instance_start(self, node, instance, hvp, bep):
462 72737a7f Iustin Pop
    """Starts an instance.
463 a8083063 Iustin Pop

464 72737a7f Iustin Pop
    This is a single-node call.
465 a8083063 Iustin Pop

466 72737a7f Iustin Pop
    """
467 0eca8e0c Iustin Pop
    idict = self._InstDict(instance, hvp=hvp, bep=bep)
468 0eca8e0c Iustin Pop
    return self._SingleNodeCall(node, "instance_start", [idict])
469 a8083063 Iustin Pop
470 6263189c Guido Trotter
  def call_instance_shutdown(self, node, instance, timeout):
471 72737a7f Iustin Pop
    """Stops an instance.
472 a8083063 Iustin Pop

473 72737a7f Iustin Pop
    This is a single-node call.
474 2a10865c Iustin Pop

475 72737a7f Iustin Pop
    """
476 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_shutdown",
477 6263189c Guido Trotter
                                [self._InstDict(instance), timeout])
478 2a10865c Iustin Pop
479 6906a9d8 Guido Trotter
  def call_migration_info(self, node, instance):
480 6906a9d8 Guido Trotter
    """Gather the information necessary to prepare an instance migration.
481 6906a9d8 Guido Trotter

482 6906a9d8 Guido Trotter
    This is a single-node call.
483 6906a9d8 Guido Trotter

484 6906a9d8 Guido Trotter
    @type node: string
485 6906a9d8 Guido Trotter
    @param node: the node on which the instance is currently running
486 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
487 6906a9d8 Guido Trotter
    @param instance: the instance definition
488 6906a9d8 Guido Trotter

489 6906a9d8 Guido Trotter
    """
490 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "migration_info",
491 6906a9d8 Guido Trotter
                                [self._InstDict(instance)])
492 6906a9d8 Guido Trotter
493 6906a9d8 Guido Trotter
  def call_accept_instance(self, node, instance, info, target):
494 6906a9d8 Guido Trotter
    """Prepare a node to accept an instance.
495 6906a9d8 Guido Trotter

496 6906a9d8 Guido Trotter
    This is a single-node call.
497 6906a9d8 Guido Trotter

498 6906a9d8 Guido Trotter
    @type node: string
499 6906a9d8 Guido Trotter
    @param node: the target node for the migration
500 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
501 6906a9d8 Guido Trotter
    @param instance: the instance definition
502 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
503 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
504 6906a9d8 Guido Trotter
    @type target: string
505 6906a9d8 Guido Trotter
    @param target: target hostname (usually ip address) (on the node itself)
506 6906a9d8 Guido Trotter

507 6906a9d8 Guido Trotter
    """
508 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "accept_instance",
509 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, target])
510 6906a9d8 Guido Trotter
511 6906a9d8 Guido Trotter
  def call_finalize_migration(self, node, instance, info, success):
512 6906a9d8 Guido Trotter
    """Finalize any target-node migration specific operation.
513 6906a9d8 Guido Trotter

514 6906a9d8 Guido Trotter
    This is called both in case of a successful migration and in case of error
515 6906a9d8 Guido Trotter
    (in which case it should abort the migration).
516 6906a9d8 Guido Trotter

517 6906a9d8 Guido Trotter
    This is a single-node call.
518 6906a9d8 Guido Trotter

519 6906a9d8 Guido Trotter
    @type node: string
520 6906a9d8 Guido Trotter
    @param node: the target node for the migration
521 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
522 6906a9d8 Guido Trotter
    @param instance: the instance definition
523 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
524 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
525 6906a9d8 Guido Trotter
    @type success: boolean
526 6906a9d8 Guido Trotter
    @param success: whether the migration was a success or a failure
527 6906a9d8 Guido Trotter

528 6906a9d8 Guido Trotter
    """
529 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "finalize_migration",
530 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, success])
531 6906a9d8 Guido Trotter
532 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
533 72737a7f Iustin Pop
    """Migrate an instance.
534 2a10865c Iustin Pop

535 72737a7f Iustin Pop
    This is a single-node call.
536 2a10865c Iustin Pop

537 72737a7f Iustin Pop
    @type node: string
538 72737a7f Iustin Pop
    @param node: the node on which the instance is currently running
539 72737a7f Iustin Pop
    @type instance: C{objects.Instance}
540 72737a7f Iustin Pop
    @param instance: the instance definition
541 72737a7f Iustin Pop
    @type target: string
542 72737a7f Iustin Pop
    @param target: the target node name
543 72737a7f Iustin Pop
    @type live: boolean
544 72737a7f Iustin Pop
    @param live: whether the migration should be done live or not (the
545 72737a7f Iustin Pop
        interpretation of this parameter is left to the hypervisor)
546 007a2f3e Alexander Schreiber

547 72737a7f Iustin Pop
    """
548 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_migrate",
549 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), target, live])
550 007a2f3e Alexander Schreiber
551 17c3f802 Guido Trotter
  def call_instance_reboot(self, node, inst, reboot_type, shutdown_timeout):
552 72737a7f Iustin Pop
    """Reboots an instance.
553 007a2f3e Alexander Schreiber

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, "instance_reboot",
558 17c3f802 Guido Trotter
                                [self._InstDict(inst), reboot_type,
559 17c3f802 Guido Trotter
                                 shutdown_timeout])
560 a8083063 Iustin Pop
561 e557bae9 Guido Trotter
  def call_instance_os_add(self, node, inst, reinstall):
562 72737a7f Iustin Pop
    """Installs an OS on the given instance.
563 a8083063 Iustin Pop

564 72737a7f Iustin Pop
    This is a single-node call.
565 decd5f45 Iustin Pop

566 72737a7f Iustin Pop
    """
567 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_add",
568 e557bae9 Guido Trotter
                                [self._InstDict(inst), reinstall])
569 decd5f45 Iustin Pop
570 d15a9ad3 Guido Trotter
  def call_instance_run_rename(self, node, inst, old_name):
571 72737a7f Iustin Pop
    """Run the OS rename script for an instance.
572 decd5f45 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 self._SingleNodeCall(node, "instance_run_rename",
577 9a525d83 Michael Hanselmann
                                [self._InstDict(inst), old_name])
578 a8083063 Iustin Pop
579 72737a7f Iustin Pop
  def call_instance_info(self, node, instance, hname):
580 72737a7f Iustin Pop
    """Returns information about a single instance.
581 a8083063 Iustin Pop

582 72737a7f Iustin Pop
    This is a single-node call.
583 a8083063 Iustin Pop

584 9a525d83 Michael Hanselmann
    @type node: list
585 9a525d83 Michael Hanselmann
    @param node: the list of nodes to query
586 72737a7f Iustin Pop
    @type instance: string
587 72737a7f Iustin Pop
    @param instance: the instance name
588 72737a7f Iustin Pop
    @type hname: string
589 72737a7f Iustin Pop
    @param hname: the hypervisor type of the instance
590 a8083063 Iustin Pop

591 72737a7f Iustin Pop
    """
592 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_info", [instance, hname])
593 e69d05fd Iustin Pop
594 56e7640c Iustin Pop
  def call_instance_migratable(self, node, instance):
595 56e7640c Iustin Pop
    """Checks whether the given instance can be migrated.
596 56e7640c Iustin Pop

597 56e7640c Iustin Pop
    This is a single-node call.
598 56e7640c Iustin Pop

599 56e7640c Iustin Pop
    @param node: the node to query
600 56e7640c Iustin Pop
    @type instance: L{objects.Instance}
601 56e7640c Iustin Pop
    @param instance: the instance to check
602 56e7640c Iustin Pop

603 56e7640c Iustin Pop

604 56e7640c Iustin Pop
    """
605 56e7640c Iustin Pop
    return self._SingleNodeCall(node, "instance_migratable",
606 56e7640c Iustin Pop
                                [self._InstDict(instance)])
607 56e7640c Iustin Pop
608 72737a7f Iustin Pop
  def call_all_instances_info(self, node_list, hypervisor_list):
609 72737a7f Iustin Pop
    """Returns information about all instances on the given nodes.
610 a8083063 Iustin Pop

611 72737a7f Iustin Pop
    This is a multi-node call.
612 a8083063 Iustin Pop

613 72737a7f Iustin Pop
    @type node_list: list
614 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
615 72737a7f Iustin Pop
    @type hypervisor_list: list
616 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
617 a8083063 Iustin Pop

618 72737a7f Iustin Pop
    """
619 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "all_instances_info",
620 9a525d83 Michael Hanselmann
                               [hypervisor_list])
621 e69d05fd Iustin Pop
622 72737a7f Iustin Pop
  def call_instance_list(self, node_list, hypervisor_list):
623 72737a7f Iustin Pop
    """Returns the list of running instances on a given node.
624 a8083063 Iustin Pop

625 72737a7f Iustin Pop
    This is a multi-node call.
626 a8083063 Iustin Pop

627 72737a7f Iustin Pop
    @type node_list: list
628 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
629 72737a7f Iustin Pop
    @type hypervisor_list: list
630 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
631 16abfbc2 Alexander Schreiber

632 72737a7f Iustin Pop
    """
633 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "instance_list", [hypervisor_list])
634 16abfbc2 Alexander Schreiber
635 72737a7f Iustin Pop
  def call_node_tcp_ping(self, node, source, target, port, timeout,
636 72737a7f Iustin Pop
                         live_port_needed):
637 72737a7f Iustin Pop
    """Do a TcpPing on the remote node
638 a8083063 Iustin Pop

639 72737a7f Iustin Pop
    This is a single-node call.
640 caad16e2 Iustin Pop

641 72737a7f Iustin Pop
    """
642 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_tcp_ping",
643 9a525d83 Michael Hanselmann
                                [source, target, port, timeout,
644 72737a7f Iustin Pop
                                 live_port_needed])
645 a8083063 Iustin Pop
646 caad16e2 Iustin Pop
  def call_node_has_ip_address(self, node, address):
647 caad16e2 Iustin Pop
    """Checks if a node has the given IP address.
648 caad16e2 Iustin Pop

649 caad16e2 Iustin Pop
    This is a single-node call.
650 caad16e2 Iustin Pop

651 caad16e2 Iustin Pop
    """
652 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_has_ip_address", [address])
653 a8083063 Iustin Pop
654 72737a7f Iustin Pop
  def call_node_info(self, node_list, vg_name, hypervisor_type):
655 72737a7f Iustin Pop
    """Return node information.
656 e69d05fd Iustin Pop

657 72737a7f Iustin Pop
    This will return memory information and volume group size and free
658 72737a7f Iustin Pop
    space.
659 a8083063 Iustin Pop

660 72737a7f Iustin Pop
    This is a multi-node call.
661 a8083063 Iustin Pop

662 72737a7f Iustin Pop
    @type node_list: list
663 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
664 c41eea6e Iustin Pop
    @type vg_name: C{string}
665 c41eea6e Iustin Pop
    @param vg_name: the name of the volume group to ask for disk space
666 72737a7f Iustin Pop
        information
667 72737a7f Iustin Pop
    @type hypervisor_type: C{str}
668 72737a7f Iustin Pop
    @param hypervisor_type: the name of the hypervisor to ask for
669 72737a7f Iustin Pop
        memory information
670 a8083063 Iustin Pop

671 72737a7f Iustin Pop
    """
672 070e998b Iustin Pop
    return self._MultiNodeCall(node_list, "node_info",
673 070e998b Iustin Pop
                               [vg_name, hypervisor_type])
674 a8083063 Iustin Pop
675 72737a7f Iustin Pop
  def call_node_add(self, node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
676 72737a7f Iustin Pop
    """Add a node to the cluster.
677 a8083063 Iustin Pop

678 72737a7f Iustin Pop
    This is a single-node call.
679 a8083063 Iustin Pop

680 72737a7f Iustin Pop
    """
681 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_add",
682 9a525d83 Michael Hanselmann
                                [dsa, dsapub, rsa, rsapub, ssh, sshpub])
683 a8083063 Iustin Pop
684 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
685 72737a7f Iustin Pop
    """Request verification of given parameters.
686 a8083063 Iustin Pop

687 72737a7f Iustin Pop
    This is a multi-node call.
688 a8083063 Iustin Pop

689 72737a7f Iustin Pop
    """
690 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
691 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
692 a8083063 Iustin Pop
693 9a525d83 Michael Hanselmann
  @classmethod
694 3583908a Guido Trotter
  def call_node_start_master(cls, node, start_daemons, no_voting):
695 72737a7f Iustin Pop
    """Tells a node to activate itself as a master.
696 a8083063 Iustin Pop

697 72737a7f Iustin Pop
    This is a single-node call.
698 a8083063 Iustin Pop

699 72737a7f Iustin Pop
    """
700 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_start_master",
701 3583908a Guido Trotter
                                     [start_daemons, no_voting])
702 a8083063 Iustin Pop
703 9a525d83 Michael Hanselmann
  @classmethod
704 9a525d83 Michael Hanselmann
  def call_node_stop_master(cls, node, stop_daemons):
705 72737a7f Iustin Pop
    """Tells a node to demote itself from master status.
706 a8083063 Iustin Pop

707 72737a7f Iustin Pop
    This is a single-node call.
708 4e071d3b Iustin Pop

709 72737a7f Iustin Pop
    """
710 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_stop_master", [stop_daemons])
711 4e071d3b Iustin Pop
712 9a525d83 Michael Hanselmann
  @classmethod
713 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
714 72737a7f Iustin Pop
    """Query master info.
715 4e071d3b Iustin Pop

716 72737a7f Iustin Pop
    This is a multi-node call.
717 a8083063 Iustin Pop

718 72737a7f Iustin Pop
    """
719 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
720 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
721 a8083063 Iustin Pop
722 72737a7f Iustin Pop
  def call_version(self, node_list):
723 72737a7f Iustin Pop
    """Query node version.
724 a8083063 Iustin Pop

725 72737a7f Iustin Pop
    This is a multi-node call.
726 a8083063 Iustin Pop

727 72737a7f Iustin Pop
    """
728 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "version", [])
729 a8083063 Iustin Pop
730 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
731 72737a7f Iustin Pop
    """Request creation of a given block device.
732 a8083063 Iustin Pop

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

735 72737a7f Iustin Pop
    """
736 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_create",
737 9a525d83 Michael Hanselmann
                                [bdev.ToDict(), size, owner, on_primary, info])
738 a8083063 Iustin Pop
739 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
740 72737a7f Iustin Pop
    """Request removal of a given block device.
741 a8083063 Iustin Pop

742 72737a7f Iustin Pop
    This is a single-node call.
743 f3e513ad Iustin Pop

744 72737a7f Iustin Pop
    """
745 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
746 f3e513ad Iustin Pop
747 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
748 72737a7f Iustin Pop
    """Request rename of the given block devices.
749 f3e513ad Iustin Pop

750 72737a7f Iustin Pop
    This is a single-node call.
751 a8083063 Iustin Pop

752 72737a7f Iustin Pop
    """
753 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_rename",
754 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
755 a8083063 Iustin Pop
756 72737a7f Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary):
757 72737a7f Iustin Pop
    """Request assembling of a given block device.
758 a8083063 Iustin Pop

759 72737a7f Iustin Pop
    This is a single-node call.
760 a8083063 Iustin Pop

761 72737a7f Iustin Pop
    """
762 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
763 9a525d83 Michael Hanselmann
                                [disk.ToDict(), owner, on_primary])
764 a8083063 Iustin Pop
765 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
766 72737a7f Iustin Pop
    """Request shutdown of a given block device.
767 a8083063 Iustin Pop

768 72737a7f Iustin Pop
    This is a single-node call.
769 a8083063 Iustin Pop

770 72737a7f Iustin Pop
    """
771 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
772 a8083063 Iustin Pop
773 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
774 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
775 a8083063 Iustin Pop

776 72737a7f Iustin Pop
    This is a single-node call.
777 a8083063 Iustin Pop

778 72737a7f Iustin Pop
    """
779 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
780 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
781 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
782 a8083063 Iustin Pop
783 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
784 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
785 a8083063 Iustin Pop

786 72737a7f Iustin Pop
    This is a single-node call.
787 a8083063 Iustin Pop

788 72737a7f Iustin Pop
    """
789 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
790 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
791 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
792 a8083063 Iustin Pop
793 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
794 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
795 a8083063 Iustin Pop

796 72737a7f Iustin Pop
    This is a single-node call.
797 a8083063 Iustin Pop

798 72737a7f Iustin Pop
    """
799 36145b12 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_getmirrorstatus",
800 36145b12 Michael Hanselmann
                                  [dsk.ToDict() for dsk in disks])
801 edb4b374 Michael Hanselmann
    if not result.fail_msg:
802 36145b12 Michael Hanselmann
      result.payload = [objects.BlockDevStatus.FromDict(i)
803 36145b12 Michael Hanselmann
                        for i in result.payload]
804 36145b12 Michael Hanselmann
    return result
805 a8083063 Iustin Pop
806 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
807 72737a7f Iustin Pop
    """Request identification of a given block device.
808 72737a7f Iustin Pop

809 72737a7f Iustin Pop
    This is a single-node call.
810 a8083063 Iustin Pop

811 72737a7f Iustin Pop
    """
812 96acbc09 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
813 edb4b374 Michael Hanselmann
    if not result.fail_msg and result.payload is not None:
814 96acbc09 Michael Hanselmann
      result.payload = objects.BlockDevStatus.FromDict(result.payload)
815 96acbc09 Michael Hanselmann
    return result
816 d61cbe76 Iustin Pop
817 b2e7666a Iustin Pop
  def call_blockdev_close(self, node, instance_name, disks):
818 72737a7f Iustin Pop
    """Closes the given block devices.
819 d61cbe76 Iustin Pop

820 72737a7f Iustin Pop
    This is a single-node call.
821 d61cbe76 Iustin Pop

822 72737a7f Iustin Pop
    """
823 b2e7666a Iustin Pop
    params = [instance_name, [cf.ToDict() for cf in disks]]
824 b2e7666a Iustin Pop
    return self._SingleNodeCall(node, "blockdev_close", params)
825 a8083063 Iustin Pop
826 968a7623 Iustin Pop
  def call_blockdev_getsizes(self, node, disks):
827 968a7623 Iustin Pop
    """Returns the size of the given disks.
828 968a7623 Iustin Pop

829 968a7623 Iustin Pop
    This is a single-node call.
830 968a7623 Iustin Pop

831 968a7623 Iustin Pop
    """
832 968a7623 Iustin Pop
    params = [[cf.ToDict() for cf in disks]]
833 968a7623 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_getsize", params)
834 968a7623 Iustin Pop
835 6b93ec9d Iustin Pop
  def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
836 6b93ec9d Iustin Pop
    """Disconnects the network of the given drbd devices.
837 6b93ec9d Iustin Pop

838 6b93ec9d Iustin Pop
    This is a multi-node call.
839 6b93ec9d Iustin Pop

840 6b93ec9d Iustin Pop
    """
841 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_disconnect_net",
842 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
843 6b93ec9d Iustin Pop
844 6b93ec9d Iustin Pop
  def call_drbd_attach_net(self, node_list, nodes_ip,
845 6b93ec9d Iustin Pop
                           disks, instance_name, multimaster):
846 6b93ec9d Iustin Pop
    """Disconnects the given drbd devices.
847 6b93ec9d Iustin Pop

848 6b93ec9d Iustin Pop
    This is a multi-node call.
849 6b93ec9d Iustin Pop

850 6b93ec9d Iustin Pop
    """
851 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_attach_net",
852 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks],
853 6b93ec9d Iustin Pop
                                instance_name, multimaster])
854 6b93ec9d Iustin Pop
855 6b93ec9d Iustin Pop
  def call_drbd_wait_sync(self, node_list, nodes_ip, disks):
856 6b93ec9d Iustin Pop
    """Waits for the synchronization of drbd devices is complete.
857 6b93ec9d Iustin Pop

858 6b93ec9d Iustin Pop
    This is a multi-node call.
859 6b93ec9d Iustin Pop

860 6b93ec9d Iustin Pop
    """
861 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_wait_sync",
862 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
863 6b93ec9d Iustin Pop
864 9a525d83 Michael Hanselmann
  @classmethod
865 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
866 72737a7f Iustin Pop
    """Upload a file.
867 72737a7f Iustin Pop

868 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
869 72737a7f Iustin Pop
    approved file list.
870 72737a7f Iustin Pop

871 72737a7f Iustin Pop
    This is a multi-node call.
872 a8083063 Iustin Pop

873 6b294c53 Iustin Pop
    @type node_list: list
874 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
875 6b294c53 Iustin Pop
    @type file_name: str
876 6b294c53 Iustin Pop
    @param file_name: the filename to upload
877 6b294c53 Iustin Pop
    @type address_list: list or None
878 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
879 6b294c53 Iustin Pop
        to optimize the RPC speed
880 6b294c53 Iustin Pop

881 72737a7f Iustin Pop
    """
882 12bce260 Michael Hanselmann
    file_contents = utils.ReadFile(file_name)
883 12bce260 Michael Hanselmann
    data = cls._Compress(file_contents)
884 72737a7f Iustin Pop
    st = os.stat(file_name)
885 72737a7f Iustin Pop
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
886 72737a7f Iustin Pop
              st.st_atime, st.st_mtime]
887 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
888 9a525d83 Michael Hanselmann
                                    address_list=address_list)
889 72737a7f Iustin Pop
890 6ddc95ec Michael Hanselmann
  @classmethod
891 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
892 6ddc95ec Michael Hanselmann
    """Write ssconf files.
893 6ddc95ec Michael Hanselmann

894 6ddc95ec Michael Hanselmann
    This is a multi-node call.
895 6ddc95ec Michael Hanselmann

896 6ddc95ec Michael Hanselmann
    """
897 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
898 6ddc95ec Michael Hanselmann
899 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
900 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
901 72737a7f Iustin Pop

902 72737a7f Iustin Pop
    This is a multi-node call.
903 a8083063 Iustin Pop

904 72737a7f Iustin Pop
    """
905 83d92ad8 Iustin Pop
    return self._MultiNodeCall(node_list, "os_diagnose", [])
906 a8083063 Iustin Pop
907 72737a7f Iustin Pop
  def call_os_get(self, node, name):
908 72737a7f Iustin Pop
    """Returns an OS definition.
909 a8083063 Iustin Pop

910 72737a7f Iustin Pop
    This is a single-node call.
911 a8083063 Iustin Pop

912 72737a7f Iustin Pop
    """
913 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
914 84e3f66f Guido Trotter
    if not result.fail_msg and isinstance(result.payload, dict):
915 84e3f66f Guido Trotter
      result.payload = objects.OS.FromDict(result.payload)
916 781de953 Iustin Pop
    return result
917 a8083063 Iustin Pop
918 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
919 72737a7f Iustin Pop
    """Call the hooks runner.
920 a8083063 Iustin Pop

921 72737a7f Iustin Pop
    Args:
922 72737a7f Iustin Pop
      - op: the OpCode instance
923 72737a7f Iustin Pop
      - env: a dictionary with the environment
924 a8083063 Iustin Pop

925 72737a7f Iustin Pop
    This is a multi-node call.
926 a8083063 Iustin Pop

927 72737a7f Iustin Pop
    """
928 72737a7f Iustin Pop
    params = [hpath, phase, env]
929 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
930 a8083063 Iustin Pop
931 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
932 72737a7f Iustin Pop
    """Call an iallocator on a remote node
933 8d528b7c Iustin Pop

934 72737a7f Iustin Pop
    Args:
935 72737a7f Iustin Pop
      - name: the iallocator name
936 72737a7f Iustin Pop
      - input: the json-encoded input string
937 8d528b7c Iustin Pop

938 72737a7f Iustin Pop
    This is a single-node call.
939 8d528b7c Iustin Pop

940 72737a7f Iustin Pop
    """
941 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
942 8d528b7c Iustin Pop
943 72737a7f Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount):
944 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
945 4c8ba8b3 Iustin Pop

946 72737a7f Iustin Pop
    This is a single-node call.
947 4c8ba8b3 Iustin Pop

948 72737a7f Iustin Pop
    """
949 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
950 9a525d83 Michael Hanselmann
                                [cf_bdev.ToDict(), amount])
951 4c8ba8b3 Iustin Pop
952 858f3d18 Iustin Pop
  def call_blockdev_export(self, node, cf_bdev,
953 858f3d18 Iustin Pop
                           dest_node, dest_path, cluster_name):
954 858f3d18 Iustin Pop
    """Export a given disk to another node.
955 858f3d18 Iustin Pop

956 858f3d18 Iustin Pop
    This is a single-node call.
957 858f3d18 Iustin Pop

958 858f3d18 Iustin Pop
    """
959 858f3d18 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_export",
960 858f3d18 Iustin Pop
                                [cf_bdev.ToDict(), dest_node, dest_path,
961 858f3d18 Iustin Pop
                                 cluster_name])
962 858f3d18 Iustin Pop
963 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
964 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
965 a8083063 Iustin Pop

966 72737a7f Iustin Pop
    This is a single-node call.
967 a8083063 Iustin Pop

968 72737a7f Iustin Pop
    """
969 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
970 a8083063 Iustin Pop
971 72737a7f Iustin Pop
  def call_snapshot_export(self, node, snap_bdev, dest_node, instance,
972 74c47259 Iustin Pop
                           cluster_name, idx):
973 72737a7f Iustin Pop
    """Request the export of a given snapshot.
974 a8083063 Iustin Pop

975 72737a7f Iustin Pop
    This is a single-node call.
976 a8083063 Iustin Pop

977 72737a7f Iustin Pop
    """
978 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "snapshot_export",
979 9a525d83 Michael Hanselmann
                                [snap_bdev.ToDict(), dest_node,
980 9a525d83 Michael Hanselmann
                                 self._InstDict(instance), cluster_name, idx])
981 a8083063 Iustin Pop
982 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
983 72737a7f Iustin Pop
    """Request the completion of an export operation.
984 a8083063 Iustin Pop

985 72737a7f Iustin Pop
    This writes the export config file, etc.
986 a8083063 Iustin Pop

987 72737a7f Iustin Pop
    This is a single-node call.
988 a8083063 Iustin Pop

989 72737a7f Iustin Pop
    """
990 72737a7f Iustin Pop
    flat_disks = []
991 72737a7f Iustin Pop
    for disk in snap_disks:
992 a97da6b7 Iustin Pop
      if isinstance(disk, bool):
993 a97da6b7 Iustin Pop
        flat_disks.append(disk)
994 a97da6b7 Iustin Pop
      else:
995 a97da6b7 Iustin Pop
        flat_disks.append(disk.ToDict())
996 9a525d83 Michael Hanselmann
997 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
998 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
999 a8083063 Iustin Pop
1000 72737a7f Iustin Pop
  def call_export_info(self, node, path):
1001 72737a7f Iustin Pop
    """Queries the export information in a given path.
1002 a8083063 Iustin Pop

1003 72737a7f Iustin Pop
    This is a single-node call.
1004 a8083063 Iustin Pop

1005 72737a7f Iustin Pop
    """
1006 3eccac06 Iustin Pop
    return self._SingleNodeCall(node, "export_info", [path])
1007 a8083063 Iustin Pop
1008 6c0af70e Guido Trotter
  def call_instance_os_import(self, node, inst, src_node, src_images,
1009 6c0af70e Guido Trotter
                              cluster_name):
1010 72737a7f Iustin Pop
    """Request the import of a backup into an instance.
1011 a8083063 Iustin Pop

1012 72737a7f Iustin Pop
    This is a single-node call.
1013 a8083063 Iustin Pop

1014 72737a7f Iustin Pop
    """
1015 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_import",
1016 9a525d83 Michael Hanselmann
                                [self._InstDict(inst), src_node, src_images,
1017 9a525d83 Michael Hanselmann
                                 cluster_name])
1018 a8083063 Iustin Pop
1019 72737a7f Iustin Pop
  def call_export_list(self, node_list):
1020 72737a7f Iustin Pop
    """Gets the stored exports list.
1021 a8083063 Iustin Pop

1022 72737a7f Iustin Pop
    This is a multi-node call.
1023 a8083063 Iustin Pop

1024 72737a7f Iustin Pop
    """
1025 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
1026 a8083063 Iustin Pop
1027 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
1028 72737a7f Iustin Pop
    """Requests removal of a given export.
1029 a8083063 Iustin Pop

1030 72737a7f Iustin Pop
    This is a single-node call.
1031 a8083063 Iustin Pop

1032 72737a7f Iustin Pop
    """
1033 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
1034 a8083063 Iustin Pop
1035 9a525d83 Michael Hanselmann
  @classmethod
1036 9a525d83 Michael Hanselmann
  def call_node_leave_cluster(cls, node):
1037 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
1038 a8083063 Iustin Pop

1039 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
1040 72737a7f Iustin Pop
    dir.
1041 a8083063 Iustin Pop

1042 72737a7f Iustin Pop
    This is a single-node call.
1043 a8083063 Iustin Pop

1044 72737a7f Iustin Pop
    """
1045 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_leave_cluster", [])
1046 dcb93971 Michael Hanselmann
1047 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
1048 72737a7f Iustin Pop
    """Gets all volumes on node(s).
1049 dcb93971 Michael Hanselmann

1050 72737a7f Iustin Pop
    This is a multi-node call.
1051 dcb93971 Michael Hanselmann

1052 72737a7f Iustin Pop
    """
1053 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
1054 06009e27 Iustin Pop
1055 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
1056 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
1057 56aa9fd5 Iustin Pop

1058 56aa9fd5 Iustin Pop
    This is a single-node call.
1059 56aa9fd5 Iustin Pop

1060 56aa9fd5 Iustin Pop
    """
1061 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
1062 56aa9fd5 Iustin Pop
1063 f5118ade Iustin Pop
1064 f5118ade Iustin Pop
  def call_node_powercycle(self, node, hypervisor):
1065 f5118ade Iustin Pop
    """Tries to powercycle a node.
1066 f5118ade Iustin Pop

1067 f5118ade Iustin Pop
    This is a single-node call.
1068 f5118ade Iustin Pop

1069 f5118ade Iustin Pop
    """
1070 f5118ade Iustin Pop
    return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
1071 f5118ade Iustin Pop
1072 f5118ade Iustin Pop
1073 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
1074 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
1075 06009e27 Iustin Pop

1076 72737a7f Iustin Pop
    This is a multi-node call.
1077 06009e27 Iustin Pop

1078 72737a7f Iustin Pop
    """
1079 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "test_delay", [duration])
1080 5e04ed8b Manuel Franceschini
1081 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
1082 72737a7f Iustin Pop
    """Create the given file storage directory.
1083 5e04ed8b Manuel Franceschini

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

1086 72737a7f Iustin Pop
    """
1087 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
1088 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1089 5e04ed8b Manuel Franceschini
1090 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
1091 72737a7f Iustin Pop
    """Remove the given file storage directory.
1092 5e04ed8b Manuel Franceschini

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

1095 72737a7f Iustin Pop
    """
1096 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
1097 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1098 5e04ed8b Manuel Franceschini
1099 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
1100 72737a7f Iustin Pop
                                   new_file_storage_dir):
1101 72737a7f Iustin Pop
    """Rename file storage directory.
1102 5e04ed8b Manuel Franceschini

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

1105 72737a7f Iustin Pop
    """
1106 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
1107 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
1108 ca52cdeb Michael Hanselmann
1109 9a525d83 Michael Hanselmann
  @classmethod
1110 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
1111 72737a7f Iustin Pop
    """Update job queue.
1112 ca52cdeb Michael Hanselmann

1113 72737a7f Iustin Pop
    This is a multi-node call.
1114 ca52cdeb Michael Hanselmann

1115 72737a7f Iustin Pop
    """
1116 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
1117 12bce260 Michael Hanselmann
                                    [file_name, cls._Compress(content)],
1118 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1119 ca52cdeb Michael Hanselmann
1120 9a525d83 Michael Hanselmann
  @classmethod
1121 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
1122 72737a7f Iustin Pop
    """Purge job queue.
1123 ca52cdeb Michael Hanselmann

1124 72737a7f Iustin Pop
    This is a single-node call.
1125 ca52cdeb Michael Hanselmann

1126 72737a7f Iustin Pop
    """
1127 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
1128 af5ebcb1 Michael Hanselmann
1129 9a525d83 Michael Hanselmann
  @classmethod
1130 dd875d32 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, rename):
1131 72737a7f Iustin Pop
    """Rename a job queue file.
1132 af5ebcb1 Michael Hanselmann

1133 72737a7f Iustin Pop
    This is a multi-node call.
1134 af5ebcb1 Michael Hanselmann

1135 72737a7f Iustin Pop
    """
1136 dd875d32 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
1137 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1138 6217e295 Iustin Pop
1139 9a525d83 Michael Hanselmann
  @classmethod
1140 9a525d83 Michael Hanselmann
  def call_jobqueue_set_drain(cls, node_list, drain_flag):
1141 5d672980 Iustin Pop
    """Set the drain flag on the queue.
1142 5d672980 Iustin Pop

1143 5d672980 Iustin Pop
    This is a multi-node call.
1144 5d672980 Iustin Pop

1145 5d672980 Iustin Pop
    @type node_list: list
1146 5d672980 Iustin Pop
    @param node_list: the list of nodes to query
1147 5d672980 Iustin Pop
    @type drain_flag: bool
1148 5d672980 Iustin Pop
    @param drain_flag: if True, will set the drain flag, otherwise reset it.
1149 5d672980 Iustin Pop

1150 5d672980 Iustin Pop
    """
1151 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_set_drain",
1152 9a525d83 Michael Hanselmann
                                    [drain_flag])
1153 5d672980 Iustin Pop
1154 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
1155 6217e295 Iustin Pop
    """Validate the hypervisor params.
1156 6217e295 Iustin Pop

1157 6217e295 Iustin Pop
    This is a multi-node call.
1158 6217e295 Iustin Pop

1159 6217e295 Iustin Pop
    @type node_list: list
1160 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
1161 6217e295 Iustin Pop
    @type hvname: string
1162 6217e295 Iustin Pop
    @param hvname: the hypervisor name
1163 6217e295 Iustin Pop
    @type hvparams: dict
1164 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
1165 6217e295 Iustin Pop

1166 6217e295 Iustin Pop
    """
1167 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
1168 abe609b2 Guido Trotter
    hv_full = objects.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
1169 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
1170 9a525d83 Michael Hanselmann
                               [hvname, hv_full])