Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ 0e67cdbe

History | View | Annotate | Download (25.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 81010134 Iustin Pop
import socket
35 81010134 Iustin Pop
import httplib
36 58b311ca Iustin Pop
import logging
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 a8083063 Iustin Pop
44 a8083063 Iustin Pop
45 4331f6cd Michael Hanselmann
# Module level variable
46 4331f6cd Michael Hanselmann
_http_manager = None
47 4331f6cd Michael Hanselmann
48 4331f6cd Michael Hanselmann
49 4331f6cd Michael Hanselmann
def Init():
50 4331f6cd Michael Hanselmann
  """Initializes the module-global HTTP client manager.
51 4331f6cd Michael Hanselmann

52 4331f6cd Michael Hanselmann
  Must be called before using any RPC function.
53 4331f6cd Michael Hanselmann

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

65 4331f6cd Michael Hanselmann
  Must be called before quitting the program.
66 4331f6cd Michael Hanselmann

67 4331f6cd Michael Hanselmann
  """
68 4331f6cd Michael Hanselmann
  global _http_manager
69 4331f6cd Michael Hanselmann
70 4331f6cd Michael Hanselmann
  if _http_manager:
71 4331f6cd Michael Hanselmann
    _http_manager.Shutdown()
72 4331f6cd Michael Hanselmann
    _http_manager = None
73 4331f6cd Michael Hanselmann
74 4331f6cd Michael Hanselmann
75 a8083063 Iustin Pop
class Client:
76 a8083063 Iustin Pop
  """RPC Client class.
77 a8083063 Iustin Pop

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

82 a8083063 Iustin Pop
  One current bug is that generic failure is still signalled by
83 a8083063 Iustin Pop
  'False' result, which is not good. This overloading of values can
84 a8083063 Iustin Pop
  cause bugs.
85 a8083063 Iustin Pop

86 a8083063 Iustin Pop
  """
87 160e2921 Iustin Pop
  def __init__(self, procedure, body, port):
88 a8083063 Iustin Pop
    self.procedure = procedure
89 160e2921 Iustin Pop
    self.body = body
90 160e2921 Iustin Pop
    self.port = port
91 ecfe9491 Michael Hanselmann
    self.nc = {}
92 a8083063 Iustin Pop
93 d57ae7f7 Michael Hanselmann
    self._ssl_params = \
94 d57ae7f7 Michael Hanselmann
      http.HttpSslParams(ssl_key_path=constants.SSL_CERT_FILE,
95 d57ae7f7 Michael Hanselmann
                         ssl_cert_path=constants.SSL_CERT_FILE)
96 d57ae7f7 Michael Hanselmann
97 bdf7d8c0 Iustin Pop
  def ConnectList(self, node_list, address_list=None):
98 a8083063 Iustin Pop
    """Add a list of nodes to the target nodes.
99 a8083063 Iustin Pop

100 3ef3c771 Iustin Pop
    @type node_list: list
101 3ef3c771 Iustin Pop
    @param node_list: the list of node names to connect
102 bdf7d8c0 Iustin Pop
    @type address_list: list or None
103 bdf7d8c0 Iustin Pop
    @keyword address_list: either None or a list with node addresses,
104 bdf7d8c0 Iustin Pop
        which must have the same length as the node list
105 3ef3c771 Iustin Pop

106 a8083063 Iustin Pop
    """
107 bdf7d8c0 Iustin Pop
    if address_list is None:
108 bdf7d8c0 Iustin Pop
      address_list = [None for _ in node_list]
109 bdf7d8c0 Iustin Pop
    else:
110 bdf7d8c0 Iustin Pop
      assert len(node_list) == len(address_list), \
111 bdf7d8c0 Iustin Pop
             "Name and address lists should have the same length"
112 bdf7d8c0 Iustin Pop
    for node, address in zip(node_list, address_list):
113 bdf7d8c0 Iustin Pop
      self.ConnectNode(node, address)
114 bdf7d8c0 Iustin Pop
115 bdf7d8c0 Iustin Pop
  def ConnectNode(self, name, address=None):
116 a8083063 Iustin Pop
    """Add a node to the target list.
117 a8083063 Iustin Pop

118 bdf7d8c0 Iustin Pop
    @type name: str
119 bdf7d8c0 Iustin Pop
    @param name: the node name
120 bdf7d8c0 Iustin Pop
    @type address: str
121 bdf7d8c0 Iustin Pop
    @keyword address: the node address, if known
122 bdf7d8c0 Iustin Pop

123 a8083063 Iustin Pop
    """
124 ecfe9491 Michael Hanselmann
    if address is None:
125 ecfe9491 Michael Hanselmann
      address = name
126 ecfe9491 Michael Hanselmann
127 ecfe9491 Michael Hanselmann
    self.nc[name] = http.HttpClientRequest(address, self.port, http.HTTP_PUT,
128 ecfe9491 Michael Hanselmann
                                           "/%s" % self.procedure,
129 eafd8762 Michael Hanselmann
                                           post_data=self.body,
130 d57ae7f7 Michael Hanselmann
                                           ssl_params=self._ssl_params,
131 eafd8762 Michael Hanselmann
                                           ssl_verify_peer=True)
132 a8083063 Iustin Pop
133 3ef3c771 Iustin Pop
  def GetResults(self):
134 ecfe9491 Michael Hanselmann
    """Call nodes and return results.
135 ecfe9491 Michael Hanselmann

136 ecfe9491 Michael Hanselmann
    @rtype: list
137 ecfe9491 Michael Hanselmann
    @returns: List of RPC results
138 a8083063 Iustin Pop

139 a8083063 Iustin Pop
    """
140 4331f6cd Michael Hanselmann
    assert _http_manager, "RPC module not intialized"
141 4331f6cd Michael Hanselmann
142 4331f6cd Michael Hanselmann
    _http_manager.ExecRequests(self.nc.values())
143 a8083063 Iustin Pop
144 ecfe9491 Michael Hanselmann
    results = {}
145 a8083063 Iustin Pop
146 ecfe9491 Michael Hanselmann
    for name, req in self.nc.iteritems():
147 ecfe9491 Michael Hanselmann
      if req.success and req.resp_status == http.HTTP_OK:
148 7c28c575 Michael Hanselmann
        results[name] = serializer.LoadJson(req.resp_body)
149 ecfe9491 Michael Hanselmann
        continue
150 a8083063 Iustin Pop
151 d57ae7f7 Michael Hanselmann
      # TODO: Better error reporting
152 ecfe9491 Michael Hanselmann
      if req.error:
153 ecfe9491 Michael Hanselmann
        msg = req.error
154 ecfe9491 Michael Hanselmann
      else:
155 ecfe9491 Michael Hanselmann
        msg = req.resp_body
156 ecfe9491 Michael Hanselmann
157 ecfe9491 Michael Hanselmann
      logging.error("RPC error from node %s: %s", name, msg)
158 ecfe9491 Michael Hanselmann
      results[name] = False
159 ecfe9491 Michael Hanselmann
160 ecfe9491 Michael Hanselmann
    return results
161 a8083063 Iustin Pop
162 a8083063 Iustin Pop
163 72737a7f Iustin Pop
class RpcRunner(object):
164 72737a7f Iustin Pop
  """RPC runner class"""
165 a8083063 Iustin Pop
166 72737a7f Iustin Pop
  def __init__(self, cfg):
167 72737a7f Iustin Pop
    """Initialized the rpc runner.
168 a8083063 Iustin Pop

169 72737a7f Iustin Pop
    @type cfg:  C{config.ConfigWriter}
170 72737a7f Iustin Pop
    @param cfg: the configuration object that will be used to get data
171 72737a7f Iustin Pop
                about the cluster
172 a8083063 Iustin Pop

173 72737a7f Iustin Pop
    """
174 72737a7f Iustin Pop
    self._cfg = cfg
175 160e2921 Iustin Pop
    self.port = utils.GetNodeDaemonPort()
176 a8083063 Iustin Pop
177 26ba2bd8 Iustin Pop
  def _InstDict(self, instance):
178 26ba2bd8 Iustin Pop
    """Convert the given instance to a dict.
179 26ba2bd8 Iustin Pop

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

183 26ba2bd8 Iustin Pop
    @type instance: L{objects.Instance}
184 26ba2bd8 Iustin Pop
    @param instance: an Instance object
185 26ba2bd8 Iustin Pop
    @rtype: dict
186 26ba2bd8 Iustin Pop
    @return: the instance dict, with the hvparams filled with the
187 26ba2bd8 Iustin Pop
        cluster defaults
188 26ba2bd8 Iustin Pop

189 26ba2bd8 Iustin Pop
    """
190 26ba2bd8 Iustin Pop
    idict = instance.ToDict()
191 5b442704 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
192 5b442704 Iustin Pop
    idict["hvparams"] = cluster.FillHV(instance)
193 5b442704 Iustin Pop
    idict["beparams"] = cluster.FillBE(instance)
194 26ba2bd8 Iustin Pop
    return idict
195 26ba2bd8 Iustin Pop
196 25348212 Iustin Pop
  def _ConnectList(self, client, node_list):
197 25348212 Iustin Pop
    """Helper for computing node addresses.
198 25348212 Iustin Pop

199 25348212 Iustin Pop
    @type client: L{Client}
200 25348212 Iustin Pop
    @param client: a C{Client} instance
201 25348212 Iustin Pop
    @type node_list: list
202 25348212 Iustin Pop
    @param node_list: the node list we should connect
203 25348212 Iustin Pop

204 25348212 Iustin Pop
    """
205 25348212 Iustin Pop
    all_nodes = self._cfg.GetAllNodesInfo()
206 25348212 Iustin Pop
    addr_list = []
207 25348212 Iustin Pop
    for node in node_list:
208 25348212 Iustin Pop
      if node in all_nodes:
209 25348212 Iustin Pop
        val = all_nodes[node].primary_ip
210 25348212 Iustin Pop
      else:
211 25348212 Iustin Pop
        val = None
212 25348212 Iustin Pop
      addr_list.append(val)
213 25348212 Iustin Pop
    client.ConnectList(node_list, address_list=addr_list)
214 25348212 Iustin Pop
215 25348212 Iustin Pop
  def _ConnectNode(self, client, node):
216 25348212 Iustin Pop
    """Helper for computing one node's address.
217 25348212 Iustin Pop

218 25348212 Iustin Pop
    @type client: L{Client}
219 25348212 Iustin Pop
    @param client: a C{Client} instance
220 25348212 Iustin Pop
    @type node: str
221 25348212 Iustin Pop
    @param node: the node we should connect
222 25348212 Iustin Pop

223 25348212 Iustin Pop
    """
224 25348212 Iustin Pop
    node_info = self._cfg.GetNodeInfo(node)
225 25348212 Iustin Pop
    if node_info is not None:
226 25348212 Iustin Pop
      addr = node_info.primary_ip
227 25348212 Iustin Pop
    else:
228 25348212 Iustin Pop
      addr = None
229 25348212 Iustin Pop
    client.ConnectNode(node, address=addr)
230 25348212 Iustin Pop
231 9a525d83 Michael Hanselmann
  def _MultiNodeCall(self, node_list, procedure, args,
232 9a525d83 Michael Hanselmann
                     address_list=None):
233 160e2921 Iustin Pop
    """Helper for making a multi-node call
234 160e2921 Iustin Pop

235 160e2921 Iustin Pop
    """
236 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
237 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
238 9a525d83 Michael Hanselmann
    if address_list is None:
239 9a525d83 Michael Hanselmann
      self._ConnectList(c, node_list)
240 9a525d83 Michael Hanselmann
    else:
241 9a525d83 Michael Hanselmann
      c.ConnectList(node_list, address_list=address_list)
242 9a525d83 Michael Hanselmann
    return c.GetResults()
243 9a525d83 Michael Hanselmann
244 9a525d83 Michael Hanselmann
  @classmethod
245 9a525d83 Michael Hanselmann
  def _StaticMultiNodeCall(cls, node_list, procedure, args,
246 9a525d83 Michael Hanselmann
                           address_list=None):
247 160e2921 Iustin Pop
    """Helper for making a multi-node static call
248 160e2921 Iustin Pop

249 160e2921 Iustin Pop
    """
250 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
251 160e2921 Iustin Pop
    c = Client(procedure, body, utils.GetNodeDaemonPort())
252 9a525d83 Michael Hanselmann
    c.ConnectList(node_list, address_list=address_list)
253 9a525d83 Michael Hanselmann
    return c.GetResults()
254 9a525d83 Michael Hanselmann
255 9a525d83 Michael Hanselmann
  def _SingleNodeCall(self, node, procedure, args):
256 160e2921 Iustin Pop
    """Helper for making a single-node call
257 9a525d83 Michael Hanselmann

258 9a525d83 Michael Hanselmann
    """
259 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
260 160e2921 Iustin Pop
    c = Client(procedure, body, self.port)
261 9a525d83 Michael Hanselmann
    self._ConnectNode(c, node)
262 9a525d83 Michael Hanselmann
    return c.GetResults().get(node, False)
263 9a525d83 Michael Hanselmann
264 9a525d83 Michael Hanselmann
  @classmethod
265 9a525d83 Michael Hanselmann
  def _StaticSingleNodeCall(cls, node, procedure, args):
266 160e2921 Iustin Pop
    """Helper for making a single-node static call
267 9a525d83 Michael Hanselmann

268 9a525d83 Michael Hanselmann
    """
269 160e2921 Iustin Pop
    body = serializer.DumpJson(args, indent=False)
270 160e2921 Iustin Pop
    c = Client(procedure, body, utils.GetNodeDaemonPort())
271 3097c858 Michael Hanselmann
    c.ConnectNode(node)
272 9a525d83 Michael Hanselmann
    return c.GetResults().get(node, False)
273 9a525d83 Michael Hanselmann
274 72737a7f Iustin Pop
  def call_volume_list(self, node_list, vg_name):
275 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
276 a8083063 Iustin Pop

277 72737a7f Iustin Pop
    This is a multi-node call.
278 a8083063 Iustin Pop

279 72737a7f Iustin Pop
    """
280 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "volume_list", [vg_name])
281 a8083063 Iustin Pop
282 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
283 72737a7f Iustin Pop
    """Gets the volume group list.
284 a8083063 Iustin Pop

285 72737a7f Iustin Pop
    This is a multi-node call.
286 a8083063 Iustin Pop

287 72737a7f Iustin Pop
    """
288 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "vg_list", [])
289 a8083063 Iustin Pop
290 72737a7f Iustin Pop
  def call_bridges_exist(self, node, bridges_list):
291 72737a7f Iustin Pop
    """Checks if a node has all the bridges given.
292 a8083063 Iustin Pop

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

297 72737a7f Iustin Pop
    This is a single-node call.
298 a8083063 Iustin Pop

299 72737a7f Iustin Pop
    """
300 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "bridges_exist", [bridges_list])
301 a8083063 Iustin Pop
302 72737a7f Iustin Pop
  def call_instance_start(self, node, instance, extra_args):
303 72737a7f Iustin Pop
    """Starts an instance.
304 a8083063 Iustin Pop

305 72737a7f Iustin Pop
    This is a single-node call.
306 a8083063 Iustin Pop

307 72737a7f Iustin Pop
    """
308 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_start",
309 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), extra_args])
310 a8083063 Iustin Pop
311 72737a7f Iustin Pop
  def call_instance_shutdown(self, node, instance):
312 72737a7f Iustin Pop
    """Stops an instance.
313 a8083063 Iustin Pop

314 72737a7f Iustin Pop
    This is a single-node call.
315 2a10865c Iustin Pop

316 72737a7f Iustin Pop
    """
317 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_shutdown",
318 9a525d83 Michael Hanselmann
                                [self._InstDict(instance)])
319 2a10865c Iustin Pop
320 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
321 72737a7f Iustin Pop
    """Migrate an instance.
322 2a10865c Iustin Pop

323 72737a7f Iustin Pop
    This is a single-node call.
324 2a10865c Iustin Pop

325 72737a7f Iustin Pop
    @type node: string
326 72737a7f Iustin Pop
    @param node: the node on which the instance is currently running
327 72737a7f Iustin Pop
    @type instance: C{objects.Instance}
328 72737a7f Iustin Pop
    @param instance: the instance definition
329 72737a7f Iustin Pop
    @type target: string
330 72737a7f Iustin Pop
    @param target: the target node name
331 72737a7f Iustin Pop
    @type live: boolean
332 72737a7f Iustin Pop
    @param live: whether the migration should be done live or not (the
333 72737a7f Iustin Pop
        interpretation of this parameter is left to the hypervisor)
334 007a2f3e Alexander Schreiber

335 72737a7f Iustin Pop
    """
336 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_migrate",
337 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), target, live])
338 007a2f3e Alexander Schreiber
339 72737a7f Iustin Pop
  def call_instance_reboot(self, node, instance, reboot_type, extra_args):
340 72737a7f Iustin Pop
    """Reboots an instance.
341 007a2f3e Alexander Schreiber

342 72737a7f Iustin Pop
    This is a single-node call.
343 a8083063 Iustin Pop

344 72737a7f Iustin Pop
    """
345 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_reboot",
346 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), reboot_type,
347 9a525d83 Michael Hanselmann
                                 extra_args])
348 a8083063 Iustin Pop
349 d15a9ad3 Guido Trotter
  def call_instance_os_add(self, node, inst):
350 72737a7f Iustin Pop
    """Installs an OS on the given instance.
351 a8083063 Iustin Pop

352 72737a7f Iustin Pop
    This is a single-node call.
353 decd5f45 Iustin Pop

354 72737a7f Iustin Pop
    """
355 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_add",
356 9a525d83 Michael Hanselmann
                                [self._InstDict(inst)])
357 decd5f45 Iustin Pop
358 d15a9ad3 Guido Trotter
  def call_instance_run_rename(self, node, inst, old_name):
359 72737a7f Iustin Pop
    """Run the OS rename script for an instance.
360 decd5f45 Iustin Pop

361 72737a7f Iustin Pop
    This is a single-node call.
362 a8083063 Iustin Pop

363 72737a7f Iustin Pop
    """
364 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_run_rename",
365 9a525d83 Michael Hanselmann
                                [self._InstDict(inst), old_name])
366 a8083063 Iustin Pop
367 72737a7f Iustin Pop
  def call_instance_info(self, node, instance, hname):
368 72737a7f Iustin Pop
    """Returns information about a single instance.
369 a8083063 Iustin Pop

370 72737a7f Iustin Pop
    This is a single-node call.
371 a8083063 Iustin Pop

372 9a525d83 Michael Hanselmann
    @type node: list
373 9a525d83 Michael Hanselmann
    @param node: the list of nodes to query
374 72737a7f Iustin Pop
    @type instance: string
375 72737a7f Iustin Pop
    @param instance: the instance name
376 72737a7f Iustin Pop
    @type hname: string
377 72737a7f Iustin Pop
    @param hname: the hypervisor type of the instance
378 a8083063 Iustin Pop

379 72737a7f Iustin Pop
    """
380 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_info", [instance, hname])
381 e69d05fd Iustin Pop
382 72737a7f Iustin Pop
  def call_all_instances_info(self, node_list, hypervisor_list):
383 72737a7f Iustin Pop
    """Returns information about all instances on the given nodes.
384 a8083063 Iustin Pop

385 72737a7f Iustin Pop
    This is a multi-node call.
386 a8083063 Iustin Pop

387 72737a7f Iustin Pop
    @type node_list: list
388 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
389 72737a7f Iustin Pop
    @type hypervisor_list: list
390 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
391 a8083063 Iustin Pop

392 72737a7f Iustin Pop
    """
393 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "all_instances_info",
394 9a525d83 Michael Hanselmann
                               [hypervisor_list])
395 e69d05fd Iustin Pop
396 72737a7f Iustin Pop
  def call_instance_list(self, node_list, hypervisor_list):
397 72737a7f Iustin Pop
    """Returns the list of running instances on a given node.
398 a8083063 Iustin Pop

399 72737a7f Iustin Pop
    This is a multi-node call.
400 a8083063 Iustin Pop

401 72737a7f Iustin Pop
    @type node_list: list
402 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
403 72737a7f Iustin Pop
    @type hypervisor_list: list
404 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
405 16abfbc2 Alexander Schreiber

406 72737a7f Iustin Pop
    """
407 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "instance_list", [hypervisor_list])
408 16abfbc2 Alexander Schreiber
409 72737a7f Iustin Pop
  def call_node_tcp_ping(self, node, source, target, port, timeout,
410 72737a7f Iustin Pop
                         live_port_needed):
411 72737a7f Iustin Pop
    """Do a TcpPing on the remote node
412 a8083063 Iustin Pop

413 72737a7f Iustin Pop
    This is a single-node call.
414 caad16e2 Iustin Pop

415 72737a7f Iustin Pop
    """
416 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_tcp_ping",
417 9a525d83 Michael Hanselmann
                                [source, target, port, timeout,
418 72737a7f Iustin Pop
                                 live_port_needed])
419 a8083063 Iustin Pop
420 caad16e2 Iustin Pop
  def call_node_has_ip_address(self, node, address):
421 caad16e2 Iustin Pop
    """Checks if a node has the given IP address.
422 caad16e2 Iustin Pop

423 caad16e2 Iustin Pop
    This is a single-node call.
424 caad16e2 Iustin Pop

425 caad16e2 Iustin Pop
    """
426 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_has_ip_address", [address])
427 a8083063 Iustin Pop
428 72737a7f Iustin Pop
  def call_node_info(self, node_list, vg_name, hypervisor_type):
429 72737a7f Iustin Pop
    """Return node information.
430 e69d05fd Iustin Pop

431 72737a7f Iustin Pop
    This will return memory information and volume group size and free
432 72737a7f Iustin Pop
    space.
433 a8083063 Iustin Pop

434 72737a7f Iustin Pop
    This is a multi-node call.
435 a8083063 Iustin Pop

436 72737a7f Iustin Pop
    @type node_list: list
437 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
438 72737a7f Iustin Pop
    @type vgname: C{string}
439 72737a7f Iustin Pop
    @param vgname: the name of the volume group to ask for disk space
440 72737a7f Iustin Pop
        information
441 72737a7f Iustin Pop
    @type hypervisor_type: C{str}
442 72737a7f Iustin Pop
    @param hypervisor_type: the name of the hypervisor to ask for
443 72737a7f Iustin Pop
        memory information
444 a8083063 Iustin Pop

445 72737a7f Iustin Pop
    """
446 9a525d83 Michael Hanselmann
    retux = self._MultiNodeCall(node_list, "node_info",
447 9a525d83 Michael Hanselmann
                                [vg_name, hypervisor_type])
448 a8083063 Iustin Pop
449 72737a7f Iustin Pop
    for node_name in retux:
450 72737a7f Iustin Pop
      ret = retux.get(node_name, False)
451 72737a7f Iustin Pop
      if type(ret) != dict:
452 58b311ca Iustin Pop
        logging.error("could not connect to node %s", node_name)
453 72737a7f Iustin Pop
        ret = {}
454 a8083063 Iustin Pop
455 9a525d83 Michael Hanselmann
      utils.CheckDict(ret, {
456 9a525d83 Michael Hanselmann
                        'memory_total' : '-',
457 72737a7f Iustin Pop
                        'memory_dom0' : '-',
458 72737a7f Iustin Pop
                        'memory_free' : '-',
459 72737a7f Iustin Pop
                        'vg_size' : 'node_unreachable',
460 9a525d83 Michael Hanselmann
                        'vg_free' : '-',
461 9a525d83 Michael Hanselmann
                      }, "call_node_info")
462 72737a7f Iustin Pop
    return retux
463 a8083063 Iustin Pop
464 72737a7f Iustin Pop
  def call_node_add(self, node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
465 72737a7f Iustin Pop
    """Add a node to the cluster.
466 a8083063 Iustin Pop

467 72737a7f Iustin Pop
    This is a single-node call.
468 a8083063 Iustin Pop

469 72737a7f Iustin Pop
    """
470 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "node_add",
471 9a525d83 Michael Hanselmann
                                [dsa, dsapub, rsa, rsapub, ssh, sshpub])
472 a8083063 Iustin Pop
473 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
474 72737a7f Iustin Pop
    """Request verification of given parameters.
475 a8083063 Iustin Pop

476 72737a7f Iustin Pop
    This is a multi-node call.
477 a8083063 Iustin Pop

478 72737a7f Iustin Pop
    """
479 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_verify",
480 9a525d83 Michael Hanselmann
                               [checkdict, cluster_name])
481 a8083063 Iustin Pop
482 9a525d83 Michael Hanselmann
  @classmethod
483 9a525d83 Michael Hanselmann
  def call_node_start_master(cls, node, start_daemons):
484 72737a7f Iustin Pop
    """Tells a node to activate itself as a master.
485 a8083063 Iustin Pop

486 72737a7f Iustin Pop
    This is a single-node call.
487 a8083063 Iustin Pop

488 72737a7f Iustin Pop
    """
489 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_start_master",
490 9a525d83 Michael Hanselmann
                                     [start_daemons])
491 a8083063 Iustin Pop
492 9a525d83 Michael Hanselmann
  @classmethod
493 9a525d83 Michael Hanselmann
  def call_node_stop_master(cls, node, stop_daemons):
494 72737a7f Iustin Pop
    """Tells a node to demote itself from master status.
495 a8083063 Iustin Pop

496 72737a7f Iustin Pop
    This is a single-node call.
497 4e071d3b Iustin Pop

498 72737a7f Iustin Pop
    """
499 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "node_stop_master", [stop_daemons])
500 4e071d3b Iustin Pop
501 9a525d83 Michael Hanselmann
  @classmethod
502 9a525d83 Michael Hanselmann
  def call_master_info(cls, node_list):
503 72737a7f Iustin Pop
    """Query master info.
504 4e071d3b Iustin Pop

505 72737a7f Iustin Pop
    This is a multi-node call.
506 a8083063 Iustin Pop

507 72737a7f Iustin Pop
    """
508 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
509 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "master_info", [])
510 a8083063 Iustin Pop
511 72737a7f Iustin Pop
  def call_version(self, node_list):
512 72737a7f Iustin Pop
    """Query node version.
513 a8083063 Iustin Pop

514 72737a7f Iustin Pop
    This is a multi-node call.
515 a8083063 Iustin Pop

516 72737a7f Iustin Pop
    """
517 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "version", [])
518 a8083063 Iustin Pop
519 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
520 72737a7f Iustin Pop
    """Request creation of a given block device.
521 a8083063 Iustin Pop

522 72737a7f Iustin Pop
    This is a single-node call.
523 a8083063 Iustin Pop

524 72737a7f Iustin Pop
    """
525 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_create",
526 9a525d83 Michael Hanselmann
                                [bdev.ToDict(), size, owner, on_primary, info])
527 a8083063 Iustin Pop
528 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
529 72737a7f Iustin Pop
    """Request removal of a given block device.
530 a8083063 Iustin Pop

531 72737a7f Iustin Pop
    This is a single-node call.
532 f3e513ad Iustin Pop

533 72737a7f Iustin Pop
    """
534 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_remove", [bdev.ToDict()])
535 f3e513ad Iustin Pop
536 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
537 72737a7f Iustin Pop
    """Request rename of the given block devices.
538 f3e513ad Iustin Pop

539 72737a7f Iustin Pop
    This is a single-node call.
540 a8083063 Iustin Pop

541 72737a7f Iustin Pop
    """
542 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_rename",
543 9a525d83 Michael Hanselmann
                                [(d.ToDict(), uid) for d, uid in devlist])
544 a8083063 Iustin Pop
545 72737a7f Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary):
546 72737a7f Iustin Pop
    """Request assembling of a given block device.
547 a8083063 Iustin Pop

548 72737a7f Iustin Pop
    This is a single-node call.
549 a8083063 Iustin Pop

550 72737a7f Iustin Pop
    """
551 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_assemble",
552 9a525d83 Michael Hanselmann
                                [disk.ToDict(), owner, on_primary])
553 a8083063 Iustin Pop
554 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
555 72737a7f Iustin Pop
    """Request shutdown of a given block device.
556 a8083063 Iustin Pop

557 72737a7f Iustin Pop
    This is a single-node call.
558 a8083063 Iustin Pop

559 72737a7f Iustin Pop
    """
560 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_shutdown", [disk.ToDict()])
561 a8083063 Iustin Pop
562 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
563 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
564 a8083063 Iustin Pop

565 72737a7f Iustin Pop
    This is a single-node call.
566 a8083063 Iustin Pop

567 72737a7f Iustin Pop
    """
568 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_addchildren",
569 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
570 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
571 a8083063 Iustin Pop
572 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
573 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
574 a8083063 Iustin Pop

575 72737a7f Iustin Pop
    This is a single-node call.
576 a8083063 Iustin Pop

577 72737a7f Iustin Pop
    """
578 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_removechildren",
579 9a525d83 Michael Hanselmann
                                [bdev.ToDict(),
580 9a525d83 Michael Hanselmann
                                 [disk.ToDict() for disk in ndevs]])
581 a8083063 Iustin Pop
582 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
583 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
584 a8083063 Iustin Pop

585 72737a7f Iustin Pop
    This is a single-node call.
586 a8083063 Iustin Pop

587 72737a7f Iustin Pop
    """
588 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_getmirrorstatus",
589 9a525d83 Michael Hanselmann
                                [dsk.ToDict() for dsk in disks])
