Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ 4c7c81d7

History | View | Annotate | Download (24.8 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 a8083063 Iustin Pop
43 a8083063 Iustin Pop
44 a8083063 Iustin Pop
class Client:
45 a8083063 Iustin Pop
  """RPC Client class.
46 a8083063 Iustin Pop

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

51 a8083063 Iustin Pop
  One current bug is that generic failure is still signalled by
52 a8083063 Iustin Pop
  'False' result, which is not good. This overloading of values can
53 a8083063 Iustin Pop
  cause bugs.
54 a8083063 Iustin Pop

55 a8083063 Iustin Pop
  """
56 a8083063 Iustin Pop
  def __init__(self, procedure, args):
57 a8083063 Iustin Pop
    self.procedure = procedure
58 a8083063 Iustin Pop
    self.args = args
59 7c28c575 Michael Hanselmann
    self.body = serializer.DumpJson(args, indent=False)
60 a8083063 Iustin Pop
61 ecfe9491 Michael Hanselmann
    self.port = utils.GetNodeDaemonPort()
62 ecfe9491 Michael Hanselmann
    self.nodepw = utils.GetNodeDaemonPassword()
63 ecfe9491 Michael Hanselmann
    self.nc = {}
64 a8083063 Iustin Pop
65 bdf7d8c0 Iustin Pop
  def ConnectList(self, node_list, address_list=None):
66 a8083063 Iustin Pop
    """Add a list of nodes to the target nodes.
67 a8083063 Iustin Pop

68 3ef3c771 Iustin Pop
    @type node_list: list
69 3ef3c771 Iustin Pop
    @param node_list: the list of node names to connect
70 bdf7d8c0 Iustin Pop
    @type address_list: list or None
71 bdf7d8c0 Iustin Pop
    @keyword address_list: either None or a list with node addresses,
72 bdf7d8c0 Iustin Pop
        which must have the same length as the node list
73 3ef3c771 Iustin Pop

74 a8083063 Iustin Pop
    """
75 bdf7d8c0 Iustin Pop
    if address_list is None:
76 bdf7d8c0 Iustin Pop
      address_list = [None for _ in node_list]
77 bdf7d8c0 Iustin Pop
    else:
78 bdf7d8c0 Iustin Pop
      assert len(node_list) == len(address_list), \
79 bdf7d8c0 Iustin Pop
             "Name and address lists should have the same length"
80 bdf7d8c0 Iustin Pop
    for node, address in zip(node_list, address_list):
81 bdf7d8c0 Iustin Pop
      self.ConnectNode(node, address)
82 bdf7d8c0 Iustin Pop
83 bdf7d8c0 Iustin Pop
  def ConnectNode(self, name, address=None):
84 a8083063 Iustin Pop
    """Add a node to the target list.
85 a8083063 Iustin Pop

86 bdf7d8c0 Iustin Pop
    @type name: str
87 bdf7d8c0 Iustin Pop
    @param name: the node name
88 bdf7d8c0 Iustin Pop
    @type address: str
89 bdf7d8c0 Iustin Pop
    @keyword address: the node address, if known
90 bdf7d8c0 Iustin Pop

91 a8083063 Iustin Pop
    """
92 ecfe9491 Michael Hanselmann
    if address is None:
93 ecfe9491 Michael Hanselmann
      address = name
94 ecfe9491 Michael Hanselmann
95 ecfe9491 Michael Hanselmann
    self.nc[name] = http.HttpClientRequest(address, self.port, http.HTTP_PUT,
96 ecfe9491 Michael Hanselmann
                                           "/%s" % self.procedure,
97 ecfe9491 Michael Hanselmann
                                           post_data=self.body)
98 a8083063 Iustin Pop
99 3ef3c771 Iustin Pop
  def GetResults(self):
100 ecfe9491 Michael Hanselmann
    """Call nodes and return results.
101 ecfe9491 Michael Hanselmann

102 ecfe9491 Michael Hanselmann
    @rtype: list
103 ecfe9491 Michael Hanselmann
    @returns: List of RPC results
104 a8083063 Iustin Pop

105 a8083063 Iustin Pop
    """
106 ecfe9491 Michael Hanselmann
    # TODO: Shared and reused manager
107 ecfe9491 Michael Hanselmann
    mgr = http.HttpClientManager()
108 ecfe9491 Michael Hanselmann
    try:
109 ecfe9491 Michael Hanselmann
      mgr.ExecRequests(self.nc.values())
110 ecfe9491 Michael Hanselmann
    finally:
111 ecfe9491 Michael Hanselmann
      mgr.Shutdown()
112 a8083063 Iustin Pop
113 ecfe9491 Michael Hanselmann
    results = {}
114 a8083063 Iustin Pop
115 ecfe9491 Michael Hanselmann
    for name, req in self.nc.iteritems():
116 ecfe9491 Michael Hanselmann
      if req.success and req.resp_status == http.HTTP_OK:
117 7c28c575 Michael Hanselmann
        results[name] = serializer.LoadJson(req.resp_body)
118 ecfe9491 Michael Hanselmann
        continue
119 a8083063 Iustin Pop
120 ecfe9491 Michael Hanselmann
      if req.error:
121 ecfe9491 Michael Hanselmann
        msg = req.error
122 ecfe9491 Michael Hanselmann
      else:
123 ecfe9491 Michael Hanselmann
        msg = req.resp_body
124 ecfe9491 Michael Hanselmann
125 ecfe9491 Michael Hanselmann
      logging.error("RPC error from node %s: %s", name, msg)
126 ecfe9491 Michael Hanselmann
      results[name] = False
127 ecfe9491 Michael Hanselmann
128 ecfe9491 Michael Hanselmann
    return results
129 a8083063 Iustin Pop
130 a8083063 Iustin Pop
131 72737a7f Iustin Pop
class RpcRunner(object):
132 72737a7f Iustin Pop
  """RPC runner class"""
133 a8083063 Iustin Pop
134 72737a7f Iustin Pop
  def __init__(self, cfg):
135 72737a7f Iustin Pop
    """Initialized the rpc runner.
136 a8083063 Iustin Pop

137 72737a7f Iustin Pop
    @type cfg:  C{config.ConfigWriter}
138 72737a7f Iustin Pop
    @param cfg: the configuration object that will be used to get data
139 72737a7f Iustin Pop
                about the cluster
140 a8083063 Iustin Pop

141 72737a7f Iustin Pop
    """
142 72737a7f Iustin Pop
    self._cfg = cfg
143 a8083063 Iustin Pop
144 26ba2bd8 Iustin Pop
  def _InstDict(self, instance):
145 26ba2bd8 Iustin Pop
    """Convert the given instance to a dict.
146 26ba2bd8 Iustin Pop

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

150 26ba2bd8 Iustin Pop
    @type instance: L{objects.Instance}
151 26ba2bd8 Iustin Pop
    @param instance: an Instance object
152 26ba2bd8 Iustin Pop
    @rtype: dict
153 26ba2bd8 Iustin Pop
    @return: the instance dict, with the hvparams filled with the
154 26ba2bd8 Iustin Pop
        cluster defaults
155 26ba2bd8 Iustin Pop

156 26ba2bd8 Iustin Pop
    """
157 26ba2bd8 Iustin Pop
    idict = instance.ToDict()
158 5b442704 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
159 5b442704 Iustin Pop
    idict["hvparams"] = cluster.FillHV(instance)
160 5b442704 Iustin Pop
    idict["beparams"] = cluster.FillBE(instance)
161 26ba2bd8 Iustin Pop
    return idict
162 26ba2bd8 Iustin Pop
163 25348212 Iustin Pop
  def _ConnectList(self, client, node_list):
164 25348212 Iustin Pop
    """Helper for computing node addresses.
165 25348212 Iustin Pop

166 25348212 Iustin Pop
    @type client: L{Client}
167 25348212 Iustin Pop
    @param client: a C{Client} instance
168 25348212 Iustin Pop
    @type node_list: list
169 25348212 Iustin Pop
    @param node_list: the node list we should connect
170 25348212 Iustin Pop

171 25348212 Iustin Pop
    """
172 25348212 Iustin Pop
    all_nodes = self._cfg.GetAllNodesInfo()
173 25348212 Iustin Pop
    addr_list = []
174 25348212 Iustin Pop
    for node in node_list:
175 25348212 Iustin Pop
      if node in all_nodes:
176 25348212 Iustin Pop
        val = all_nodes[node].primary_ip
177 25348212 Iustin Pop
      else:
178 25348212 Iustin Pop
        val = None
179 25348212 Iustin Pop
      addr_list.append(val)
180 25348212 Iustin Pop
    client.ConnectList(node_list, address_list=addr_list)
181 25348212 Iustin Pop
182 25348212 Iustin Pop
  def _ConnectNode(self, client, node):
183 25348212 Iustin Pop
    """Helper for computing one node's address.
184 25348212 Iustin Pop

185 25348212 Iustin Pop
    @type client: L{Client}
186 25348212 Iustin Pop
    @param client: a C{Client} instance
187 25348212 Iustin Pop
    @type node: str
188 25348212 Iustin Pop
    @param node: the node we should connect
189 25348212 Iustin Pop

190 25348212 Iustin Pop
    """
191 25348212 Iustin Pop
    node_info = self._cfg.GetNodeInfo(node)
192 25348212 Iustin Pop
    if node_info is not None:
193 25348212 Iustin Pop
      addr = node_info.primary_ip
194 25348212 Iustin Pop
    else:
195 25348212 Iustin Pop
      addr = None
196 25348212 Iustin Pop
    client.ConnectNode(node, address=addr)
197 25348212 Iustin Pop
198 72737a7f Iustin Pop
  def call_volume_list(self, node_list, vg_name):
199 72737a7f Iustin Pop
    """Gets the logical volumes present in a given volume group.
200 a8083063 Iustin Pop

201 72737a7f Iustin Pop
    This is a multi-node call.
202 a8083063 Iustin Pop

203 72737a7f Iustin Pop
    """
204 72737a7f Iustin Pop
    c = Client("volume_list", [vg_name])
205 25348212 Iustin Pop
    self._ConnectList(c, node_list)
206 3ef3c771 Iustin Pop
    return c.GetResults()
207 a8083063 Iustin Pop
208 72737a7f Iustin Pop
  def call_vg_list(self, node_list):
209 72737a7f Iustin Pop
    """Gets the volume group list.
210 a8083063 Iustin Pop

211 72737a7f Iustin Pop
    This is a multi-node call.
212 a8083063 Iustin Pop

213 72737a7f Iustin Pop
    """
214 72737a7f Iustin Pop
    c = Client("vg_list", [])
215 25348212 Iustin Pop
    self._ConnectList(c, node_list)
216 3ef3c771 Iustin Pop
    return c.GetResults()
217 a8083063 Iustin Pop
218 72737a7f Iustin Pop
  def call_bridges_exist(self, node, bridges_list):
219 72737a7f Iustin Pop
    """Checks if a node has all the bridges given.
220 a8083063 Iustin Pop

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

225 72737a7f Iustin Pop
    This is a single-node call.
226 a8083063 Iustin Pop

227 72737a7f Iustin Pop
    """
228 72737a7f Iustin Pop
    c = Client("bridges_exist", [bridges_list])
229 25348212 Iustin Pop
    self._ConnectNode(c, node)
230 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
231 a8083063 Iustin Pop
232 72737a7f Iustin Pop
  def call_instance_start(self, node, instance, extra_args):
233 72737a7f Iustin Pop
    """Starts an instance.
234 a8083063 Iustin Pop

235 72737a7f Iustin Pop
    This is a single-node call.
236 a8083063 Iustin Pop

237 72737a7f Iustin Pop
    """
238 26ba2bd8 Iustin Pop
    c = Client("instance_start", [self._InstDict(instance), extra_args])
239 25348212 Iustin Pop
    self._ConnectNode(c, node)
240 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
241 a8083063 Iustin Pop
242 72737a7f Iustin Pop
  def call_instance_shutdown(self, node, instance):
243 72737a7f Iustin Pop
    """Stops an instance.
244 a8083063 Iustin Pop

245 72737a7f Iustin Pop
    This is a single-node call.
246 2a10865c Iustin Pop

247 72737a7f Iustin Pop
    """
248 26ba2bd8 Iustin Pop
    c = Client("instance_shutdown", [self._InstDict(instance)])
249 25348212 Iustin Pop
    self._ConnectNode(c, node)
250 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
251 2a10865c Iustin Pop
252 72737a7f Iustin Pop
  def call_instance_migrate(self, node, instance, target, live):
253 72737a7f Iustin Pop
    """Migrate an instance.
254 2a10865c Iustin Pop

255 72737a7f Iustin Pop
    This is a single-node call.
256 2a10865c Iustin Pop

257 72737a7f Iustin Pop
    @type node: string
258 72737a7f Iustin Pop
    @param node: the node on which the instance is currently running
259 72737a7f Iustin Pop
    @type instance: C{objects.Instance}
260 72737a7f Iustin Pop
    @param instance: the instance definition
261 72737a7f Iustin Pop
    @type target: string
262 72737a7f Iustin Pop
    @param target: the target node name
263 72737a7f Iustin Pop
    @type live: boolean
264 72737a7f Iustin Pop
    @param live: whether the migration should be done live or not (the
265 72737a7f Iustin Pop
        interpretation of this parameter is left to the hypervisor)
266 007a2f3e Alexander Schreiber

267 72737a7f Iustin Pop
    """
268 26ba2bd8 Iustin Pop
    c = Client("instance_migrate", [self._InstDict(instance), target, live])
269 25348212 Iustin Pop
    self._ConnectNode(c, node)
270 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
271 007a2f3e Alexander Schreiber
272 72737a7f Iustin Pop
  def call_instance_reboot(self, node, instance, reboot_type, extra_args):
273 72737a7f Iustin Pop
    """Reboots an instance.
274 007a2f3e Alexander Schreiber

275 72737a7f Iustin Pop
    This is a single-node call.
276 a8083063 Iustin Pop

277 72737a7f Iustin Pop
    """
278 26ba2bd8 Iustin Pop
    c = Client("instance_reboot", [self._InstDict(instance),
279 26ba2bd8 Iustin Pop
                                   reboot_type, extra_args])
280 25348212 Iustin Pop
    self._ConnectNode(c, node)
281 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
282 a8083063 Iustin Pop
283 d15a9ad3 Guido Trotter
  def call_instance_os_add(self, node, inst):
284 72737a7f Iustin Pop
    """Installs an OS on the given instance.
285 a8083063 Iustin Pop

286 72737a7f Iustin Pop
    This is a single-node call.
287 decd5f45 Iustin Pop

288 72737a7f Iustin Pop
    """
289 d15a9ad3 Guido Trotter
    params = [self._InstDict(inst)]
290 72737a7f Iustin Pop
    c = Client("instance_os_add", params)
291 25348212 Iustin Pop
    self._ConnectNode(c, node)
292 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
293 decd5f45 Iustin Pop
294 d15a9ad3 Guido Trotter
  def call_instance_run_rename(self, node, inst, old_name):
295 72737a7f Iustin Pop
    """Run the OS rename script for an instance.
296 decd5f45 Iustin Pop

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

299 72737a7f Iustin Pop
    """
300 d15a9ad3 Guido Trotter
    params = [self._InstDict(inst), old_name]
301 72737a7f Iustin Pop
    c = Client("instance_run_rename", params)
302 25348212 Iustin Pop
    self._ConnectNode(c, node)
303 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
304 a8083063 Iustin Pop
305 72737a7f Iustin Pop
  def call_instance_info(self, node, instance, hname):
306 72737a7f Iustin Pop
    """Returns information about a single instance.
307 a8083063 Iustin Pop

308 72737a7f Iustin Pop
    This is a single-node call.
309 a8083063 Iustin Pop

310 72737a7f Iustin Pop
    @type node_list: list
311 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
312 72737a7f Iustin Pop
    @type instance: string
313 72737a7f Iustin Pop
    @param instance: the instance name
314 72737a7f Iustin Pop
    @type hname: string
315 72737a7f Iustin Pop
    @param hname: the hypervisor type of the instance
316 a8083063 Iustin Pop

317 72737a7f Iustin Pop
    """
318 16ad1a83 Iustin Pop
    c = Client("instance_info", [instance, hname])
319 25348212 Iustin Pop
    self._ConnectNode(c, node)
320 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
321 e69d05fd Iustin Pop
322 72737a7f Iustin Pop
  def call_all_instances_info(self, node_list, hypervisor_list):
323 72737a7f Iustin Pop
    """Returns information about all instances on the given nodes.
324 a8083063 Iustin Pop

325 72737a7f Iustin Pop
    This is a multi-node call.
326 a8083063 Iustin Pop

327 72737a7f Iustin Pop
    @type node_list: list
328 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
329 72737a7f Iustin Pop
    @type hypervisor_list: list
330 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
331 a8083063 Iustin Pop

332 72737a7f Iustin Pop
    """
333 72737a7f Iustin Pop
    c = Client("all_instances_info", [hypervisor_list])
334 25348212 Iustin Pop
    self._ConnectList(c, node_list)
335 3ef3c771 Iustin Pop
    return c.GetResults()
336 e69d05fd Iustin Pop
337 72737a7f Iustin Pop
  def call_instance_list(self, node_list, hypervisor_list):
338 72737a7f Iustin Pop
    """Returns the list of running instances on a given node.
339 a8083063 Iustin Pop

340 72737a7f Iustin Pop
    This is a multi-node call.
341 a8083063 Iustin Pop

342 72737a7f Iustin Pop
    @type node_list: list
343 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
344 72737a7f Iustin Pop
    @type hypervisor_list: list
345 72737a7f Iustin Pop
    @param hypervisor_list: the hypervisors to query for instances
346 16abfbc2 Alexander Schreiber

347 72737a7f Iustin Pop
    """
348 72737a7f Iustin Pop
    c = Client("instance_list", [hypervisor_list])
349 25348212 Iustin Pop
    self._ConnectList(c, node_list)
350 3ef3c771 Iustin Pop
    return c.GetResults()
351 16abfbc2 Alexander Schreiber
352 72737a7f Iustin Pop
  def call_node_tcp_ping(self, node, source, target, port, timeout,
353 72737a7f Iustin Pop
                         live_port_needed):
354 72737a7f Iustin Pop
    """Do a TcpPing on the remote node
355 a8083063 Iustin Pop

356 72737a7f Iustin Pop
    This is a single-node call.
357 caad16e2 Iustin Pop

358 72737a7f Iustin Pop
    """
359 72737a7f Iustin Pop
    c = Client("node_tcp_ping", [source, target, port, timeout,
360 72737a7f Iustin Pop
                                 live_port_needed])
361 25348212 Iustin Pop
    self._ConnectNode(c, node)
362 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
363 a8083063 Iustin Pop
364 caad16e2 Iustin Pop
  def call_node_has_ip_address(self, node, address):
365 caad16e2 Iustin Pop
    """Checks if a node has the given IP address.
366 caad16e2 Iustin Pop

367 caad16e2 Iustin Pop
    This is a single-node call.
368 caad16e2 Iustin Pop

369 caad16e2 Iustin Pop
    """
370 caad16e2 Iustin Pop
    c = Client("node_has_ip_address", [address])
371 25348212 Iustin Pop
    self._ConnectNode(c, node)
372 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
373 a8083063 Iustin Pop
374 72737a7f Iustin Pop
  def call_node_info(self, node_list, vg_name, hypervisor_type):
375 72737a7f Iustin Pop
    """Return node information.
376 e69d05fd Iustin Pop

377 72737a7f Iustin Pop
    This will return memory information and volume group size and free
378 72737a7f Iustin Pop
    space.
379 a8083063 Iustin Pop

380 72737a7f Iustin Pop
    This is a multi-node call.
381 a8083063 Iustin Pop

382 72737a7f Iustin Pop
    @type node_list: list
383 72737a7f Iustin Pop
    @param node_list: the list of nodes to query
384 72737a7f Iustin Pop
    @type vgname: C{string}
385 72737a7f Iustin Pop
    @param vgname: the name of the volume group to ask for disk space
386 72737a7f Iustin Pop
        information
387 72737a7f Iustin Pop
    @type hypervisor_type: C{str}
388 72737a7f Iustin Pop
    @param hypervisor_type: the name of the hypervisor to ask for
389 72737a7f Iustin Pop
        memory information
390 a8083063 Iustin Pop

391 72737a7f Iustin Pop
    """
392 72737a7f Iustin Pop
    c = Client("node_info", [vg_name, hypervisor_type])
393 25348212 Iustin Pop
    self._ConnectList(c, node_list)
394 3ef3c771 Iustin Pop
    retux = c.GetResults()
395 a8083063 Iustin Pop
396 72737a7f Iustin Pop
    for node_name in retux:
397 72737a7f Iustin Pop
      ret = retux.get(node_name, False)
398 72737a7f Iustin Pop
      if type(ret) != dict:
399 58b311ca Iustin Pop
        logging.error("could not connect to node %s", node_name)
400 72737a7f Iustin Pop
        ret = {}
401 a8083063 Iustin Pop
402 72737a7f Iustin Pop
      utils.CheckDict(ret,
403 72737a7f Iustin Pop
                      { 'memory_total' : '-',
404 72737a7f Iustin Pop
                        'memory_dom0' : '-',
405 72737a7f Iustin Pop
                        'memory_free' : '-',
406 72737a7f Iustin Pop
                        'vg_size' : 'node_unreachable',
407 72737a7f Iustin Pop
                        'vg_free' : '-' },
408 72737a7f Iustin Pop
                      "call_node_info",
409 72737a7f Iustin Pop
                      )
410 72737a7f Iustin Pop
    return retux
411 a8083063 Iustin Pop
412 72737a7f Iustin Pop
  def call_node_add(self, node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
413 72737a7f Iustin Pop
    """Add a node to the cluster.
414 a8083063 Iustin Pop

415 72737a7f Iustin Pop
    This is a single-node call.
416 a8083063 Iustin Pop

417 72737a7f Iustin Pop
    """
418 72737a7f Iustin Pop
    params = [dsa, dsapub, rsa, rsapub, ssh, sshpub]
419 72737a7f Iustin Pop
    c = Client("node_add", params)
420 25348212 Iustin Pop
    self._ConnectNode(c, node)
421 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
422 a8083063 Iustin Pop
423 72737a7f Iustin Pop
  def call_node_verify(self, node_list, checkdict, cluster_name):
424 72737a7f Iustin Pop
    """Request verification of given parameters.
425 a8083063 Iustin Pop

426 72737a7f Iustin Pop
    This is a multi-node call.
427 a8083063 Iustin Pop

428 72737a7f Iustin Pop
    """
429 72737a7f Iustin Pop
    c = Client("node_verify", [checkdict, cluster_name])
430 25348212 Iustin Pop
    self._ConnectList(c, node_list)
431 3ef3c771 Iustin Pop
    return c.GetResults()
432 a8083063 Iustin Pop
433 72737a7f Iustin Pop
  @staticmethod
434 72737a7f Iustin Pop
  def call_node_start_master(node, start_daemons):
435 72737a7f Iustin Pop
    """Tells a node to activate itself as a master.
436 a8083063 Iustin Pop

437 72737a7f Iustin Pop
    This is a single-node call.
438 a8083063 Iustin Pop

439 72737a7f Iustin Pop
    """
440 72737a7f Iustin Pop
    c = Client("node_start_master", [start_daemons])
441 3ef3c771 Iustin Pop
    c.ConnectNode(node)
442 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
443 a8083063 Iustin Pop
444 72737a7f Iustin Pop
  @staticmethod
445 72737a7f Iustin Pop
  def call_node_stop_master(node, stop_daemons):
446 72737a7f Iustin Pop
    """Tells a node to demote itself from master status.
447 a8083063 Iustin Pop

448 72737a7f Iustin Pop
    This is a single-node call.
449 4e071d3b Iustin Pop

450 72737a7f Iustin Pop
    """
451 72737a7f Iustin Pop
    c = Client("node_stop_master", [stop_daemons])
452 3ef3c771 Iustin Pop
    c.ConnectNode(node)
453 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
454 4e071d3b Iustin Pop
455 72737a7f Iustin Pop
  @staticmethod
456 72737a7f Iustin Pop
  def call_master_info(node_list):
457 72737a7f Iustin Pop
    """Query master info.
458 4e071d3b Iustin Pop

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

461 72737a7f Iustin Pop
    """
462 72737a7f Iustin Pop
    # TODO: should this method query down nodes?
463 72737a7f Iustin Pop
    c = Client("master_info", [])
464 3ef3c771 Iustin Pop
    c.ConnectList(node_list)
465 3ef3c771 Iustin Pop
    return c.GetResults()
466 a8083063 Iustin Pop
467 72737a7f Iustin Pop
  def call_version(self, node_list):
468 72737a7f Iustin Pop
    """Query node version.
469 a8083063 Iustin Pop

470 72737a7f Iustin Pop
    This is a multi-node call.
471 a8083063 Iustin Pop

472 72737a7f Iustin Pop
    """
473 72737a7f Iustin Pop
    c = Client("version", [])
474 25348212 Iustin Pop
    self._ConnectList(c, node_list)
475 3ef3c771 Iustin Pop
    return c.GetResults()
476 a8083063 Iustin Pop
477 72737a7f Iustin Pop
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
478 72737a7f Iustin Pop
    """Request creation of a given block device.
479 a8083063 Iustin Pop

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

482 72737a7f Iustin Pop
    """
483 72737a7f Iustin Pop
    params = [bdev.ToDict(), size, owner, on_primary, info]
484 72737a7f Iustin Pop
    c = Client("blockdev_create", params)
485 25348212 Iustin Pop
    self._ConnectNode(c, node)
486 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
487 a8083063 Iustin Pop
488 72737a7f Iustin Pop
  def call_blockdev_remove(self, node, bdev):
489 72737a7f Iustin Pop
    """Request removal of a given block device.
490 a8083063 Iustin Pop

491 72737a7f Iustin Pop
    This is a single-node call.
492 f3e513ad Iustin Pop

493 72737a7f Iustin Pop
    """
494 72737a7f Iustin Pop
    c = Client("blockdev_remove", [bdev.ToDict()])
495 25348212 Iustin Pop
    self._ConnectNode(c, node)
496 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
497 f3e513ad Iustin Pop
498 72737a7f Iustin Pop
  def call_blockdev_rename(self, node, devlist):
499 72737a7f Iustin Pop
    """Request rename of the given block devices.
500 f3e513ad Iustin Pop

501 72737a7f Iustin Pop
    This is a single-node call.
502 a8083063 Iustin Pop

503 72737a7f Iustin Pop
    """
504 72737a7f Iustin Pop
    params = [(d.ToDict(), uid) for d, uid in devlist]
505 72737a7f Iustin Pop
    c = Client("blockdev_rename", params)
506 25348212 Iustin Pop
    self._ConnectNode(c, node)
507 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
508 a8083063 Iustin Pop
509 72737a7f Iustin Pop
  def call_blockdev_assemble(self, node, disk, owner, on_primary):
510 72737a7f Iustin Pop
    """Request assembling of a given block device.
511 a8083063 Iustin Pop

512 72737a7f Iustin Pop
    This is a single-node call.
513 a8083063 Iustin Pop

514 72737a7f Iustin Pop
    """
515 72737a7f Iustin Pop
    params = [disk.ToDict(), owner, on_primary]
516 72737a7f Iustin Pop
    c = Client("blockdev_assemble", params)
517 25348212 Iustin Pop
    self._ConnectNode(c, node)
518 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
519 a8083063 Iustin Pop
520 72737a7f Iustin Pop
  def call_blockdev_shutdown(self, node, disk):
521 72737a7f Iustin Pop
    """Request shutdown of a given block device.
522 a8083063 Iustin Pop

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

525 72737a7f Iustin Pop
    """
526 72737a7f Iustin Pop
    c = Client("blockdev_shutdown", [disk.ToDict()])
527 25348212 Iustin Pop
    self._ConnectNode(c, node)
528 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
529 a8083063 Iustin Pop
530 72737a7f Iustin Pop
  def call_blockdev_addchildren(self, node, bdev, ndevs):
531 72737a7f Iustin Pop
    """Request adding a list of children to a (mirroring) device.
532 a8083063 Iustin Pop

533 72737a7f Iustin Pop
    This is a single-node call.
534 a8083063 Iustin Pop

535 72737a7f Iustin Pop
    """
536 72737a7f Iustin Pop
    params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
537 72737a7f Iustin Pop
    c = Client("blockdev_addchildren", params)
538 25348212 Iustin Pop
    self._ConnectNode(c, node)
539 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
540 a8083063 Iustin Pop
541 72737a7f Iustin Pop
  def call_blockdev_removechildren(self, node, bdev, ndevs):
542 72737a7f Iustin Pop
    """Request removing a list of children from a (mirroring) device.
543 a8083063 Iustin Pop

544 72737a7f Iustin Pop
    This is a single-node call.
545 a8083063 Iustin Pop

546 72737a7f Iustin Pop
    """
547 72737a7f Iustin Pop
    params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
548 72737a7f Iustin Pop
    c = Client("blockdev_removechildren", params)
549 25348212 Iustin Pop
    self._ConnectNode(c, node)
550 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
551 a8083063 Iustin Pop
552 72737a7f Iustin Pop
  def call_blockdev_getmirrorstatus(self, node, disks):
553 72737a7f Iustin Pop
    """Request status of a (mirroring) device.
554 a8083063 Iustin Pop

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

557 72737a7f Iustin Pop
    """
558 72737a7f Iustin Pop
    params = [dsk.ToDict() for dsk in disks]
559 72737a7f Iustin Pop
    c = Client("blockdev_getmirrorstatus", params)
560 25348212 Iustin Pop
    self._ConnectNode(c, node)
561 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
562 a8083063 Iustin Pop
563 72737a7f Iustin Pop
  def call_blockdev_find(self, node, disk):
564 72737a7f Iustin Pop
    """Request identification of a given block device.
565 72737a7f Iustin Pop

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

568 72737a7f Iustin Pop
    """
569 72737a7f Iustin Pop
    c = Client("blockdev_find", [disk.ToDict()])
570 25348212 Iustin Pop
    self._ConnectNode(c, node)
571 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
572 d61cbe76 Iustin Pop
573 72737a7f Iustin Pop
  def call_blockdev_close(self, node, disks):
574 72737a7f Iustin Pop
    """Closes the given block devices.
575 d61cbe76 Iustin Pop

576 72737a7f Iustin Pop
    This is a single-node call.
577 d61cbe76 Iustin Pop

578 72737a7f Iustin Pop
    """
579 72737a7f Iustin Pop
    params = [cf.ToDict() for cf in disks]
580 72737a7f Iustin Pop
    c = Client("blockdev_close", params)
581 25348212 Iustin Pop
    self._ConnectNode(c, node)
582 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
583 a8083063 Iustin Pop
584 72737a7f Iustin Pop
  @staticmethod
585 6b294c53 Iustin Pop
  def call_upload_file(node_list, file_name, address_list=None):
586 72737a7f Iustin Pop
    """Upload a file.
587 72737a7f Iustin Pop

588 72737a7f Iustin Pop
    The node will refuse the operation in case the file is not on the
589 72737a7f Iustin Pop
    approved file list.
590 72737a7f Iustin Pop

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

593 6b294c53 Iustin Pop
    @type node_list: list
594 6b294c53 Iustin Pop
    @param node_list: the list of node names to upload to
595 6b294c53 Iustin Pop
    @type file_name: str
596 6b294c53 Iustin Pop
    @param file_name: the filename to upload
597 6b294c53 Iustin Pop
    @type address_list: list or None
598 6b294c53 Iustin Pop
    @keyword address_list: an optional list of node addresses, in order
599 6b294c53 Iustin Pop
        to optimize the RPC speed
600 6b294c53 Iustin Pop

601 72737a7f Iustin Pop
    """
602 4c7c81d7 Michael Hanselmann
    data = utils.ReadFile(file_name)
603 72737a7f Iustin Pop
    st = os.stat(file_name)
604 72737a7f Iustin Pop
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
605 72737a7f Iustin Pop
              st.st_atime, st.st_mtime]
606 72737a7f Iustin Pop
    c = Client("upload_file", params)
607 6b294c53 Iustin Pop
    c.ConnectList(node_list, address_list=address_list)
608 3ef3c771 Iustin Pop
    return c.GetResults()
609 72737a7f Iustin Pop
610 72737a7f Iustin Pop
  def call_os_diagnose(self, node_list):
611 72737a7f Iustin Pop
    """Request a diagnose of OS definitions.
612 72737a7f Iustin Pop

613 72737a7f Iustin Pop
    This is a multi-node call.
614 a8083063 Iustin Pop

615 72737a7f Iustin Pop
    """
616 72737a7f Iustin Pop
    c = Client("os_diagnose", [])
617 25348212 Iustin Pop
    self._ConnectList(c, node_list)
618 3ef3c771 Iustin Pop
    result = c.GetResults()
619 72737a7f Iustin Pop
    new_result = {}
620 72737a7f Iustin Pop
    for node_name in result:
621 72737a7f Iustin Pop
      if result[node_name]:
622 72737a7f Iustin Pop
        nr = [objects.OS.FromDict(oss) for oss in result[node_name]]
623 72737a7f Iustin Pop
      else:
624 72737a7f Iustin Pop
        nr = []
625 72737a7f Iustin Pop
      new_result[node_name] = nr
626 72737a7f Iustin Pop
    return new_result
627 a8083063 Iustin Pop
628 72737a7f Iustin Pop
  def call_os_get(self, node, name):
629 72737a7f Iustin Pop
    """Returns an OS definition.
630 a8083063 Iustin Pop

631 72737a7f Iustin Pop
    This is a single-node call.
632 a8083063 Iustin Pop

633 72737a7f Iustin Pop
    """
634 72737a7f Iustin Pop
    c = Client("os_get", [name])
635 25348212 Iustin Pop
    self._ConnectNode(c, node)
636 3ef3c771 Iustin Pop
    result = c.GetResults().get(node, False)
637 72737a7f Iustin Pop
    if isinstance(result, dict):
638 72737a7f Iustin Pop
      return objects.OS.FromDict(result)
639 72737a7f Iustin Pop
    else:
640 72737a7f Iustin Pop
      return result
641 a8083063 Iustin Pop
642 72737a7f Iustin Pop
  def call_hooks_runner(self, node_list, hpath, phase, env):
643 72737a7f Iustin Pop
    """Call the hooks runner.
644 a8083063 Iustin Pop

645 72737a7f Iustin Pop
    Args:
646 72737a7f Iustin Pop
      - op: the OpCode instance
647 72737a7f Iustin Pop
      - env: a dictionary with the environment
648 a8083063 Iustin Pop

649 72737a7f Iustin Pop
    This is a multi-node call.
650 a8083063 Iustin Pop

651 72737a7f Iustin Pop
    """
652 72737a7f Iustin Pop
    params = [hpath, phase, env]
653 72737a7f Iustin Pop
    c = Client("hooks_runner", params)
654 25348212 Iustin Pop
    self._ConnectList(c, node_list)
655 3ef3c771 Iustin Pop
    result = c.GetResults()
656 72737a7f Iustin Pop
    return result
657 a8083063 Iustin Pop
658 72737a7f Iustin Pop
  def call_iallocator_runner(self, node, name, idata):
659 72737a7f Iustin Pop
    """Call an iallocator on a remote node
660 8d528b7c Iustin Pop

661 72737a7f Iustin Pop
    Args:
662 72737a7f Iustin Pop
      - name: the iallocator name
663 72737a7f Iustin Pop
      - input: the json-encoded input string
664 8d528b7c Iustin Pop

665 72737a7f Iustin Pop
    This is a single-node call.
666 8d528b7c Iustin Pop

667 72737a7f Iustin Pop
    """
668 72737a7f Iustin Pop
    params = [name, idata]
669 72737a7f Iustin Pop
    c = Client("iallocator_runner", params)
670 25348212 Iustin Pop
    self._ConnectNode(c, node)
671 3ef3c771 Iustin Pop
    result = c.GetResults().get(node, False)
672 72737a7f Iustin Pop
    return result
673 8d528b7c Iustin Pop
674 72737a7f Iustin Pop
  def call_blockdev_grow(self, node, cf_bdev, amount):
675 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
676 4c8ba8b3 Iustin Pop

677 72737a7f Iustin Pop
    This is a single-node call.
678 4c8ba8b3 Iustin Pop

679 72737a7f Iustin Pop
    """
680 72737a7f Iustin Pop
    c = Client("blockdev_grow", [cf_bdev.ToDict(), amount])
681 25348212 Iustin Pop
    self._ConnectNode(c, node)
682 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
683 4c8ba8b3 Iustin Pop
684 72737a7f Iustin Pop
  def call_blockdev_snapshot(self, node, cf_bdev):
685 72737a7f Iustin Pop
    """Request a snapshot of the given block device.
686 a8083063 Iustin Pop

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

689 72737a7f Iustin Pop
    """
690 72737a7f Iustin Pop
    c = Client("blockdev_snapshot", [cf_bdev.ToDict()])
691 25348212 Iustin Pop
    self._ConnectNode(c, node)
692 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
693 a8083063 Iustin Pop
694 72737a7f Iustin Pop
  def call_snapshot_export(self, node, snap_bdev, dest_node, instance,
695 74c47259 Iustin Pop
                           cluster_name, idx):
696 72737a7f Iustin Pop
    """Request the export of a given snapshot.
697 a8083063 Iustin Pop

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

700 72737a7f Iustin Pop
    """
701 26ba2bd8 Iustin Pop
    params = [snap_bdev.ToDict(), dest_node,
702 74c47259 Iustin Pop
              self._InstDict(instance), cluster_name, idx]
703 72737a7f Iustin Pop
    c = Client("snapshot_export", params)
704 25348212 Iustin Pop
    self._ConnectNode(c, node)
705 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
706 a8083063 Iustin Pop
707 72737a7f Iustin Pop
  def call_finalize_export(self, node, instance, snap_disks):
708 72737a7f Iustin Pop
    """Request the completion of an export operation.
709 a8083063 Iustin Pop

710 72737a7f Iustin Pop
    This writes the export config file, etc.
711 a8083063 Iustin Pop

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

714 72737a7f Iustin Pop
    """
715 72737a7f Iustin Pop
    flat_disks = []
716 72737a7f Iustin Pop
    for disk in snap_disks:
717 72737a7f Iustin Pop
      flat_disks.append(disk.ToDict())
718 26ba2bd8 Iustin Pop
    params = [self._InstDict(instance), flat_disks]
719 72737a7f Iustin Pop
    c = Client("finalize_export", params)
720 25348212 Iustin Pop
    self._ConnectNode(c, node)
721 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
722 a8083063 Iustin Pop
723 72737a7f Iustin Pop
  def call_export_info(self, node, path):
724 72737a7f Iustin Pop
    """Queries the export information in a given path.
725 a8083063 Iustin Pop

726 72737a7f Iustin Pop
    This is a single-node call.
727 a8083063 Iustin Pop

728 72737a7f Iustin Pop
    """
729 72737a7f Iustin Pop
    c = Client("export_info", [path])
730 25348212 Iustin Pop
    self._ConnectNode(c, node)
731 3ef3c771 Iustin Pop
    result = c.GetResults().get(node, False)
732 72737a7f Iustin Pop
    if not result:
733 72737a7f Iustin Pop
      return result
734 72737a7f Iustin Pop
    return objects.SerializableConfigParser.Loads(str(result))
735 a8083063 Iustin Pop
736 6c0af70e Guido Trotter
  def call_instance_os_import(self, node, inst, src_node, src_images,
737 6c0af70e Guido Trotter
                              cluster_name):
738 72737a7f Iustin Pop
    """Request the import of a backup into an instance.
739 a8083063 Iustin Pop

740 72737a7f Iustin Pop
    This is a single-node call.
741 a8083063 Iustin Pop

742 72737a7f Iustin Pop
    """
743 6c0af70e Guido Trotter
    params = [self._InstDict(inst), src_node, src_images, cluster_name]
744 72737a7f Iustin Pop
    c = Client("instance_os_import", params)
745 25348212 Iustin Pop
    self._ConnectNode(c, node)
746 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
747 a8083063 Iustin Pop
748 72737a7f Iustin Pop
  def call_export_list(self, node_list):
749 72737a7f Iustin Pop
    """Gets the stored exports list.
750 a8083063 Iustin Pop

751 72737a7f Iustin Pop
    This is a multi-node call.
752 a8083063 Iustin Pop

753 72737a7f Iustin Pop
    """
754 72737a7f Iustin Pop
    c = Client("export_list", [])
755 25348212 Iustin Pop
    self._ConnectList(c, node_list)
756 3ef3c771 Iustin Pop
    result = c.GetResults()
757 72737a7f Iustin Pop
    return result
758 a8083063 Iustin Pop
759 72737a7f Iustin Pop
  def call_export_remove(self, node, export):
760 72737a7f Iustin Pop
    """Requests removal of a given export.
761 a8083063 Iustin Pop

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

764 72737a7f Iustin Pop
    """
765 72737a7f Iustin Pop
    c = Client("export_remove", [export])
766 25348212 Iustin Pop
    self._ConnectNode(c, node)
767 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
768 a8083063 Iustin Pop
769 15396f60 Michael Hanselmann
  @staticmethod
770 15396f60 Michael Hanselmann
  def call_node_leave_cluster(node):
771 72737a7f Iustin Pop
    """Requests a node to clean the cluster information it has.
772 a8083063 Iustin Pop

773 72737a7f Iustin Pop
    This will remove the configuration information from the ganeti data
774 72737a7f Iustin Pop
    dir.
775 a8083063 Iustin Pop

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

778 72737a7f Iustin Pop
    """
779 72737a7f Iustin Pop
    c = Client("node_leave_cluster", [])
780 3ef3c771 Iustin Pop
    c.ConnectNode(node)
781 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
782 dcb93971 Michael Hanselmann
783 72737a7f Iustin Pop
  def call_node_volumes(self, node_list):
784 72737a7f Iustin Pop
    """Gets all volumes on node(s).
785 dcb93971 Michael Hanselmann

786 72737a7f Iustin Pop
    This is a multi-node call.
787 dcb93971 Michael Hanselmann

788 72737a7f Iustin Pop
    """
789 72737a7f Iustin Pop
    c = Client("node_volumes", [])
790 25348212 Iustin Pop
    self._ConnectList(c, node_list)
791 3ef3c771 Iustin Pop
    return c.GetResults()
792 06009e27 Iustin Pop
793 72737a7f Iustin Pop
  def call_test_delay(self, node_list, duration):
794 72737a7f Iustin Pop
    """Sleep for a fixed time on given node(s).
795 06009e27 Iustin Pop

796 72737a7f Iustin Pop
    This is a multi-node call.
797 06009e27 Iustin Pop

798 72737a7f Iustin Pop
    """
799 72737a7f Iustin Pop
    c = Client("test_delay", [duration])
800 25348212 Iustin Pop
    self._ConnectList(c, node_list)
801 3ef3c771 Iustin Pop
    return c.GetResults()
802 5e04ed8b Manuel Franceschini
803 72737a7f Iustin Pop
  def call_file_storage_dir_create(self, node, file_storage_dir):
804 72737a7f Iustin Pop
    """Create the given file storage directory.
805 5e04ed8b Manuel Franceschini

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

808 72737a7f Iustin Pop
    """
809 72737a7f Iustin Pop
    c = Client("file_storage_dir_create", [file_storage_dir])
810 25348212 Iustin Pop
    self._ConnectNode(c, node)
811 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
812 5e04ed8b Manuel Franceschini
813 72737a7f Iustin Pop
  def call_file_storage_dir_remove(self, node, file_storage_dir):
814 72737a7f Iustin Pop
    """Remove the given file storage directory.
815 5e04ed8b Manuel Franceschini

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

818 72737a7f Iustin Pop
    """
819 72737a7f Iustin Pop
    c = Client("file_storage_dir_remove", [file_storage_dir])
820 25348212 Iustin Pop
    self._ConnectNode(c, node)
821 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
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 72737a7f Iustin Pop
    c = Client("file_storage_dir_rename",
831 72737a7f Iustin Pop
               [old_file_storage_dir, new_file_storage_dir])
832 25348212 Iustin Pop
    self._ConnectNode(c, node)
833 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
834 ca52cdeb Michael Hanselmann
835 72737a7f Iustin Pop
  @staticmethod
836 99aabbed Iustin Pop
  def call_jobqueue_update(node_list, address_list, file_name, content):
837 72737a7f Iustin Pop
    """Update job queue.
838 ca52cdeb Michael Hanselmann

839 72737a7f Iustin Pop
    This is a multi-node call.
840 ca52cdeb Michael Hanselmann

841 72737a7f Iustin Pop
    """
842 72737a7f Iustin Pop
    c = Client("jobqueue_update", [file_name, content])
843 99aabbed Iustin Pop
    c.ConnectList(node_list, address_list=address_list)
844 3ef3c771 Iustin Pop
    result = c.GetResults()
845 72737a7f Iustin Pop
    return result
846 ca52cdeb Michael Hanselmann
847 72737a7f Iustin Pop
  @staticmethod
848 72737a7f Iustin Pop
  def call_jobqueue_purge(node):
849 72737a7f Iustin Pop
    """Purge job queue.
850 ca52cdeb Michael Hanselmann

851 72737a7f Iustin Pop
    This is a single-node call.
852 ca52cdeb Michael Hanselmann

853 72737a7f Iustin Pop
    """
854 72737a7f Iustin Pop
    c = Client("jobqueue_purge", [])
855 3ef3c771 Iustin Pop
    c.ConnectNode(node)
856 3ef3c771 Iustin Pop
    return c.GetResults().get(node, False)
857 af5ebcb1 Michael Hanselmann
858 72737a7f Iustin Pop
  @staticmethod
859 99aabbed Iustin Pop
  def call_jobqueue_rename(node_list, address_list, old, new):
860 72737a7f Iustin Pop
    """Rename a job queue file.
861 af5ebcb1 Michael Hanselmann

862 72737a7f Iustin Pop
    This is a multi-node call.
863 af5ebcb1 Michael Hanselmann

864 72737a7f Iustin Pop
    """
865 72737a7f Iustin Pop
    c = Client("jobqueue_rename", [old, new])
866 99aabbed Iustin Pop
    c.ConnectList(node_list, address_list=address_list)
867 3ef3c771 Iustin Pop
    result = c.GetResults()
868 72737a7f Iustin Pop
    return result
869 6217e295 Iustin Pop
870 6217e295 Iustin Pop
871 5d672980 Iustin Pop
  @staticmethod
872 5d672980 Iustin Pop
  def call_jobqueue_set_drain(node_list, drain_flag):
873 5d672980 Iustin Pop
    """Set the drain flag on the queue.
874 5d672980 Iustin Pop

875 5d672980 Iustin Pop
    This is a multi-node call.
876 5d672980 Iustin Pop

877 5d672980 Iustin Pop
    @type node_list: list
878 5d672980 Iustin Pop
    @param node_list: the list of nodes to query
879 5d672980 Iustin Pop
    @type drain_flag: bool
880 5d672980 Iustin Pop
    @param drain_flag: if True, will set the drain flag, otherwise reset it.
881 5d672980 Iustin Pop

882 5d672980 Iustin Pop
    """
883 5d672980 Iustin Pop
    c = Client("jobqueue_set_drain", [drain_flag])
884 3ef3c771 Iustin Pop
    c.ConnectList(node_list)
885 3ef3c771 Iustin Pop
    result = c.GetResults()
886 5d672980 Iustin Pop
    return result
887 5d672980 Iustin Pop
888 5d672980 Iustin Pop
889 6217e295 Iustin Pop
  def call_hypervisor_validate_params(self, node_list, hvname, hvparams):
890 6217e295 Iustin Pop
    """Validate the hypervisor params.
891 6217e295 Iustin Pop

892 6217e295 Iustin Pop
    This is a multi-node call.
893 6217e295 Iustin Pop

894 6217e295 Iustin Pop
    @type node_list: list
895 6217e295 Iustin Pop
    @param node_list: the list of nodes to query
896 6217e295 Iustin Pop
    @type hvname: string
897 6217e295 Iustin Pop
    @param hvname: the hypervisor name
898 6217e295 Iustin Pop
    @type hvparams: dict
899 6217e295 Iustin Pop
    @param hvparams: the hypervisor parameters to be validated
900 6217e295 Iustin Pop

901 6217e295 Iustin Pop
    """
902 6217e295 Iustin Pop
    cluster = self._cfg.GetClusterInfo()
903 6217e295 Iustin Pop
    hv_full = cluster.FillDict(cluster.hvparams.get(hvname, {}), hvparams)
904 6217e295 Iustin Pop
    c = Client("hypervisor_validate_params", [hvname, hv_full])
905 25348212 Iustin Pop
    self._ConnectList(c, node_list)
906 3ef3c771 Iustin Pop
    result = c.GetResults()
907 6217e295 Iustin Pop
    return result