Revision 72737a7f lib/rpc.py

b/lib/rpc.py
23 23

  
24 24
"""
25 25

  
26
# pylint: disable-msg=C0103
26
# pylint: disable-msg=C0103,R0201,R0904
27
# C0103: Invalid name, since call_ are not valid
28
# R0201: Method could be a function, we keep all rpcs instance methods
29
# as not to change them back and forth between static/instance methods
30
# if they need to start using instance attributes
31
# R0904: Too many public methods
27 32

  
28 33
import os
29 34
import socket
......
140 145
      self.results[node] = nc.get_response()
141 146

  
142 147

  
143
def call_volume_list(node_list, vg_name):
144
  """Gets the logical volumes present in a given volume group.
148
class RpcRunner(object):
149
  """RPC runner class"""
145 150

  
146
  This is a multi-node call.
151
  def __init__(self, cfg):
152
    """Initialized the rpc runner.
147 153

  
148
  """
149
  c = Client("volume_list", [vg_name])
150
  c.connect_list(node_list)
151
  c.run()
152
  return c.getresult()
154
    @type cfg:  C{config.ConfigWriter}
155
    @param cfg: the configuration object that will be used to get data
156
                about the cluster
153 157

  
158
    """
159
    self._cfg = cfg
154 160

  
155
def call_vg_list(node_list):
156
  """Gets the volume group list.
161
  def call_volume_list(self, node_list, vg_name):
162
    """Gets the logical volumes present in a given volume group.
157 163

  
158
  This is a multi-node call.
164
    This is a multi-node call.
159 165

  
160
  """
161
  c = Client("vg_list", [])
162
  c.connect_list(node_list)
163
  c.run()
164
  return c.getresult()
166
    """
167
    c = Client("volume_list", [vg_name])
168
    c.connect_list(node_list)
169
    c.run()
170
    return c.getresult()
165 171

  
172
  def call_vg_list(self, node_list):
173
    """Gets the volume group list.
166 174

  
167
def call_bridges_exist(node, bridges_list):
168
  """Checks if a node has all the bridges given.
175
    This is a multi-node call.
169 176

  
170
  This method checks if all bridges given in the bridges_list are
171
  present on the remote node, so that an instance that uses interfaces
172
  on those bridges can be started.
177
    """
178
    c = Client("vg_list", [])
179
    c.connect_list(node_list)
180
    c.run()
181
    return c.getresult()
173 182

  
174
  This is a single-node call.
175 183

  
176
  """
177
  c = Client("bridges_exist", [bridges_list])
178
  c.connect(node)
179
  c.run()
180
  return c.getresult().get(node, False)
184
  def call_bridges_exist(self, node, bridges_list):
185
    """Checks if a node has all the bridges given.
181 186

  
187
    This method checks if all bridges given in the bridges_list are
188
    present on the remote node, so that an instance that uses interfaces
189
    on those bridges can be started.
182 190

  
183
def call_instance_start(node, instance, extra_args):
184
  """Starts an instance.
191
    This is a single-node call.
185 192

  
186
  This is a single-node call.
193
    """
194
    c = Client("bridges_exist", [bridges_list])
195
    c.connect(node)
196
    c.run()
197
    return c.getresult().get(node, False)
187 198

  
188
  """
189
  c = Client("instance_start", [instance.ToDict(), extra_args])
190
  c.connect(node)
191
  c.run()
192
  return c.getresult().get(node, False)
193 199

  
200
  def call_instance_start(self, node, instance, extra_args):
201
    """Starts an instance.
194 202

  
195
def call_instance_shutdown(node, instance):
196
  """Stops an instance.
203
    This is a single-node call.
197 204

  
198
  This is a single-node call.
205
    """
206
    c = Client("instance_start", [instance.ToDict(), extra_args])
207
    c.connect(node)
208
    c.run()
209
    return c.getresult().get(node, False)
199 210

  
200
  """
201
  c = Client("instance_shutdown", [instance.ToDict()])
202
  c.connect(node)
203
  c.run()
204
  return c.getresult().get(node, False)
205 211

  
212
  def call_instance_shutdown(self, node, instance):
213
    """Stops an instance.
206 214

  
207
def call_instance_migrate(node, instance, target, live):
208
  """Migrate an instance.
215
    This is a single-node call.
209 216

  
210
  This is a single-node call.
217
    """
218
    c = Client("instance_shutdown", [instance.ToDict()])
219
    c.connect(node)
220
    c.run()
221
    return c.getresult().get(node, False)
211 222

  
212
  @type node: string
213
  @param node: the node on which the instance is currently running
214
  @type instance: C{objects.Instance}
215
  @param instance: the instance definition
216
  @type target: string
217
  @param target: the target node name
218
  @type live: boolean
219
  @param live: whether the migration should be done live or not (the
220
      interpretation of this parameter is left to the hypervisor)
221 223

  
222
  """
223
  c = Client("instance_migrate", [instance.ToDict(), target, live])
224
  c.connect(node)
225
  c.run()
226
  return c.getresult().get(node, False)
224
  def call_instance_migrate(self, node, instance, target, live):
225
    """Migrate an instance.
227 226

  
227
    This is a single-node call.
228 228

  
229
def call_instance_reboot(node, instance, reboot_type, extra_args):
230
  """Reboots an instance.
229
    @type node: string
230
    @param node: the node on which the instance is currently running
231
    @type instance: C{objects.Instance}
232
    @param instance: the instance definition
233
    @type target: string
234
    @param target: the target node name
235
    @type live: boolean
236
    @param live: whether the migration should be done live or not (the
237
        interpretation of this parameter is left to the hypervisor)
231 238

  
232
  This is a single-node call.
239
    """