590 a8083063 Iustin Pop
591 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
592 72737a7f Iustin Pop
    """Request identification of a given block device.
593 72737a7f Iustin Pop

594 72737a7f Iustin Pop
    This is a single-node call.
595 a8083063 Iustin Pop

596 72737a7f Iustin Pop
    """
597 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_find", [disk.ToDict()])
598 d61cbe76 Iustin Pop
599 72737a7f Iustin Pop
  def call_blockdev_close(self, node, disks):
600 72737a7f Iustin Pop
    """Closes the given block devices.
601 d61cbe76 Iustin Pop

602 72737a7f Iustin Pop
    This is a single-node call.
603 d61cbe76 Iustin Pop

604 72737a7f Iustin Pop
    """
605 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_close",
606 9a525d83 Michael Hanselmann
                                [cf.ToDict() for cf in disks])
607 a8083063 Iustin Pop
608 9a525d83 Michael Hanselmann
  @classmethod
609 9a525d83 Michael Hanselmann
  def call_upload_file(cls, node_list, file_name, address_list=None):
610 72737a7f Iustin Pop
    """Upload a file.
611 72737a7f Iustin Pop

612 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
613 72737a7f Iustin Pop
    approved file list.
614 72737a7f Iustin Pop

615 72737a7f Iustin Pop
    This is a multi-node call.
616 a8083063 Iustin Pop

617 6b294c53 Iustin Pop
    @type node_list: list
618 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
619 6b294c53 Iustin Pop
    @type file_name: str
620 6b294c53 Iustin Pop
    @param file_name: the filename to upload
621 6b294c53 Iustin Pop
    @type address_list: list or None
622 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
623 6b294c53 Iustin Pop
        to optimize the RPC speed
624 6b294c53 Iustin Pop

625 72737a7f Iustin Pop
    """
