Revision 3016bc1f

b/lib/client/gnt_instance.py
1327 1327
             " specifying a secondary node")
1328 1328
    return 1
1329 1329

  
1330
  if opts.offline_inst:
1331
    offline = True
1332
  elif opts.online_inst:
1333
    offline = False
1334
  else:
1335
    offline = None
1336

  
1330 1337
  op = opcodes.OpInstanceSetParams(instance_name=args[0],
1331 1338
                                   nics=opts.nics,
1332 1339
                                   disks=opts.disks,
......
1340 1347
                                   force_variant=opts.force_variant,
1341 1348
                                   force=opts.force,
1342 1349
                                   wait_for_sync=opts.wait_for_sync,
1343
                                   offline_inst=opts.offline_inst,
1344
                                   online_inst=opts.online_inst,
1350
                                   offline=offline,
1345 1351
                                   ignore_ipolicy=opts.ignore_ipolicy)
1346 1352

  
1347 1353
  # even if here we process the result, we allow submit only
b/lib/cmdlib.py
11806 11806
  def CheckArguments(self):
11807 11807
    if not (self.op.nics or self.op.disks or self.op.disk_template or
11808 11808
            self.op.hvparams or self.op.beparams or self.op.os_name or
11809
            self.op.online_inst or self.op.offline_inst or
11810
            self.op.runtime_mem):
11809
            self.op.offline is not None or self.op.runtime_mem):
11811 11810
      raise errors.OpPrereqError("No changes submitted", errors.ECODE_INVAL)
11812 11811

  
11813 11812
    if self.op.hvparams:
......
12327 12326
                                     (disk_op, len(instance.disks)),
12328 12327
                                     errors.ECODE_INVAL)
12329 12328

  
12330
    # disabling the instance
12331
    if self.op.offline_inst:
12329
    if self.op.offline is None:
12330
      # Ignore
12331
      pass
12332
    elif self.op.offline:
12333
      # Mark instance as offline
12332 12334
      _CheckInstanceState(self, instance, INSTANCE_DOWN,
12333 12335
                          msg="cannot change instance state to offline")
12334

  
12335
    # enabling the instance
12336
    if self.op.online_inst:
12336
    else:
12337
      # Mark instance as online, but stopped
12337 12338
      _CheckInstanceState(self, instance, INSTANCE_OFFLINE,
12338 12339
                          msg="cannot make instance go online")
12339 12340

  
......
12619 12620
      for key, val in self.op.osparams.iteritems():
12620 12621
        result.append(("os/%s" % key, val))
12621 12622

  
12622
    # online/offline instance
12623
    if self.op.online_inst:
12624
      self.cfg.MarkInstanceDown(instance.name)
12625
      result.append(("admin_state", constants.ADMINST_DOWN))
12626
    if self.op.offline_inst:
12623
    if self.op.offline is None:
12624
      # Ignore
12625
      pass
12626
    elif self.op.offline:
12627
      # Mark instance as offline
12627 12628
      self.cfg.MarkInstanceOffline(instance.name)
12628 12629
      result.append(("admin_state", constants.ADMINST_OFFLINE))
12630
    else:
12631
      # Mark instance as online, but stopped
12632
      self.cfg.MarkInstanceDown(instance.name)
12633
      result.append(("admin_state", constants.ADMINST_DOWN))
12629 12634

  
12630 12635
    self.cfg.Update(instance, feedback_fn)
12631 12636

  
b/lib/opcodes.py
1401 1401
    ("osparams", None, ht.TMaybeDict, "Per-instance OS parameters"),
1402 1402
    ("wait_for_sync", True, ht.TBool,
1403 1403
     "Whether to wait for the disk to synchronize, when changing template"),
1404
    ("offline_inst", False, ht.TBool,
1405
     "Whether to turn off the down instance completely"),
1406
    ("online_inst", False, ht.TBool,
1407
     "Whether to enable the offline instance"),
1404
    ("offline", None, ht.TMaybeBool, "Whether to mark instance as offline"),
1408 1405
    ]
1409 1406
  OP_RESULT = _TSetParamsResult
1410 1407

  
b/qa/ganeti-qa.py
226 226
  RunTestIf("instance-shutdown", qa_instance.TestInstanceShutdown, instance)
227 227
  RunTestIf(["instance-shutdown", "instance-console", "rapi"],
228 228
            qa_rapi.TestRapiStoppedInstanceConsole, instance)
229
  RunTestIf(["instance-shutdown", "instance-modify"],
230
            qa_instance.TestInstanceStoppedModify, instance)
229 231
  RunTestIf("instance-shutdown", qa_instance.TestInstanceStartup, instance)
230 232

  
231 233
  # Test shutdown/start via RAPI
b/qa/qa_instance.py
252 252
  # check no-modify
253 253
  AssertCommand(["gnt-instance", "modify", instance["name"]], fail=True)
254 254

  
255
  # Marking offline/online while instance is running must fail
256
  for arg in ["--online", "--offline"]:
257
    AssertCommand(["gnt-instance", "modify", arg, instance["name"]], fail=True)
258

  
259

  
260
def TestInstanceStoppedModify(instance):
261
  """gnt-instance modify (stopped instance)"""
262
  name = instance["name"]
263

  
264
  # Assume instance was not marked offline, so marking it online must fail
265
  AssertCommand(["gnt-instance", "modify", "--online", name], fail=True)
266

  
267
  # Mark instance as offline
268
  AssertCommand(["gnt-instance", "modify", "--offline", name])
269

  
270
  # And online again
271
  AssertCommand(["gnt-instance", "modify", "--online", name])
272

  
255 273

  
256 274
def TestInstanceConvertDisk(instance, snode):
257 275
  """gnt-instance modify -t"""

Also available in: Unified diff