diff options
author | Pawel Koniszewski <pawel.koniszewski@intel.com> | 2016-02-15 19:34:44 +0100 |
---|---|---|
committer | Paul Murray <pmurray@hpe.com> | 2016-02-25 13:59:11 +0000 |
commit | 62c76301a281b41282531f6419d55823106270d1 (patch) | |
tree | c4d92be1c6e5c5c0e276a8df5a273d65c6b62219 | |
parent | cd88097ff59ad40002ac4f624b53efe72bc84386 (diff) | |
download | python-novaclient-62c76301a281b41282531f6419d55823106270d1.tar.gz |
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
-rw-r--r-- | novaclient/__init__.py | 2 | ||||
-rw-r--r-- | novaclient/tests/unit/fixture_data/server_migrations.py | 27 | ||||
-rw-r--r-- | novaclient/tests/unit/v2/fakes.py | 3 | ||||
-rw-r--r-- | novaclient/tests/unit/v2/test_server_migrations.py | 33 | ||||
-rw-r--r-- | novaclient/tests/unit/v2/test_shell.py | 6 | ||||
-rw-r--r-- | novaclient/v2/client.py | 3 | ||||
-rw-r--r-- | novaclient/v2/server_migrations.py | 42 | ||||
-rw-r--r-- | novaclient/v2/shell.py | 9 |
8 files changed, 124 insertions, 1 deletions
diff --git a/novaclient/__init__.py b/novaclient/__init__.py index f5588d09..509d2a20 100644 --- a/novaclient/__init__.py +++ b/novaclient/__init__.py @@ -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") diff --git a/novaclient/tests/unit/fixture_data/server_migrations.py b/novaclient/tests/unit/fixture_data/server_migrations.py new file mode 100644 index 00000000..3aed49a5 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/server_migrations.py @@ -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) diff --git a/novaclient/tests/unit/v2/fakes.py b/novaclient/tests/unit/v2/fakes.py index e0efff06..d3d1e405 100644 --- a/novaclient/tests/unit/v2/fakes.py +++ b/novaclient/tests/unit/v2/fakes.py @@ -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): diff --git a/novaclient/tests/unit/v2/test_server_migrations.py b/novaclient/tests/unit/v2/test_server_migrations.py new file mode 100644 index 00000000..12c5a269 --- /dev/null +++ b/novaclient/tests/unit/v2/test_server_migrations.py @@ -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) diff --git a/novaclient/tests/unit/v2/test_shell.py b/novaclient/tests/unit/v2/test_shell.py index eb86eee9..cb30ce40 100644 --- a/novaclient/tests/unit/v2/test_shell.py +++ b/novaclient/tests/unit/v2/test_shell.py @@ -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) diff --git a/novaclient/v2/client.py b/novaclient/v2/client.py index a3ec98fe..56339a34 100644 --- a/novaclient/v2/client.py +++ b/novaclient/v2/client.py @@ -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: diff --git a/novaclient/v2/server_migrations.py b/novaclient/v2/server_migrations.py new file mode 100644 index 00000000..476c0a80 --- /dev/null +++ b/novaclient/v2/server_migrations.py @@ -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) diff --git a/novaclient/v2/shell.py b/novaclient/v2/shell.py index 95b892d8..d5087ca6 100644 --- a/novaclient/v2/shell.py +++ b/novaclient/v2/shell.py @@ -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', |