Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ 045dd6d9

History | View | Annotate | Download (34.9 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 1645d22d Michael Hanselmann
101 ed83f5cc Iustin Pop
    if offline:
102 4c4e4e1e Iustin Pop
      self.fail_msg = "Node is marked offline"
103 f2def43a Iustin Pop
      self.data = self.payload = None
104 ed83f5cc Iustin Pop
    elif failed:
105 4c4e4e1e Iustin Pop
      self.fail_msg = self._EnsureErr(data)
106 f2def43a Iustin Pop
      self.data = self.payload = None
107 781de953 Iustin Pop
    else:
108 781de953 Iustin Pop
      self.data = data
109 d3c8b360 Iustin Pop
      if not isinstance(self.data, (tuple, list)):
110 4c4e4e1e Iustin Pop
        self.fail_msg = ("RPC layer error: invalid result type (%s)" %
111 4c4e4e1e Iustin Pop
                         type(self.data))
112 1645d22d Michael Hanselmann
        self.payload = None
113 d3c8b360 Iustin Pop
      elif len(data) != 2:
114 4c4e4e1e Iustin Pop
        self.fail_msg = ("RPC layer error: invalid result length (%d), "
115 4c4e4e1e Iustin Pop
                         "expected 2" % len(self.data))
116 1645d22d Michael Hanselmann
        self.payload = None
117 d3c8b360 Iustin Pop
      elif not self.data[0]:
118 4c4e4e1e Iustin Pop
        self.fail_msg = self._EnsureErr(self.data[1])
119 1645d22d Michael Hanselmann
        self.payload = None
120 f2def43a Iustin Pop
      else:
121 d3c8b360 Iustin Pop
        # finally success
122 4c4e4e1e Iustin Pop
        self.fail_msg = None
123 d3c8b360 Iustin Pop
        self.payload = data[1]
124 d3c8b360 Iustin Pop
125 1645d22d Michael Hanselmann
    assert hasattr(self, "call")
126 1645d22d Michael Hanselmann
    assert hasattr(self, "data")
127 1645d22d Michael Hanselmann
    assert hasattr(self, "fail_msg")
128 1645d22d Michael Hanselmann
    assert hasattr(self, "node")
129 1645d22d Michael Hanselmann
    assert hasattr(self, "offline")
130 1645d22d Michael Hanselmann
    assert hasattr(self, "payload")
131 1645d22d Michael Hanselmann
132 d3c8b360 Iustin Pop
  @staticmethod
133 d3c8b360 Iustin Pop
  def _EnsureErr(val):
134 d3c8b360 Iustin Pop
    """Helper to ensure we return a 'True' value for error."""
135 d3c8b360 Iustin Pop
    if val:
136 d3c8b360 Iustin Pop
      return val
137 d3c8b360 Iustin Pop
    else:
138 d3c8b360 Iustin Pop
      return "No error information"
139 781de953 Iustin Pop
140 045dd6d9 Iustin Pop
  def Raise(self, msg, prereq=False, ecode=None):
141 781de953 Iustin Pop
    """If the result has failed, raise an OpExecError.
142 781de953 Iustin Pop

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

146 781de953 Iustin Pop
    """
147 4c4e4e1e Iustin Pop
    if not self.fail_msg:
148 4c4e4e1e Iustin Pop
      return
149 4c4e4e1e Iustin Pop
150 4c4e4e1e Iustin Pop
    if not msg: # one could pass None for default message
151 4c4e4e1e Iustin Pop
      msg = ("Call '%s' to node '%s' has failed: %s" %
152 4c4e4e1e Iustin Pop
             (self.call, self.node, self.fail_msg))
153 4c4e4e1e Iustin Pop
    else:
154 4c4e4e1e Iustin Pop
      msg = "%s: %s" % (msg, self.fail_msg)
155 4c4e4e1e Iustin Pop
    if prereq:
156 4c4e4e1e Iustin Pop
      ec = errors.OpPrereqError
157 4c4e4e1e Iustin Pop
    else:
158 4c4e4e1e Iustin Pop
      ec = errors.OpExecError
159 045dd6d9 Iustin Pop
    if ecode is not None:
160 045dd6d9 Iustin Pop
      args = (msg, prereq)
161 045dd6d9 Iustin Pop
    else:
162 045dd6d9 Iustin Pop
      args = (msg, )
163 045dd6d9 Iustin Pop
    raise ec(*args)
164 781de953 Iustin Pop
165 781de953 Iustin Pop
166 a8083063 Iustin Pop
class Client:
167 a8083063 Iustin Pop
  """RPC Client class.
168 a8083063 Iustin Pop

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

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

177 a8083063 Iustin Pop
  """
178 160e2921 Iustin Pop
  def __init__(self, procedure, body, port):
179 a8083063 Iustin Pop
    self.procedure = procedure
180 160e2921 Iustin Pop
    self.body = body
181 160e2921 Iustin Pop
    self.port = port
182 ecfe9491 Michael Hanselmann
    self.nc = {}
183 a8083063 Iustin Pop
184 d57ae7f7 Michael Hanselmann
    self._ssl_params = \
185 d57ae7f7 Michael Hanselmann
      http.HttpSslParams(ssl_key_path=constants.SSL_CERT_FILE,
186 d57ae7f7 Michael Hanselmann
                         ssl_cert_path=constants.SSL_CERT_FILE)
187 d57ae7f7 Michael Hanselmann
188 bdf7d8c0 Iustin Pop
  def ConnectList(self, node_list, address_list=None):
189 a8083063 Iustin Pop
    """Add a list of nodes to the target nodes.
190 a8083063 Iustin Pop

191 3ef3c771 Iustin Pop
    @type node_list: list
192 3ef3c771 Iustin Pop
    @param node_list: the list of node names to connect
193 bdf7d8c0 Iustin Pop
    @type address_list: list or None
194 bdf7d8c0 Iustin Pop
    @keyword address_list: either None or a list with node addresses,
195 bdf7d8c0 Iustin Pop
        which must have the same length as the node list
196 3ef3c771 Iustin Pop

197 a8083063 Iustin Pop
    """
198 bdf7d8c0 Iustin Pop
    if address_list is None:
199 bdf7d8c0 Iustin Pop
      address_list = [None for _ in node_list]
200 bdf7d8c0 Iustin Pop
    else:
201 bdf7d8c0 Iustin Pop
      assert len(node_list) == len(address_list), \
202 bdf7d8c0 Iustin Pop
             "Name and address lists should have the same length"
203 bdf7d8c0 Iustin Pop
    for node, address in zip(node_list, address_list):
204 bdf7d8c0 Iustin Pop
      self.ConnectNode(node, address)
205 bdf7d8c0 Iustin Pop
206 bdf7d8c0 Iustin Pop
  def ConnectNode(self, name, address=None):
207 a8083063 Iustin Pop
    """Add a node to the target list.
208 a8083063 Iustin Pop

209 bdf7d8c0 Iustin Pop
    @type name: str
210 bdf7d8c0 Iustin Pop
    @param name: the node name
211 bdf7d8c0 Iustin Pop
    @type address: str
212 bdf7d8c0 Iustin Pop
    @keyword address: the node address, if known
213 bdf7d8c0 Iustin Pop

214 a8083063 Iustin Pop
    """
215 ecfe9491 Michael Hanselmann
    if address is None:
216 ecfe9491 Michael Hanselmann
      address = name
217 ecfe9491 Michael Hanselmann
218 ae88ef45 Michael Hanselmann
    self.nc[name] = \
219 ae88ef45 Michael Hanselmann
      http.client.HttpClientRequest(address, self.port, http.HTTP_PUT,
220 ae88ef45 Michael Hanselmann
                                    "/%s" % self.procedure,
221 ae88ef45 Michael Hanselmann
                                    post_data=self.body,
222 ae88ef45 Michael Hanselmann
                                    ssl_params=self._ssl_params,
223 ae88ef45 Michael Hanselmann
                                    ssl_verify_peer=True)
224 a8083063 Iustin Pop
225 3ef3c771 Iustin Pop
  def GetResults(self):
226 ecfe9491 Michael Hanselmann
    """Call nodes and return results.
227 ecfe9491 Michael Hanselmann

228 ecfe9491 Michael Hanselmann
    @rtype: list
229 5fcc718f Iustin Pop
    @return: List of RPC results
230 a8083063 Iustin Pop

231 a8083063 Iustin Pop
    """
232 5bbd3f7f Michael Hanselmann
    assert _http_manager, "RPC module not initialized"
233 4331f6cd Michael Hanselmann
234 4331f6cd Michael Hanselmann
    _http_manager.ExecRequests(self.nc.values())
235 a8083063 Iustin Pop
236 ecfe9491 Michael Hanselmann
    results = {}
237 a8083063 Iustin Pop
238 ecfe9491 Michael Hanselmann
    for name, req in self.nc.iteritems():
239 ae88ef45 Michael Hanselmann
      if req.success and req.resp_status_code == http.HTTP_OK:
240 781de953 Iustin Pop
        results[name] = RpcResult(data=serializer.LoadJson(req.resp_body),
241 781de953 Iustin Pop
                                  node=name, call=self.procedure)
242 ecfe9491 Michael Hanselmann
        continue
243 a8083063 Iustin Pop
244 d57ae7f7 Michael Hanselmann
      # TODO: Better error reporting
245 ecfe9491 Michael Hanselmann
      if req.error:
246 ecfe9491 Michael Hanselmann
        msg = req.error
247 ecfe9491 Michael Hanselmann
      else:
248 ecfe9491 Michael Hanselmann
        msg = req.resp_body
249 ecfe9491 Michael Hanselmann
250 1b8acf70 Iustin Pop
      logging.error("RPC error in %s from node %s: %s",
251 1b8acf70 Iustin Pop
                    self.procedure, name, msg)
252 781de953 Iustin Pop
      results[name] = RpcResult(data=msg, failed=True, node=name,
253 781de953 Iustin Pop
                                call=self.procedure)
254 ecfe9491 Michael Hanselmann
255 ecfe9491 Michael Hanselmann
    return results
256 a8083063 Iustin Pop
257 a8083063 Iustin Pop
258 72737a7f Iustin Pop
class RpcRunner(object):
259 72737a7f Iustin Pop
  """RPC runner class"""
260 a8083063 Iustin Pop
261 72737a7f Iustin Pop
  def __init__(self, cfg):
262 72737a7f Iustin Pop
    """Initialized the rpc runner.
263 a8083063 Iustin Pop

264 72737a7f Iustin Pop
    @type cfg:  C{config.ConfigWriter}
265 72737a7f Iustin Pop
    @param cfg: the configuration object that will be used to get data
266 72737a7f Iustin Pop
                about the cluster
267 a8083063 Iustin Pop

268 72737a7f Iustin Pop
    """
269 72737a7f Iustin Pop
    self._cfg = cfg
270 cd50653c Guido Trotter
    self.port = utils.GetDaemonPort(constants.NODED)
271 a8083063 Iustin Pop
272 0eca8e0c Iustin Pop
  def _InstDict(self, instance, hvp=None, bep=None):
273 26ba2bd8 Iustin Pop
    """Convert the given instance to a dict.
274 26ba2bd8 Iustin Pop

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

278 26ba2bd8 Iustin Pop
    @type instance: L{objects.Instance}
279 26ba2bd8 Iustin Pop
    @param instance: an Instance object
280 0eca8e0c Iustin Pop
    @type hvp: dict or None
281 5bbd3f7f Michael Hanselmann
    @param hvp: a dictionary with overridden hypervisor parameters
282 0eca8e0c Iustin Pop
    @type bep: dict or None
283 5bbd3f7f Michael Hanselmann
    @param bep: a dictionary with overridden backend parameters
284 26ba2bd8 Iustin Pop
    @rtype: dict
285 26ba2bd8 Iustin Pop
    @return: the instance dict, with the hvparams filled with the
286 26ba2bd8 Iustin Pop
        cluster defaults
287 26ba2bd8 Iustin Pop

288 26ba2bd8 Iustin Pop
    """
289 26ba2bd8 Iustin Pop
    idict = instance.ToDict()
290 5b442704 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
291 5b442704 Iustin Pop
    idict["hvparams"] = cluster.FillHV(instance)
292 0eca8e0c Iustin Pop
    if hvp is not None:
293 0eca8e0c Iustin Pop
      idict["hvparams"].update(hvp)
294 5b442704 Iustin Pop
    idict["beparams"] = cluster.FillBE(instance)
295 0eca8e0c Iustin Pop
    if bep is not None:
296 0eca8e0c Iustin Pop
      idict["beparams"].update(bep)
297 b848ce79 Guido Trotter
    for nic in idict["nics"]:
298 b848ce79 Guido Trotter
      nic['nicparams'] = objects.FillDict(
299 b848ce79 Guido Trotter
        cluster.nicparams[constants.PP_DEFAULT],
300 b848ce79 Guido Trotter
        nic['nicparams'])
301 26ba2bd8 Iustin Pop
    return idict
302 26ba2bd8 Iustin Pop
303 84b45587 Iustin Pop
  def _ConnectList(self, client, node_list, call):
304 25348212 Iustin Pop
    """Helper for computing node addresses.
305 25348212 Iustin Pop

306 6af6270a Iustin Pop
    @type client: L{ganeti.rpc.Client}
307 25348212 Iustin Pop
    @param client: a C{Client} instance
308 25348212 Iustin Pop
    @type node_list: list
309 25348212 Iustin Pop
    @param node_list: the node list we should connect
310 84b45587 Iustin Pop
    @type call: string
311 84b45587 Iustin Pop
    @param call: the name of the remote procedure call, for filling in
312 84b45587 Iustin Pop
        correctly any eventual offline nodes' results
313 25348212 Iustin Pop

314 25348212 Iustin Pop
    """
315 25348212 Iustin Pop
    all_nodes = self._cfg.GetAllNodesInfo()
316 ed83f5cc Iustin Pop
    name_list = []
317 25348212 Iustin Pop
    addr_list = []
318 ed83f5cc Iustin Pop
    skip_dict = {}
319 25348212 Iustin Pop
    for node in node_list:
320 25348212 Iustin Pop
      if node in all_nodes:
321 ed83f5cc Iustin Pop
        if all_nodes[node].offline:
322 84b45587 Iustin Pop
          skip_dict[node] = RpcResult(node=node, offline=True, call=call)
323 ed83f5cc Iustin Pop
          continue
324 25348212 Iustin Pop
        val = all_nodes[node].primary_ip
325 25348212 Iustin Pop
      else:
326 25348212 Iustin Pop
        val = None
327 25348212 Iustin Pop
      addr_list.append(val)
328 ed83f5cc Iustin Pop
      name_list.append(node)
329 ed83f5cc Iustin Pop
    if name_list:
330 ed83f5cc Iustin Pop
      client.ConnectList(name_list, address_list=addr_list)
331 ed83f5cc Iustin Pop
    return skip_dict
332 25348212 Iustin Pop
333 84b45587 Iustin Pop
  def _ConnectNode(self, client, node, call):
334 25348212 Iustin Pop
    """Helper for computing one node's address.
335 25348212 Iustin Pop

336 6af6270a Iustin Pop
    @type client: L{ganeti.rpc.Client}
337 25348212 Iustin Pop
    @param client: a C{Client} instance
338 25348212 Iustin Pop
    @type node: str
339 25348212 Iustin Pop
    @param node: the node we should connect
340 84b45587 Iustin Pop
    @type call: string
341 84b45587 Iustin Pop
    @param call: the name of the remote procedure call, for filling in
342 84b45587 Iustin Pop
        correctly any eventual offline nodes' results
343 25348212 Iustin Pop

344 25348212 Iustin Pop
    """
345 25348212 Iustin Pop
    node_info = self._cfg.GetNodeInfo(node)
346 25348212 Iustin Pop
    if node_info is not None:
347 ed83f5cc Iustin Pop
      if node_info.offline:
348 84b45587 Iustin Pop
        return RpcResult(node=node, offline=True, call=call)
349 25348212 Iustin Pop
      addr = node_info.primary_ip
350 25348212 Iustin Pop
    else:
351 25348212 Iustin Pop
      addr = None
352 25348212 Iustin Pop
    client.ConnectNode(node, address=addr)
353 25348212 Iustin Pop
354 ed83f5cc Iustin Pop
  def _MultiNodeCall(self, node_list, procedure, args):
355 160e2921 Iustin Pop
    """Helper for making a multi-node call
356 160e2921 Iustin Pop

357 160e2921 Iustin Pop
    """
358 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
359 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
360 84b45587 Iustin Pop
    skip_dict = self._ConnectList(c, node_list, procedure)
361 ed83f5cc Iustin Pop
    skip_dict.update(c.GetResults())
362 ed83f5cc Iustin Pop
    return skip_dict
363 9a525d83 Michael Hanselmann
364 9a525d83 Michael Hanselmann
  @classmethod
365 9a525d83 Michael Hanselmann
  def _StaticMultiNodeCall(cls, node_list, procedure, args,
366 9a525d83 Michael Hanselmann
                           address_list=None):
367 160e2921 Iustin Pop
    """Helper for making a multi-node static call
368 160e2921 Iustin Pop

369 160e2921 Iustin Pop
    """
370 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
371 cd50653c Guido Trotter
    c = Client(procedure, body, utils.GetDaemonPort(constants.NODED))
372 9a525d83 Michael Hanselmann
    c.ConnectList(node_list, address_list=address_list)
373 9a525d83 Michael Hanselmann
    return c.GetResults()
374 9a525d83 Michael Hanselmann
375 9a525d83 Michael Hanselmann
  def _SingleNodeCall(self, node, procedure, args):
376 160e2921 Iustin Pop
    """Helper for making a single-node call
377 9a525d83 Michael Hanselmann

378 9a525d83 Michael Hanselmann
    """
379 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
380 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
381 84b45587 Iustin Pop
    result = self._ConnectNode(c, node, procedure)
382 ed83f5cc Iustin Pop
    if result is None:
383 ed83f5cc Iustin Pop
      # we did connect, node is not offline
384 ed83f5cc Iustin Pop
      result = c.GetResults()[node]
385 ed83f5cc Iustin Pop
    return result
386 9a525d83 Michael Hanselmann
387 9a525d83 Michael Hanselmann
  @classmethod
388 9a525d83 Michael Hanselmann
  def _StaticSingleNodeCall(cls, node, procedure, args):
389 160e2921 Iustin Pop
    """Helper for making a single-node static call
390 9a525d83 Michael Hanselmann

391 9a525d83 Michael Hanselmann
    """
392 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
393 cd50653c Guido Trotter
    c = Client(procedure, body, utils.GetDaemonPort(constants.NODED))
394 3097c858 Michael Hanselmann
    c.ConnectNode(node)
395 ed83f5cc Iustin Pop
    return c.GetResults()[node]
396 9a525d83 Michael Hanselmann
397 12bce260 Michael Hanselmann
  @staticmethod
398 12bce260 Michael Hanselmann
  def _Compress(data):
399 12bce260 Michael Hanselmann
    """Compresses a string for transport over RPC.
400 12bce260 Michael Hanselmann

401 12bce260 Michael Hanselmann
    Small amounts of data are not compressed.
402 12bce260 Michael Hanselmann

403 12bce260 Michael Hanselmann
    @type data: str
404 12bce260 Michael Hanselmann
    @param data: Data
405 12bce260 Michael Hanselmann
    @rtype: tuple
406 12bce260 Michael Hanselmann
    @return: Encoded data to send
407 12bce260 Michael Hanselmann

408 12bce260 Michael Hanselmann
    """
409 12bce260 Michael Hanselmann
    # Small amounts of data are not compressed
410 12bce260 Michael Hanselmann
    if len(data) < 512:
411 12bce260 Michael Hanselmann
      return (constants.RPC_ENCODING_NONE, data)
412 12bce260 Michael Hanselmann
413 12bce260 Michael Hanselmann
    # Compress with zlib and encode in base64
414 12bce260 Michael Hanselmann
    return (constants.RPC_ENCODING_ZLIB_BASE64,
415 12bce260 Michael Hanselmann
            base64.b64encode(zlib.compress(data, 3)))
416 12bce260 Michael Hanselmann
417 781de953 Iustin Pop
  #
418 781de953 Iustin Pop
  # Begin RPC calls
419 781de953 Iustin Pop
  #
420 781de953 Iustin Pop
421 b2a6ccd4 Iustin Pop
  def call_lv_list(self, node_list, vg_name):
422 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
423 a8083063 Iustin Pop

424 72737a7f Iustin Pop
    This is a multi-node call.
425 a8083063 Iustin Pop

426 72737a7f Iustin Pop
    """
427 b2a6ccd4 Iustin Pop
    return self._MultiNodeCall(node_list, "lv_list", [vg_name])
428 a8083063 Iustin Pop
429 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
430 72737a7f Iustin Pop
    """Gets the volume group list.
431 a8083063 Iustin Pop

432 72737a7f Iustin Pop
    This is a multi-node call.
433 a8083063 Iustin Pop

434 72737a7f Iustin Pop
    """
435 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "vg_list", [])
436 a8083063 Iustin Pop
437 e337de97 Michael Hanselmann
  def call_storage_list(self, node_list, su_name, su_args, name, fields):
438 8979196a Michael Hanselmann
    """Get list of storage units.
439 e337de97 Michael Hanselmann

440 e337de97 Michael Hanselmann
    This is a multi-node call.
441 e337de97 Michael Hanselmann

442 e337de97 Michael Hanselmann
    """
443 e337de97 Michael Hanselmann
    return self._MultiNodeCall(node_list, "storage_list",
444 e337de97 Michael Hanselmann
                               [su_name, su_args, name, fields])
445 e337de97 Michael Hanselmann
446 8979196a Michael Hanselmann
  def call_storage_modify(self, node, su_name, su_args, name, changes):
447 8979196a Michael Hanselmann
    """Modify a storage unit.
448 8979196a Michael Hanselmann

449 8979196a Michael Hanselmann
    This is a single-node call.
450 8979196a Michael Hanselmann

451 8979196a Michael Hanselmann
    """
452 8979196a Michael Hanselmann
    return self._SingleNodeCall(node, "storage_modify",
453 8979196a Michael Hanselmann
                                [su_name, su_args, name, changes])
454 8979196a Michael Hanselmann
455 637b8d7e Michael Hanselmann
  def call_storage_execute(self, node, su_name, su_args, name, op):
456 637b8d7e Michael Hanselmann
    """Executes an operation on a storage unit.
457 637b8d7e Michael Hanselmann

458 637b8d7e Michael Hanselmann
    This is a single-node call.
459 637b8d7e Michael Hanselmann

460 637b8d7e Michael Hanselmann
    """
461 637b8d7e Michael Hanselmann
    return self._SingleNodeCall(node, "storage_execute",
462 637b8d7e Michael Hanselmann
                                [su_name, su_args, name, op])
463 637b8d7e Michael Hanselmann
464 72737a7f Iustin Pop
  def call_bridges_exist(self, node, bridges_list):
465 72737a7f Iustin Pop
    """Checks if a node has all the bridges given.
466 a8083063 Iustin Pop

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

471 72737a7f Iustin Pop
    This is a single-node call.
472 a8083063 Iustin Pop

473 72737a7f Iustin Pop
    """
474 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
475 a8083063 Iustin Pop
476 0eca8e0c Iustin Pop
  def call_instance_start(self, node, instance, hvp, bep):
477 72737a7f Iustin Pop
    """Starts an instance.
478 a8083063 Iustin Pop

479 72737a7f Iustin Pop
    This is a single-node call.
480 a8083063 Iustin Pop

481 72737a7f Iustin Pop
    """
482 0eca8e0c Iustin Pop
    idict = self._InstDict(instance, hvp=hvp, bep=bep)
483 0eca8e0c Iustin Pop
    return self._SingleNodeCall(node, "instance_start", [idict])
484 a8083063 Iustin Pop
485 6263189c Guido Trotter
  def call_instance_shutdown(self, node, instance, timeout):
486 72737a7f Iustin Pop
    """Stops an instance.
487 a8083063 Iustin Pop

488 72737a7f Iustin Pop
    This is a single-node call.
489 2a10865c Iustin Pop

490 72737a7f Iustin Pop
    """
491 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_shutdown",
492 6263189c Guido Trotter
                                [self._InstDict(instance), timeout])
493 2a10865c Iustin Pop
494 6906a9d8 Guido Trotter
  def call_migration_info(self, node, instance):
495 6906a9d8 Guido Trotter
    """Gather the information necessary to prepare an instance migration.
496 6906a9d8 Guido Trotter

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

499 6906a9d8 Guido Trotter
    @type node: string
500 6906a9d8 Guido Trotter
    @param node: the node on which the instance is currently running
501 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
502 6906a9d8 Guido Trotter
    @param instance: the instance definition
503 6906a9d8 Guido Trotter

504 6906a9d8 Guido Trotter
    """
505 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "migration_info",
506 6906a9d8 Guido Trotter
                                [self._InstDict(instance)])
507 6906a9d8 Guido Trotter
508 6906a9d8 Guido Trotter
  def call_accept_instance(self, node, instance, info, target):
509 6906a9d8 Guido Trotter
    """Prepare a node to accept an instance.
510 6906a9d8 Guido Trotter

511 6906a9d8 Guido Trotter
    This is a single-node call.
512 6906a9d8 Guido Trotter

513 6906a9d8 Guido Trotter
    @type node: string
514 6906a9d8 Guido Trotter
    @param node: the target node for the migration
515 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
516 6906a9d8 Guido Trotter
    @param instance: the instance definition
517 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
518 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
519 6906a9d8 Guido Trotter
    @type target: string
520 6906a9d8 Guido Trotter
    @param target: target hostname (usually ip address) (on the node itself)
521 6906a9d8 Guido Trotter

522 6906a9d8 Guido Trotter
    """
523 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "accept_instance",
524 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, target])
525 6906a9d8 Guido Trotter
526 6906a9d8 Guido Trotter
  def call_finalize_migration(self, node, instance, info, success):
527 6906a9d8 Guido Trotter
    """Finalize any target-node migration specific operation.
528 6906a9d8 Guido Trotter

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

532 6906a9d8 Guido Trotter
    This is a single-node call.
533 6906a9d8 Guido Trotter

534 6906a9d8 Guido Trotter
    @type node: string
535 6906a9d8 Guido Trotter
    @param node: the target node for the migration
536 6906a9d8 Guido Trotter
    @type instance: C{objects.Instance}
537 6906a9d8 Guido Trotter
    @param instance: the instance definition
538 6906a9d8 Guido Trotter
    @type info: opaque/hypervisor specific (string/data)
539 6906a9d8 Guido Trotter
    @param info: result for the call_migration_info call
540 6906a9d8 Guido Trotter
    @type success: boolean
541 6906a9d8 Guido Trotter
    @param success: whether the migration was a success or a failure
542 6906a9d8 Guido Trotter

543 6906a9d8 Guido Trotter
    """
544 6906a9d8 Guido Trotter
    return self._SingleNodeCall(node, "finalize_migration",
545 6906a9d8 Guido Trotter
                                [self._InstDict(instance), info, success])
546 6906a9d8 Guido Trotter
547 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
548 72737a7f Iustin Pop
    """Migrate an instance.
549 2a10865c Iustin Pop

550 72737a7f Iustin Pop
    This is a single-node call.
551 2a10865c Iustin Pop

552 72737a7f Iustin Pop
    @type node: string
553 72737a7f Iustin Pop
    @param node: the node on which the instance is currently running
554 72737a7f Iustin Pop
    @type instance: C{objects.Instance}
555 72737a7f Iustin Pop
    @param instance: the instance definition
556 72737a7f Iustin Pop
    @type target: string
557 72737a7f Iustin Pop
    @param target: the target node name
558 72737a7f Iustin Pop
    @type live: boolean
559 72737a7f Iustin Pop
    @param live: whether the migration should be done live or not (the
560 72737a7f Iustin Pop
        interpretation of this parameter is left to the hypervisor)
561 007a2f3e Alexander Schreiber

562 72737a7f Iustin Pop
    """
563 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_migrate",
564 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), target, live])
565 007a2f3e Alexander Schreiber
566 17c3f802 Guido Trotter
  def call_instance_reboot(self, node, inst, reboot_type, shutdown_timeout):
567 72737a7f Iustin Pop
    """Reboots an instance.
568 007a2f3e Alexander Schreiber

569 72737a7f Iustin Pop
    This is a single-node call.
570 a8083063 Iustin Pop

571 72737a7f Iustin Pop
    """
572 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_reboot",
573 17c3f802 Guido Trotter
                                [self._InstDict(inst), reboot_type,
574 17c3f802 Guido Trotter
                                 shutdown_timeout])
575 a8083063 Iustin Pop
576 e557bae9 Guido Trotter
  def call_instance_os_add(self, node, inst, reinstall):
577 72737a7f Iustin Pop
    """Installs an OS on the given instance.
578 a8083063 Iustin Pop

579 72737a7f Iustin Pop
    This is a single-node call.
580 decd5f45 Iustin Pop

581 72737a7f Iustin Pop
    """
582 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_add",
583 e557bae9 Guido Trotter
                                [self._InstDict(inst), reinstall])
584 decd5f45 Iustin Pop
585 d15a9ad3 Guido Trotter
  def call_instance_run_rename(self, node, inst, old_name):
586 72737a7f Iustin Pop
    """Run the OS rename script for an instance.
587 decd5f45 Iustin Pop

588 72737a7f Iustin Pop
    This is a single-node call.
589 a8083063 Iustin Pop

590 72737a7f Iustin Pop
    """
591 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_run_rename",
592 9a525d83 Michael Hanselmann
                                [self._InstDict(inst), old_name])
593 a8083063 Iustin Pop
594 72737a7f Iustin Pop
  def call_instance_info(self, node, instance, hname):
595 72737a7f Iustin Pop
    """Returns information about a single instance.
596 a8083063 Iustin Pop

597 72737a7f Iustin Pop
    This is a single-node call.
598 a8083063 Iustin Pop

599 9a525d83 Michael Hanselmann
    @type node: list
600 9a525d83 Michael Hanselmann
    @param node: the list of nodes to query
601 72737a7f Iustin Pop
    @type instance: string
602 72737a7f Iustin Pop
    @param instance: the instance name
603 72737a7f Iustin Pop
    @type hname: string
604 72737a7f Iustin Pop
    @param hname: the hypervisor type of the instance
605 a8083063 Iustin Pop

606 72737a7f Iustin Pop
    """
607 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_info", [instance, hname])
608 e69d05fd Iustin Pop
609 56e7640c Iustin Pop
  def call_instance_migratable(self, node, instance):
610 56e7640c Iustin Pop
    """Checks whether the given instance can be migrated.
611 56e7640c Iustin Pop

612 56e7640c Iustin Pop
    This is a single-node call.
613 56e7640c Iustin Pop

614 56e7640c Iustin Pop
    @param node: the node to query
615 56e7640c Iustin Pop
    @type instance: L{objects.Instance}
616 56e7640c Iustin Pop
    @param instance: the instance to check
617 56e7640c Iustin Pop

618 56e7640c Iustin Pop

619 56e7640c Iustin Pop
    """
620 56e7640c Iustin Pop
    return self._SingleNodeCall(node, "instance_migratable",
621 56e7640c Iustin Pop
                                [self._InstDict(instance)])
622 56e7640c Iustin Pop
623 72737a7f Iustin Pop
  def call_all_instances_info(self, node_list, hypervisor_list):
624 72737a7f Iustin Pop
    """Returns information about all instances on the given nodes.
625 a8083063 Iustin Pop

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

628 72737a7f Iustin Pop
    @type node_list: list
629 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
630 72737a7f Iustin Pop
    @type hypervisor_list: list
631 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
632 a8083063 Iustin Pop

633 72737a7f Iustin Pop
    """
634 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "all_instances_info",
635 9a525d83 Michael Hanselmann
                               [hypervisor_list])
636 e69d05fd Iustin Pop
637 72737a7f Iustin Pop
  def call_instance_list(self, node_list, hypervisor_list):
638 72737a7f Iustin Pop
    """Returns the list of running instances on a given node.
639 a8083063 Iustin Pop

640 72737a7f Iustin Pop
    This is a multi-node call.
641 a8083063 Iustin Pop

642 72737a7f Iustin Pop
    @type node_list: list
643 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
644 72737a7f Iustin Pop
    @type hypervisor_list: list
645 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
646 16abfbc2 Alexander Schreiber

647 72737a7f Iustin Pop
    """
648 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "instance_list", [hypervisor_list])
649 16abfbc2 Alexander Schreiber
650 72737a7f Iustin Pop
  def call_node_tcp_ping(self, node, source, target, port, timeout,
651 72737a7f Iustin Pop
                         live_port_needed):
652 72737a7f Iustin Pop
    """Do a TcpPing on the remote node
653 a8083063 Iustin Pop

654 72737a7f Iustin Pop
    This is a single-node call.
655 caad16e2 Iustin Pop

656 72737a7f Iustin Pop
    """
657 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_tcp_ping",
658 9a525d83 Michael Hanselmann
                                [source, target, port, timeout,
659 72737a7f Iustin Pop
                                 live_port_needed])
660 a8083063 Iustin Pop
661 caad16e2 Iustin Pop
  def call_node_has_ip_address(self, node, address):
662 caad16e2 Iustin Pop
    """Checks if a node has the given IP address.
663 caad16e2 Iustin Pop

664 caad16e2 Iustin Pop
    This is a single-node call.
665 caad16e2 Iustin Pop

666 caad16e2 Iustin Pop
    """
667 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_has_ip_address", [address])
668 a8083063 Iustin Pop
669 72737a7f Iustin Pop
  def call_node_info(self, node_list, vg_name, hypervisor_type):
670 72737a7f Iustin Pop
    """Return node information.
671 e69d05fd Iustin Pop

672 72737a7f Iustin Pop
    This will return memory information and volume group size and free
673 72737a7f Iustin Pop
    space.
674 a8083063 Iustin Pop

675 72737a7f Iustin Pop
    This is a multi-node call.
676 a8083063 Iustin Pop

677 72737a7f Iustin Pop
    @type node_list: list
678 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
679 c41eea6e Iustin Pop
    @type vg_name: C{string}
680 c41eea6e Iustin Pop
    @param vg_name: the name of the volume group to ask for disk space
681 72737a7f Iustin Pop
        information
682 72737a7f Iustin Pop
    @type hypervisor_type: C{str}
683 72737a7f Iustin Pop
    @param hypervisor_type: the name of the hypervisor to ask for
684 72737a7f Iustin Pop
        memory information
685 a8083063 Iustin Pop

686 72737a7f Iustin Pop
    """
687 070e998b Iustin Pop
    return self._MultiNodeCall(node_list, "node_info",
688 070e998b Iustin Pop
                               [vg_name, hypervisor_type])
689 a8083063 Iustin Pop
690 72737a7f Iustin Pop
  def call_node_add(self, node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
691 72737a7f Iustin Pop
    """Add a node to the cluster.
692 a8083063 Iustin Pop

693 72737a7f Iustin Pop
    This is a single-node call.
694 a8083063 Iustin Pop

695 72737a7f Iustin Pop
    """
696 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_add",
697 9a525d83 Michael Hanselmann
                                [dsa, dsapub, rsa, rsapub, ssh, sshpub])
698 a8083063 Iustin Pop
699 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
700 72737a7f Iustin Pop
    """Request verification of given parameters.
701 a8083063 Iustin Pop

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

704 72737a7f Iustin Pop
    """
705 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
706 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
707 a8083063 Iustin Pop
708 9a525d83 Michael Hanselmann
  @classmethod
709 3583908a Guido Trotter
  def call_node_start_master(cls, node, start_daemons, no_voting):
710 72737a7f Iustin Pop
    """Tells a node to activate itself as a master.
711 a8083063 Iustin Pop

712 72737a7f Iustin Pop
    This is a single-node call.
713 a8083063 Iustin Pop

714 72737a7f Iustin Pop
    """
715 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_start_master",
716 3583908a Guido Trotter
                                     [start_daemons, no_voting])
717 a8083063 Iustin Pop
718 9a525d83 Michael Hanselmann
  @classmethod
719 9a525d83 Michael Hanselmann
  def call_node_stop_master(cls, node, stop_daemons):
720 72737a7f Iustin Pop
    """Tells a node to demote itself from master status.
721 a8083063 Iustin Pop

722 72737a7f Iustin Pop
    This is a single-node call.
723 4e071d3b Iustin Pop

724 72737a7f Iustin Pop
    """
725 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_stop_master", [stop_daemons])
726 4e071d3b Iustin Pop
727 9a525d83 Michael Hanselmann
  @classmethod
728 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
729 72737a7f Iustin Pop
    """Query master info.
730 4e071d3b Iustin Pop

731 72737a7f Iustin Pop
    This is a multi-node call.
732 a8083063 Iustin Pop

733 72737a7f Iustin Pop
    """
734 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
735 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
736 a8083063 Iustin Pop
737 8f215968 Michael Hanselmann
  @classmethod
738 8f215968 Michael Hanselmann
  def call_version(cls, node_list):
739 72737a7f Iustin Pop
    """Query node version.
740 a8083063 Iustin Pop

741 72737a7f Iustin Pop
    This is a multi-node call.
742 a8083063 Iustin Pop

743 72737a7f Iustin Pop
    """
744 8f215968 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "version", [])
745 a8083063 Iustin Pop
746 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
747 72737a7f Iustin Pop
    """Request creation of a given block device.
748 a8083063 Iustin Pop

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

751 72737a7f Iustin Pop
    """
752 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_create",
753 9a525d83 Michael Hanselmann
                                [bdev.ToDict(), size, owner, on_primary, info])
754 a8083063 Iustin Pop
755 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
756 72737a7f Iustin Pop
    """Request removal of a given block device.
757 a8083063 Iustin Pop

758 72737a7f Iustin Pop
    This is a single-node call.
759 f3e513ad Iustin Pop

760 72737a7f Iustin Pop
    """
761 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
762 f3e513ad Iustin Pop
763 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
764 72737a7f Iustin Pop
    """Request rename of the given block devices.
765 f3e513ad Iustin Pop

766 72737a7f Iustin Pop
    This is a single-node call.
767 a8083063 Iustin Pop

768 72737a7f Iustin Pop
    """
769 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_rename",
770 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
771 a8083063 Iustin Pop
772 72737a7f Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary):
773 72737a7f Iustin Pop
    """Request assembling of a given block device.
774 a8083063 Iustin Pop

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

777 72737a7f Iustin Pop
    """
778 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
779 9a525d83 Michael Hanselmann
                                [disk.ToDict(), owner, on_primary])
780 a8083063 Iustin Pop
781 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
782 72737a7f Iustin Pop
    """Request shutdown of a given block device.
783 a8083063 Iustin Pop

784 72737a7f Iustin Pop
    This is a single-node call.
785 a8083063 Iustin Pop

786 72737a7f Iustin Pop
    """
787 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
788 a8083063 Iustin Pop
789 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
790 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) 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_addchildren",
796 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
797 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
798 a8083063 Iustin Pop
799 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
800 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
801 a8083063 Iustin Pop

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

804 72737a7f Iustin Pop
    """
805 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
806 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
807 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
808 a8083063 Iustin Pop
809 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
810 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
811 a8083063 Iustin Pop

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

814 72737a7f Iustin Pop
    """
815 36145b12 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_getmirrorstatus",
816 36145b12 Michael Hanselmann
                                  [dsk.ToDict() for dsk in disks])
817 edb4b374 Michael Hanselmann
    if not result.fail_msg:
818 36145b12 Michael Hanselmann
      result.payload = [objects.BlockDevStatus.FromDict(i)
819 36145b12 Michael Hanselmann
                        for i in result.payload]
820 36145b12 Michael Hanselmann
    return result
821 a8083063 Iustin Pop
822 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
823 72737a7f Iustin Pop
    """Request identification of a given block device.
824 72737a7f Iustin Pop

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

827 72737a7f Iustin Pop
    """
828 96acbc09 Michael Hanselmann
    result = self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
829 edb4b374 Michael Hanselmann
    if not result.fail_msg and result.payload is not None:
830 96acbc09 Michael Hanselmann
      result.payload = objects.BlockDevStatus.FromDict(result.payload)
831 96acbc09 Michael Hanselmann
    return result
832 d61cbe76 Iustin Pop
833 b2e7666a Iustin Pop
  def call_blockdev_close(self, node, instance_name, disks):
834 72737a7f Iustin Pop
    """Closes the given block devices.
835 d61cbe76 Iustin Pop

836 72737a7f Iustin Pop
    This is a single-node call.
837 d61cbe76 Iustin Pop

838 72737a7f Iustin Pop
    """
839 b2e7666a Iustin Pop
    params = [instance_name, [cf.ToDict() for cf in disks]]
840 b2e7666a Iustin Pop
    return self._SingleNodeCall(node, "blockdev_close", params)
841 a8083063 Iustin Pop
842 968a7623 Iustin Pop
  def call_blockdev_getsizes(self, node, disks):
843 968a7623 Iustin Pop
    """Returns the size of the given disks.
844 968a7623 Iustin Pop

845 968a7623 Iustin Pop
    This is a single-node call.
846 968a7623 Iustin Pop

847 968a7623 Iustin Pop
    """
848 968a7623 Iustin Pop
    params = [[cf.ToDict() for cf in disks]]
849 968a7623 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_getsize", params)
850 968a7623 Iustin Pop
851 6b93ec9d Iustin Pop
  def call_drbd_disconnect_net(self, node_list, nodes_ip, disks):
852 6b93ec9d Iustin Pop
    """Disconnects the network of the given drbd devices.
853 6b93ec9d Iustin Pop

854 6b93ec9d Iustin Pop
    This is a multi-node call.
855 6b93ec9d Iustin Pop

856 6b93ec9d Iustin Pop
    """
857 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_disconnect_net",
858 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
859 6b93ec9d Iustin Pop
860 6b93ec9d Iustin Pop
  def call_drbd_attach_net(self, node_list, nodes_ip,
861 6b93ec9d Iustin Pop
                           disks, instance_name, multimaster):
862 6b93ec9d Iustin Pop
    """Disconnects the given drbd devices.
863 6b93ec9d Iustin Pop

864 6b93ec9d Iustin Pop
    This is a multi-node call.
865 6b93ec9d Iustin Pop

866 6b93ec9d Iustin Pop
    """
867 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_attach_net",
868 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks],
869 6b93ec9d Iustin Pop
                                instance_name, multimaster])
870 6b93ec9d Iustin Pop
871 6b93ec9d Iustin Pop
  def call_drbd_wait_sync(self, node_list, nodes_ip, disks):
872 6b93ec9d Iustin Pop
    """Waits for the synchronization of drbd devices is complete.
873 6b93ec9d Iustin Pop

874 6b93ec9d Iustin Pop
    This is a multi-node call.
875 6b93ec9d Iustin Pop

876 6b93ec9d Iustin Pop
    """
877 6b93ec9d Iustin Pop
    return self._MultiNodeCall(node_list, "drbd_wait_sync",
878 6b93ec9d Iustin Pop
                               [nodes_ip, [cf.ToDict() for cf in disks]])
879 6b93ec9d Iustin Pop
880 9a525d83 Michael Hanselmann
  @classmethod
881 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
882 72737a7f Iustin Pop
    """Upload a file.
883 72737a7f Iustin Pop

884 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
885 72737a7f Iustin Pop
    approved file list.
886 72737a7f Iustin Pop

887 72737a7f Iustin Pop
    This is a multi-node call.
888 a8083063 Iustin Pop

889 6b294c53 Iustin Pop
    @type node_list: list
890 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
891 6b294c53 Iustin Pop
    @type file_name: str
892 6b294c53 Iustin Pop
    @param file_name: the filename to upload
893 6b294c53 Iustin Pop
    @type address_list: list or None
894 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
895 6b294c53 Iustin Pop
        to optimize the RPC speed
896 6b294c53 Iustin Pop

897 72737a7f Iustin Pop
    """
898 12bce260 Michael Hanselmann
    file_contents = utils.ReadFile(file_name)
899 12bce260 Michael Hanselmann
    data = cls._Compress(file_contents)
900 72737a7f Iustin Pop
    st = os.stat(file_name)
901 72737a7f Iustin Pop
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
902 72737a7f Iustin Pop
              st.st_atime, st.st_mtime]
903 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
904 9a525d83 Michael Hanselmann
                                    address_list=address_list)
905 72737a7f Iustin Pop
906 6ddc95ec Michael Hanselmann
  @classmethod
907 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
908 6ddc95ec Michael Hanselmann
    """Write ssconf files.
909 6ddc95ec Michael Hanselmann

910 6ddc95ec Michael Hanselmann
    This is a multi-node call.
911 6ddc95ec Michael Hanselmann

912 6ddc95ec Michael Hanselmann
    """
913 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
914 6ddc95ec Michael Hanselmann
915 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
916 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
917 72737a7f Iustin Pop

918 72737a7f Iustin Pop
    This is a multi-node call.
919 a8083063 Iustin Pop

920 72737a7f Iustin Pop
    """
921 83d92ad8 Iustin Pop
    return self._MultiNodeCall(node_list, "os_diagnose", [])
922 a8083063 Iustin Pop
923 72737a7f Iustin Pop
  def call_os_get(self, node, name):
924 72737a7f Iustin Pop
    """Returns an OS definition.
925 a8083063 Iustin Pop

926 72737a7f Iustin Pop
    This is a single-node call.
927 a8083063 Iustin Pop

928 72737a7f Iustin Pop
    """
929 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
930 84e3f66f Guido Trotter
    if not result.fail_msg and isinstance(result.payload, dict):
931 84e3f66f Guido Trotter
      result.payload = objects.OS.FromDict(result.payload)
932 781de953 Iustin Pop
    return result
933 a8083063 Iustin Pop
934 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
935 72737a7f Iustin Pop
    """Call the hooks runner.
936 a8083063 Iustin Pop

937 72737a7f Iustin Pop
    Args:
938 72737a7f Iustin Pop
      - op: the OpCode instance
939 72737a7f Iustin Pop
      - env: a dictionary with the environment
940 a8083063 Iustin Pop

941 72737a7f Iustin Pop
    This is a multi-node call.
942 a8083063 Iustin Pop

943 72737a7f Iustin Pop
    """
944 72737a7f Iustin Pop
    params = [hpath, phase, env]
945 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
946 a8083063 Iustin Pop
947 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
948 72737a7f Iustin Pop
    """Call an iallocator on a remote node
949 8d528b7c Iustin Pop

950 72737a7f Iustin Pop
    Args:
951 72737a7f Iustin Pop
      - name: the iallocator name
952 72737a7f Iustin Pop
      - input: the json-encoded input string
953 8d528b7c Iustin Pop

954 72737a7f Iustin Pop
    This is a single-node call.
955 8d528b7c Iustin Pop

956 72737a7f Iustin Pop
    """
957 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
958 8d528b7c Iustin Pop
959 72737a7f Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount):
960 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
961 4c8ba8b3 Iustin Pop