626 4c7c81d7 Michael Hanselmann
    data = utils.ReadFile(file_name)
627 72737a7f Iustin Pop
    st = os.stat(file_name)
628 72737a7f Iustin Pop
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
629 72737a7f Iustin Pop
              st.st_atime, st.st_mtime]
630 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "upload_file", params,
631 9a525d83 Michael Hanselmann
                                    address_list=address_list)
632 72737a7f Iustin Pop
633 6ddc95ec Michael Hanselmann
  @classmethod
634 03d1dba2 Michael Hanselmann
  def call_write_ssconf_files(cls, node_list, values):
635 6ddc95ec Michael Hanselmann
    """Write ssconf files.
636 6ddc95ec Michael Hanselmann

637 6ddc95ec Michael Hanselmann
    This is a multi-node call.
638 6ddc95ec Michael Hanselmann

639 6ddc95ec Michael Hanselmann
    """
640 03d1dba2 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "write_ssconf_files", [values])
641 6ddc95ec Michael Hanselmann
642 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
643 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
644 72737a7f Iustin Pop

645 72737a7f Iustin Pop
    This is a multi-node call.
646 a8083063 Iustin Pop

647 72737a7f Iustin Pop
    """
648 9a525d83 Michael Hanselmann
    result = self._MultiNodeCall(node_list, "os_diagnose", [])
649 9a525d83 Michael Hanselmann
650 72737a7f Iustin Pop
    new_result = {}
651 72737a7f Iustin Pop
    for node_name in result:
652 72737a7f Iustin Pop
      if result[node_name]:
653 72737a7f Iustin Pop
        nr = [objects.OS.FromDict(oss) for oss in result[node_name]]
654 72737a7f Iustin Pop
      else:
655 72737a7f Iustin Pop
        nr = []
656 72737a7f Iustin Pop
      new_result[node_name] = nr
657 72737a7f Iustin Pop
    return new_result
658 a8083063 Iustin Pop
659 72737a7f Iustin Pop
  def call_os_get(self, node, name):
660 72737a7f Iustin Pop
    """Returns an OS definition.
