diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index 0a96eb86de..c3aec0ed70 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -2064,6 +2064,44 @@ class AbortMigration(command.Command): server.id, parsed_args.migration) +class ForceCompleteMigration(command.Command): + """Force an ongoing live migration to complete. + + This command requires ``--os-compute-api-version`` 2.22 or greater. + """ + + def get_parser(self, prog_name): + parser = super(ForceCompleteMigration, self).get_parser(prog_name) + parser.add_argument( + 'server', + metavar='', + help=_('Server (name or ID)'), + ) + parser.add_argument( + 'migration', + metavar='', + help=_('Migration (ID)') + ) + return parser + + def take_action(self, parsed_args): + compute_client = self.app.client_manager.compute + + if compute_client.api_version < api_versions.APIVersion('2.22'): + msg = _( + '--os-compute-api-version 2.22 or greater is required to ' + 'support the server migration force complete command' + ) + raise exceptions.CommandError(msg) + + server = utils.find_resource( + compute_client.servers, + parsed_args.server, + ) + compute_client.server_migrations.live_migrate_force_complete( + server.id, parsed_args.migration) + + class PauseServer(command.Command): _description = _("Pause server(s)") diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py index 9ac2935236..3b98c873ec 100644 --- a/openstackclient/tests/unit/compute/v2/test_server.py +++ b/openstackclient/tests/unit/compute/v2/test_server.py @@ -4263,6 +4263,57 @@ class TestServerMigrationAbort(TestServer): str(ex)) +class TestServerMigrationForceComplete(TestServer): + + def setUp(self): + super(TestServerMigrationForceComplete, self).setUp() + + self.server = compute_fakes.FakeServer.create_one_server() + + # Return value for utils.find_resource for server. + self.servers_mock.get.return_value = self.server + + # Get the command object to test + self.cmd = server.ForceCompleteMigration(self.app, None) + + def test_migration_force_complete(self): + self.app.client_manager.compute.api_version = api_versions.APIVersion( + '2.22') + + arglist = [ + self.server.id, + '2', # arbitrary migration ID + ] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.servers_mock.get.assert_called_with(self.server.id) + self.server_migrations_mock.live_migrate_force_complete\ + .assert_called_with(self.server.id, '2',) + self.assertIsNone(result) + + def test_migration_force_complete_pre_v222(self): + self.app.client_manager.compute.api_version = api_versions.APIVersion( + '2.21') + + arglist = [ + self.server.id, + '2', # arbitrary migration ID + ] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + ex = self.assertRaises( + exceptions.CommandError, + self.cmd.take_action, + parsed_args) + self.assertIn( + '--os-compute-api-version 2.22 or greater is required', + str(ex)) + + class TestServerPause(TestServer): def setUp(self): diff --git a/releasenotes/notes/bug-2007513-ae39456aeb93bb98.yaml b/releasenotes/notes/bug-2007513-ae39456aeb93bb98.yaml new file mode 100644 index 0000000000..56de14b2c5 --- /dev/null +++ b/releasenotes/notes/bug-2007513-ae39456aeb93bb98.yaml @@ -0,0 +1,4 @@ +--- +features: + - Add ``server migration force complete`` command to force complete + ongoing live migrations. diff --git a/setup.cfg b/setup.cfg index 56934a192b..8363ec6cfd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -110,6 +110,7 @@ openstack.compute.v2 = server_migrate_revert = openstackclient.compute.v2.server:MigrateRevert server_migration_list = openstackclient.compute.v2.server:ListMigration server_migration_abort = openstackclient.compute.v2.server:AbortMigration + server_migration_force_complete = openstackclient.compute.v2.server:ForceCompleteMigration server_pause = openstackclient.compute.v2.server:PauseServer server_reboot = openstackclient.compute.v2.server:RebootServer server_rebuild = openstackclient.compute.v2.server:RebuildServer