962 72737a7f Iustin Pop
    This is a single-node call.
963 4c8ba8b3 Iustin Pop

964 72737a7f Iustin Pop
    """
965 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
966 9a525d83 Michael Hanselmann
                                [cf_bdev.ToDict(), amount])
967 4c8ba8b3 Iustin Pop
968 858f3d18 Iustin Pop
  def call_blockdev_export(self, node, cf_bdev,
969 858f3d18 Iustin Pop
                           dest_node, dest_path, cluster_name):
970 858f3d18 Iustin Pop
    """Export a given disk to another node.
971 858f3d18 Iustin Pop

972 858f3d18 Iustin Pop
    This is a single-node call.
973 858f3d18 Iustin Pop

974 858f3d18 Iustin Pop
    """
975 858f3d18 Iustin Pop
    return self._SingleNodeCall(node, "blockdev_export",
976 858f3d18 Iustin Pop
                                [cf_bdev.ToDict(), dest_node, dest_path,
977 858f3d18 Iustin Pop
                                 cluster_name])
978 858f3d18 Iustin Pop
979 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
980 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
981 a8083063 Iustin Pop

982 72737a7f Iustin Pop
    This is a single-node call.
983 a8083063 Iustin Pop

984 72737a7f Iustin Pop
    """
985 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
986 a8083063 Iustin Pop
987 72737a7f Iustin Pop
  def call_snapshot_export(self, node, snap_bdev, dest_node, instance,
988 74c47259 Iustin Pop
                           cluster_name, idx):
