Revision 1fa6fcba

b/lib/backend.py
1328 1328
  return block_devices
1329 1329

  
1330 1330

  
1331
def StartInstance(instance, startup_paused):
1331
def StartInstance(instance, startup_paused, reason, store_reason=True):
1332 1332
  """Start an instance.
1333 1333

  
1334 1334
  @type instance: L{objects.Instance}
1335 1335
  @param instance: the instance object
1336 1336
  @type startup_paused: bool
1337 1337
  @param instance: pause instance at startup?
1338
  @type reason: list of reasons
1339
  @param reason: the reason trail for this startup
1340
  @type store_reason: boolean
1341
  @param store_reason: whether to store the shutdown reason trail on file
1338 1342
  @rtype: None
1339 1343

  
1340 1344
  """
......
1348 1352
    block_devices = _GatherAndLinkBlockDevs(instance)
1349 1353
    hyper = hypervisor.GetHypervisor(instance.hypervisor)
1350 1354
    hyper.StartInstance(instance, block_devices, startup_paused)
1355
    if store_reason:
1356
      _StoreInstReasonTrail(instance.name, reason)
1351 1357
  except errors.BlockDeviceError, err:
1352 1358
    _Fail("Block device error: %s", err, exc=True)
1353 1359
  except errors.HypervisorError, err:
......
1467 1473
  elif reboot_type == constants.INSTANCE_REBOOT_HARD:
1468 1474
    try:
1469 1475
      InstanceShutdown(instance, shutdown_timeout, reason, store_reason=False)
1470
      result = StartInstance(instance, False)
1476
      result = StartInstance(instance, False, reason, store_reason=False)
1471 1477
      _StoreInstReasonTrail(instance.name, reason)
1472 1478
      return result
1473 1479
    except errors.HypervisorError, err:
b/lib/cmdlib.py
7349 7349
    """
7350 7350
    instance = self.instance
7351 7351
    force = self.op.force
7352
    reason = self.op.reason
7352 7353

  
7353 7354
    if not self.op.no_remember:
7354 7355
      self.cfg.MarkInstanceUp(instance.name)
......
7365 7366
        self.rpc.call_instance_start(node_current,
7366 7367
                                     (instance, self.op.hvparams,
7367 7368
                                      self.op.beparams),
7368
                                     self.op.startup_paused)
7369
                                     self.op.startup_paused, reason)
7369 7370
      msg = result.fail_msg
7370 7371
      if msg:
7371 7372
        _ShutdownInstanceDisks(self, instance)
......
7458 7459
                     instance.name)
7459 7460
      _StartInstanceDisks(self, instance, ignore_secondaries)
7460 7461
      result = self.rpc.call_instance_start(node_current,
7461
                                            (instance, None, None), False)
7462
                                            (instance, None, None), False,
7463
                                             reason)
7462 7464
      msg = result.fail_msg
7463 7465
      if msg:
7464 7466
        _ShutdownInstanceDisks(self, instance)
......
8557 8559
        raise errors.OpExecError("Can't activate the instance's disks")
8558 8560

  
8559 8561
      result = self.rpc.call_instance_start(target_node,
8560
                                            (instance, None, None), False)
8562
                                            (instance, None, None), False,
8563
                                             self.op.reason)
8561 8564
      msg = result.fail_msg
8562 8565
      if msg:
8563 8566
        _ShutdownInstanceDisks(self, instance)
......
9297 9300
      self.feedback_fn("* starting the instance on the target node %s" %
9298 9301
                       target_node)
9299 9302
      result = self.rpc.call_instance_start(target_node, (instance, None, None),
9300
                                            False)
9303
                                            False, self.lu.op.reason)
9301 9304
      msg = result.fail_msg
9302 9305
      if msg:
9303 9306
        _ShutdownInstanceDisks(self.lu, instance)
......
11229 11232
      logging.info("Starting instance %s on node %s", instance, pnode_name)
11230 11233
      feedback_fn("* starting instance...")
11231 11234
      result = self.rpc.call_instance_start(pnode_name, (iobj, None, None),
11232
                                            False)
11235
                                            False, self.op.reason)
11233 11236
      result.Raise("Could not start instance")
11234 11237

  
11235 11238
    return list(iobj.all_nodes)
......
14963 14966
          assert not activate_disks
14964 14967
          feedback_fn("Starting instance %s" % instance.name)
14965 14968
          result = self.rpc.call_instance_start(src_node,
14966
                                                (instance, None, None), False)
14969
                                                (instance, None, None), False,
14970
                                                 self.op.reason)
14967 14971
          msg = result.fail_msg
14968 14972
          if msg:
14969 14973
            feedback_fn("Failed to start instance: %s" % msg)
b/lib/rapi/client.py
1057 1057
                             ("/%s/instances/%s/shutdown" %
1058 1058
                              (GANETI_RAPI_VERSION, instance)), query, body)
1059 1059

  
1060
  def StartupInstance(self, instance, dry_run=False, no_remember=False):
1060
  def StartupInstance(self, instance, dry_run=False, no_remember=False,
1061
                      reason=None):
1061 1062
    """Starts up an instance.
