Revision a396b2d6 tools/move-instance

b/tools/move-instance
39 39
from ganeti import objects
40 40
from ganeti import compat
41 41
from ganeti import rapi
42
from ganeti import errors
42 43

  
43 44
import ganeti.rapi.client # pylint: disable=W0611
44 45
import ganeti.rapi.client_utils
......
301 302
  def __init__(self, src_instance_name, dest_instance_name,
302 303
               dest_pnode, dest_snode, compress, dest_iallocator,
303 304
               dest_disk_template, hvparams,
304
               beparams, osparams, nics):
305
               beparams, osparams, nics, opportunistic_tries,
306
               opportunistic_delay):
305 307
    """Initializes this class.
306 308

  
307 309
    @type src_instance_name: string
......
327 329
    @param osparams: OS parameters to override
328 330
    @type nics: dict or None
329 331
    @param nics: NICs to override
332
    @type opportunistic_tries: int or None
333
    @param opportunistic_tries: Number of opportunistic creation attempts to
334
                                perform
335
    @type opportunistic_delay: int or None
336
    @param opportunistic_delay: Delay between successive creation attempts, in
337
                                seconds
330 338

  
331 339
    """
332 340
    self.src_instance_name = src_instance_name
......
341 349
    self.osparams = osparams
342 350
    self.nics = nics
343 351

  
352
    if opportunistic_tries is not None:
353
      self.opportunistic_tries = opportunistic_tries
354
    else:
355
      self.opportunistic_tries = 0
356

  
357
    if opportunistic_delay is not None:
358
      self.opportunistic_delay = opportunistic_delay
359
    else:
360
      self.opportunistic_delay = constants.DEFAULT_OPPORTUNISTIC_RETRY_INTERVAL
361

  
344 362
    self.error_message = None
345 363

  
346 364

  
......
462 480

  
463 481
    logging.info("Creating instance %s in remote-import mode",
464 482
                 mrt.move.dest_instance_name)
465
    job_id = self._CreateInstance(dest_client, mrt.move.dest_instance_name,
466
                                  mrt.move.dest_pnode, mrt.move.dest_snode,
467
                                  mrt.move.compress,
468
                                  mrt.move.dest_iallocator,
469
                                  mrt.move.dest_disk_template,
470
                                  mrt.src_instinfo, mrt.src_expinfo,
471
                                  mrt.move.hvparams, mrt.move.beparams,
472
                                  mrt.move.beparams, mrt.move.nics)
473
    mrt.PollJob(dest_client, job_id,
474
                remote_import_fn=compat.partial(self._SetImportInfo, mrt))
475

  
476
    logging.info("Import successful")
483

  
484
    # Depending on whether opportunistic tries are enabled, we may have to
485
    # make multiple creation attempts
486
    creation_attempts = [True] * mrt.move.opportunistic_tries
487

  
488
    # But the last one is never opportunistic, and will block until completion
489
    # or failure
490
    creation_attempts.append(False)
491

  
492
    for is_attempt_opportunistic in creation_attempts:
493
      job_id = self._CreateInstance(dest_client, mrt.move.dest_instance_name,
494
                                    mrt.move.dest_pnode, mrt.move.dest_snode,
495
                                    mrt.move.compress,
496
                                    mrt.move.dest_iallocator,
497
                                    mrt.move.dest_disk_template,
498
                                    mrt.src_instinfo, mrt.src_expinfo,
499
                                    mrt.move.hvparams, mrt.move.beparams,
500
                                    mrt.move.beparams, mrt.move.nics,
501
                                    is_attempt_opportunistic
502
                                    )
503

  
504
      try:
505
        # The completion of this block signifies that the import has been
506
        # completed successfullly
507
        mrt.PollJob(dest_client, job_id,
508
                    remote_import_fn=compat.partial(self._SetImportInfo, mrt))
509
        logging.info("Import successful")
510
        return
511
      except errors.OpPrereqError, err:
512
        # Any exception in the non-opportunistic creation is to be passed on,
513
        # as well as exceptions apart from resources temporarily unavailable
514
        if not is_attempt_opportunistic or \
515
           err.args[1] != rapi.client.ECODE_TEMP_NORES:
516
          raise
517

  
518
      logging.info("Opportunistic attempt unsuccessful, waiting %d seconds"
519
                   " before another creation attempt is made",
520
                   mrt.move.opportunistic_delay)
521
      time.sleep(mrt.move.opportunistic_delay)
477 522

  
478 523
  @staticmethod
479 524
  def _SetImportInfo(mrt, impinfo):
......
494 539
  @staticmethod
495 540
  def _CreateInstance(cl, name, pnode, snode, compress, iallocator,
496 541
                      dest_disk_template, instance, expinfo, override_hvparams,
497
                      override_beparams, override_osparams, override_nics):
542
                      override_beparams, override_osparams, override_nics,
543
                      is_attempt_opportunistic):
498 544
    """Starts the instance creation in remote import mode.
499 545

  
500 546
    @type cl: L{rapi.client.GanetiRapiClient}
......
523 569
    @param override_osparams: OS parameters to override
524 570
    @type override_nics: dict or None
525 571
    @param override_nics: NICs to override
572
    @type is_attempt_opportunistic: bool
573
    @param is_attempt_opportunistic: Whether to use opportunistic locking or not
526 574
    @return: Job ID
527 575

  
528 576
    """
......
602 650
                             hvparams=objects.FillDict(inst_hvparams,
603 651
                                                       override_hvparams),
604 652
                             osparams=objects.FillDict(inst_osparams,
605
                                                       override_osparams))
653
                                                       override_osparams),
654
                             opportunistic_locking=is_attempt_opportunistic
655
                             )
606 656

  
607 657

  
608 658
class MoveSourceExecutor(object):
......
961 1011
                              options.hvparams,
962 1012
                              options.beparams,
963 1013
                              options.osparams,
964
                              options.nics))
1014
                              options.nics,
1015
                              options.opportunistic_tries,
1016
                              options.opportunistic_delay))
965 1017

  
966 1018
  assert len(moves) == len(instance_names)
967 1019

  

Also available in: Unified diff