989 72737a7f Iustin Pop
    """Request the export of a given snapshot.
990 a8083063 Iustin Pop

991 72737a7f Iustin Pop
    This is a single-node call.
992 a8083063 Iustin Pop

993 72737a7f Iustin Pop
    """
994 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "snapshot_export",
995 9a525d83 Michael Hanselmann
                                [snap_bdev.ToDict(), dest_node,
996 9a525d83 Michael Hanselmann
                                 self._InstDict(instance), cluster_name, idx])
997 a8083063 Iustin Pop
998 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
999 72737a7f Iustin Pop
    """Request the completion of an export operation.
1000 a8083063 Iustin Pop

1001 72737a7f Iustin Pop
    This writes the export config file, etc.
1002 a8083063 Iustin Pop

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

1005 72737a7f Iustin Pop
    """
1006 72737a7f Iustin Pop
    flat_disks = []
1007 72737a7f Iustin Pop
    for disk in snap_disks:
1008 a97da6b7 Iustin Pop
      if isinstance(disk, bool):
1009 a97da6b7 Iustin Pop
        flat_disks.append(disk)
1010 a97da6b7 Iustin Pop
      else:
1011 a97da6b7 Iustin Pop
        flat_disks.append(disk.ToDict())
1012 9a525d83 Michael Hanselmann
1013 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
1014 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
1015 a8083063 Iustin Pop
1016 72737a7f Iustin Pop
  def call_export_info(self, node, path):
