Revision 55cec070

b/lib/backend.py
1424 1424
  _RemoveBlockDevLinks(iname, instance.disks)
1425 1425

  
1426 1426

  
1427
def InstanceReboot(instance, reboot_type, shutdown_timeout):
1427
def InstanceReboot(instance, reboot_type, shutdown_timeout, reason):
1428 1428
  """Reboot an instance.
1429 1429

  
1430 1430
  @type instance: L{objects.Instance}
......
1442 1442
        instance (instead of a call_instance_reboot RPC)
1443 1443
  @type shutdown_timeout: integer
1444 1444
  @param shutdown_timeout: maximum timeout for soft shutdown
1445
  @type reason: list of reasons
1446
  @param reason: the reason trail for this reboot
1445 1447
  @rtype: None
1446 1448

  
1447 1449
  """
......
1460 1462
    try:
1461 1463
      InstanceShutdown(instance, shutdown_timeout)
1462 1464
      result = StartInstance(instance, False)
1465
      _StoreInstReasonTrail(instance.name, reason)
1463 1466
      return result
1464 1467
    except errors.HypervisorError, err:
1465 1468
      _Fail("Failed to hard reboot instance %s: %s", instance.name, err)
b/lib/cmdlib.py
7440 7440
    instance = self.instance
7441 7441
    ignore_secondaries = self.op.ignore_secondaries
7442 7442
    reboot_type = self.op.reboot_type
7443
    reason = self.op.reason
7443 7444

  
7444 7445
    remote_info = self.rpc.call_instance_info(instance.primary_node,
7445 7446
                                              instance.name,
......
7455 7456
        self.cfg.SetDiskID(disk, node_current)
7456 7457
      result = self.rpc.call_instance_reboot(node_current, instance,
7457 7458
                                             reboot_type,
7458
                                             self.op.shutdown_timeout)
7459
                                             self.op.shutdown_timeout, reason)
7459 7460
      result.Raise("Could not reboot instance")
7460 7461
    else:
7461 7462
      if instance_running:
b/lib/rapi/client.py
1001 1001
                              (GANETI_RAPI_VERSION, instance)), query, None)
1002 1002

  
1003 1003
  def RebootInstance(self, instance, reboot_type=None, ignore_secondaries=None,
1004
                     dry_run=False):
1004
                     dry_run=False, reason=None):
1005 1005
    """Reboots an instance.
1006 1006

  
1007 1007
    @type instance: str
......
1013 1013
        while re-assembling disks (in hard-reboot mode only)
1014 1014
    @type dry_run: bool
1015 1015
    @param dry_run: whether to perform a dry run
1016
    @type reason: string
1017
    @param reason: the reason for the reboot
1016 1018
    @rtype: string
1017 1019
    @return: job id
1018 1020

  
......
1022 1024
    _AppendIf(query, reboot_type, ("type", reboot_type))
1023 1025
    _AppendIf(query, ignore_secondaries is not None,
1024 1026
              ("ignore_secondaries", ignore_secondaries))
1027
    _AppendIf(query, reason, ("reason", reason))
1025 1028

  
1026 1029
    return self._SendRequest(HTTP_POST,
1027 1030
                             ("/%s/instances/%s/reboot" %
b/lib/rpc_defs.py
230 230
    ("inst", ED_INST_DICT, "Instance object"),
231 231
    ("reboot_type", None, None),
232 232
    ("shutdown_timeout", None, None),
233
    ("reason", None, "The reason for the reboot"),
233 234
    ], None, None, "Returns the list of running instances on the given nodes"),
234 235
  ("instance_shutdown", SINGLE, None, constants.RPC_TMO_NORMAL, [
235 236
    ("instance", ED_INST_DICT, "Instance object"),
b/lib/server/noded.py
660 660
    instance = objects.Instance.FromDict(params[0])
661 661
    reboot_type = params[1]
662 662
    shutdown_timeout = params[2]
663
    return backend.InstanceReboot(instance, reboot_type, shutdown_timeout)
663
    trail = params[3]
664
    _extendReasonTrail(trail, "reboot")
665
    return backend.InstanceReboot(instance, reboot_type, shutdown_timeout,
666
                                  trail)
664 667

  
665 668
  @staticmethod
666 669
  def perspective_instance_balloon_memory(params):
b/test/py/ganeti.rapi.client_unittest.py
594 594
  def testRebootInstance(self):
595 595
    self.rapi.AddResponse("6146")
596 596
    job_id = self.client.RebootInstance("i-bar", reboot_type="hard",
597
                                        ignore_secondaries=True, dry_run=True)
597
                                        ignore_secondaries=True, dry_run=True,
598
                                        reason="Updates")
598 599
    self.assertEqual(6146, job_id)
599 600
    self.assertHandler(rlib2.R_2_instances_name_reboot)
600 601
    self.assertItems(["i-bar"])
601 602
    self.assertDryRun()
602 603
    self.assertQuery("type", ["hard"])
603 604
    self.assertQuery("ignore_secondaries", ["1"])
605
    self.assertQuery("reason", ["Updates"])
604 606

  
605 607
  def testRebootInstanceDefaultReason(self):
606 608
    self.rapi.AddResponse("6146")
......
612 614
    self.assertDryRun()
613 615
    self.assertQuery("type", ["hard"])
614 616
    self.assertQuery("ignore_secondaries", ["1"])
617
    self.assertQuery("reason", None)
615 618

  
616 619
  def testShutdownInstance(self):
617 620
    self.rapi.AddResponse("1487")
b/test/py/ganeti.rapi.rlib2_unittest.py
370 370
    handler = _CreateHandler(rlib2.R_2_instances_name_reboot, ["inst847"], {
371 371
      "dry-run": ["1"],
372 372
      "ignore_secondaries": ["1"],
373
      "reason": ["System update"],
373 374
      }, {}, clfactory)
374 375
    job_id = handler.POST()
375 376

  
......
383 384
    self.assertEqual(op.reboot_type, constants.INSTANCE_REBOOT_HARD)
384 385
    self.assertTrue(op.ignore_secondaries)
385 386
    self.assertTrue(op.dry_run)
387
    self.assertEqual(op.reason[0][0], constants.OPCODE_REASON_SRC_USER)
388
    self.assertEqual(op.reason[0][1], "System update")
389
    self.assertEqual(op.reason[1][0],
390
                     "%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
391
                                "instances_name_reboot"))
392
    self.assertEqual(op.reason[1][1], "")
386 393

  
387 394
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
388 395

  

Also available in: Unified diff