diff --git a/lib/cli.py b/lib/cli.py index 57ff3eb0a9dfbe724dfd58e88e1756b34b618df7..60e86e7376d74777752f6e7cd047694ae9bb30ef 100644 --- a/lib/cli.py +++ b/lib/cli.py @@ -69,6 +69,7 @@ __all__ = [ "DRAINED_OPT", "DRY_RUN_OPT", "DRBD_HELPER_OPT", + "DST_NODE_OPT", "EARLY_RELEASE_OPT", "ENABLED_HV_OPT", "ERROR_CODES_OPT", @@ -839,6 +840,11 @@ REMOVE_INSTANCE_OPT = cli_option("--remove-instance", dest="remove_instance", action="store_true", default=False, help="Remove the instance from the cluster") +DST_NODE_OPT = cli_option("-n", "--target-node", dest="dst_node", + help="Specifies the new node for the instance", + metavar="NODE", default=None, + completion_suggest=OPT_COMPL_ONE_NODE) + NEW_SECONDARY_OPT = cli_option("-n", "--new-secondary", dest="dst_node", help="Specifies the new secondary node", metavar="NODE", default=None, diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py index 66d030f7fb965c93e6861dd62ed3a89e13c15de6..8b2524f0e57c77c1f0790bd405d92fe5b39f05f4 100644 --- a/lib/client/gnt_instance.py +++ b/lib/client/gnt_instance.py @@ -755,6 +755,12 @@ def FailoverInstance(opts, args): cl = GetClient() instance_name = args[0] force = opts.force + iallocator = opts.iallocator + target_node = opts.dst_node + + if iallocator and target_node: + raise errors.OpPrereqError("Specify either an iallocator (-I), or a target" + " node (-n) but not both", errors.ECODE_INVAL) if not force: _EnsureInstancesExist(cl, [instance_name]) @@ -767,7 +773,9 @@ def FailoverInstance(opts, args): op = opcodes.OpInstanceFailover(instance_name=instance_name, ignore_consistency=opts.ignore_consistency, - shutdown_timeout=opts.shutdown_timeout) + shutdown_timeout=opts.shutdown_timeout, + iallocator=iallocator, + target_node=target_node) SubmitOrSend(op, opts, cl=cl) return 0 @@ -787,6 +795,12 @@ def MigrateInstance(opts, args): cl = GetClient() instance_name = args[0] force = opts.force + iallocator = opts.iallocator + target_node = opts.dst_node + + if iallocator and target_node: + raise errors.OpPrereqError("Specify either an iallocator (-I), or a target" + " node (-n) but not both", errors.ECODE_INVAL) if not force: _EnsureInstancesExist(cl, [instance_name]) @@ -814,7 +828,8 @@ def MigrateInstance(opts, args): mode = opts.migration_mode op = opcodes.OpInstanceMigrate(instance_name=instance_name, mode=mode, - cleanup=opts.cleanup) + cleanup=opts.cleanup, iallocator=iallocator, + target_node=target_node) SubmitOpCode(op, cl=cl, opts=opts) return 0 @@ -1344,15 +1359,15 @@ commands = { 'failover': ( FailoverInstance, ARGS_ONE_INSTANCE, [FORCE_OPT, IGNORE_CONSIST_OPT, SUBMIT_OPT, SHUTDOWN_TIMEOUT_OPT, - DRY_RUN_OPT, PRIORITY_OPT], + DRY_RUN_OPT, PRIORITY_OPT, DST_NODE_OPT, IALLOCATOR_OPT], "[-f] <instance>", "Stops the instance and starts it on the backup node," - " using the remote mirror (only for instances of type drbd)"), + " using the remote mirror (only for mirrored instances)"), 'migrate': ( MigrateInstance, ARGS_ONE_INSTANCE, [FORCE_OPT, NONLIVE_OPT, MIGRATION_MODE_OPT, CLEANUP_OPT, DRY_RUN_OPT, - PRIORITY_OPT], + PRIORITY_OPT, DST_NODE_OPT, IALLOCATOR_OPT], "[-f] <instance>", "Migrate instance to its secondary node" - " (only for instances of type drbd)"), + " (only for mirrored instances)"), 'move': ( MoveInstance, ARGS_ONE_INSTANCE, [FORCE_OPT, SUBMIT_OPT, SINGLE_NODE_OPT, SHUTDOWN_TIMEOUT_OPT, diff --git a/lib/client/gnt_node.py b/lib/client/gnt_node.py index d88c517aa2dd41a5ff5acd8bb4251f41bcae3e1c..8420c88c72838279ae2d08a4ebf53614e66960cb 100644 --- a/lib/client/gnt_node.py +++ b/lib/client/gnt_node.py @@ -338,7 +338,8 @@ def FailoverNode(opts, args): jex = JobExecutor(cl=cl, opts=opts) for iname in pinst: op = opcodes.OpInstanceFailover(instance_name=iname, - ignore_consistency=opts.ignore_consistency) + ignore_consistency=opts.ignore_consistency, + iallocator=opts.iallocator) jex.QueueJob(iname, op) results = jex.GetResults() bad_cnt = len([row for row in results if not row[0]]) @@ -380,7 +381,8 @@ def MigrateNode(opts, args): mode = constants.HT_MIGRATION_NONLIVE else: mode = opts.migration_mode - op = opcodes.OpNodeMigrate(node_name=args[0], mode=mode) + op = opcodes.OpNodeMigrate(node_name=args[0], mode=mode, + iallocator=opts.iallocator) SubmitOpCode(op, cl=cl, opts=opts) @@ -815,13 +817,15 @@ commands = { "Relocate the secondary instances from a node" " to other nodes (only for instances with drbd disk template)"), 'failover': ( - FailoverNode, ARGS_ONE_NODE, [FORCE_OPT, IGNORE_CONSIST_OPT, PRIORITY_OPT], + FailoverNode, ARGS_ONE_NODE, [FORCE_OPT, IGNORE_CONSIST_OPT, + IALLOCATOR_OPT, PRIORITY_OPT], "[-f] <node>", "Stops the primary instances on a node and start them on their" " secondary node (only for instances with drbd disk template)"), 'migrate': ( MigrateNode, ARGS_ONE_NODE, - [FORCE_OPT, NONLIVE_OPT, MIGRATION_MODE_OPT, PRIORITY_OPT], + [FORCE_OPT, NONLIVE_OPT, MIGRATION_MODE_OPT, + IALLOCATOR_OPT, PRIORITY_OPT], "[-f] <node>", "Migrate all the primary instance on a node away from it" " (only for instances of type drbd)"),