1017 72737a7f Iustin Pop
    """Queries the export information in a given path.
1018 a8083063 Iustin Pop

1019 72737a7f Iustin Pop
    This is a single-node call.
1020 a8083063 Iustin Pop

1021 72737a7f Iustin Pop
    """
1022 3eccac06 Iustin Pop
    return self._SingleNodeCall(node, "export_info", [path])
1023 a8083063 Iustin Pop
1024 6c0af70e Guido Trotter
  def call_instance_os_import(self, node, inst, src_node, src_images,
1025 6c0af70e Guido Trotter
                              cluster_name):
1026 72737a7f Iustin Pop
    """Request the import of a backup into an instance.
1027 a8083063 Iustin Pop

1028 72737a7f Iustin Pop
    This is a single-node call.
1029 a8083063 Iustin Pop

1030 72737a7f Iustin Pop
    """
1031 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_import",
1032 9a525d83 Michael Hanselmann
                                [self._InstDict(inst), src_node, src_images,
1033 9a525d83 Michael Hanselmann
                                 cluster_name])
1034 a8083063 Iustin Pop
1035 72737a7f Iustin Pop
  def call_export_list(self, node_list):
1036 72737a7f Iustin Pop
    """Gets the stored exports list.
1037 a8083063 Iustin Pop

1038 72737a7f Iustin Pop
    This is a multi-node call.
1039 a8083063 Iustin Pop

1040 72737a7f Iustin Pop
    """
