Microversion 2.56 - Enable cold migration with target host
Change-Id: I4deea811ffae3e7944d5ec10ca0bbf2bfa056a7c Implements: blueprint cold-migration-with-target-queens
This commit is contained in:
parent
d18436ca5d
commit
e5e8cebc81
@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
|
||||
# when client supported the max version, and bumped sequentially, otherwise
|
||||
# the client may break due to server side new version may include some
|
||||
# backward incompatible change.
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.55")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.56")
|
||||
|
@ -452,6 +452,8 @@ class V1(Base):
|
||||
# but we can not specify version in data_fixture now and this is
|
||||
# V1 data, so just let it pass
|
||||
pass
|
||||
elif action == 'migrate':
|
||||
return None
|
||||
elif action == 'rebuild':
|
||||
body = body[action]
|
||||
adminPass = body.get('adminPass', 'randompassword')
|
||||
|
@ -687,7 +687,7 @@ class FakeSessionClient(base_client.SessionClient):
|
||||
# Server actions
|
||||
#
|
||||
|
||||
none_actions = ['revertResize', 'migrate', 'os-stop', 'os-start',
|
||||
none_actions = ['revertResize', 'os-stop', 'os-start',
|
||||
'forceDelete', 'restore', 'pause', 'unpause', 'unlock',
|
||||
'unrescue', 'resume', 'suspend', 'lock', 'shelve',
|
||||
'shelveOffload', 'unshelve', 'resetNetwork']
|
||||
@ -749,6 +749,15 @@ class FakeSessionClient(base_client.SessionClient):
|
||||
if self.api_version < api_versions.APIVersion("2.25"):
|
||||
expected.add('disk_over_commit')
|
||||
assert set(body[action].keys()) == expected
|
||||
elif action == 'migrate':
|
||||
if self.api_version < api_versions.APIVersion("2.56"):
|
||||
assert body[action] is None
|
||||
else:
|
||||
expected = set()
|
||||
if 'host' in body[action].keys():
|
||||
# host can be optional
|
||||
expected.add('host')
|
||||
assert set(body[action].keys()) == expected
|
||||
elif action == 'rebuild':
|
||||
body = body[action]
|
||||
adminPass = body.get('adminPass', 'randompassword')
|
||||
|
@ -1581,3 +1581,26 @@ class ServersV254Test(ServersV252Test):
|
||||
'1234', fakes.FAKE_IMAGE_UUID_1,
|
||||
key_name='test_keypair')
|
||||
self.assertIn('key_name', six.text_type(ex.message))
|
||||
|
||||
|
||||
class ServersV256Test(ServersV254Test):
|
||||
|
||||
api_version = "2.56"
|
||||
|
||||
def test_migrate_server(self):
|
||||
s = self.cs.servers.get(1234)
|
||||
ret = s.migrate()
|
||||
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'migrate': {}})
|
||||
ret = s.migrate(host='target-host')
|
||||
self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'migrate': {'host': 'target-host'}})
|
||||
|
||||
def test_migrate_server_pre_256_fails(self):
|
||||
self.cs.api_version = api_versions.APIVersion('2.55')
|
||||
s = self.cs.servers.get(1234)
|
||||
ex = self.assertRaises(TypeError,
|
||||
s.migrate, host='target-host')
|
||||
self.assertIn('host', six.text_type(ex))
|
||||
|
@ -1628,6 +1628,23 @@ class ShellTest(utils.TestCase):
|
||||
self.run_command('migrate sample-server')
|
||||
self.assert_called('POST', '/servers/1234/action', {'migrate': None})
|
||||
|
||||
def test_migrate_pre_v256(self):
|
||||
self.assertRaises(SystemExit,
|
||||
self.run_command,
|
||||
'migrate --host target-host sample-server',
|
||||
api_version='2.55')
|
||||
|
||||
def test_migrate_v256(self):
|
||||
self.run_command('migrate sample-server',
|
||||
api_version='2.56')
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'migrate': {}})
|
||||
|
||||
self.run_command('migrate --host target-host sample-server',
|
||||
api_version='2.56')
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
{'migrate': {'host': 'target-host'}})
|
||||
|
||||
def test_resize(self):
|
||||
self.run_command('resize sample-server 1')
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
|
@ -327,6 +327,7 @@ class Server(base.Resource):
|
||||
"""Diagnostics -- Retrieve server diagnostics."""
|
||||
return self.manager.diagnostics(self)
|
||||
|
||||
@api_versions.wraps("2.0", "2.55")
|
||||
def migrate(self):
|
||||
"""
|
||||
Migrate a server to a new host.
|
||||
@ -335,6 +336,16 @@ class Server(base.Resource):
|
||||
"""
|
||||
return self.manager.migrate(self)
|
||||
|
||||
@api_versions.wraps("2.56")
|
||||
def migrate(self, host=None):
|
||||
"""
|
||||
Migrate a server to a new host.
|
||||
|
||||
:param host: (Optional) The target host.
|
||||
:returns: An instance of novaclient.base.TupleWithMeta
|
||||
"""
|
||||
return self.manager.migrate(self, host=host)
|
||||
|
||||
def remove_fixed_ip(self, address):
|
||||
"""
|
||||
Remove an IP address.
|
||||
@ -1545,6 +1556,7 @@ class ServerManager(base.BootingManagerWithFind):
|
||||
body, **kwargs)
|
||||
return Server(self, body['server'], resp=resp)
|
||||
|
||||
@api_versions.wraps("2.0", "2.55")
|
||||
def migrate(self, server):
|
||||
"""
|
||||
Migrate a server to a new host.
|
||||
@ -1554,6 +1566,22 @@ class ServerManager(base.BootingManagerWithFind):
|
||||
"""
|
||||
return self._action('migrate', server)
|
||||
|
||||
@api_versions.wraps("2.56")
|
||||
def migrate(self, server, host=None):
|
||||
"""
|
||||
Migrate a server to a new host.
|
||||
|
||||
:param server: The :class:`Server` (or its ID).
|
||||
:param host: (Optional) The target host.
|
||||
:returns: An instance of novaclient.base.TupleWithMeta
|
||||
"""
|
||||
info = {}
|
||||
|
||||
if host:
|
||||
info['host'] = host
|
||||
|
||||
return self._action('migrate', server, info)
|
||||
|
||||
def resize(self, server, flavor, disk_config=None, **kwargs):
|
||||
"""
|
||||
Resize a server's resources.
|
||||
|
@ -1950,6 +1950,12 @@ def do_resize_revert(cs, args):
|
||||
|
||||
|
||||
@utils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||
@utils.arg(
|
||||
'--host',
|
||||
metavar='<host>',
|
||||
default=None,
|
||||
help=_('Destination host name.'),
|
||||
start_version='2.56')
|
||||
@utils.arg(
|
||||
'--poll',
|
||||
dest='poll',
|
||||
@ -1957,9 +1963,13 @@ def do_resize_revert(cs, args):
|
||||
default=False,
|
||||
help=_('Report the server migration progress until it completes.'))
|
||||
def do_migrate(cs, args):
|
||||
"""Migrate a server. The new host will be selected by the scheduler."""
|
||||
"""Migrate a server."""
|
||||
update_kwargs = {}
|
||||
if 'host' in args and args.host:
|
||||
update_kwargs['host'] = args.host
|
||||
|
||||
server = _find_server(cs, args.server)
|
||||
server.migrate()
|
||||
server.migrate(**update_kwargs)
|
||||
|
||||
if args.poll:
|
||||
_poll_for_status(cs.servers.get, server.id, 'migrating',
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- Added a new ``--host`` option to ``nova migrate`` command
|
||||
in microversion 2.56. It enables administrators to specify
|
||||
a target host when cold migating a server. The target host will be
|
||||
validated by the scheduler. The target host cannot be the same as
|
||||
the current host on which the server is running and must be in the
|
||||
same cell that the server is currently in.
|
Loading…
Reference in New Issue
Block a user