compute: Add 'server migration show' command

This replaces the 'server-migration-show' command provided by
novaclient.

Change-Id: I413310b481cc13b70853eb579417f6e6fad10d98
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
Stephen Finucane 2021-01-20 10:11:37 +00:00
parent 32ae1857d1
commit f80fe2d8cf
5 changed files with 242 additions and 1 deletions

View File

@ -2603,6 +2603,70 @@ class ListMigration(command.Lister):
return self.print_migrations(parsed_args, compute_client, migrations) return self.print_migrations(parsed_args, compute_client, migrations)
class ShowMigration(command.Command):
"""Show a migration for a given server."""
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
parser.add_argument(
'server',
metavar='<server>',
help=_('Server (name or ID)'),
)
parser.add_argument(
'migration',
metavar='<migration>',
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.24'):
msg = _(
'--os-compute-api-version 2.24 or greater is required to '
'support the server migration show command'
)
raise exceptions.CommandError(msg)
server = utils.find_resource(
compute_client.servers,
parsed_args.server,
)
server_migration = compute_client.server_migrations.get(
server.id, parsed_args.migration,
)
columns = (
'ID',
'Server UUID',
'Status',
'Source Compute',
'Source Node',
'Dest Compute',
'Dest Host',
'Dest Node',
'Memory Total Bytes',
'Memory Processed Bytes',
'Memory Remaining Bytes',
'Disk Total Bytes',
'Disk Processed Bytes',
'Disk Remaining Bytes',
'Created At',
'Updated At',
)
if compute_client.api_version >= api_versions.APIVersion('2.59'):
columns += ('UUID',)
if compute_client.api_version >= api_versions.APIVersion('2.80'):
columns += ('User ID', 'Project ID')
data = utils.get_item_properties(server_migration, columns)
return columns, data
class AbortMigration(command.Command): class AbortMigration(command.Command):
"""Cancel an ongoing live migration. """Cancel an ongoing live migration.

View File

@ -1633,6 +1633,59 @@ class FakeMigration(object):
return migrations return migrations
class FakeServerMigration(object):
"""Fake one or more server migrations."""
@staticmethod
def create_one_server_migration(attrs=None, methods=None):
"""Create a fake server migration.
:param Dictionary attrs:
A dictionary with all attributes
:param Dictionary methods:
A dictionary with all methods
:return:
A FakeResource object, with id, type, and so on
"""
attrs = attrs or {}
methods = methods or {}
# Set default attributes.
migration_info = {
"created_at": "2016-01-29T13:42:02.000000",
"dest_compute": "compute2",
"dest_host": "1.2.3.4",
"dest_node": "node2",
"id": random.randint(1, 999),
"server_uuid": uuid.uuid4().hex,
"source_compute": "compute1",
"source_node": "node1",
"status": "running",
"memory_total_bytes": random.randint(1, 99999),
"memory_processed_bytes": random.randint(1, 99999),
"memory_remaining_bytes": random.randint(1, 99999),
"disk_total_bytes": random.randint(1, 99999),
"disk_processed_bytes": random.randint(1, 99999),
"disk_remaining_bytes": random.randint(1, 99999),
"updated_at": "2016-01-29T13:42:02.000000",
# added in 2.59
"uuid": uuid.uuid4().hex,
# added in 2.80
"user_id": uuid.uuid4().hex,
"project_id": uuid.uuid4().hex,
}
# Overwrite default attributes.
migration_info.update(attrs)
migration = fakes.FakeResource(
info=copy.deepcopy(migration_info),
methods=methods,
loaded=True)
return migration
class FakeVolumeAttachment(object): class FakeVolumeAttachment(object):
"""Fake one or more volume attachments (BDMs).""" """Fake one or more volume attachments (BDMs)."""

View File

@ -4888,6 +4888,124 @@ class TestListMigrationV280(TestListMigration):
str(ex)) str(ex))
class TestServerMigrationShow(TestServer):
def setUp(self):
super().setUp()
self.server = compute_fakes.FakeServer.create_one_server()
self.servers_mock.get.return_value = self.server
self.server_migration = compute_fakes.FakeServerMigration\
.create_one_server_migration()
self.server_migrations_mock.get.return_value = self.server_migration
self.columns = (
'ID',
'Server UUID',
'Status',
'Source Compute',
'Source Node',
'Dest Compute',
'Dest Host',
'Dest Node',
'Memory Total Bytes',
'Memory Processed Bytes',
'Memory Remaining Bytes',
'Disk Total Bytes',
'Disk Processed Bytes',
'Disk Remaining Bytes',
'Created At',
'Updated At',
)
self.data = (
self.server_migration.id,
self.server_migration.server_uuid,
self.server_migration.status,
self.server_migration.source_compute,
self.server_migration.source_node,
self.server_migration.dest_compute,
self.server_migration.dest_host,
self.server_migration.dest_node,
self.server_migration.memory_total_bytes,
self.server_migration.memory_processed_bytes,
self.server_migration.memory_remaining_bytes,
self.server_migration.disk_total_bytes,
self.server_migration.disk_processed_bytes,
self.server_migration.disk_remaining_bytes,
self.server_migration.created_at,
self.server_migration.updated_at,
)
# Get the command object to test
self.cmd = server.ShowMigration(self.app, None)
def _test_server_migration_show(self):
arglist = [
self.server.id,
'2', # arbitrary migration ID
]
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
self.servers_mock.get.assert_called_with(self.server.id)
self.server_migrations_mock.get.assert_called_with(
self.server.id, '2',)
def test_server_migration_show(self):
self.app.client_manager.compute.api_version = api_versions.APIVersion(
'2.24')
self._test_server_migration_show()
def test_server_migration_show_v259(self):
self.app.client_manager.compute.api_version = api_versions.APIVersion(
'2.59')
self.columns += ('UUID',)
self.data += (self.server_migration.uuid,)
self._test_server_migration_show()
def test_server_migration_show_v280(self):
self.app.client_manager.compute.api_version = api_versions.APIVersion(
'2.80')
self.columns += ('UUID', 'User ID', 'Project ID')
self.data += (
self.server_migration.uuid,
self.server_migration.user_id,
self.server_migration.project_id,
)
self._test_server_migration_show()
def test_server_migration_show_pre_v224(self):
self.app.client_manager.compute.api_version = api_versions.APIVersion(
'2.23')
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.24 or greater is required',
str(ex))
class TestServerMigrationAbort(TestServer): class TestServerMigrationAbort(TestServer):
def setUp(self): def setUp(self):