1041 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
1042 a8083063 Iustin Pop
1043 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
1044 72737a7f Iustin Pop
    """Requests removal of a given export.
1045 a8083063 Iustin Pop

1046 72737a7f Iustin Pop
    This is a single-node call.
1047 a8083063 Iustin Pop

1048 72737a7f Iustin Pop
    """
1049 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
1050 a8083063 Iustin Pop
1051 9a525d83 Michael Hanselmann
  @classmethod
1052 b989b9d9 Ken Wehr
  def call_node_leave_cluster(cls, node, modify_ssh_setup):
1053 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
1054 a8083063 Iustin Pop

1055 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
1056 72737a7f Iustin Pop
    dir.
1057 a8083063 Iustin Pop

1058 72737a7f Iustin Pop
    This is a single-node call.
1059 a8083063 Iustin Pop

1060 72737a7f Iustin Pop
    """
1061 b989b9d9 Ken Wehr
    return cls._StaticSingleNodeCall(node, "node_leave_cluster",
1062 b989b9d9 Ken Wehr
                                     [modify_ssh_setup])
1063 dcb93971 Michael Hanselmann
1064 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
1065 72737a7f Iustin Pop
    """Gets all volumes on node(s).
1066 dcb93971 Michael Hanselmann

1067 72737a7f Iustin Pop
    This is a multi-node call.