240
    c = Client("instance_migrate", [instance.ToDict(), target, live])
241
    c.connect(node)
242
    c.run()
243
    return c.getresult().get(node, False)
233 244

  
234
  """
235
  c = Client("instance_reboot", [instance.ToDict(), reboot_type, extra_args])
236
  c.connect(node)
237
  c.run()
238
  return c.getresult().get(node, False)
239 245

  
246
  def call_instance_reboot(self, node, instance, reboot_type, extra_args):
247
    """Reboots an instance.
240 248

  
241
def call_instance_os_add(node, inst, osdev, swapdev):
242
  """Installs an OS on the given instance.
249
    This is a single-node call.
243 250

  
244
  This is a single-node call.
251
    """
252
    c = Client("instance_reboot", [instance.ToDict(), reboot_type, extra_args])
253
    c.connect(node)
254
    c.run()
255
    return c.getresult().get(node, False)
245 256

  
246
  """
247
  params = [inst.ToDict(), osdev, swapdev]
248
  c = Client("instance_os_add", params)
249
  c.connect(node)
250
  c.run()
251
  return c.getresult().get(node, False)
252 257

  
258
  def call_instance_os_add(self, node, inst, osdev, swapdev):
259
    """Installs an OS on the given instance.
253 260

  
254
def call_instance_run_rename(node, inst, old_name, osdev, swapdev):
255
  """Run the OS rename script for an instance.
261
    This is a single-node call.
256 262

  
257
  This is a single-node call.
263
    """
264
    params = [inst.ToDict(), osdev, swapdev]
265
    c = Client("instance_os_add", params)
266
    c.connect(node)
267
    c.run()
268
    return c.getresult().get(node, False)
258 269

  
259
  """
260
  params = [inst.ToDict(), old_name, osdev, swapdev]
261
  c = Client("instance_run_rename", params)
262
  c.connect(node)
263
  c.run()
264
  return c.getresult().get(node, False)
265 270

  
271
  def call_instance_run_rename(self, node, inst, old_name, osdev, swapdev):
272
    """Run the OS rename script for an instance.
266 273

  
267
def call_instance_info(node, instance, hname):
268
  """Returns information about a single instance.
274
    This is a single-node call.
269 275

  
270
  This is a single-node call.
276
    """
277
    params = [inst.ToDict(), old_name, osdev, swapdev]
278
    c = Client("instance_run_rename", params)
279
    c.connect(node)
280
    c.run()
281
    return c.getresult().get(node, False)
271 282

  
272
  @type node_list: list
273
  @param node_list: the list of nodes to query
274
  @type instance: string
275
  @param instance: the instance name
276
  @type hname: string
277
  @param hname: the hypervisor type of the instance
278 283

  
279
  """
280
  c = Client("instance_info", [instance])
281
  c.connect(node)
282
  c.run()
283
  return c.getresult().get(node, False)
284
  def call_instance_info(self, node, instance, hname):
285
    """Returns information about a single instance.
284 286

  
287
    This is a single-node call.
285 288

  
286
def call_all_instances_info(node_list, hypervisor_list):
287
  """Returns information about all instances on the given nodes.
289
    @type node_list: list
290
    @param node_list: the list of nodes to query
291
    @type instance: string
292
    @param instance: the instance name
293
    @type hname: string
294
    @param hname: the hypervisor type of the instance
288 295

  
289
  This is a multi-node call.
296
    """
297
    c = Client("instance_info", [instance])
298
    c.connect(node)
299
    c.run()
300
    return c.getresult().get(node, False)
290 301

  
291
  @type node_list: list
292
  @param node_list: the list of nodes to query
293
  @type hypervisor_list: list
294
  @param hypervisor_list: the hypervisors to query for instances
295 302

  
296
  """
297
  c = Client("all_instances_info", [hypervisor_list])
298
  c.connect_list(node_list)
299
  c.run()
300
  return c.getresult()
303
  def call_all_instances_info(self, node_list, hypervisor_list):
304
    """Returns information about all instances on the given nodes.
301 305

  
306
    This is a multi-node call.
302 307

  
303
def call_instance_list(node_list, hypervisor_list):
304
  """Returns the list of running instances on a given node.
308
    @type node_list: list
309
    @param node_list: the list of nodes to query
310
    @type hypervisor_list: list
311
    @param hypervisor_list: the hypervisors to query for instances
305 312

  
306
  This is a multi-node call.
313
    """
314
    c = Client("all_instances_info", [hypervisor_list])
315
    c.connect_list(node_list)
316
    c.run()
317
    return c.getresult()
307 318

  
308
  @type node_list: list
309
  @param node_list: the list of nodes to query
310
  @type hypervisor_list: list
311
  @param hypervisor_list: the hypervisors to query for instances
312 319

  
313
  """
314
  c = Client("instance_list", [hypervisor_list])
315
  c.connect_list(node_list)
316
  c.run()
317
  return c.getresult()
320
  def call_instance_list(self, node_list, hypervisor_list):
321
    """Returns the list of running instances on a given node.
318 322

  
323
    This is a multi-node call.
