compute: Migrate 'server migrate' to SDK

Change-Id: I56d31c2fd4f8bf19eedd8f9eecd8a41cdafc5b55
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane
2024-05-09 13:22:13 +01:00
parent abef798f30
commit c8621e5b8b
2 changed files with 152 additions and 101 deletions

View File

@@ -3139,11 +3139,10 @@ revert to release the new server and restart the old one."""
self.app.stdout.write('\rProgress: %s' % progress) self.app.stdout.write('\rProgress: %s' % progress)
self.app.stdout.flush() self.app.stdout.flush()
compute_client = self.app.client_manager.compute compute_client = self.app.client_manager.sdk_connection.compute
server = utils.find_resource( server = compute_client.find_server(
compute_client.servers, parsed_args.server, ignore_missing=False
parsed_args.server,
) )
if parsed_args.live_migration: if parsed_args.live_migration:
@@ -3151,9 +3150,7 @@ revert to release the new server and restart the old one."""
block_migration = parsed_args.block_migration block_migration = parsed_args.block_migration
if block_migration is None: if block_migration is None:
if compute_client.api_version < api_versions.APIVersion( if not sdk_utils.supports_microversion(compute_client, '2.25'):
'2.25'
):
block_migration = False block_migration = False
else: else:
block_migration = 'auto' block_migration = 'auto'
@@ -3166,10 +3163,8 @@ revert to release the new server and restart the old one."""
# want to support, so if the user is using --live-migration # want to support, so if the user is using --live-migration
# and --host, we want to enforce that they are using version # and --host, we want to enforce that they are using version
# 2.30 or greater. # 2.30 or greater.
if ( if parsed_args.host and not sdk_utils.supports_microversion(
parsed_args.host compute_client, '2.30'
and compute_client.api_version
< api_versions.APIVersion('2.30')
): ):
raise exceptions.CommandError( raise exceptions.CommandError(
'--os-compute-api-version 2.30 or greater is required ' '--os-compute-api-version 2.30 or greater is required '
@@ -3179,13 +3174,13 @@ revert to release the new server and restart the old one."""
# The host parameter is required in the API even if None. # The host parameter is required in the API even if None.
kwargs['host'] = parsed_args.host kwargs['host'] = parsed_args.host
if compute_client.api_version < api_versions.APIVersion('2.25'): if not sdk_utils.supports_microversion(compute_client, '2.25'):
kwargs['disk_over_commit'] = parsed_args.disk_overcommit kwargs['disk_overcommit'] = parsed_args.disk_overcommit
# We can't use an argparse default value because then we can't # We can't use an argparse default value because then we can't
# distinguish between explicit 'False' and unset for the below # distinguish between explicit 'False' and unset for the below
# case (microversion >= 2.25) # case (microversion >= 2.25)
if kwargs['disk_over_commit'] is None: if kwargs['disk_overcommit'] is None:
kwargs['disk_over_commit'] = False kwargs['disk_overcommit'] = False
elif parsed_args.disk_overcommit is not None: elif parsed_args.disk_overcommit is not None:
# TODO(stephenfin): Raise an error here in OSC 7.0 # TODO(stephenfin): Raise an error here in OSC 7.0
msg = _( msg = _(
@@ -3196,7 +3191,7 @@ revert to release the new server and restart the old one."""
) )
self.log.warning(msg) self.log.warning(msg)
server.live_migrate(**kwargs) compute_client.live_migrate_server(server, **kwargs)
else: # cold migration else: # cold migration
if parsed_args.block_migration or parsed_args.disk_overcommit: if parsed_args.block_migration or parsed_args.disk_overcommit:
raise exceptions.CommandError( raise exceptions.CommandError(
@@ -3205,9 +3200,7 @@ revert to release the new server and restart the old one."""
"specified" "specified"
) )
if parsed_args.host: if parsed_args.host:
if compute_client.api_version < api_versions.APIVersion( if not sdk_utils.supports_microversion(compute_client, '2.56'):
'2.56'
):
msg = _( msg = _(
'--os-compute-api-version 2.56 or greater is ' '--os-compute-api-version 2.56 or greater is '
'required to use --host without --live-migration.' 'required to use --host without --live-migration.'
@@ -3215,13 +3208,13 @@ revert to release the new server and restart the old one."""
raise exceptions.CommandError(msg) raise exceptions.CommandError(msg)
kwargs = {'host': parsed_args.host} if parsed_args.host else {} kwargs = {'host': parsed_args.host} if parsed_args.host else {}
server.migrate(**kwargs) compute_client.migrate_server(server, **kwargs)
if parsed_args.wait: if parsed_args.wait:
if utils.wait_for_status( if utils.wait_for_status(
compute_client.servers.get, compute_client.get_server,
server.id, server.id,
success_status=['active', 'verify_resize'], success_status=('active', 'verify_resize'),
callback=_show_progress, callback=_show_progress,
): ):
self.app.stdout.write( self.app.stdout.write(

View File

@@ -5616,17 +5616,10 @@ class TestServerMigrate(TestServer):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
methods = { self.server = compute_fakes.create_one_sdk_server()
'migrate': None, self.compute_sdk_client.find_server.return_value = self.server
'live_migrate': None, self.compute_sdk_client.migrate_server.return_value = None
} self.compute_sdk_client.live_migrate_server.return_value = None
self.server = compute_fakes.create_one_server(methods=methods)
# This is the return value for utils.find_resource()
self.servers_mock.get.return_value = self.server
self.servers_mock.migrate.return_value = None
self.servers_mock.live_migrate.return_value = None
# Get the command object to test # Get the command object to test
self.cmd = server.MigrateServer(self.app, None) self.cmd = server.MigrateServer(self.app, None)
@@ -5641,18 +5634,24 @@ class TestServerMigrate(TestServer):
('disk_overcommit', None), ('disk_overcommit', None),
('wait', False), ('wait', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.server.migrate.assert_called_with() self.server.id, ignore_missing=False
self.assertNotCalled(self.servers_mock.live_migrate) )
self.compute_sdk_client.migrate_server.assert_called_once_with(
self.server,
)
self.compute_sdk_client.live_migrate_server.assert_not_called()
self.assertIsNone(result) self.assertIsNone(result)
def test_server_migrate_with_host_2_56(self): def test_server_migrate_with_host(self):
# Tests that --host is allowed for a cold migration # Tests that --host is allowed for a cold migration
# for microversion 2.56 and greater. # for microversion 2.56 and greater.
self.set_compute_api_version('2.56')
arglist = [ arglist = [
'--host', '--host',
'fakehost', 'fakehost',
@@ -5665,15 +5664,17 @@ class TestServerMigrate(TestServer):
('disk_overcommit', None), ('disk_overcommit', None),
('wait', False), ('wait', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.set_compute_api_version('2.56')
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.server.migrate.assert_called_with(host='fakehost') self.server.id, ignore_missing=False
self.assertNotCalled(self.servers_mock.live_migrate) )
self.compute_sdk_client.migrate_server.assert_called_once_with(
self.server, host='fakehost'
)
self.compute_sdk_client.live_migrate_server.assert_not_called()
self.assertIsNone(result) self.assertIsNone(result)
def test_server_migrate_with_block_migration(self): def test_server_migrate_with_block_migration(self):
@@ -5687,15 +5688,17 @@ class TestServerMigrate(TestServer):
('disk_overcommit', None), ('disk_overcommit', None),
('wait', False), ('wait', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises( self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args exceptions.CommandError, self.cmd.take_action, parsed_args
) )
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.assertNotCalled(self.servers_mock.live_migrate) self.server.id, ignore_missing=False
self.assertNotCalled(self.servers_mock.migrate) )
self.compute_sdk_client.migrate_server.assert_not_called()
self.compute_sdk_client.live_migrate_server.assert_not_called()
def test_server_migrate_with_disk_overcommit(self): def test_server_migrate_with_disk_overcommit(self):
arglist = [ arglist = [
@@ -5708,19 +5711,23 @@ class TestServerMigrate(TestServer):
('disk_overcommit', True), ('disk_overcommit', True),
('wait', False), ('wait', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises( self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args exceptions.CommandError, self.cmd.take_action, parsed_args
) )
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.assertNotCalled(self.servers_mock.live_migrate) self.server.id, ignore_missing=False
self.assertNotCalled(self.servers_mock.migrate) )
self.compute_sdk_client.migrate_server.assert_not_called()
self.compute_sdk_client.live_migrate_server.assert_not_called()
def test_server_migrate_with_host_pre_v256(self): def test_server_migrate_with_host_pre_v256(self):
# Tests that --host is not allowed for a cold migration # Tests that --host is not allowed for a cold migration
# before microversion 2.56 (the test defaults to 2.1). # before microversion 2.56 (the test defaults to 2.1).
self.set_compute_api_version('2.55')
arglist = [ arglist = [
'--host', '--host',
'fakehost', 'fakehost',
@@ -5746,9 +5753,11 @@ class TestServerMigrate(TestServer):
str(ex), str(ex),
) )
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.assertNotCalled(self.servers_mock.live_migrate) self.server.id, ignore_missing=False
self.assertNotCalled(self.servers_mock.migrate) )
self.compute_sdk_client.migrate_server.assert_not_called()
self.compute_sdk_client.live_migrate_server.assert_not_called()
def test_server_live_migrate(self): def test_server_live_migrate(self):
# Tests the --live-migration option without --host or --live. # Tests the --live-migration option without --host or --live.
@@ -5763,19 +5772,26 @@ class TestServerMigrate(TestServer):
('disk_overcommit', None), ('disk_overcommit', None),
('wait', False), ('wait', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.server.live_migrate.assert_called_with( self.server.id, ignore_missing=False
block_migration=False, disk_over_commit=False, host=None
) )
self.assertNotCalled(self.servers_mock.migrate) self.compute_sdk_client.live_migrate_server.assert_called_once_with(
self.server,
block_migration=False,
host=None,
disk_overcommit=False,
)
self.compute_sdk_client.migrate_server.assert_not_called()
self.assertIsNone(result) self.assertIsNone(result)
def test_server_live_migrate_with_host(self): def test_server_live_migrate_with_host(self):
# This requires --os-compute-api-version >= 2.30 so the test uses 2.30. # This requires --os-compute-api-version >= 2.30 so the test uses 2.30.
self.set_compute_api_version('2.30')
arglist = [ arglist = [
'--live-migration', '--live-migration',
'--host', '--host',
@@ -5789,24 +5805,28 @@ class TestServerMigrate(TestServer):
('disk_overcommit', None), ('disk_overcommit', None),
('wait', False), ('wait', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.set_compute_api_version('2.30')
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.server.id, ignore_missing=False
)
# No disk_overcommit and block_migration defaults to auto with # No disk_overcommit and block_migration defaults to auto with
# microversion >= 2.25 # microversion >= 2.25
self.server.live_migrate.assert_called_with( self.compute_sdk_client.live_migrate_server.assert_called_once_with(
block_migration='auto', host='fakehost' self.server,
block_migration='auto',
host='fakehost',
) )
self.assertNotCalled(self.servers_mock.migrate) self.compute_sdk_client.migrate_server.assert_not_called()
self.assertIsNone(result) self.assertIsNone(result)
def test_server_live_migrate_with_host_pre_v230(self): def test_server_live_migrate_with_host_pre_v230(self):
# Tests that the --host option is not supported for --live-migration # Tests that the --host option is not supported for --live-migration
# before microversion 2.30 (the test defaults to 2.1). # before microversion 2.30 (the test defaults to 2.1).
self.set_compute_api_version('2.29')
arglist = [ arglist = [
'--live-migration', '--live-migration',
'--host', '--host',
@@ -5820,12 +5840,11 @@ class TestServerMigrate(TestServer):
('disk_overcommit', None), ('disk_overcommit', None),
('wait', False), ('wait', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
ex = self.assertRaises( ex = self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args exceptions.CommandError, self.cmd.take_action, parsed_args
) )
# Make sure it's the error we expect. # Make sure it's the error we expect.
self.assertIn( self.assertIn(
'--os-compute-api-version 2.30 or greater is required ' '--os-compute-api-version 2.30 or greater is required '
@@ -5833,11 +5852,15 @@ class TestServerMigrate(TestServer):
str(ex), str(ex),
) )
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.assertNotCalled(self.servers_mock.live_migrate) self.server.id, ignore_missing=False
self.assertNotCalled(self.servers_mock.migrate) )
self.compute_sdk_client.migrate_server.assert_not_called()
self.compute_sdk_client.live_migrate_server.assert_not_called()
def test_server_block_live_migrate(self): def test_server_block_live_migrate(self):
self.set_compute_api_version('2.24')
arglist = [ arglist = [
'--live-migration', '--live-migration',
'--block-migration', '--block-migration',
@@ -5851,18 +5874,25 @@ class TestServerMigrate(TestServer):
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.set_compute_api_version('2.24')
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.server.live_migrate.assert_called_with( self.server.id, ignore_missing=False
block_migration=True, disk_over_commit=False, host=None
) )
self.assertNotCalled(self.servers_mock.migrate) # No disk_overcommit and block_migration defaults to auto with
# microversion >= 2.25
self.compute_sdk_client.live_migrate_server.assert_called_once_with(
self.server,
block_migration=True,
disk_overcommit=False,
host=None,
)
self.compute_sdk_client.migrate_server.assert_not_called()
self.assertIsNone(result) self.assertIsNone(result)
def test_server_live_migrate_with_disk_overcommit(self): def test_server_live_migrate_with_disk_overcommit(self):
self.set_compute_api_version('2.24')
arglist = [ arglist = [
'--live-migration', '--live-migration',
'--disk-overcommit', '--disk-overcommit',
@@ -5874,20 +5904,25 @@ class TestServerMigrate(TestServer):
('disk_overcommit', True), ('disk_overcommit', True),
('wait', False), ('wait', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.set_compute_api_version('2.24')
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.server.live_migrate.assert_called_with( self.server.id, ignore_missing=False
block_migration=False, disk_over_commit=True, host=None
) )
self.assertNotCalled(self.servers_mock.migrate) self.compute_sdk_client.live_migrate_server.assert_called_once_with(
self.server,
block_migration=False,
disk_overcommit=True,
host=None,
)
self.compute_sdk_client.migrate_server.assert_not_called()
self.assertIsNone(result) self.assertIsNone(result)
def test_server_live_migrate_with_disk_overcommit_post_v224(self): def test_server_live_migrate_with_disk_overcommit_post_v224(self):
self.set_compute_api_version('2.25')
arglist = [ arglist = [
'--live-migration', '--live-migration',
'--disk-overcommit', '--disk-overcommit',
@@ -5899,20 +5934,23 @@ class TestServerMigrate(TestServer):
('disk_overcommit', True), ('disk_overcommit', True),
('wait', False), ('wait', False),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.set_compute_api_version('2.25')
with mock.patch.object(self.cmd.log, 'warning') as mock_warning: with mock.patch.object(self.cmd.log, 'warning') as mock_warning:
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
# There should be no 'disk_over_commit' value present self.server.id, ignore_missing=False
self.server.live_migrate.assert_called_with(
block_migration='auto', host=None
) )
self.assertNotCalled(self.servers_mock.migrate) # There should be no 'disk_over_commit' value present
self.compute_sdk_client.live_migrate_server.assert_called_once_with(
self.server,
block_migration='auto',
host=None,
)
self.compute_sdk_client.migrate_server.assert_not_called()
self.assertIsNone(result) self.assertIsNone(result)
# A warning should have been logged for using --disk-overcommit. # A warning should have been logged for using --disk-overcommit.
mock_warning.assert_called_once() mock_warning.assert_called_once()
self.assertIn( self.assertIn(
@@ -5932,13 +5970,23 @@ class TestServerMigrate(TestServer):
('disk_overcommit', None), ('disk_overcommit', None),
('wait', True), ('wait', True),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args) result = self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.server.migrate.assert_called_with() self.server.id, ignore_missing=False
self.assertNotCalled(self.servers_mock.live_migrate) )
self.compute_sdk_client.migrate_server.assert_called_once_with(
self.server,
)
self.compute_sdk_client.live_migrate_server.assert_not_called()
mock_wait_for_status.assert_called_once_with(
self.compute_sdk_client.get_server,
self.server.id,
success_status=('active', 'verify_resize'),
callback=mock.ANY,
)
self.assertIsNone(result) self.assertIsNone(result)
@mock.patch.object(common_utils, 'wait_for_status', return_value=False) @mock.patch.object(common_utils, 'wait_for_status', return_value=False)
@@ -5953,15 +6001,25 @@ class TestServerMigrate(TestServer):
('disk_overcommit', None), ('disk_overcommit', None),
('wait', True), ('wait', True),
] ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises( self.assertRaises(
exceptions.CommandError, self.cmd.take_action, parsed_args exceptions.CommandError, self.cmd.take_action, parsed_args
) )
self.servers_mock.get.assert_called_with(self.server.id) self.compute_sdk_client.find_server.assert_called_once_with(
self.server.migrate.assert_called_with() self.server.id, ignore_missing=False
self.assertNotCalled(self.servers_mock.live_migrate) )
self.compute_sdk_client.migrate_server.assert_called_once_with(
self.server,
)
self.compute_sdk_client.live_migrate_server.assert_not_called()
mock_wait_for_status.assert_called_once_with(
self.compute_sdk_client.get_server,
self.server.id,
success_status=('active', 'verify_resize'),
callback=mock.ANY,
)
class TestServerReboot(TestServer): class TestServerReboot(TestServer):