1068 dcb93971 Michael Hanselmann

1069 72737a7f Iustin Pop
    """
1070 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
1071 06009e27 Iustin Pop
1072 56aa9fd5 Iustin Pop
  def call_node_demote_from_mc(self, node):
1073 56aa9fd5 Iustin Pop
    """Demote a node from the master candidate role.
1074 56aa9fd5 Iustin Pop

1075 56aa9fd5 Iustin Pop
    This is a single-node call.
1076 56aa9fd5 Iustin Pop

1077 56aa9fd5 Iustin Pop
    """
1078 56aa9fd5 Iustin Pop
    return self._SingleNodeCall(node, "node_demote_from_mc", [])
1079 56aa9fd5 Iustin Pop
1080 f5118ade Iustin Pop
1081 f5118ade Iustin Pop
  def call_node_powercycle(self, node, hypervisor):
1082 f5118ade Iustin Pop
    """Tries to powercycle a node.
1083 f5118ade Iustin Pop

1084 f5118ade Iustin Pop
    This is a single-node call.
1085 f5118ade Iustin Pop

1086 f5118ade Iustin Pop
    """
1087 f5118ade Iustin Pop
    return self._SingleNodeCall(node, "node_powercycle", [hypervisor])
1088 f5118ade Iustin Pop
1089 f5118ade Iustin Pop
1090 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
1091 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
1092 06009e27 Iustin Pop

1093 72737a7f Iustin Pop
    This is a multi-node call.
1094 06009e27 Iustin Pop

1095 72737a7f Iustin Pop
    """