661 a8083063 Iustin Pop

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

664 72737a7f Iustin Pop
    """
665 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "os_get", [name])
666 72737a7f Iustin Pop
    if isinstance(result, dict):
667 72737a7f Iustin Pop
      return objects.OS.FromDict(result)
668 72737a7f Iustin Pop
    else:
669 72737a7f Iustin Pop
      return result
670 a8083063 Iustin Pop
671 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
672 72737a7f Iustin Pop
    """Call the hooks runner.
673 a8083063 Iustin Pop

674 72737a7f Iustin Pop
    Args:
675 72737a7f Iustin Pop
      - op: the OpCode instance
676 72737a7f Iustin Pop
      - env: a dictionary with the environment
677 a8083063 Iustin Pop

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

680 72737a7f Iustin Pop
    """
681 72737a7f Iustin Pop
    params = [hpath, phase, env]
682 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hooks_runner", params)
683 a8083063 Iustin Pop
684 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
685 72737a7f Iustin Pop
    """Call an iallocator on a remote node
686 8d528b7c Iustin Pop

687 72737a7f Iustin Pop
    Args:
688 72737a7f Iustin Pop
      - name: the iallocator name
689 72737a7f Iustin Pop
      - input: the json-encoded input string
690 8d528b7c Iustin Pop