319 324

  
320
def call_node_tcp_ping(node, source, target, port, timeout, live_port_needed):
321
  """Do a TcpPing on the remote node
325
    @type node_list: list
326
    @param node_list: the list of nodes to query
327
    @type hypervisor_list: list
328
    @param hypervisor_list: the hypervisors to query for instances
322 329

  
323
  This is a single-node call.
324
  """
325
  c = Client("node_tcp_ping", [source, target, port, timeout,
326
                               live_port_needed])
327
  c.connect(node)
328
  c.run()
329
  return c.getresult().get(node, False)
330
    """
331
    c = Client("instance_list", [hypervisor_list])
332
    c.connect_list(node_list)
333
    c.run()
334
    return c.getresult()
330 335

  
331 336

  
332
def call_node_info(node_list, vg_name, hypervisor_type):
333
  """Return node information.
337
  def call_node_tcp_ping(self, node, source, target, port, timeout,
338
                         live_port_needed):
339
    """Do a TcpPing on the remote node
334 340

  
335
  This will return memory information and volume group size and free
336
  space.
341
    This is a single-node call.
342
    """
343
    c = Client("node_tcp_ping", [source, target, port, timeout,
344
                                 live_port_needed])
345
    c.connect(node)
346
    c.run()
347
    return c.getresult().get(node, False)
337 348

  
338
  This is a multi-node call.
339 349

  
340
  @type node_list: list
341
  @param node_list: the list of nodes to query
342
  @type vgname: C{string}
343
  @param vgname: the name of the volume group to ask for disk space information
344
  @type hypervisor_type: C{str}
345
  @param hypervisor_type: the name of the hypervisor to ask for
346
      memory information
350
  def call_node_info(self, node_list, vg_name, hypervisor_type):
351
    """Return node information.
347 352

  
348
  """
349
  c = Client("node_info", [vg_name, hypervisor_type])
350
  c.connect_list(node_list)
351
  c.run()
352
  retux = c.getresult()
353
    This will return memory information and volume group size and free
354
    space.
353 355

  
354
  for node_name in retux:
355
    ret = retux.get(node_name, False)
356
    if type(ret) != dict:
357
      logger.Error("could not connect to node %s" % (node_name))
358
      ret = {}
356
    This is a multi-node call.
359 357

  
360
    utils.CheckDict(ret,
361
                    { 'memory_total' : '-',
362
                      'memory_dom0' : '-',
363
                      'memory_free' : '-',
364
                      'vg_size' : 'node_unreachable',
365
                      'vg_free' : '-' },
366
                    "call_node_info",
367
                    )
368
  return retux
358
    @type node_list: list
359
    @param node_list: the list of nodes to query
360
    @type vgname: C{string}
361
    @param vgname: the name of the volume group to ask for disk space
362
        information
363
    @type hypervisor_type: C{str}
364
    @param hypervisor_type: the name of the hypervisor to ask for
365
        memory information
369 366

  
367
    """
368
    c = Client("node_info", [vg_name, hypervisor_type])
369
    c.connect_list(node_list)
370
    c.run()
371
    retux = c.getresult()
370 372

  
371
def call_node_add(node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
372
  """Add a node to the cluster.
373
    for node_name in retux:
374
      ret = retux.get(node_name, False)
375
      if type(ret) != dict:
376
        logger.Error("could not connect to node %s" % (node_name))
377
        ret = {}
373 378

  
374
  This is a single-node call.
379
      utils.CheckDict(ret,
380
                      { 'memory_total' : '-',
381
                        'memory_dom0' : '-',
382
                        'memory_free' : '-',
383
                        'vg_size' : 'node_unreachable',
384
                        'vg_free' : '-' },
385
                      "call_node_info",
386
                      )
387
    return retux
375 388

  
376
  """
377
  params = [dsa, dsapub, rsa, rsapub, ssh, sshpub]
378
  c = Client("node_add", params)
379
  c.connect(node)
380
  c.run()
381
  return c.getresult().get(node, False)
382 389

  
390
  def call_node_add(self, node, dsa, dsapub, rsa, rsapub, ssh, sshpub):
391
    """Add a node to the cluster.
383 392

  
384
def call_node_verify(node_list, checkdict, cluster_name):
385
  """Request verification of given parameters.
393
    This is a single-node call.
386 394

  
387
  This is a multi-node call.
395
    """
396
    params = [dsa, dsapub, rsa, rsapub, ssh, sshpub]
397
    c = Client("node_add", params)
398
    c.connect(node)
399
    c.run()
400
    return c.getresult().get(node, False)
388 401

  
389
  """
390
  c = Client("node_verify", [checkdict, cluster_name])
391
  c.connect_list(node_list)
392
  c.run()
393
  return c.getresult()
394 402

  
403
  def call_node_verify(self, node_list, checkdict, cluster_name):
404
    """Request verification of given parameters.
395 405

  
396
def call_node_start_master(node, start_daemons):
397
  """Tells a node to activate itself as a master.
406
    This is a multi-node call.
398 407

  
399
  This is a single-node call.
408
    """
409
    c = Client("node_verify", [checkdict, cluster_name])
410
    c.connect_list(node_list)
411
    c.run()
412
    return c.getresult()
400 413

  
401
  """
402
  c = Client("node_start_master", [start_daemons])
403
  c.connect(node)
404
  c.run()
405
  return c.getresult().get(node, False)
406 414

  
415
  @staticmethod
416
  def call_node_start_master(node, start_daemons):
417
    """Tells a node to activate itself as a master.