1096 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "test_delay", [duration])
1097 5e04ed8b Manuel Franceschini
1098 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
1099 72737a7f Iustin Pop
    """Create the given file storage directory.
1100 5e04ed8b Manuel Franceschini

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

1103 72737a7f Iustin Pop
    """
1104 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
1105 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1106 5e04ed8b Manuel Franceschini
1107 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
1108 72737a7f Iustin Pop
    """Remove the given file storage directory.
1109 5e04ed8b Manuel Franceschini

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

1112 72737a7f Iustin Pop
    """
1113 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
1114 9a525d83 Michael Hanselmann
                                [file_storage_dir])
1115 5e04ed8b Manuel Franceschini
1116 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
1117 72737a7f Iustin Pop
                                   new_file_storage_dir):
1118 72737a7f Iustin Pop
    """Rename file storage directory.
1119 5e04ed8b Manuel Franceschini

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

1122 72737a7f Iustin Pop
    """
1123 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
1124 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
1125 ca52cdeb Michael Hanselmann
1126 9a525d83 Michael Hanselmann
  @classmethod
1127 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
1128 72737a7f Iustin Pop
    """Update job queue.
1129 ca52cdeb Michael Hanselmann

1130 72737a7f Iustin Pop
    This is a multi-node call.
1131 ca52cdeb Michael Hanselmann

1132 72737a7f Iustin Pop
    """