691 72737a7f Iustin Pop
    This is a single-node call.
692 8d528b7c Iustin Pop

693 72737a7f Iustin Pop
    """
694 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "iallocator_runner", [name, idata])
695 8d528b7c Iustin Pop
696 72737a7f Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount):
697 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
698 4c8ba8b3 Iustin Pop

699 72737a7f Iustin Pop
    This is a single-node call.
700 4c8ba8b3 Iustin Pop

701 72737a7f Iustin Pop
    """
702 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_grow",
703 9a525d83 Michael Hanselmann
                                [cf_bdev.ToDict(), amount])
704 4c8ba8b3 Iustin Pop
705 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
706 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
707 a8083063 Iustin Pop

708 72737a7f Iustin Pop
    This is a single-node call.
709 a8083063 Iustin Pop

710 72737a7f Iustin Pop
    """
711 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "blockdev_snapshot", [cf_bdev.ToDict()])
712 a8083063 Iustin Pop
713 72737a7f Iustin Pop
  def call_snapshot_export(self, node, snap_bdev, dest_node, instance,
714 74c47259 Iustin Pop
                           cluster_name, idx):
715 72737a7f Iustin Pop
    """Request the export of a given snapshot.
716 a8083063 Iustin Pop

717 72737a7f Iustin Pop
    This is a single-node call.
