Revision b6aaf437

b/lib/cli.py
192 192
  "YES_DOIT_OPT",
193 193
  "DISK_STATE_OPT",
194 194
  "HV_STATE_OPT",
195
  "IGNORE_IPOLICY_OPT",
195 196
  # Generic functions for CLI programs
196 197
  "ConfirmOperation",
197 198
  "GenericMain",
......
1334 1335
                                " format hypervisor:option=value,..."),
1335 1336
                          type="identkeyval")
1336 1337

  
1338
IGNORE_IPOLICY_OPT = cli_option("--ignore-ipolicy", dest="ignore_ipolicy",
1339
                                action="store_true", default=False,
1340
                                help="Ignore instance policy violations")
1341

  
1337 1342

  
1338 1343
#: Options provided by all commands
1339 1344
COMMON_OPTS = [DEBUG_OPT]
b/lib/client/gnt_instance.py
791 791
                                  ignore_consistency=opts.ignore_consistency,
792 792
                                  shutdown_timeout=opts.shutdown_timeout,
793 793
                                  iallocator=iallocator,
794
                                  target_node=target_node)
794
                                  target_node=target_node,
795
                                  ignore_ipolicy=opts.ignore_ipolicy)
795 796
  SubmitOrSend(op, opts, cl=cl)
796 797
  return 0
797 798

  
......
1436 1437
  "failover": (
1437 1438
    FailoverInstance, ARGS_ONE_INSTANCE,
1438 1439
    [FORCE_OPT, IGNORE_CONSIST_OPT, SUBMIT_OPT, SHUTDOWN_TIMEOUT_OPT,
1439
     DRY_RUN_OPT, PRIORITY_OPT, DST_NODE_OPT, IALLOCATOR_OPT],
1440
     DRY_RUN_OPT, PRIORITY_OPT, DST_NODE_OPT, IALLOCATOR_OPT,
1441
     IGNORE_IPOLICY_OPT],
1440 1442
    "[-f] <instance>", "Stops the instance, changes its primary node and"
1441 1443
    " (if it was originally running) starts it on the new node"
1442 1444
    " (the secondary for mirrored instances or any node"
b/lib/cmdlib.py
7244 7244
                                       cleanup=False,
7245 7245
                                       failover=True,
7246 7246
                                       ignore_consistency=ignore_consistency,
7247
                                       shutdown_timeout=shutdown_timeout)
7247
                                       shutdown_timeout=shutdown_timeout,
7248
                                       ignore_ipolicy=self.op.ignore_ipolicy)
7248 7249
    self.tasklets = [self._migrater]
7249 7250

  
7250 7251
  def DeclareLocks(self, level):
......
7644 7645
                            and target node
7645 7646
  @type shutdown_timeout: int
7646 7647
  @ivar shutdown_timeout: In case of failover timeout of the shutdown
7648
  @type ignore_ipolicy: bool
7649
  @ivar ignore_ipolicy: If true, we can ignore instance policy when migrating
7647 7650

  
7648 7651
  """
7649 7652

  
......
7654 7657
  def __init__(self, lu, instance_name, cleanup=False,
7655 7658
               failover=False, fallback=False,
7656 7659
               ignore_consistency=False,
7657
               shutdown_timeout=constants.DEFAULT_SHUTDOWN_TIMEOUT):
7660
               shutdown_timeout=constants.DEFAULT_SHUTDOWN_TIMEOUT,
7661
               ignore_ipolicy=False):
7658 7662
    """Initializes this class.
7659 7663

  
7660 7664
    """
......
7668 7672
    self.fallback = fallback
7669 7673
    self.ignore_consistency = ignore_consistency
7670 7674
    self.shutdown_timeout = shutdown_timeout
7675
    self.ignore_ipolicy = ignore_ipolicy
7671 7676

  
7672 7677
  def CheckPrereq(self):
7673 7678
    """Check prerequisites.
......
7679 7684
    instance = self.cfg.GetInstanceInfo(instance_name)
7680 7685
    assert instance is not None
7681 7686
    self.instance = instance
7687
    cluster = self.cfg.GetClusterInfo()