407 418

  
408
def call_node_stop_master(node, stop_daemons):
409
  """Tells a node to demote itself from master status.
419
    This is a single-node call.
410 420

  
411
  This is a single-node call.
421
    """
422
    c = Client("node_start_master", [start_daemons])
423
    c.connect(node)
424
    c.run()
425
    return c.getresult().get(node, False)
412 426

  
413
  """
414
  c = Client("node_stop_master", [stop_daemons])
415
  c.connect(node)
416
  c.run()
417
  return c.getresult().get(node, False)
418 427

  
428
  @staticmethod
429
  def call_node_stop_master(node, stop_daemons):
430
    """Tells a node to demote itself from master status.
419 431

  
420
def call_master_info(node_list):
421
  """Query master info.
432
    This is a single-node call.
422 433

  
423
  This is a multi-node call.
434
    """
435
    c = Client("node_stop_master", [stop_daemons])
436
    c.connect(node)
437
    c.run()
438
    return c.getresult().get(node, False)
424 439

  
425
  """
426
  c = Client("master_info", [])
427
  c.connect_list(node_list)
428
  c.run()
429
  return c.getresult()
430 440

  
441
  @staticmethod
442
  def call_master_info(node_list):
443
    """Query master info.
431 444

  
432
def call_version(node_list):
433
  """Query node version.
445
    This is a multi-node call.
434 446

  
435
  This is a multi-node call.
447
    """
448
    # TODO: should this method query down nodes?
449
    c = Client("master_info", [])
450
    c.connect_list(node_list)
451
    c.run()
452
    return c.getresult()
436 453

  
437
  """
438
  c = Client("version", [])
439
  c.connect_list(node_list)
440
  c.run()
441
  return c.getresult()
442 454

  
455
  def call_version(self, node_list):
456
    """Query node version.
443 457

  
444
def call_blockdev_create(node, bdev, size, owner, on_primary, info):
445
  """Request creation of a given block device.
458
    This is a multi-node call.
446 459

  
447
  This is a single-node call.
460
    """
461
    c = Client("version", [])
462
    c.connect_list(node_list)
463
    c.run()
464
    return c.getresult()
448 465

  
449
  """
450
  params = [bdev.ToDict(), size, owner, on_primary, info]
451
  c = Client("blockdev_create", params)
452
  c.connect(node)
453
  c.run()
454
  return c.getresult().get(node, False)
455 466

  
467
  def call_blockdev_create(self, node, bdev, size, owner, on_primary, info):
468
    """Request creation of a given block device.
456 469

  
457
def call_blockdev_remove(node, bdev):
458
  """Request removal of a given block device.
470
    This is a single-node call.
459 471

  
460
  This is a single-node call.
472
    """
473
    params = [bdev.ToDict(), size, owner, on_primary, info]
474
    c = Client("blockdev_create", params)
475
    c.connect(node)
476
    c.run()
477
    return c.getresult().get(node, False)
461 478

  
462
  """
463
  c = Client("blockdev_remove", [bdev.ToDict()])
464
  c.connect(node)
465
  c.run()
466
  return c.getresult().get(node, False)
467 479

  
480
  def call_blockdev_remove(self, node, bdev):
481
    """Request removal of a given block device.
468 482

  
469
def call_blockdev_rename(node, devlist):
470
  """Request rename of the given block devices.
483
    This is a single-node call.
471 484

  
472
  This is a single-node call.
485
    """
486
    c = Client("blockdev_remove", [bdev.ToDict()])
487
    c.connect(node)
488
    c.run()
489
    return c.getresult().get(node, False)
473 490

  
474
  """
475
  params = [(d.ToDict(), uid) for d, uid in devlist]
476
  c = Client("blockdev_rename", params)
477
  c.connect(node)
478
  c.run()
479
  return c.getresult().get(node, False)
480 491

  
492
  def call_blockdev_rename(self, node, devlist):
493
    """Request rename of the given block devices.
481 494

  
482
def call_blockdev_assemble(node, disk, owner, on_primary):
483
  """Request assembling of a given block device.
495
    This is a single-node call.
484 496

  
485
  This is a single-node call.
497
    """
498
    params = [(d.ToDict(), uid) for d, uid in devlist]
499
    c = Client("blockdev_rename", params)
500
    c.connect(node)
501
    c.run()
502
    return c.getresult().get(node, False)
486 503

  
487
  """
488
  params = [disk.ToDict(), owner, on_primary]
489
  c = Client("blockdev_assemble", params)
490
  c.connect(node)
491
  c.run()
492
  return c.getresult().get(node, False)
493 504

  
505
  def call_blockdev_assemble(self, node, disk, owner, on_primary):
506
    """Request assembling of a given block device.
494 507

  
495
def call_blockdev_shutdown(node, disk):
496
  """Request shutdown of a given block device.
508
    This is a single-node call.
497 509

  
498
  This is a single-node call.
510
    """
511
    params = [disk.ToDict(), owner, on_primary]
512
    c = Client("blockdev_assemble", params)
513
    c.connect(node)
514
    c.run()
515
    return c.getresult().get(node, False)
499 516

  
500
  """
501
  c = Client("blockdev_shutdown", [disk.ToDict()])
502
  c.connect(node)
503
  c.run()
504
  return c.getresult().get(node, False)
505 517

  
518
  def call_blockdev_shutdown(self, node, disk):
519
    """Request shutdown of a given block device.