718 a8083063 Iustin Pop

719 72737a7f Iustin Pop
    """
720 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "snapshot_export",
721 9a525d83 Michael Hanselmann
                                [snap_bdev.ToDict(), dest_node,
722 9a525d83 Michael Hanselmann
                                 self._InstDict(instance), cluster_name, idx])
723 a8083063 Iustin Pop
724 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
725 72737a7f Iustin Pop
    """Request the completion of an export operation.
726 a8083063 Iustin Pop

727 72737a7f Iustin Pop
    This writes the export config file, etc.
728 a8083063 Iustin Pop

729 72737a7f Iustin Pop
    This is a single-node call.
730 a8083063 Iustin Pop

731 72737a7f Iustin Pop
    """
732 72737a7f Iustin Pop
    flat_disks = []
733 72737a7f Iustin Pop
    for disk in snap_disks:
734 72737a7f Iustin Pop
      flat_disks.append(disk.ToDict())
735 9a525d83 Michael Hanselmann
736 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "finalize_export",
737 9a525d83 Michael Hanselmann
                                [self._InstDict(instance), flat_disks])
738 a8083063 Iustin Pop
739 72737a7f Iustin Pop
  def call_export_info(self, node, path):
740 72737a7f Iustin Pop
    """Queries the export information in a given path.