7682 7688

  
7683 7689
    if (not self.cleanup and
7684 7690
        not instance.admin_state == constants.ADMINST_UP and
......
7706 7712
        # BuildHooksEnv
7707 7713
        self.target_node = self.lu.op.target_node
7708 7714

  
7715
      # Check that the target node is correct in terms of instance policy
7716
      nodeinfo = self.cfg.GetNodeInfo(self.target_node)
7717
      ipolicy = _CalculateGroupIPolicy(cluster, nodeinfo.group)
7718
      _CheckTargetNodeIPolicy(self.lu, ipolicy, instance, nodeinfo,
7719
                              ignore=self.ignore_ipolicy)
7720

  
7709 7721
      # self.target_node is already populated, either directly or by the
7710 7722
      # iallocator run
7711 7723
      target_node = self.target_node
......
7739 7751
                                   " node can be passed)" %
7740 7752
                                   (instance.disk_template, text),
7741 7753
                                   errors.ECODE_INVAL)
7754
      nodeinfo = self.cfg.GetNodeInfo(target_node)
7755
      ipolicy = _CalculateGroupIPolicy(cluster, nodeinfo.group)
7756
      _CheckTargetNodeIPolicy(self.lu, ipolicy, instance, nodeinfo,
7757
                              ignore=self.ignore_ipolicy)
7742 7758

  
7743
    i_be = self.cfg.GetClusterInfo().FillBE(instance)
7759
    i_be = cluster.FillBE(instance)
7744 7760

  
7745 7761
    # check memory requirements on the secondary node
7746 7762
    if not self.failover or instance.admin_state == constants.ADMINST_UP:
......
7796 7812
        self.lu.op.live = None
7797 7813
      elif self.lu.op.mode is None:
7798 7814
        # read the default value from the hypervisor
7799
        i_hv = self.cfg.GetClusterInfo().FillHV(self.instance,
7800
                                                skip_globals=False)
7815
        i_hv = cluster.FillHV(self.instance, skip_globals=False)
7801 7816
        self.lu.op.mode = i_hv[constants.HV_MIGRATION_MODE]
7802 7817

  
7803 7818
      self.live = self.lu.op.mode == constants.HT_MIGRATION_LIVE
......
7809 7824
    """Run the allocator based on input opcode.
7810 7825

  
7811 7826
    """
7827
    # FIXME: add a self.ignore_ipolicy option
7812 7828
    ial = IAllocator(self.cfg, self.rpc,
7813 7829
                     mode=constants.IALLOCATOR_MODE_RELOC,
7814 7830
                     name=self.instance_name,
b/lib/opcodes.py
152 152
_PHvState = ("hv_state", None, ht.TMaybeDict, "Set hypervisor states")
153 153
_PDiskState = ("disk_state", None, ht.TMaybeDict, "Set disk states")
154 154

  
155

  
156
_PIgnoreIpolicy = ("ignore_ipolicy", False, ht.TBool,
157
                   "Whether to ignore ipolicy violations")
158

  
155 159
#: OP_ID conversion regular expression
156 160
_OPID_RE = re.compile("([a-z])([A-Z])")
157 161

  
......
1236 1240
    _PShutdownTimeout,
1237 1241
    _PIgnoreConsistency,
1238 1242
    _PMigrationTargetNode,
1243
    _PIgnoreIpolicy,
1239 1244
    ("iallocator", None, ht.TMaybeString,
1240 1245
     "Iallocator for deciding the target node for shared-storage instances"),
1241 1246
    ]
b/man/gnt-instance.rst
1380 1380
^^^^^^^^
1381 1381

  
1382 1382
**failover** [-f] [--ignore-consistency] [--shutdown-timeout=*N*]
1383
[--submit] {*instance*}
1383
[--submit] [--ignore-ipolicy] {*instance*}
1384 1384

  
1385 1385
Failover will stop the instance (if running), change its primary node,
1386 1386
and if it was originally running it will start it again (on the new
......
1406 1406
but not wait for its completion. The job ID will be shown so that it
1407 1407
can be examined via **gnt-job info**.
1408 1408

  
1409
If ``--ignore-ipolicy`` is given any instance policy violations occuring
1410
during this operation are ignored.
1411

  
1409 1412
Example::
1410 1413

  
1411 1414
    # gnt-instance failover instance1.example.com

Also available in: Unified diff