506 520

  
507
def call_blockdev_addchildren(node, bdev, ndevs):
508
  """Request adding a list of children to a (mirroring) device.
521
    This is a single-node call.
509 522

  
510
  This is a single-node call.
523
    """
524
    c = Client("blockdev_shutdown", [disk.ToDict()])
525
    c.connect(node)
526
    c.run()
527
    return c.getresult().get(node, False)
511 528

  
512
  """
513
  params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
514
  c = Client("blockdev_addchildren", params)
515
  c.connect(node)
516
  c.run()
517
  return c.getresult().get(node, False)
518 529

  
530
  def call_blockdev_addchildren(self, node, bdev, ndevs):
531
    """Request adding a list of children to a (mirroring) device.
519 532

  
520
def call_blockdev_removechildren(node, bdev, ndevs):
521
  """Request removing a list of children from a (mirroring) device.
533
    This is a single-node call.
522 534

  
523
  This is a single-node call.
535
    """
536
    params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
537
    c = Client("blockdev_addchildren", params)
538
    c.connect(node)
539
    c.run()
540
    return c.getresult().get(node, False)
524 541

  
525
  """
526
  params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
527
  c = Client("blockdev_removechildren", params)
528
  c.connect(node)
529
  c.run()
530
  return c.getresult().get(node, False)
531 542

  
543
  def call_blockdev_removechildren(self, node, bdev, ndevs):
544
    """Request removing a list of children from a (mirroring) device.
532 545

  
533
def call_blockdev_getmirrorstatus(node, disks):
534
  """Request status of a (mirroring) device.
546
    This is a single-node call.
535 547

  
536
  This is a single-node call.
548
    """
549
    params = [bdev.ToDict(), [disk.ToDict() for disk in ndevs]]
550
    c = Client("blockdev_removechildren", params)
551
    c.connect(node)
552
    c.run()
553
    return c.getresult().get(node, False)
537 554

  
538
  """
539
  params = [dsk.ToDict() for dsk in disks]
540
  c = Client("blockdev_getmirrorstatus", params)
541
  c.connect(node)
542
  c.run()
543
  return c.getresult().get(node, False)
544 555

  
556
  def call_blockdev_getmirrorstatus(self, node, disks):
557
    """Request status of a (mirroring) device.
545 558

  
546
def call_blockdev_find(node, disk):
547
  """Request identification of a given block device.
559
    This is a single-node call.
548 560

  
549
  This is a single-node call.
561
    """
562
    params = [dsk.ToDict() for dsk in disks]
563
    c = Client("blockdev_getmirrorstatus", params)
564
    c.connect(node)
565
    c.run()
566
    return c.getresult().get(node, False)
550 567

  
551
  """
552
  c = Client("blockdev_find", [disk.ToDict()])
553
  c.connect(node)
554
  c.run()
555
  return c.getresult().get(node, False)
556 568

  
569
  def call_blockdev_find(self, node, disk):
570
    """Request identification of a given block device.
571

  
572
    This is a single-node call.
557 573

  
558
def call_blockdev_close(node, disks):
559
  """Closes the given block devices.
574
    """
575
    c = Client("blockdev_find", [disk.ToDict()])
576
    c.connect(node)
577
    c.run()
578
    return c.getresult().get(node, False)
560 579

  
561
  This is a single-node call.
562 580

  
563
  """
564
  params = [cf.ToDict() for cf in disks]
565
  c = Client("blockdev_close", params)
566
  c.connect(node)
567
  c.run()
568
  return c.getresult().get(node, False)
581
  def call_blockdev_close(self, node, disks):
582
    """Closes the given block devices.
569 583

  
584
    This is a single-node call.
570 585

  
571
def call_upload_file(node_list, file_name):
572
  """Upload a file.
586
    """
587
    params = [cf.ToDict() for cf in disks]
588
    c = Client("blockdev_close", params)
589
    c.connect(node)
590
    c.run()
591
    return c.getresult().get(node, False)
573 592

  
574
  The node will refuse the operation in case the file is not on the
575
  approved file list.
576 593

  
577
  This is a multi-node call.
594
  @staticmethod
595
  def call_upload_file(node_list, file_name):
596
    """Upload a file.
578 597

  
579
  """
580
  fh = file(file_name)
581
  try:
582
    data = fh.read()
583
  finally:
584
    fh.close()
585
  st = os.stat(file_name)
586
  params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
587
            st.st_atime, st.st_mtime]
588
  c = Client("upload_file", params)
589
  c.connect_list(node_list)
590
  c.run()
591
  return c.getresult()
598
    The node will refuse the operation in case the file is not on the
599
    approved file list.
592 600

  
601
    This is a multi-node call.
593 602

  
594
def call_os_diagnose(node_list):
595
  """Request a diagnose of OS definitions.
603
    """
604
    fh = file(file_name)
605
    try:
606
      data = fh.read()
607
    finally:
608
      fh.close()
609
    st = os.stat(file_name)
610
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
611
              st.st_atime, st.st_mtime]
612
    c = Client("upload_file", params)
613
    c.connect_list(node_list)
614
    c.run()
615
    return c.getresult()
616

  
617
  @staticmethod
618
  def call_upload_file(node_list, file_name):
619
    """Upload a file.
620

  
621
    The node will refuse the operation in case the file is not on the
622
    approved file list.
623

  
624
    This is a multi-node call.
596 625

  
597
  This is a multi-node call.
626
    """
627
    fh = file(file_name)
628
    try:
629
      data = fh.read()
630
    finally:
631
      fh.close()