741 a8083063 Iustin Pop

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

744 72737a7f Iustin Pop
    """
745 9a525d83 Michael Hanselmann
    result = self._SingleNodeCall(node, "export_info", [path])
746 72737a7f Iustin Pop
    if not result:
747 72737a7f Iustin Pop
      return result
748 72737a7f Iustin Pop
    return objects.SerializableConfigParser.Loads(str(result))
749 a8083063 Iustin Pop
750 6c0af70e Guido Trotter
  def call_instance_os_import(self, node, inst, src_node, src_images,
751 6c0af70e Guido Trotter
                              cluster_name):
752 72737a7f Iustin Pop
    """Request the import of a backup into an instance.
753 a8083063 Iustin Pop

754 72737a7f Iustin Pop
    This is a single-node call.
755 a8083063 Iustin Pop

756 72737a7f Iustin Pop
    """
757 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "instance_os_import",
758 9a525d83 Michael Hanselmann
                                [self._InstDict(inst), src_node, src_images,
759 9a525d83 Michael Hanselmann
                                 cluster_name])
760 a8083063 Iustin Pop
761 72737a7f Iustin Pop
  def call_export_list(self, node_list):
762 72737a7f Iustin Pop
    """Gets the stored exports list.
763 a8083063 Iustin Pop

764 72737a7f Iustin Pop
    This is a multi-node call.
765 a8083063 Iustin Pop

766 72737a7f Iustin Pop
    """
767 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "export_list", [])
768 a8083063 Iustin Pop
769 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
770 72737a7f Iustin Pop
    """Requests removal of a given export.
771 a8083063 Iustin Pop

772 72737a7f Iustin Pop
    This is a single-node call.
773 a8083063 Iustin Pop

774 72737a7f Iustin Pop
    """
775 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "export_remove", [export])
776 a8083063 Iustin Pop
777 9a525d83 Michael Hanselmann
  @classmethod
778 9a525d83 Michael Hanselmann
  def call_node_leave_cluster(cls, node):
779 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
780 a8083063 Iustin Pop

781 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
782 72737a7f Iustin Pop
    dir.
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 cls._StaticSingleNodeCall(node, "node_leave_cluster", [])
788 dcb93971 Michael Hanselmann
789 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
790 72737a7f Iustin Pop
    """Gets all volumes on node(s).