1062 1063

  
1063 1064
    @type instance: str
......
1066 1067
    @param dry_run: whether to perform a dry run
1067 1068
    @type no_remember: bool
1068 1069
    @param no_remember: if true, will not record the state change
1070
    @type reason: string
1071
    @param reason: the reason for the startup
1069 1072
    @rtype: string
1070 1073
    @return: job id
1071 1074

  
......
1073 1076
    query = []
1074 1077
    _AppendDryRunIf(query, dry_run)
1075 1078
    _AppendIf(query, no_remember, ("no_remember", 1))
1079
    _AppendIf(query, reason, ("reason", reason))
1076 1080

  
1077 1081
    return self._SendRequest(HTTP_PUT,
1078 1082
                             ("/%s/instances/%s/startup" %
b/lib/rpc_defs.py
279 279
  ("instance_start", SINGLE, None, constants.RPC_TMO_NORMAL, [
280 280
    ("instance_hvp_bep", ED_INST_DICT_HVP_BEP_DP, None),
281 281
    ("startup_paused", None, None),
282
    ("reason", None, "The reason for the startup"),
282 283
    ], None, None, "Starts an instance"),
283 284
  ("instance_os_add", SINGLE, None, constants.RPC_TMO_1DAY, [
284 285
    ("instance_osp", ED_INST_DICT_OSP_DP, None),
b/lib/server/noded.py
598 598
    """Start an instance.
599 599

  
600 600
    """
601
    (instance_name, startup_paused) = params
601
    (instance_name, startup_paused, trail) = params
602 602
    instance = objects.Instance.FromDict(instance_name)
603
    return backend.StartInstance(instance, startup_paused)
603
    _extendReasonTrail(trail, "start")
604
    return backend.StartInstance(instance, startup_paused, trail)
604 605

  
605 606
  @staticmethod
606 607
  def perspective_migration_info(params):
b/test/py/ganeti.rapi.client_unittest.py
638 638
  def testStartupInstance(self):
639 639
    self.rapi.AddResponse("27149")
640 640
    self.assertEqual(27149, self.client.StartupInstance("bar-instance",
641
                                                        dry_run=True,
642
                                                        reason="New"))
643
    self.assertHandler(rlib2.R_2_instances_name_startup)
644
    self.assertItems(["bar-instance"])
645
    self.assertDryRun()
646
    self.assertQuery("reason", ["New"])
647

  
648
  def testStartupInstanceDefaultReason(self):
649
    self.rapi.AddResponse("27149")
650
    self.assertEqual(27149, self.client.StartupInstance("bar-instance",
641 651
                                                        dry_run=True))
642 652
    self.assertHandler(rlib2.R_2_instances_name_startup)
643 653
    self.assertItems(["bar-instance"])
644 654
    self.assertDryRun()
655
    self.assertQuery("reason", None)
645 656

  
646 657
  def testReinstallInstance(self):
647 658
    self.rapi.AddResponse(serializer.DumpJson([]))
b/test/py/ganeti.rapi.rlib2_unittest.py
400 400
    handler = _CreateHandler(rlib2.R_2_instances_name_startup, ["inst31083"], {
401 401
      "force": ["1"],
402 402
      "no_remember": ["1"],
403
      "reason": ["Newly created instance"],
403 404
      }, {}, clfactory)
404 405
    job_id = handler.PUT()
405 406

  
......
413 414
    self.assertTrue(op.no_remember)
414 415
    self.assertTrue(op.force)
415 416
    self.assertFalse(op.dry_run)
417
    self.assertEqual(op.reason[0][0], constants.OPCODE_REASON_SRC_USER)
418
    self.assertEqual(op.reason[0][1], "Newly created instance")
419
    self.assertEqual(op.reason[1][0],
420
                     "%s:%s" % (constants.OPCODE_REASON_SRC_RLIB2,
421
                                "instances_name_startup"))
422
    self.assertEqual(op.reason[1][1], "")
416 423

  
417 424
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
418 425

  

Also available in: Unified diff