632
    st = os.stat(file_name)
633
    params = [file_name, data, st.st_mode, st.st_uid, st.st_gid,
634
              st.st_atime, st.st_mtime]
635
    c = Client("upload_file", params)
636
    c.connect_list(node_list)
637
    c.run()
638
    return c.getresult()
639

  
640
  def call_os_diagnose(self, node_list):
641
    """Request a diagnose of OS definitions.
642

  
643
    This is a multi-node call.
598 644

  
599
  """
600
  c = Client("os_diagnose", [])
601
  c.connect_list(node_list)
602
  c.run()
603
  result = c.getresult()
604
  new_result = {}
605
  for node_name in result:
606
    if result[node_name]:
607
      nr = [objects.OS.FromDict(oss) for oss in result[node_name]]
608
    else:
609
      nr = []
610
    new_result[node_name] = nr
611
  return new_result
645
    """
646
    c = Client("os_diagnose", [])
647
    c.connect_list(node_list)
648
    c.run()
649
    result = c.getresult()
650
    new_result = {}
651
    for node_name in result:
652
      if result[node_name]:
653
        nr = [objects.OS.FromDict(oss) for oss in result[node_name]]
654
      else:
655
        nr = []
656
      new_result[node_name] = nr
657
    return new_result
612 658

  
613 659

  
614
def call_os_get(node, name):
615
  """Returns an OS definition.
660
  def call_os_get(self, node, name):
661
    """Returns an OS definition.
616 662

  
617
  This is a single-node call.
663
    This is a single-node call.
618 664

  
619
  """
620
  c = Client("os_get", [name])
621
  c.connect(node)
622
  c.run()
623
  result = c.getresult().get(node, False)
624
  if isinstance(result, dict):
625
    return objects.OS.FromDict(result)
626
  else:
627
    return result
665
    """
666
    c = Client("os_get", [name])
667
    c.connect(node)
668
    c.run()
669
    result = c.getresult().get(node, False)
670
    if isinstance(result, dict):
671
      return objects.OS.FromDict(result)
672
    else:
673
      return result
628 674

  
629 675

  
630
def call_hooks_runner(node_list, hpath, phase, env):
631
  """Call the hooks runner.
676
  def call_hooks_runner(self, node_list, hpath, phase, env):
677
    """Call the hooks runner.
632 678

  
633
  Args:
634
    - op: the OpCode instance
635
    - env: a dictionary with the environment
679
    Args:
680
      - op: the OpCode instance
681
      - env: a dictionary with the environment
636 682

  
637
  This is a multi-node call.
683
    This is a multi-node call.
638 684

  
639
  """
640
  params = [hpath, phase, env]
641
  c = Client("hooks_runner", params)
642
  c.connect_list(node_list)
643
  c.run()
644
  result = c.getresult()
645
  return result
685
    """
686
    params = [hpath, phase, env]
687
    c = Client("hooks_runner", params)
688
    c.connect_list(node_list)
689
    c.run()
690
    result = c.getresult()
691
    return result
646 692

  
647 693

  
648
def call_iallocator_runner(node, name, idata):
649
  """Call an iallocator on a remote node
694
  def call_iallocator_runner(self, node, name, idata):
695
    """Call an iallocator on a remote node
650 696

  
651
  Args:
652
    - name: the iallocator name
653
    - input: the json-encoded input string
697
    Args:
698
      - name: the iallocator name
699
      - input: the json-encoded input string
654 700

  
655
  This is a single-node call.
701
    This is a single-node call.
656 702

  
657
  """
658
  params = [name, idata]
659
  c = Client("iallocator_runner", params)
660
  c.connect(node)
661
  c.run()
662
  result = c.getresult().get(node, False)
663
  return result
703
    """
704
    params = [name, idata]
705
    c = Client("iallocator_runner", params)
706
    c.connect(node)
707
    c.run()
708
    result = c.getresult().get(node, False)
709
    return result
664 710

  
665 711

  
666
def call_blockdev_grow(node, cf_bdev, amount):
667
  """Request a snapshot of the given block device.
712
  def call_blockdev_grow(self, node, cf_bdev, amount):
713
    """Request a snapshot of the given block device.
668 714

  
669
  This is a single-node call.
715
    This is a single-node call.
670 716

  
671
  """
672
  c = Client("blockdev_grow", [cf_bdev.ToDict(), amount])
673
  c.connect(node)
674
  c.run()
675
  return c.getresult().get(node, False)
717
    """
718
    c = Client("blockdev_grow", [cf_bdev.ToDict(), amount])
719
    c.connect(node)
720
    c.run()
721
    return c.getresult().get(node, False)
676 722

  
677 723

  
678
def call_blockdev_snapshot(node, cf_bdev):
679
  """Request a snapshot of the given block device.
724
  def call_blockdev_snapshot(self, node, cf_bdev):
725
    """Request a snapshot of the given block device.
680 726

  
681
  This is a single-node call.
727
    This is a single-node call.
682 728

  
683
  """
684
  c = Client("blockdev_snapshot", [cf_bdev.ToDict()])
685
  c.connect(node)
686
  c.run()
687
  return c.getresult().get(node, False)
729
    """
730
    c = Client("blockdev_snapshot", [cf_bdev.ToDict()])
731
    c.connect(node)
732
    c.run()
733
    return c.getresult().get(node, False)
688 734

  
689 735

  
690
def call_snapshot_export(node, snap_bdev, dest_node, instance, cluster_name):
691
  """Request the export of a given snapshot.
