diff --git a/lib/cli.py b/lib/cli.py index 7fc8d05d8f629655f0bba41f6d3be04c2b46b7af..c1a7287ff1073faac4b02a8aa202e865c0e87bc4 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -51,6 +51,7 @@ __all__ = [ "ALLOCATABLE_OPT", "ALLOC_POLICY_OPT", "ALL_OPT", + "ALLOW_FAILOVER_OPT", "AUTO_PROMOTE_OPT", "AUTO_REPLACE_OPT", "BACKEND_OPT", @@ -758,6 +759,12 @@ IGNORE_CONSIST_OPT = cli_option("--ignore-consistency", help="Ignore the consistency of the disks on" " the secondary") +ALLOW_FAILOVER_OPT = cli_option("--allow-failover", + dest="allow_failover", + action="store_true", default=False, + help="If migration is not possible fallback to" + " failover") + NONLIVE_OPT = cli_option("--non-live", dest="live", default=True, action="store_false", help="Do a non-live migration (this usually means" diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py index d4a9c1c151a437d2edc4b5a0c3a8f585ea165ce8..51cf2c3fd1e820421dffe24e48bcda5ef0df2170 100644 --- a/lib/client/gnt_instance.py +++ b/lib/client/gnt_instance.py @@ -829,7 +829,8 @@ def MigrateInstance(opts, args): op = opcodes.OpInstanceMigrate(instance_name=instance_name, mode=mode, cleanup=opts.cleanup, iallocator=iallocator, - target_node=target_node) + target_node=target_node, + allow_failover=opts.allow_failover) SubmitOpCode(op, cl=cl, opts=opts) return 0 @@ -1365,7 +1366,7 @@ commands = { 'migrate': ( MigrateInstance, ARGS_ONE_INSTANCE, [FORCE_OPT, NONLIVE_OPT, MIGRATION_MODE_OPT, CLEANUP_OPT, DRY_RUN_OPT, - PRIORITY_OPT, DST_NODE_OPT, IALLOCATOR_OPT], + PRIORITY_OPT, DST_NODE_OPT, IALLOCATOR_OPT, ALLOW_FAILOVER_OPT], "[-f] <instance>", "Migrate instance to its secondary node" " (only for mirrored instances)"), 'move': ( diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst index 8c08c649e7ad724d7ba319b043d8616e8cea291c..d65ae7e1fc1b6d45aafd939b5cf025b60204a1d4 100644 --- a/man/gnt-instance.rst +++ b/man/gnt-instance.rst @@ -1219,8 +1219,8 @@ MIGRATE **migrate** [-f] {--cleanup} {*instance*} -**migrate** [-f] [--non-live] [--migration-mode=live\|non-live] -{*instance*} +**migrate** [-f] [--allow-failover] [--non-live] +[--migration-mode=live\|non-live] {*instance*} Migrate will move the instance to its secondary node without shutdown. It only works for instances having the drbd8 disk @@ -1252,6 +1252,11 @@ instances's disks are configured correctly. In this mode, the The option ``-f`` will skip the prompting for confirmation. +If ``--allow-failover`` is specified it tries to fallback to failover if +it already can determine that a migration wont work (i.e. if the +instance is shutdown). Please note that the fallback will not happen +during execution. If a migration fails during execution it still fails. + Example (and expected output):: # gnt-instance migrate instance1 diff --git a/qa/qa_instance.py b/qa/qa_instance.py index d13ff79ca1fd9284d035ae067c1ebefc228b3d72..ab2a0f4a8989dad69dd9aee4179d5df83662080c 100644 --- a/qa/qa_instance.py +++ b/qa/qa_instance.py @@ -177,6 +177,12 @@ def TestInstanceMigrate(instance): AssertCommand(cmd) # ... and back AssertCommand(cmd) + AssertCommand(["gnt-instance", "shutdown", instance["name"]]) + AssertCommand(cmd, fail=True) + AssertCommand(["gnt-instance", "migrate", "--force", "--allow-failover", + instance["name"]]) + AssertCommand(["gnt-instance", "start", instance["name"]]) + AssertCommand(cmd) def TestInstanceInfo(instance):