View File

@ -0,0 +1,5 @@
---
features:
- |
Add ``server migration show`` commands. This can be used to show detailed
information about an ongoing server migration.

View File

@ -110,9 +110,10 @@ openstack.compute.v2 =
server_migrate = openstackclient.compute.v2.server:MigrateServer server_migrate = openstackclient.compute.v2.server:MigrateServer
server_migrate_confirm = openstackclient.compute.v2.server:MigrateConfirm server_migrate_confirm = openstackclient.compute.v2.server:MigrateConfirm
server_migrate_revert = openstackclient.compute.v2.server:MigrateRevert 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_abort = openstackclient.compute.v2.server:AbortMigration
server_migration_force_complete = openstackclient.compute.v2.server:ForceCompleteMigration server_migration_force_complete = openstackclient.compute.v2.server:ForceCompleteMigration
server_migration_list = openstackclient.compute.v2.server:ListMigration
server_migration_show = openstackclient.compute.v2.server:ShowMigration
server_pause = openstackclient.compute.v2.server:PauseServer server_pause = openstackclient.compute.v2.server:PauseServer
server_reboot = openstackclient.compute.v2.server:RebootServer server_reboot = openstackclient.compute.v2.server:RebootServer
server_rebuild = openstackclient.compute.v2.server:RebuildServer server_rebuild = openstackclient.compute.v2.server:RebuildServer