736
  def call_snapshot_export(self, node, snap_bdev, dest_node, instance,
737
                           cluster_name):
738
    """Request the export of a given snapshot.
692 739

  
693
  This is a single-node call.
740
    This is a single-node call.
694 741

  
695
  """
696
  params = [snap_bdev.ToDict(), dest_node, instance.ToDict(), cluster_name]
697
  c = Client("snapshot_export", params)
698
  c.connect(node)
699
  c.run()
700
  return c.getresult().get(node, False)
742
    """
743
    params = [snap_bdev.ToDict(), dest_node, instance.ToDict(), cluster_name]
744
    c = Client("snapshot_export", params)
745
    c.connect(node)
746
    c.run()
747
    return c.getresult().get(node, False)
701 748

  
702 749

  
703
def call_finalize_export(node, instance, snap_disks):
704
  """Request the completion of an export operation.
750
  def call_finalize_export(self, node, instance, snap_disks):
751
    """Request the completion of an export operation.
705 752

  
706
  This writes the export config file, etc.
753
    This writes the export config file, etc.
707 754

  
708
  This is a single-node call.
755
    This is a single-node call.
709 756

  
710
  """
711
  flat_disks = []
712
  for disk in snap_disks:
713
    flat_disks.append(disk.ToDict())
714
  params = [instance.ToDict(), flat_disks]
715
  c = Client("finalize_export", params)
716
  c.connect(node)
717
  c.run()
718
  return c.getresult().get(node, False)
757
    """
758
    flat_disks = []
759
    for disk in snap_disks:
760
      flat_disks.append(disk.ToDict())
761
    params = [instance.ToDict(), flat_disks]
762
    c = Client("finalize_export", params)
763
    c.connect(node)
764
    c.run()
765
    return c.getresult().get(node, False)
719 766

  
720 767

  
721
def call_export_info(node, path):
722
  """Queries the export information in a given path.
768
  def call_export_info(self, node, path):
769
    """Queries the export information in a given path.
723 770

  
724
  This is a single-node call.
771
    This is a single-node call.
725 772

  
726
  """
727
  c = Client("export_info", [path])
728
  c.connect(node)
729
  c.run()
730
  result = c.getresult().get(node, False)
731
  if not result:
732
    return result
733
  return objects.SerializableConfigParser.Loads(str(result))
773
    """
774
    c = Client("export_info", [path])
775
    c.connect(node)
776
    c.run()
777
    result = c.getresult().get(node, False)
778
    if not result:
779
      return result
780
    return objects.SerializableConfigParser.Loads(str(result))
734 781

  
735 782

  
736
def call_instance_os_import(node, inst, osdev, swapdev,
737
                            src_node, src_image, cluster_name):
738
  """Request the import of a backup into an instance.
783
  def call_instance_os_import(self, node, inst, osdev, swapdev,
784
                              src_node, src_image, cluster_name):
785
    """Request the import of a backup into an instance.
739 786

  
740
  This is a single-node call.
787
    This is a single-node call.
741 788

  
742
  """
743
  params = [inst.ToDict(), osdev, swapdev, src_node, src_image, cluster_name]
744
  c = Client("instance_os_import", params)
745
  c.connect(node)
746
  c.run()
747
  return c.getresult().get(node, False)
789
    """
790
    params = [inst.ToDict(), osdev, swapdev, src_node, src_image, cluster_name]
791
    c = Client("instance_os_import", params)
792
    c.connect(node)
793
    c.run()
794
    return c.getresult().get(node, False)
748 795

  
749 796

  
750
def call_export_list(node_list):
751
  """Gets the stored exports list.
797
  def call_export_list(self, node_list):
798
    """Gets the stored exports list.
752 799

  
753
  This is a multi-node call.
800
    This is a multi-node call.
754 801

  
755
  """
756
  c = Client("export_list", [])
757
  c.connect_list(node_list)
758
  c.run()
759
  result = c.getresult()
760
  return result
802
    """
803
    c = Client("export_list", [])
804
    c.connect_list(node_list)
805
    c.run()
806
    result = c.getresult()
807
    return result
761 808

  
762 809

  
763
def call_export_remove(node, export):
764
  """Requests removal of a given export.
810
  def call_export_remove(self, node, export):
811
    """Requests removal of a given export.
765 812

  
766
  This is a single-node call.
813
    This is a single-node call.
767 814

  
768
  """
769
  c = Client("export_remove", [export])
770
  c.connect(node)
771
  c.run()
772
  return c.getresult().get(node, False)
815
    """
816
    c = Client("export_remove", [export])
817
    c.connect(node)
818
    c.run()
819
    return c.getresult().get(node, False)
773 820

  
774 821

  
775
def call_node_leave_cluster(node):
776
  """Requests a node to clean the cluster information it has.
822
  def call_node_leave_cluster(self, node):
823
    """Requests a node to clean the cluster information it has.
777 824

  
778
  This will remove the configuration information from the ganeti data
779
  dir.
825
    This will remove the configuration information from the ganeti data
826
    dir.
780 827

  
781
  This is a single-node call.
828
    This is a single-node call.
782 829

  
783
  """
784
  c = Client("node_leave_cluster", [])
785
  c.connect(node)
786
  c.run()
787
  return c.getresult().get(node, False)
