Support for forcing live migration to complete
In API microversion 2.22 in Nova there is new ServerMigrations resource that allows opertators to force on-going live migration to complete: https://review.openstack.org/#/c/245921/ This patch implements new method in python-novaclient to take advantage of the new API: nova live-migration-force-complete <instance_id/name> <migration_id> Change-Id: I823c20b4e0c7b63e905f564a7dff13d3fb314a26 Implements blueprint pause-vm-during-live-migration
This commit is contained in:
parent
cd88097ff5
commit
62c76301a2
@ -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.21")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.22")
|
||||
|
27
novaclient/tests/unit/fixture_data/server_migrations.py
Normal file
27
novaclient/tests/unit/fixture_data/server_migrations.py
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright 2016 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from novaclient.tests.unit.fixture_data import base
|
||||
|
||||
|
||||
class Fixture(base.Fixture):
|
||||
base_url = 'servers'
|
||||
|
||||
def setUp(self):
|
||||
super(Fixture, self).setUp()
|
||||
url = self.url('1234', 'migrations', '1', 'action')
|
||||
self.requests.register_uri('POST', url,
|
||||
status_code=202,
|
||||
headers=self.json_headers)
|
@ -2432,6 +2432,9 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
self, **kw):
|
||||
return (202, {}, None)
|
||||
|
||||
def post_servers_1234_migrations_1_action(self, body):
|
||||
return (202, {}, None)
|
||||
|
||||
|
||||
class FakeSessionClient(fakes.FakeClient, client.Client):
|
||||
|
||||
|
33
novaclient/tests/unit/v2/test_server_migrations.py
Normal file
33
novaclient/tests/unit/v2/test_server_migrations.py
Normal file
@ -0,0 +1,33 @@
|
||||
# Copyright 2016 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from novaclient import api_versions
|
||||
from novaclient.tests.unit.fixture_data import client
|
||||
from novaclient.tests.unit.fixture_data import server_migrations as data
|
||||
from novaclient.tests.unit import utils
|
||||
|
||||
|
||||
class ServerMigrationsTest(utils.FixturedTestCase):
|
||||
client_fixture_class = client.V1
|
||||
data_fixture_class = data.Fixture
|
||||
|
||||
def setUp(self):
|
||||
super(ServerMigrationsTest, self).setUp()
|
||||
self.cs.api_version = api_versions.APIVersion("2.22")
|
||||
|
||||
def test_live_migration_force_complete(self):
|
||||
body = {'force_complete': None}
|
||||
self.cs.server_migrations.live_migrate_force_complete(1234, 1)
|
||||
self.assert_called('POST', '/servers/1234/migrations/1/action', body)
|
@ -1681,6 +1681,12 @@ class ShellTest(utils.TestCase):
|
||||
'block_migration': True,
|
||||
'disk_over_commit': True}})
|
||||
|
||||
def test_live_migration_force_complete(self):
|
||||
self.run_command('live-migration-force-complete sample-server 1',
|
||||
api_version='2.22')
|
||||
self.assert_called('POST', '/servers/1234/migrations/1/action',
|
||||
{'force_complete': None})
|
||||
|
||||
def test_host_evacuate_live_with_no_target_host(self):
|
||||
self.run_command('host-evacuate-live hyper')
|
||||
self.assert_called('GET', '/os-hypervisors/hyper/servers', pos=0)
|
||||
|
@ -41,6 +41,7 @@ from novaclient.v2 import security_group_default_rules
|
||||
from novaclient.v2 import security_group_rules
|
||||
from novaclient.v2 import security_groups
|
||||
from novaclient.v2 import server_groups
|
||||
from novaclient.v2 import server_migrations
|
||||
from novaclient.v2 import servers
|
||||
from novaclient.v2 import services
|
||||
from novaclient.v2 import usage
|
||||
@ -167,6 +168,8 @@ class Client(object):
|
||||
self.availability_zones = \
|
||||
availability_zones.AvailabilityZoneManager(self)
|
||||
self.server_groups = server_groups.ServerGroupsManager(self)
|
||||
self.server_migrations = \
|
||||
server_migrations.ServerMigrationsManager(self)
|
||||
|
||||
# Add in any extensions...
|
||||
if extensions:
|
||||
|
42
novaclient/v2/server_migrations.py
Normal file
42
novaclient/v2/server_migrations.py
Normal file
@ -0,0 +1,42 @@
|
||||
# Copyright 2016 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from novaclient import api_versions
|
||||
from novaclient import base
|
||||
|
||||
|
||||
class ServerMigration(base.Resource):
|
||||
def __repr__(self):
|
||||
return "<ServerMigration>"
|
||||
|
||||
|
||||
class ServerMigrationsManager(base.Manager):
|
||||
resource_class = ServerMigration
|
||||
|
||||
@api_versions.wraps("2.22")
|
||||
def live_migrate_force_complete(self, server, migration):
|
||||
"""
|
||||
Force on-going live migration to complete
|
||||
|
||||
:param server: The :class:`Server` (or its ID)
|
||||
:param migration: Migration id that will be forced to complete
|
||||
:returns: An instance of novaclient.base.TupleWithMeta
|
||||
"""
|
||||
body = {'force_complete': None}
|
||||
resp, body = self.api.client.post(
|
||||
'/servers/%s/migrations/%s/action' % (base.getid(server),
|
||||
base.getid(migration)),
|
||||
body=body)
|
||||
return self.convert_into_with_meta(body, resp)
|
@ -3838,6 +3838,15 @@ def do_live_migration(cs, args):
|
||||
args.disk_over_commit)
|
||||
|
||||
|
||||
@api_versions.wraps("2.22")
|
||||
@cliutils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||
@cliutils.arg('migration', metavar='<migration>', help=_('ID of migration.'))
|
||||
def do_live_migration_force_complete(cs, args):
|
||||
"""Force on-going live migration to complete."""
|
||||
server = _find_server(cs, args.server)
|
||||
cs.server_migrations.live_migrate_force_complete(server, args.migration)
|
||||
|
||||
|
||||
@cliutils.arg(
|
||||
'--all-tenants',
|
||||
action='store_const',
|
||||
|
Loading…
x
Reference in New Issue
Block a user