791 dcb93971 Michael Hanselmann

792 72737a7f Iustin Pop
    This is a multi-node call.
793 dcb93971 Michael Hanselmann

794 72737a7f Iustin Pop
    """
795 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "node_volumes", [])
796 06009e27 Iustin Pop
797 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
798 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
799 06009e27 Iustin Pop

800 72737a7f Iustin Pop
    This is a multi-node call.
801 06009e27 Iustin Pop

802 72737a7f Iustin Pop
    """
803 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "test_delay", [duration])
804 5e04ed8b Manuel Franceschini
805 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
806 72737a7f Iustin Pop
    """Create the given file storage directory.
807 5e04ed8b Manuel Franceschini

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

810 72737a7f Iustin Pop
    """
811 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_create",
812 9a525d83 Michael Hanselmann
                                [file_storage_dir])
813 5e04ed8b Manuel Franceschini
814 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
815 72737a7f Iustin Pop
    """Remove the given file storage directory.
816 5e04ed8b Manuel Franceschini

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

819 72737a7f Iustin Pop
    """
820 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_remove",
821 9a525d83 Michael Hanselmann
                                [file_storage_dir])
822 5e04ed8b Manuel Franceschini
823 72737a7f Iustin Pop
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
824 72737a7f Iustin Pop
                                   new_file_storage_dir):
825 72737a7f Iustin Pop
    """Rename file storage directory.
826 5e04ed8b Manuel Franceschini

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

829 72737a7f Iustin Pop
    """
830 9a525d83 Michael Hanselmann
    return self._SingleNodeCall(node, "file_storage_dir_rename",
831 9a525d83 Michael Hanselmann
                                [old_file_storage_dir, new_file_storage_dir])
832 ca52cdeb Michael Hanselmann
833 9a525d83 Michael Hanselmann
  @classmethod
834 9a525d83 Michael Hanselmann
  def call_jobqueue_update(cls, node_list, address_list, file_name, content):
835 72737a7f Iustin Pop
    """Update job queue.
836 ca52cdeb Michael Hanselmann

837 72737a7f Iustin Pop
    This is a multi-node call.
838 ca52cdeb Michael Hanselmann

839 72737a7f Iustin Pop
    """
840 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_update",
841 9a525d83 Michael Hanselmann
                                    [file_name, content],
842 9a525d83 Michael Hanselmann
                                    address_list=address_list)
843 ca52cdeb Michael Hanselmann
844 9a525d83 Michael Hanselmann
  @classmethod
845 9a525d83 Michael Hanselmann
  def call_jobqueue_purge(cls, node):
846 72737a7f Iustin Pop
    """Purge job queue.
847 ca52cdeb Michael Hanselmann

848 72737a7f Iustin Pop
    This is a single-node call.
849 ca52cdeb Michael Hanselmann

850 72737a7f Iustin Pop
    """
851 9a525d83 Michael Hanselmann
    return cls._StaticSingleNodeCall(node, "jobqueue_purge", [])
852 af5ebcb1 Michael Hanselmann
853 9a525d83 Michael Hanselmann
  @classmethod
854 9a525d83 Michael Hanselmann
  def call_jobqueue_rename(cls, node_list, address_list, old, new):
855 72737a7f Iustin Pop
    """Rename a job queue file.
856 af5ebcb1 Michael Hanselmann

857 72737a7f Iustin Pop
    This is a multi-node call.
858 af5ebcb1 Michael Hanselmann

859 72737a7f Iustin Pop
    """
860 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_rename", [old, new],
861 9a525d83 Michael Hanselmann
                                    address_list=address_list)
862 6217e295 Iustin Pop
863 9a525d83 Michael Hanselmann
  @classmethod
864 9a525d83 Michael Hanselmann
  def call_jobqueue_set_drain(cls, node_list, drain_flag):
865 5d672980 Iustin Pop
    """Set the drain flag on the queue.
866 5d672980 Iustin Pop

867 5d672980 Iustin Pop
    This is a multi-node call.
868 5d672980 Iustin Pop

869 5d672980 Iustin Pop
    @type node_list: list
870 5d672980 Iustin Pop
    @param node_list: the list of nodes to query
871 5d672980 Iustin Pop
    @type drain_flag: bool
872 5d672980 Iustin Pop
    @param drain_flag: if True, will set the drain flag, otherwise reset it.
873 5d672980 Iustin Pop

874 5d672980 Iustin Pop
    """
875 9a525d83 Michael Hanselmann
    return cls._StaticMultiNodeCall(node_list, "jobqueue_set_drain",
876 9a525d83 Michael Hanselmann
                                    [drain_flag])
877 5d672980 Iustin Pop
878 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
879 6217e295 Iustin Pop
    """Validate the hypervisor params.
880 6217e295 Iustin Pop

881 6217e295 Iustin Pop
    This is a multi-node call.
882 6217e295 Iustin Pop

883 6217e295 Iustin Pop
    @type node_list: list
884 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
885 6217e295 Iustin Pop
    @type hvname: string
886 6217e295 Iustin Pop
    @param hvname: the hypervisor name
887 6217e295 Iustin Pop
    @type hvparams: dict
888 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
889 6217e295 Iustin Pop

890 6217e295 Iustin Pop
    """
891 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
892 6217e295 Iustin Pop
    hv_full = cluster.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
893 9a525d83 Michael Hanselmann
    return self._MultiNodeCall(node_list, "hypervisor_validate_params",
894 9a525d83 Michael Hanselmann
                               [hvname, hv_full])