830
    """
831
    c = Client("node_leave_cluster", [])
832
    c.connect(node)
833
    c.run()
834
    return c.getresult().get(node, False)
788 835

  
789 836

  
790
def call_node_volumes(node_list):
791
  """Gets all volumes on node(s).
837
  def call_node_volumes(self, node_list):
838
    """Gets all volumes on node(s).
792 839

  
793
  This is a multi-node call.
840
    This is a multi-node call.
794 841

  
795
  """
796
  c = Client("node_volumes", [])
797
  c.connect_list(node_list)
798
  c.run()
799
  return c.getresult()
842
    """
843
    c = Client("node_volumes", [])
844
    c.connect_list(node_list)
845
    c.run()
846
    return c.getresult()
800 847

  
801 848

  
802
def call_test_delay(node_list, duration):
803
  """Sleep for a fixed time on given node(s).
849
  def call_test_delay(self, node_list, duration):
850
    """Sleep for a fixed time on given node(s).
804 851

  
805
  This is a multi-node call.
852
    This is a multi-node call.
806 853

  
807
  """
808
  c = Client("test_delay", [duration])
809
  c.connect_list(node_list)
810
  c.run()
811
  return c.getresult()
854
    """
855
    c = Client("test_delay", [duration])
856
    c.connect_list(node_list)
857
    c.run()
858
    return c.getresult()
812 859

  
813 860

  
814
def call_file_storage_dir_create(node, file_storage_dir):
815
  """Create the given file storage directory.
861
  def call_file_storage_dir_create(self, node, file_storage_dir):
862
    """Create the given file storage directory.
816 863

  
817
  This is a single-node call.
864
    This is a single-node call.
818 865

  
819
  """
820
  c = Client("file_storage_dir_create", [file_storage_dir])
821
  c.connect(node)
822
  c.run()
823
  return c.getresult().get(node, False)
866
    """
867
    c = Client("file_storage_dir_create", [file_storage_dir])
868
    c.connect(node)
869
    c.run()
870
    return c.getresult().get(node, False)
824 871

  
825 872

  
826
def call_file_storage_dir_remove(node, file_storage_dir):
827
  """Remove the given file storage directory.
873
  def call_file_storage_dir_remove(self, node, file_storage_dir):
874
    """Remove the given file storage directory.
828 875

  
829
  This is a single-node call.
876
    This is a single-node call.
830 877

  
831
  """
832
  c = Client("file_storage_dir_remove", [file_storage_dir])
833
  c.connect(node)
834
  c.run()
835
  return c.getresult().get(node, False)
878
    """
879
    c = Client("file_storage_dir_remove", [file_storage_dir])
880
    c.connect(node)
881
    c.run()
882
    return c.getresult().get(node, False)
836 883

  
837 884

  
838
def call_file_storage_dir_rename(node, old_file_storage_dir,
839
                                 new_file_storage_dir):
840
  """Rename file storage directory.
885
  def call_file_storage_dir_rename(self, node, old_file_storage_dir,
886
                                   new_file_storage_dir):
887
    """Rename file storage directory.
841 888

  
842
  This is a single-node call.
889
    This is a single-node call.
843 890

  
844
  """
845
  c = Client("file_storage_dir_rename",
846
             [old_file_storage_dir, new_file_storage_dir])
847
  c.connect(node)
848
  c.run()
849
  return c.getresult().get(node, False)
891
    """
892
    c = Client("file_storage_dir_rename",
893
               [old_file_storage_dir, new_file_storage_dir])
894
    c.connect(node)
895
    c.run()
896
    return c.getresult().get(node, False)
850 897

  
851 898

  
852
def call_jobqueue_update(node_list, file_name, content):
853
  """Update job queue.
899
  @staticmethod
900
  def call_jobqueue_update(node_list, file_name, content):
901
    """Update job queue.
854 902

  
855
  This is a multi-node call.
903
    This is a multi-node call.
856 904

  
857
  """
858
  c = Client("jobqueue_update", [file_name, content])
859
  c.connect_list(node_list)
860
  c.run()
861
  result = c.getresult()
862
  return result
905
    """
906
    c = Client("jobqueue_update", [file_name, content])
907
    c.connect_list(node_list)
908
    c.run()
909
    result = c.getresult()
910
    return result
863 911

  
864 912

  
865
def call_jobqueue_purge(node):
866
  """Purge job queue.
913
  @staticmethod
914
  def call_jobqueue_purge(node):
915
    """Purge job queue.
867 916

  
868
  This is a single-node call.
917
    This is a single-node call.
869 918

  
870
  """
871
  c = Client("jobqueue_purge", [])
872
  c.connect(node)
873
  c.run()
874
  return c.getresult().get(node, False)
919
    """
920
    c = Client("jobqueue_purge", [])
921
    c.connect(node)
922
    c.run()
923
    return c.getresult().get(node, False)
875 924

  
876 925

  
877
def call_jobqueue_rename(node_list, old, new):
878
  """Rename a job queue file.
926
  @staticmethod
927
  def call_jobqueue_rename(node_list, old, new):
928
    """Rename a job queue file.
879 929

  
880
  This is a multi-node call.
930
    This is a multi-node call.
881 931

  
882
  """
883
  c = Client("jobqueue_rename", [old, new])
884
  c.connect_list(node_list)
885
  c.run()
886
  result = c.getresult()
887
  return result
932
    """
933
    c = Client("jobqueue_rename", [old, new])
934
    c.connect_list(node_list)
935
    c.run()
936
    result = c.getresult()
937
    return result

Also available in: Unified diff