Statistics
| Branch: | Tag: | Revision:

root / lib / rpc.py @ a82ce292

History | View | Annotate | Download (18.3 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 a8083063 Iustin Pop
"""Script to show add a new node to the cluster
23 a8083063 Iustin Pop

24 a8083063 Iustin Pop
"""
25 a8083063 Iustin Pop
26 a8083063 Iustin Pop
# pylint: disable-msg=C0103
27 a8083063 Iustin Pop
28 a8083063 Iustin Pop
import os
29 81010134 Iustin Pop
import socket
30 81010134 Iustin Pop
import httplib
31 a8083063 Iustin Pop
32 81010134 Iustin Pop
import simplejson
33 a8083063 Iustin Pop
34 a8083063 Iustin Pop
from ganeti import logger
35 a8083063 Iustin Pop
from ganeti import utils
36 a8083063 Iustin Pop
from ganeti import objects
37 a8083063 Iustin Pop
from ganeti import ssconf
38 a8083063 Iustin Pop
39 7c0d6283 Michael Hanselmann
40 a8083063 Iustin Pop
class NodeController:
41 a8083063 Iustin Pop
  """Node-handling class.
42 a8083063 Iustin Pop

43 a8083063 Iustin Pop
  For each node that we speak with, we create an instance of this
44 a8083063 Iustin Pop
  class, so that we have a safe place to store the details of this
45 a8083063 Iustin Pop
  individual call.
46 a8083063 Iustin Pop

47 a8083063 Iustin Pop
  """
48 a8083063 Iustin Pop
  def __init__(self, parent, node):
49 a8083063 Iustin Pop
    self.parent = parent
50 a8083063 Iustin Pop
    self.node = node
51 81010134 Iustin Pop
    self.failed = False
52 a8083063 Iustin Pop
53 81010134 Iustin Pop
    self.http_conn = hc = httplib.HTTPConnection(node, self.parent.port)
54 a8083063 Iustin Pop
    try:
55 81010134 Iustin Pop
      hc.connect()
56 81010134 Iustin Pop
      hc.putrequest('PUT', "/%s" % self.parent.procedure,
57 81010134 Iustin Pop
                    skip_accept_encoding=True)
58 81010134 Iustin Pop
      hc.putheader('Content-Length', str(len(parent.body)))
59 81010134 Iustin Pop
      hc.endheaders()
60 81010134 Iustin Pop
      hc.send(parent.body)
61 81010134 Iustin Pop
    except socket.error, err:
62 81010134 Iustin Pop
      logger.Error("Error connecting to %s: %s" % (node, str(err)))
63 81010134 Iustin Pop
      self.failed = True
64 81010134 Iustin Pop
65 81010134 Iustin Pop
  def get_response(self):
66 81010134 Iustin Pop
    """Try to process the response from the node.
67 a8083063 Iustin Pop

68 a8083063 Iustin Pop
    """
69 81010134 Iustin Pop
    if self.failed:
70 81010134 Iustin Pop
      # we already failed in connect
71 a8083063 Iustin Pop
      return False
72 81010134 Iustin Pop
    resp = self.http_conn.getresponse()
73 81010134 Iustin Pop
    if resp.status != 200:
74 a8083063 Iustin Pop
      return False
75 81010134 Iustin Pop
    try:
76 81010134 Iustin Pop
      length = int(resp.getheader('Content-Length', '0'))
77 81010134 Iustin Pop
    except ValueError:
78 81010134 Iustin Pop
      return False
79 81010134 Iustin Pop
    if not length:
80 81010134 Iustin Pop
      logger.Error("Zero-length reply from %s" % self.node)
81 81010134 Iustin Pop
      return False
82 81010134 Iustin Pop
    payload = resp.read(length)
83 81010134 Iustin Pop
    unload = simplejson.loads(payload)
84 81010134 Iustin Pop
    return unload
85 a8083063 Iustin Pop
86 a8083063 Iustin Pop
87 a8083063 Iustin Pop
class Client:
88 a8083063 Iustin Pop
  """RPC Client class.
89 a8083063 Iustin Pop

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

94 a8083063 Iustin Pop
  One current bug is that generic failure is still signalled by
95 a8083063 Iustin Pop
  'False' result, which is not good. This overloading of values can
96 a8083063 Iustin Pop
  cause bugs.
97 a8083063 Iustin Pop

98 a8083063 Iustin Pop
  """
99 a8083063 Iustin Pop
  result_set = False
100 a8083063 Iustin Pop
  result = False
101 a8083063 Iustin Pop
  allresult = []
102 a8083063 Iustin Pop
103 a8083063 Iustin Pop
  def __init__(self, procedure, args):
104 a8083063 Iustin Pop
    ss = ssconf.SimpleStore()
105 a8083063 Iustin Pop
    self.port = ss.GetNodeDaemonPort()
106 a8083063 Iustin Pop
    self.nodepw = ss.GetNodeDaemonPassword()
107 a8083063 Iustin Pop
    self.nc = {}
108 a8083063 Iustin Pop
    self.results = {}
109 a8083063 Iustin Pop
    self.procedure = procedure
110 a8083063 Iustin Pop
    self.args = args
111 81010134 Iustin Pop
    self.body = simplejson.dumps(args)
112 a8083063 Iustin Pop
113 a8083063 Iustin Pop
  #--- generic connector -------------
114 a8083063 Iustin Pop
115 a8083063 Iustin Pop
  def connect_list(self, node_list):
116 a8083063 Iustin Pop
    """Add a list of nodes to the target nodes.
117 a8083063 Iustin Pop

118 a8083063 Iustin Pop
    """
119 a8083063 Iustin Pop
    for node in node_list:
120 a8083063 Iustin Pop
      self.connect(node)
121 a8083063 Iustin Pop
122 a8083063 Iustin Pop
  def connect(self, connect_node):
123 a8083063 Iustin Pop
    """Add a node to the target list.
124 a8083063 Iustin Pop

125 a8083063 Iustin Pop
    """
126 a8083063 Iustin Pop
    self.nc[connect_node] = nc = NodeController(self, connect_node)
127 a8083063 Iustin Pop
128 a8083063 Iustin Pop
  def getresult(self):
129 a8083063 Iustin Pop
    """Return the results of the call.
130 a8083063 Iustin Pop

131 a8083063 Iustin Pop
    """
132 a8083063 Iustin Pop
    return self.results
133 a8083063 Iustin Pop
134 a8083063 Iustin Pop
  def run(self):
135 a8083063 Iustin Pop
    """Wrapper over reactor.run().
136 a8083063 Iustin Pop

137 a8083063 Iustin Pop
    This function simply calls reactor.run() if we have any requests
138 a8083063 Iustin Pop
    queued, otherwise it does nothing.
139 a8083063 Iustin Pop

140 a8083063 Iustin Pop
    """
141 81010134 Iustin Pop
    for node, nc in self.nc.items():
142 81010134 Iustin Pop
      self.results[node] = nc.get_response()
143 a8083063 Iustin Pop
144 a8083063 Iustin Pop
145 a8083063 Iustin Pop
def call_volume_list(node_list, vg_name):
146 a8083063 Iustin Pop
  """Gets the logical volumes present in a given volume group.
147 a8083063 Iustin Pop

148 a8083063 Iustin Pop
  This is a multi-node call.
149 a8083063 Iustin Pop

150 a8083063 Iustin Pop
  """
151 a8083063 Iustin Pop
  c = Client("volume_list", [vg_name])
152 a8083063 Iustin Pop
  c.connect_list(node_list)
153 a8083063 Iustin Pop
  c.run()
154 a8083063 Iustin Pop
  return c.getresult()
155 a8083063 Iustin Pop
156 a8083063 Iustin Pop
157 a8083063 Iustin Pop
def call_vg_list(node_list):
158 a8083063 Iustin Pop
  """Gets the volume group list.
159 a8083063 Iustin Pop

160 a8083063 Iustin Pop
  This is a multi-node call.
161 a8083063 Iustin Pop

162 a8083063 Iustin Pop
  """
163 a8083063 Iustin Pop
  c = Client("vg_list", [])
164 a8083063 Iustin Pop
  c.connect_list(node_list)
165 a8083063 Iustin Pop
  c.run()
166 a8083063 Iustin Pop
  return c.getresult()
167 a8083063 Iustin Pop
168 a8083063 Iustin Pop
169 a8083063 Iustin Pop
def call_bridges_exist(node, bridges_list):
170 a8083063 Iustin Pop
  """Checks if a node has all the bridges given.
171 a8083063 Iustin Pop

172 a8083063 Iustin Pop
  This method checks if all bridges given in the bridges_list are
173 a8083063 Iustin Pop
  present on the remote node, so that an instance that uses interfaces
174 a8083063 Iustin Pop
  on those bridges can be started.
175 a8083063 Iustin Pop

176 a8083063 Iustin Pop
  This is a single-node call.
177 a8083063 Iustin Pop

178 a8083063 Iustin Pop
  """
179 a8083063 Iustin Pop
  c = Client("bridges_exist", [bridges_list])
180 a8083063 Iustin Pop
  c.connect(node)
181 a8083063 Iustin Pop
  c.run()
182 a8083063 Iustin Pop
  return c.getresult().get(node, False)
183 a8083063 Iustin Pop
184 a8083063 Iustin Pop
185 a8083063 Iustin Pop
def call_instance_start(node, instance, extra_args):
186 2f8598a5 Alexander Schreiber
  """Starts an instance.
187 a8083063 Iustin Pop

188 a8083063 Iustin Pop
  This is a single-node call.
189 a8083063 Iustin Pop

190 a8083063 Iustin Pop
  """
191 319856a9 Michael Hanselmann
  c = Client("instance_start", [instance.ToDict(), extra_args])
192 a8083063 Iustin Pop
  c.connect(node)
193 a8083063 Iustin Pop
  c.run()
194 a8083063 Iustin Pop
  return c.getresult().get(node, False)
195 a8083063 Iustin Pop
196 a8083063 Iustin Pop
197 a8083063 Iustin Pop
def call_instance_shutdown(node, instance):
198 a8083063 Iustin Pop
  """Stops an instance.
199 a8083063 Iustin Pop

200 a8083063 Iustin Pop
  This is a single-node call.
201 a8083063 Iustin Pop

202 a8083063 Iustin Pop
  """
203 319856a9 Michael Hanselmann
  c = Client("instance_shutdown", [instance.ToDict()])
204 a8083063 Iustin Pop
  c.connect(node)
205 a8083063 Iustin Pop
  c.run()
206 a8083063 Iustin Pop
  return c.getresult().get(node, False)
207 a8083063 Iustin Pop
208 a8083063 Iustin Pop
209 2a10865c Iustin Pop
def call_instance_migrate(node, instance, target, live):
210 2a10865c Iustin Pop
  """Migrate an instance.
211 2a10865c Iustin Pop

212 2a10865c Iustin Pop
  This is a single-node call.
213 2a10865c Iustin Pop

214 2a10865c Iustin Pop
  """
215 2a10865c Iustin Pop
  c = Client("instance_migrate", [instance.name, target, live])
216 2a10865c Iustin Pop
  c.connect(node)
217 2a10865c Iustin Pop
  c.run()
218 2a10865c Iustin Pop
  return c.getresult().get(node, False)
219 2a10865c Iustin Pop
220 2a10865c Iustin Pop
221 007a2f3e Alexander Schreiber
def call_instance_reboot(node, instance, reboot_type, extra_args):
222 007a2f3e Alexander Schreiber
  """Reboots an instance.
223 007a2f3e Alexander Schreiber

224 007a2f3e Alexander Schreiber
  This is a single-node call.
225 007a2f3e Alexander Schreiber

226 007a2f3e Alexander Schreiber
  """
227 007a2f3e Alexander Schreiber
  c = Client("instance_reboot", [instance.ToDict(), reboot_type, extra_args])
228 007a2f3e Alexander Schreiber
  c.connect(node)
229 007a2f3e Alexander Schreiber
  c.run()
230 007a2f3e Alexander Schreiber
  return c.getresult().get(node, False)
231 007a2f3e Alexander Schreiber
232 007a2f3e Alexander Schreiber
233 a8083063 Iustin Pop
def call_instance_os_add(node, inst, osdev, swapdev):
234 a8083063 Iustin Pop
  """Installs an OS on the given instance.
235 a8083063 Iustin Pop

236 a8083063 Iustin Pop
  This is a single-node call.
237 a8083063 Iustin Pop

238 a8083063 Iustin Pop
  """
239 319856a9 Michael Hanselmann
  params = [inst.ToDict(), osdev, swapdev]
240 a8083063 Iustin Pop
  c = Client("instance_os_add", params)
241 a8083063 Iustin Pop
  c.connect(node)
242 a8083063 Iustin Pop
  c.run()
243 a8083063 Iustin Pop
  return c.getresult().get(node, False)
244 a8083063 Iustin Pop
245 a8083063 Iustin Pop
246 decd5f45 Iustin Pop
def call_instance_run_rename(node, inst, old_name, osdev, swapdev):
247 decd5f45 Iustin Pop
  """Run the OS rename script for an instance.
248 decd5f45 Iustin Pop

249 decd5f45 Iustin Pop
  This is a single-node call.
250 decd5f45 Iustin Pop

251 decd5f45 Iustin Pop
  """
252 319856a9 Michael Hanselmann
  params = [inst.ToDict(), old_name, osdev, swapdev]
253 decd5f45 Iustin Pop
  c = Client("instance_run_rename", params)
254 decd5f45 Iustin Pop
  c.connect(node)
255 decd5f45 Iustin Pop
  c.run()
256 decd5f45 Iustin Pop
  return c.getresult().get(node, False)
257 decd5f45 Iustin Pop
258 decd5f45 Iustin Pop
259 a8083063 Iustin Pop
def call_instance_info(node, instance):
260 a8083063 Iustin Pop
  """Returns information about a single instance.
261 a8083063 Iustin Pop

262 a8083063 Iustin Pop
  This is a single-node call.
263 a8083063 Iustin Pop

264 a8083063 Iustin Pop
  """
265 a8083063 Iustin Pop
  c = Client("instance_info", [instance])
266 a8083063 Iustin Pop
  c.connect(node)
267 a8083063 Iustin Pop
  c.run()
268 a8083063 Iustin Pop
  return c.getresult().get(node, False)
269 a8083063 Iustin Pop
270 a8083063 Iustin Pop
271 a8083063 Iustin Pop
def call_all_instances_info(node_list):
272 a8083063 Iustin Pop
  """Returns information about all instances on a given node.
273 a8083063 Iustin Pop

274 a8083063 Iustin Pop
  This is a single-node call.
275 a8083063 Iustin Pop

276 a8083063 Iustin Pop
  """
277 a8083063 Iustin Pop
  c = Client("all_instances_info", [])
278 a8083063 Iustin Pop
  c.connect_list(node_list)
279 a8083063 Iustin Pop
  c.run()
280 a8083063 Iustin Pop
  return c.getresult()
281 a8083063 Iustin Pop
282 a8083063 Iustin Pop
283 a8083063 Iustin Pop
def call_instance_list(node_list):
284 a8083063 Iustin Pop
  """Returns the list of running instances on a given node.
285 a8083063 Iustin Pop

286 a8083063 Iustin Pop
  This is a single-node call.
287 a8083063 Iustin Pop

288 a8083063 Iustin Pop
  """
289 a8083063 Iustin Pop
  c = Client("instance_list", [])
290 a8083063 Iustin Pop
  c.connect_list(node_list)
291 a8083063 Iustin Pop
  c.run()
292 a8083063 Iustin Pop
  return c.getresult()
293 a8083063 Iustin Pop
294 a8083063 Iustin Pop
295 16abfbc2 Alexander Schreiber
def call_node_tcp_ping(node, source, target, port, timeout, live_port_needed):
296 16abfbc2 Alexander Schreiber
  """Do a TcpPing on the remote node
297 16abfbc2 Alexander Schreiber

298 16abfbc2 Alexander Schreiber
  This is a single-node call.
299 16abfbc2 Alexander Schreiber
  """
300 16abfbc2 Alexander Schreiber
  c = Client("node_tcp_ping", [source, target, port, timeout,
301 16abfbc2 Alexander Schreiber
                               live_port_needed])
302 16abfbc2 Alexander Schreiber
  c.connect(node)
303 16abfbc2 Alexander Schreiber
  c.run()
304 16abfbc2 Alexander Schreiber
  return c.getresult().get(node, False)
305 16abfbc2 Alexander Schreiber
306 16abfbc2 Alexander Schreiber
307 a8083063 Iustin Pop
def call_node_info(node_list, vg_name):
308 a8083063 Iustin Pop
  """Return node information.
309 a8083063 Iustin Pop

310 a8083063 Iustin Pop
  This will return memory information and volume group size and free
311 a8083063 Iustin Pop
  space.
312 a8083063 Iustin Pop

313 a8083063 Iustin Pop
  This is a multi-node call.
314 a8083063 Iustin Pop

315 a8083063 Iustin Pop
  """
316 a8083063 Iustin Pop
  c = Client("node_info", [vg_name])
317 a8083063 Iustin Pop
  c.connect_list(node_list)
318 a8083063 Iustin Pop
  c.run()
319 a8083063 Iustin Pop
  retux = c.getresult()
320 a8083063 Iustin Pop
321 a8083063 Iustin Pop
  for node_name in retux:
322 a8083063 Iustin Pop
    ret = retux.get(node_name, False)
323 a8083063 Iustin Pop
    if type(ret) != dict:
324 a8083063 Iustin Pop
      logger.Error("could not connect to node %s" % (node_name))
325 a8083063 Iustin Pop
      ret = {}
326 a8083063 Iustin Pop
327 a8083063 Iustin Pop
    utils.CheckDict(ret,
328 a8083063 Iustin Pop
                    { 'memory_total' : '-',
329 a8083063 Iustin Pop
                      'memory_dom0' : '-',
330 a8083063 Iustin Pop
                      'memory_free' : '-',
331 a8083063 Iustin Pop
                      'vg_size' : 'node_unreachable',
332 a8083063 Iustin Pop
                      'vg_free' : '-' },
333 a8083063 Iustin Pop
                    "call_node_info",
334 a8083063 Iustin Pop
                    )
335 a8083063 Iustin Pop
  return retux
336 a8083063 Iustin Pop
337 a8083063 Iustin Pop
338 a8083063 Iustin Pop
def call_node_add(node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
339 a8083063 Iustin Pop
  """Add a node to the cluster.
340 a8083063 Iustin Pop

341 a8083063 Iustin Pop
  This is a single-node call.
342 a8083063 Iustin Pop

343 a8083063 Iustin Pop
  """
344 a8083063 Iustin Pop
  params = [dsa, dsapub, rsa, rsapub, ssh, sshpub]
345 a8083063 Iustin Pop
  c = Client("node_add", params)
346 a8083063 Iustin Pop
  c.connect(node)
347 a8083063 Iustin Pop
  c.run()
348 a8083063 Iustin Pop
  return c.getresult().get(node, False)
349 a8083063 Iustin Pop
350 a8083063 Iustin Pop
351 a8083063 Iustin Pop
def call_node_verify(node_list, checkdict):
352 a8083063 Iustin Pop
  """Request verification of given parameters.
353 a8083063 Iustin Pop

354 a8083063 Iustin Pop
  This is a multi-node call.
355 a8083063 Iustin Pop

356 a8083063 Iustin Pop
  """
357 a8083063 Iustin Pop
  c = Client("node_verify", [checkdict])
358 a8083063 Iustin Pop
  c.connect_list(node_list)
359 a8083063 Iustin Pop
  c.run()
360 a8083063 Iustin Pop
  return c.getresult()
361 a8083063 Iustin Pop
362 a8083063 Iustin Pop
363 1c65840b Iustin Pop
def call_node_start_master(node, start_daemons):
364 a8083063 Iustin Pop
  """Tells a node to activate itself as a master.
365 a8083063 Iustin Pop

366 a8083063 Iustin Pop
  This is a single-node call.
367 a8083063 Iustin Pop

368 a8083063 Iustin Pop
  """
369 1c65840b Iustin Pop
  c = Client("node_start_master", [start_daemons])
370 a8083063 Iustin Pop
  c.connect(node)
371 a8083063 Iustin Pop
  c.run()
372 a8083063 Iustin Pop
  return c.getresult().get(node, False)
373 a8083063 Iustin Pop
374 a8083063 Iustin Pop
375 1c65840b Iustin Pop
def call_node_stop_master(node, stop_daemons):
376 a8083063 Iustin Pop
  """Tells a node to demote itself from master status.
377 a8083063 Iustin Pop

378 a8083063 Iustin Pop
  This is a single-node call.
379 a8083063 Iustin Pop

380 a8083063 Iustin Pop
  """
381 1c65840b Iustin Pop
  c = Client("node_stop_master", [stop_daemons])
382 a8083063 Iustin Pop
  c.connect(node)
383 a8083063 Iustin Pop
  c.run()
384 a8083063 Iustin Pop
  return c.getresult().get(node, False)
385 a8083063 Iustin Pop
386 a8083063 Iustin Pop
387 a8083063 Iustin Pop
def call_version(node_list):
388 a8083063 Iustin Pop
  """Query node version.
389 a8083063 Iustin Pop

390 a8083063 Iustin Pop
  This is a multi-node call.
391 a8083063 Iustin Pop

392 a8083063 Iustin Pop
  """
393 a8083063 Iustin Pop
  c = Client("version", [])
394 a8083063 Iustin Pop
  c.connect_list(node_list)
395 a8083063 Iustin Pop
  c.run()
396 a8083063 Iustin Pop
  return c.getresult()
397 a8083063 Iustin Pop
398 a8083063 Iustin Pop
399 3f78eef2 Iustin Pop
def call_blockdev_create(node, bdev, size, owner, on_primary, info):
400 a8083063 Iustin Pop
  """Request creation of a given block device.
401 a8083063 Iustin Pop

402 a8083063 Iustin Pop
  This is a single-node call.
403 a8083063 Iustin Pop

404 a8083063 Iustin Pop
  """
405 3f78eef2 Iustin Pop
  params = [bdev.ToDict(), size, owner, on_primary, info]
406 a8083063 Iustin Pop
  c = Client("blockdev_create", params)
407 a8083063 Iustin Pop
  c.connect(node)
408 a8083063 Iustin Pop
  c.run()
409 a8083063 Iustin Pop
  return c.getresult().get(node, False)
410 a8083063 Iustin Pop
411 a8083063 Iustin Pop
412 a8083063 Iustin Pop
def call_blockdev_remove(node, bdev):
413 a8083063 Iustin Pop
  """Request removal of a given block device.
414 a8083063 Iustin Pop

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

417 a8083063 Iustin Pop
  """
418 319856a9 Michael Hanselmann
  c = Client("blockdev_remove", [bdev.ToDict()])
419 a8083063 Iustin Pop
  c.connect(node)
420 a8083063 Iustin Pop
  c.run()
421 a8083063 Iustin Pop
  return c.getresult().get(node, False)
422 a8083063 Iustin Pop
423 a8083063 Iustin Pop
424 f3e513ad Iustin Pop
def call_blockdev_rename(node, devlist):
425 f3e513ad Iustin Pop
  """Request rename of the given block devices.
426 f3e513ad Iustin Pop

427 f3e513ad Iustin Pop
  This is a single-node call.
428 f3e513ad Iustin Pop

429 f3e513ad Iustin Pop
  """
430 f3e513ad Iustin Pop
  params = [(d.ToDict(), uid) for d, uid in devlist]
431 f3e513ad Iustin Pop
  c = Client("blockdev_rename", params)
432 f3e513ad Iustin Pop
  c.connect(node)
433 f3e513ad Iustin Pop
  c.run()
434 f3e513ad Iustin Pop
  return c.getresult().get(node, False)
435 f3e513ad Iustin Pop
436 f3e513ad Iustin Pop
437 3f78eef2 Iustin Pop
def call_blockdev_assemble(node, disk, owner, on_primary):
438 a8083063 Iustin Pop
  """Request assembling of a given block device.
439 a8083063 Iustin Pop

440 a8083063 Iustin Pop
  This is a single-node call.
441 a8083063 Iustin Pop

442 a8083063 Iustin Pop
  """
443 3f78eef2 Iustin Pop
  params = [disk.ToDict(), owner, on_primary]
444 a8083063 Iustin Pop
  c = Client("blockdev_assemble", params)
445 a8083063 Iustin Pop
  c.connect(node)
446 a8083063 Iustin Pop
  c.run()
447 a8083063 Iustin Pop
  return c.getresult().get(node, False)
448 a8083063 Iustin Pop
449 a8083063 Iustin Pop
450 a8083063 Iustin Pop
def call_blockdev_shutdown(node, disk):
451 a8083063 Iustin Pop
  """Request shutdown of a given block device.
452 a8083063 Iustin Pop

453 a8083063 Iustin Pop
  This is a single-node call.
454 a8083063 Iustin Pop

455 a8083063 Iustin Pop
  """
456 319856a9 Michael Hanselmann
  c = Client("blockdev_shutdown", [disk.ToDict()])
457 a8083063 Iustin Pop
  c.connect(node)
458 a8083063 Iustin Pop
  c.run()
459 a8083063 Iustin Pop
  return c.getresult().get(node, False)
460 a8083063 Iustin Pop
461 a8083063 Iustin Pop
462 153d9724 Iustin Pop
def call_blockdev_addchildren(node, bdev, ndevs):
463 153d9724 Iustin Pop
  """Request adding a list of children to a (mirroring) device.
464 a8083063 Iustin Pop

465 a8083063 Iustin Pop
  This is a single-node call.
466 a8083063 Iustin Pop

467 a8083063 Iustin Pop
  """
468 153d9724 Iustin Pop
  params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
469 153d9724 Iustin Pop
  c = Client("blockdev_addchildren", params)
470 a8083063 Iustin Pop
  c.connect(node)
471 a8083063 Iustin Pop
  c.run()
472 a8083063 Iustin Pop
  return c.getresult().get(node, False)
473 a8083063 Iustin Pop
474 a8083063 Iustin Pop
475 153d9724 Iustin Pop
def call_blockdev_removechildren(node, bdev, ndevs):
476 153d9724 Iustin Pop
  """Request removing a list of children from a (mirroring) device.
477 a8083063 Iustin Pop

478 a8083063 Iustin Pop
  This is a single-node call.
479 a8083063 Iustin Pop

480 a8083063 Iustin Pop
  """
481 153d9724 Iustin Pop
  params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
482 153d9724 Iustin Pop
  c = Client("blockdev_removechildren", params)
483 a8083063 Iustin Pop
  c.connect(node)
484 a8083063 Iustin Pop
  c.run()
485 a8083063 Iustin Pop
  return c.getresult().get(node, False)
486 a8083063 Iustin Pop
487 a8083063 Iustin Pop
488 a8083063 Iustin Pop
def call_blockdev_getmirrorstatus(node, disks):
489 a8083063 Iustin Pop
  """Request status of a (mirroring) device.
490 a8083063 Iustin Pop

491 a8083063 Iustin Pop
  This is a single-node call.
492 a8083063 Iustin Pop

493 a8083063 Iustin Pop
  """
494 319856a9 Michael Hanselmann
  params = [dsk.ToDict() for dsk in disks]
495 a8083063 Iustin Pop
  c = Client("blockdev_getmirrorstatus", params)
496 a8083063 Iustin Pop
  c.connect(node)
497 a8083063 Iustin Pop
  c.run()
498 a8083063 Iustin Pop
  return c.getresult().get(node, False)
499 a8083063 Iustin Pop
500 a8083063 Iustin Pop
501 a8083063 Iustin Pop
def call_blockdev_find(node, disk):
502 a8083063 Iustin Pop
  """Request identification of a given block device.
503 a8083063 Iustin Pop

504 a8083063 Iustin Pop
  This is a single-node call.
505 a8083063 Iustin Pop

506 a8083063 Iustin Pop
  """
507 319856a9 Michael Hanselmann
  c = Client("blockdev_find", [disk.ToDict()])
508 a8083063 Iustin Pop
  c.connect(node)
509 a8083063 Iustin Pop
  c.run()
510 a8083063 Iustin Pop
  return c.getresult().get(node, False)
511 a8083063 Iustin Pop
512 a8083063 Iustin Pop
513 d61cbe76 Iustin Pop
def call_blockdev_close(node, disks):
514 d61cbe76 Iustin Pop
  """Closes the given block devices.
515 d61cbe76 Iustin Pop

516 d61cbe76 Iustin Pop
  This is a single-node call.
517 d61cbe76 Iustin Pop

518 d61cbe76 Iustin Pop
  """
519 d61cbe76 Iustin Pop
  params = [cf.ToDict() for cf in disks]
520 d61cbe76 Iustin Pop
  c = Client("blockdev_close", params)
521 d61cbe76 Iustin Pop
  c.connect(node)
522 d61cbe76 Iustin Pop
  c.run()
523 d61cbe76 Iustin Pop
  return c.getresult().get(node, False)
524 d61cbe76 Iustin Pop
525 d61cbe76 Iustin Pop
526 a8083063 Iustin Pop
def call_upload_file(node_list, file_name):
527 a8083063 Iustin Pop
  """Upload a file.
528 a8083063 Iustin Pop

529 a8083063 Iustin Pop
  The node will refuse the operation in case the file is not on the
530 a8083063 Iustin Pop
  approved file list.
531 a8083063 Iustin Pop

532 a8083063 Iustin Pop
  This is a multi-node call.
533 a8083063 Iustin Pop

534 a8083063 Iustin Pop
  """
535 a8083063 Iustin Pop
  fh = file(file_name)
536 a8083063 Iustin Pop
  try:
537 a8083063 Iustin Pop
    data = fh.read()
538 a8083063 Iustin Pop
  finally:
539 a8083063 Iustin Pop
    fh.close()
540 a8083063 Iustin Pop
  st = os.stat(file_name)
541 a8083063 Iustin Pop
  params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
542 a8083063 Iustin Pop
            st.st_atime, st.st_mtime]
543 a8083063 Iustin Pop
  c = Client("upload_file", params)
544 a8083063 Iustin Pop
  c.connect_list(node_list)
545 a8083063 Iustin Pop
  c.run()
546 a8083063 Iustin Pop
  return c.getresult()
547 a8083063 Iustin Pop
548 a8083063 Iustin Pop
549 a8083063 Iustin Pop
def call_os_diagnose(node_list):
550 a8083063 Iustin Pop
  """Request a diagnose of OS definitions.
551 a8083063 Iustin Pop

552 a8083063 Iustin Pop
  This is a multi-node call.
553 a8083063 Iustin Pop

554 a8083063 Iustin Pop
  """
555 a8083063 Iustin Pop
  c = Client("os_diagnose", [])
556 a8083063 Iustin Pop
  c.connect_list(node_list)
557 a8083063 Iustin Pop
  c.run()
558 a8083063 Iustin Pop
  result = c.getresult()
559 a8083063 Iustin Pop
  new_result = {}
560 a8083063 Iustin Pop
  for node_name in result:
561 a8083063 Iustin Pop
    if result[node_name]:
562 4e679f11 Guido Trotter
      nr = [objects.OS.FromDict(oss) for oss in result[node_name]]
563 4e679f11 Guido Trotter
    else:
564 4e679f11 Guido Trotter
      nr = []
565 a8083063 Iustin Pop
    new_result[node_name] = nr
566 a8083063 Iustin Pop
  return new_result
567 a8083063 Iustin Pop
568 a8083063 Iustin Pop
569 00fe9e38 Guido Trotter
def call_os_get(node, name):
570 a8083063 Iustin Pop
  """Returns an OS definition.
571 a8083063 Iustin Pop

572 00fe9e38 Guido Trotter
  This is a single-node call.
573 a8083063 Iustin Pop

574 a8083063 Iustin Pop
  """
575 a8083063 Iustin Pop
  c = Client("os_get", [name])
576 00fe9e38 Guido Trotter
  c.connect(node)
577 a8083063 Iustin Pop
  c.run()
578 00fe9e38 Guido Trotter
  result = c.getresult().get(node, False)
579 00fe9e38 Guido Trotter
  if isinstance(result, dict):
580 dfa96ded Guido Trotter
    return objects.OS.FromDict(result)
581 00fe9e38 Guido Trotter
  else:
582 dfa96ded Guido Trotter
    return result
583 a8083063 Iustin Pop
584 a8083063 Iustin Pop
585 a8083063 Iustin Pop
def call_hooks_runner(node_list, hpath, phase, env):
586 a8083063 Iustin Pop
  """Call the hooks runner.
587 a8083063 Iustin Pop

588 a8083063 Iustin Pop
  Args:
589 a8083063 Iustin Pop
    - op: the OpCode instance
590 a8083063 Iustin Pop
    - env: a dictionary with the environment
591 a8083063 Iustin Pop

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

594 a8083063 Iustin Pop
  """
595 a8083063 Iustin Pop
  params = [hpath, phase, env]
596 a8083063 Iustin Pop
  c = Client("hooks_runner", params)
597 a8083063 Iustin Pop
  c.connect_list(node_list)
598 a8083063 Iustin Pop
  c.run()
599 a8083063 Iustin Pop
  result = c.getresult()
600 a8083063 Iustin Pop
  return result
601 a8083063 Iustin Pop
602 a8083063 Iustin Pop
603 8d528b7c Iustin Pop
def call_iallocator_runner(node, name, idata):
604 8d528b7c Iustin Pop
  """Call an iallocator on a remote node
605 8d528b7c Iustin Pop

606 8d528b7c Iustin Pop
  Args:
607 8d528b7c Iustin Pop
    - name: the iallocator name
608 8d528b7c Iustin Pop
    - input: the json-encoded input string
609 8d528b7c Iustin Pop

610 8d528b7c Iustin Pop
  This is a single-node call.
611 8d528b7c Iustin Pop

612 8d528b7c Iustin Pop
  """
613 8d528b7c Iustin Pop
  params = [name, idata]
614 8d528b7c Iustin Pop
  c = Client("iallocator_runner", params)
615 8d528b7c Iustin Pop
  c.connect(node)
616 8d528b7c Iustin Pop
  c.run()
617 8d528b7c Iustin Pop
  result = c.getresult().get(node, False)
618 8d528b7c Iustin Pop
  return result
619 8d528b7c Iustin Pop
620 8d528b7c Iustin Pop
621 4c8ba8b3 Iustin Pop
def call_blockdev_grow(node, cf_bdev, amount):
622 4c8ba8b3 Iustin Pop
  """Request a snapshot of the given block device.
623 4c8ba8b3 Iustin Pop

624 4c8ba8b3 Iustin Pop
  This is a single-node call.
625 4c8ba8b3 Iustin Pop

626 4c8ba8b3 Iustin Pop
  """
627 4c8ba8b3 Iustin Pop
  c = Client("blockdev_grow", [cf_bdev.ToDict(), amount])
628 4c8ba8b3 Iustin Pop
  c.connect(node)
629 4c8ba8b3 Iustin Pop
  c.run()
630 4c8ba8b3 Iustin Pop
  return c.getresult().get(node, False)
631 4c8ba8b3 Iustin Pop
632 4c8ba8b3 Iustin Pop
633 a8083063 Iustin Pop
def call_blockdev_snapshot(node, cf_bdev):
634 a8083063 Iustin Pop
  """Request a snapshot of the given block device.
635 a8083063 Iustin Pop

636 a8083063 Iustin Pop
  This is a single-node call.
637 a8083063 Iustin Pop

638 a8083063 Iustin Pop
  """
639 319856a9 Michael Hanselmann
  c = Client("blockdev_snapshot", [cf_bdev.ToDict()])
640 a8083063 Iustin Pop
  c.connect(node)
641 a8083063 Iustin Pop
  c.run()
642 a8083063 Iustin Pop
  return c.getresult().get(node, False)
643 a8083063 Iustin Pop
644 a8083063 Iustin Pop
645 a8083063 Iustin Pop
def call_snapshot_export(node, snap_bdev, dest_node, instance):
646 a8083063 Iustin Pop
  """Request the export of a given snapshot.
647 a8083063 Iustin Pop

648 a8083063 Iustin Pop
  This is a single-node call.
649 a8083063 Iustin Pop

650 a8083063 Iustin Pop
  """
651 319856a9 Michael Hanselmann
  params = [snap_bdev.ToDict(), dest_node, instance.ToDict()]
652 a8083063 Iustin Pop
  c = Client("snapshot_export", params)
653 a8083063 Iustin Pop
  c.connect(node)
654 a8083063 Iustin Pop
  c.run()
655 a8083063 Iustin Pop
  return c.getresult().get(node, False)
656 a8083063 Iustin Pop
657 a8083063 Iustin Pop
658 a8083063 Iustin Pop
def call_finalize_export(node, instance, snap_disks):
659 a8083063 Iustin Pop
  """Request the completion of an export operation.
660 a8083063 Iustin Pop

661 a8083063 Iustin Pop
  This writes the export config file, etc.
662 a8083063 Iustin Pop

663 a8083063 Iustin Pop
  This is a single-node call.
664 a8083063 Iustin Pop

665 a8083063 Iustin Pop
  """
666 a8083063 Iustin Pop
  flat_disks = []
667 a8083063 Iustin Pop
  for disk in snap_disks:
668 319856a9 Michael Hanselmann
    flat_disks.append(disk.ToDict())
669 319856a9 Michael Hanselmann
  params = [instance.ToDict(), flat_disks]
670 a8083063 Iustin Pop
  c = Client("finalize_export", params)
671 a8083063 Iustin Pop
  c.connect(node)
672 a8083063 Iustin Pop
  c.run()
673 a8083063 Iustin Pop
  return c.getresult().get(node, False)
674 a8083063 Iustin Pop
675 a8083063 Iustin Pop
676 a8083063 Iustin Pop
def call_export_info(node, path):
677 a8083063 Iustin Pop
  """Queries the export information in a given path.
678 a8083063 Iustin Pop

679 a8083063 Iustin Pop
  This is a single-node call.
680 a8083063 Iustin Pop

681 a8083063 Iustin Pop
  """
682 a8083063 Iustin Pop
  c = Client("export_info", [path])
683 a8083063 Iustin Pop
  c.connect(node)
684 a8083063 Iustin Pop
  c.run()
685 a8083063 Iustin Pop
  result = c.getresult().get(node, False)
686 a8083063 Iustin Pop
  if not result:
687 a8083063 Iustin Pop
    return result
688 2d3e73c4 Michael Hanselmann
  return objects.SerializableConfigParser.Loads(str(result))
689 a8083063 Iustin Pop
690 a8083063 Iustin Pop
691 a8083063 Iustin Pop
def call_instance_os_import(node, inst, osdev, swapdev, src_node, src_image):
692 a8083063 Iustin Pop
  """Request the import of a backup into an instance.
693 a8083063 Iustin Pop

694 a8083063 Iustin Pop
  This is a single-node call.
695 a8083063 Iustin Pop

696 a8083063 Iustin Pop
  """
697 319856a9 Michael Hanselmann
  params = [inst.ToDict(), osdev, swapdev, src_node, src_image]
698 a8083063 Iustin Pop
  c = Client("instance_os_import", params)
699 a8083063 Iustin Pop
  c.connect(node)
700 a8083063 Iustin Pop
  c.run()
701 a8083063 Iustin Pop
  return c.getresult().get(node, False)
702 a8083063 Iustin Pop
703 a8083063 Iustin Pop
704 a8083063 Iustin Pop
def call_export_list(node_list):
705 a8083063 Iustin Pop
  """Gets the stored exports list.
706 a8083063 Iustin Pop

707 a8083063 Iustin Pop
  This is a multi-node call.
708 a8083063 Iustin Pop

709 a8083063 Iustin Pop
  """
710 a8083063 Iustin Pop
  c = Client("export_list", [])
711 a8083063 Iustin Pop
  c.connect_list(node_list)
712 a8083063 Iustin Pop
  c.run()
713 a8083063 Iustin Pop
  result = c.getresult()
714 a8083063 Iustin Pop
  return result
715 a8083063 Iustin Pop
716 a8083063 Iustin Pop
717 a8083063 Iustin Pop
def call_export_remove(node, export):
718 a8083063 Iustin Pop
  """Requests removal of a given export.
719 a8083063 Iustin Pop

720 a8083063 Iustin Pop
  This is a single-node call.
721 a8083063 Iustin Pop

722 a8083063 Iustin Pop
  """
723 a8083063 Iustin Pop
  c = Client("export_remove", [export])
724 a8083063 Iustin Pop
  c.connect(node)
725 a8083063 Iustin Pop
  c.run()
726 a8083063 Iustin Pop
  return c.getresult().get(node, False)
727 a8083063 Iustin Pop
728 a8083063 Iustin Pop
729 a8083063 Iustin Pop
def call_node_leave_cluster(node):
730 a8083063 Iustin Pop
  """Requests a node to clean the cluster information it has.
731 a8083063 Iustin Pop

732 a8083063 Iustin Pop
  This will remove the configuration information from the ganeti data
733 a8083063 Iustin Pop
  dir.
734 a8083063 Iustin Pop

735 a8083063 Iustin Pop
  This is a single-node call.
736 a8083063 Iustin Pop

737 a8083063 Iustin Pop
  """
738 a8083063 Iustin Pop
  c = Client("node_leave_cluster", [])
739 a8083063 Iustin Pop
  c.connect(node)
740 a8083063 Iustin Pop
  c.run()
741 a8083063 Iustin Pop
  return c.getresult().get(node, False)
742 dcb93971 Michael Hanselmann
743 dcb93971 Michael Hanselmann
744 dcb93971 Michael Hanselmann
def call_node_volumes(node_list):
745 dcb93971 Michael Hanselmann
  """Gets all volumes on node(s).
746 dcb93971 Michael Hanselmann

747 dcb93971 Michael Hanselmann
  This is a multi-node call.
748 dcb93971 Michael Hanselmann

749 dcb93971 Michael Hanselmann
  """
750 dcb93971 Michael Hanselmann
  c = Client("node_volumes", [])
751 dcb93971 Michael Hanselmann
  c.connect_list(node_list)
752 dcb93971 Michael Hanselmann
  c.run()
753 dcb93971 Michael Hanselmann
  return c.getresult()
754 06009e27 Iustin Pop
755 06009e27 Iustin Pop
756 06009e27 Iustin Pop
def call_test_delay(node_list, duration):
757 06009e27 Iustin Pop
  """Sleep for a fixed time on given node(s).
758 06009e27 Iustin Pop

759 06009e27 Iustin Pop
  This is a multi-node call.
760 06009e27 Iustin Pop

761 06009e27 Iustin Pop
  """
762 06009e27 Iustin Pop
  c = Client("test_delay", [duration])
763 06009e27 Iustin Pop
  c.connect_list(node_list)
764 06009e27 Iustin Pop
  c.run()
765 06009e27 Iustin Pop
  return c.getresult()
766 5e04ed8b Manuel Franceschini
767 5e04ed8b Manuel Franceschini
768 5e04ed8b Manuel Franceschini
def call_file_storage_dir_create(node, file_storage_dir):
769 5e04ed8b Manuel Franceschini
  """Create the given file storage directory.
770 5e04ed8b Manuel Franceschini

771 5e04ed8b Manuel Franceschini
  This is a single-node call.
772 5e04ed8b Manuel Franceschini

773 5e04ed8b Manuel Franceschini
  """
774 5e04ed8b Manuel Franceschini
  c = Client("file_storage_dir_create", [file_storage_dir])
775 5e04ed8b Manuel Franceschini
  c.connect(node)
776 5e04ed8b Manuel Franceschini
  c.run()
777 5e04ed8b Manuel Franceschini
  return c.getresult().get(node, False)
778 5e04ed8b Manuel Franceschini
779 5e04ed8b Manuel Franceschini
780 5e04ed8b Manuel Franceschini
def call_file_storage_dir_remove(node, file_storage_dir):
781 5e04ed8b Manuel Franceschini
  """Remove the given file storage directory.
782 5e04ed8b Manuel Franceschini

783 5e04ed8b Manuel Franceschini
  This is a single-node call.
784 5e04ed8b Manuel Franceschini

785 5e04ed8b Manuel Franceschini
  """
786 5e04ed8b Manuel Franceschini
  c = Client("file_storage_dir_remove", [file_storage_dir])
787 5e04ed8b Manuel Franceschini
  c.connect(node)
788 5e04ed8b Manuel Franceschini
  c.run()
789 5e04ed8b Manuel Franceschini
  return c.getresult().get(node, False)
790 5e04ed8b Manuel Franceschini
791 5e04ed8b Manuel Franceschini
792 5e04ed8b Manuel Franceschini
def call_file_storage_dir_rename(node, old_file_storage_dir,
793 5e04ed8b Manuel Franceschini
                                 new_file_storage_dir):
794 5e04ed8b Manuel Franceschini
  """Rename file storage directory.
795 5e04ed8b Manuel Franceschini

796 5e04ed8b Manuel Franceschini
  This is a single-node call.
797 5e04ed8b Manuel Franceschini

798 5e04ed8b Manuel Franceschini
  """
799 5e04ed8b Manuel Franceschini
  c = Client("file_storage_dir_rename",
800 5e04ed8b Manuel Franceschini
             [old_file_storage_dir, new_file_storage_dir])
801 5e04ed8b Manuel Franceschini
  c.connect(node)
802 5e04ed8b Manuel Franceschini
  c.run()
803 5e04ed8b Manuel Franceschini
  return c.getresult().get(node, False)
804 ca52cdeb Michael Hanselmann
805 ca52cdeb Michael Hanselmann
806 ca52cdeb Michael Hanselmann
def call_jobqueue_update(node_list, file_name, content):
807 ca52cdeb Michael Hanselmann
  """Update job queue.
808 ca52cdeb Michael Hanselmann

809 ca52cdeb Michael Hanselmann
  This is a multi-node call.
810 ca52cdeb Michael Hanselmann

811 ca52cdeb Michael Hanselmann
  """
812 ca52cdeb Michael Hanselmann
  c = Client("jobqueue_update", [file_name, content])
813 ca52cdeb Michael Hanselmann
  c.connect_list(node_list)
814 ca52cdeb Michael Hanselmann
  c.run()
815 ca52cdeb Michael Hanselmann
  result = c.getresult()
816 ca52cdeb Michael Hanselmann
  return result
817 ca52cdeb Michael Hanselmann
818 ca52cdeb Michael Hanselmann
819 ca52cdeb Michael Hanselmann
def call_jobqueue_purge(node):
820 ca52cdeb Michael Hanselmann
  """Purge job queue.
821 ca52cdeb Michael Hanselmann

822 ca52cdeb Michael Hanselmann
  This is a single-node call.
823 ca52cdeb Michael Hanselmann

824 ca52cdeb Michael Hanselmann
  """
825 ca52cdeb Michael Hanselmann
  c = Client("jobqueue_purge", [])
826 ca52cdeb Michael Hanselmann
  c.connect(node)
827 ca52cdeb Michael Hanselmann
  c.run()
828 ca52cdeb Michael Hanselmann
  return c.getresult().get(node, False)
829 af5ebcb1 Michael Hanselmann
830 af5ebcb1 Michael Hanselmann
831 af5ebcb1 Michael Hanselmann
def call_jobqueue_rename(node_list, old, new):
832 af5ebcb1 Michael Hanselmann
  """Rename a job queue file.
833 af5ebcb1 Michael Hanselmann

834 af5ebcb1 Michael Hanselmann
  This is a multi-node call.
835 af5ebcb1 Michael Hanselmann

836 af5ebcb1 Michael Hanselmann
  """
837 af5ebcb1 Michael Hanselmann
  c = Client("jobqueue_rename", [old, new])
838 af5ebcb1 Michael Hanselmann
  c.connect_list(node_list)
839 af5ebcb1 Michael Hanselmann
  c.run()
840 af5ebcb1 Michael Hanselmann
  result = c.getresult()
841 af5ebcb1 Michael Hanselmann
  return result