1133 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
1134 12bce260 Michael Hanselmann
                                    [file_name, cls._Compress(content)],
1135 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1136 ca52cdeb Michael Hanselmann
1137 9a525d83 Michael Hanselmann
  @classmethod
1138 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
1139 72737a7f Iustin Pop
    """Purge job queue.
1140 ca52cdeb Michael Hanselmann

1141 72737a7f Iustin Pop
    This is a single-node call.
1142 ca52cdeb Michael Hanselmann

1143 72737a7f Iustin Pop
    """
1144 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
1145 af5ebcb1 Michael Hanselmann
1146 9a525d83 Michael Hanselmann
  @classmethod
1147 dd875d32 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, rename):
1148 72737a7f Iustin Pop
    """Rename a job queue file.
1149 af5ebcb1 Michael Hanselmann

1150 72737a7f Iustin Pop
    This is a multi-node call.
1151 af5ebcb1 Michael Hanselmann

1152 72737a7f Iustin Pop
    """
1153 dd875d32 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", rename,
1154 9a525d83 Michael Hanselmann
                                    address_list=address_list)
1155 6217e295 Iustin Pop
1156 9a525d83 Michael Hanselmann
  @classmethod
1157 9a525d83 Michael Hanselmann
  def call_jobqueue_set_drain(cls, node_list, drain_flag):
1158 5d672980 Iustin Pop
    """Set the drain flag on the queue.
1159 5d672980 Iustin Pop

1160 5d672980 Iustin Pop
    This is a multi-node call.
1161 5d672980 Iustin Pop

1162 5d672980 Iustin Pop
    @type node_list: list
1163 5d672980 Iustin Pop
    @param node_list: the list of nodes to query
1164 5d672980 Iustin Pop
    @type drain_flag: bool
1165 5d672980 Iustin Pop
    @param drain_flag: if True, will set the drain flag, otherwise reset it.
1166 5d672980 Iustin Pop

1167 5d672980 Iustin Pop
    """
1168 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_set_drain",
1169 9a525d83 Michael Hanselmann
                                    [drain_flag])
1170 5d672980 Iustin Pop
1171 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
1172 6217e295 Iustin Pop
    """Validate the hypervisor params.
1173 6217e295 Iustin Pop

1174 6217e295 Iustin Pop
    This is a multi-node call.
1175 6217e295 Iustin Pop

1176 6217e295 Iustin Pop
    @type node_list: list
1177 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
1178 6217e295 Iustin Pop
    @type hvname: string
1179 6217e295 Iustin Pop
    @param hvname: the hypervisor name
1180 6217e295 Iustin Pop
    @type hvparams: dict
1181 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
1182 6217e295 Iustin Pop

1183 6217e295 Iustin Pop
    """
1184 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
1185 abe609b2 Guido Trotter
    hv_full = objects.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
1186 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
1187 9a525d83 Michael Hanselmann
                               [hvname, hv_full])