Add aggregate-cache-images command and client routines
This adds the ability to request image precache support for an aggregate in support of the matching server feature. Related to blueprint image-precache-support Depends-On: https://review.opendev.org/#/c/687140 Change-Id: Id354ccfa99e500a598685e6b794c12160ea2a990
This commit is contained in:
parent
e1bb4378db
commit
71c29a184b
@ -73,6 +73,9 @@ nova usage
|
||||
``aggregate-add-host``
|
||||
Add the host to the specified aggregate.
|
||||
|
||||
``aggregate-cache-images``
|
||||
Request images be pre-cached on hosts within an aggregate.
|
||||
|
||||
``aggregate-create``
|
||||
Create a new aggregate with the specified
|
||||
details.
|
||||
@ -756,6 +759,25 @@ Add the host to the specified aggregate.
|
||||
``<host>``
|
||||
The host to add to the aggregate.
|
||||
|
||||
.. _nova_aggregate-cache-images:
|
||||
|
||||
nova aggregate-cache-images
|
||||
---------------------------
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
usage: nova aggregate-cache-images <aggregate> <image> [<image> ..]
|
||||
|
||||
Request image(s) be pre-cached on hosts within the aggregate.
|
||||
|
||||
**Positional arguments:**
|
||||
|
||||
``<aggregate>``
|
||||
Name or ID of aggregate.
|
||||
|
||||
``<image>``
|
||||
Name or ID of image(s) to cache.
|
||||
|
||||
.. _nova_aggregate-create:
|
||||
|
||||
nova aggregate-create
|
||||
|
@ -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.80")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.81")
|
||||
|
@ -51,3 +51,10 @@ class Fixture(base.Fixture):
|
||||
|
||||
self.requests_mock.delete(self.url(1), status_code=202,
|
||||
headers=self.json_headers)
|
||||
|
||||
self.requests_mock.register_uri('POST', self.url(1),
|
||||
json={},
|
||||
headers=self.json_headers)
|
||||
self.requests_mock.post(self.url(1, 'images'),
|
||||
json={},
|
||||
headers=self.json_headers)
|
||||
|
@ -1734,6 +1734,9 @@ class FakeSessionClient(base_client.SessionClient):
|
||||
def delete_os_aggregates_1(self, **kw):
|
||||
return (202, {}, None)
|
||||
|
||||
def post_os_aggregates_1_images(self, body, **kw):
|
||||
return (202, {}, None)
|
||||
|
||||
#
|
||||
# Services
|
||||
#
|
||||
|
@ -13,11 +13,14 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from novaclient import api_versions
|
||||
from novaclient import exceptions
|
||||
from novaclient.tests.unit.fixture_data import aggregates as data
|
||||
from novaclient.tests.unit.fixture_data import client
|
||||
from novaclient.tests.unit import utils
|
||||
from novaclient.tests.unit.v2 import fakes
|
||||
from novaclient.v2 import aggregates
|
||||
from novaclient.v2 import images
|
||||
|
||||
|
||||
class AggregatesTest(utils.FixturedTestCase):
|
||||
@ -161,3 +164,40 @@ class AggregatesTest(utils.FixturedTestCase):
|
||||
result3 = self.cs.aggregates.delete(aggregate)
|
||||
self.assert_request_id(result3, fakes.FAKE_REQUEST_ID_LIST)
|
||||
self.assert_called('DELETE', '/os-aggregates/1')
|
||||
|
||||
|
||||
class AggregatesV281Test(utils.FixturedTestCase):
|
||||
api_version = "2.81"
|
||||
data_fixture_class = data.Fixture
|
||||
|
||||
scenarios = [('original', {'client_fixture_class': client.V1}),
|
||||
('session', {'client_fixture_class': client.SessionV1})]
|
||||
|
||||
def setUp(self):
|
||||
super(AggregatesV281Test, self).setUp()
|
||||
self.cs.api_version = api_versions.APIVersion(self.api_version)
|
||||
|
||||
def test_cache_images(self):
|
||||
aggregate = self.cs.aggregates.list()[0]
|
||||
_images = [images.Image(self.cs.aggregates, {'id': '1'}),
|
||||
images.Image(self.cs.aggregates, {'id': '2'})]
|
||||
aggregate.cache_images(_images)
|
||||
expected_body = {'cache': [{'id': image.id}
|
||||
for image in _images]}
|
||||
self.assert_called('POST', '/os-aggregates/1/images',
|
||||
expected_body)
|
||||
|
||||
def test_cache_images_just_ids(self):
|
||||
aggregate = self.cs.aggregates.list()[0]
|
||||
_images = ['1']
|
||||
aggregate.cache_images(_images)
|
||||
expected_body = {'cache': [{'id': '1'}]}
|
||||
self.assert_called('POST', '/os-aggregates/1/images',
|
||||
expected_body)
|
||||
|
||||
def test_cache_images_pre281(self):
|
||||
self.cs.api_version = api_versions.APIVersion('2.80')
|
||||
aggregate = self.cs.aggregates.list()[0]
|
||||
_images = [images.Image(self.cs.aggregates, {'id': '1'})]
|
||||
self.assertRaises(exceptions.VersionNotFoundForAPIMethod,
|
||||
aggregate.cache_images, _images)
|
||||
|
@ -2884,6 +2884,30 @@ class ShellTest(utils.TestCase):
|
||||
self.run_command('aggregate-show test')
|
||||
self.assert_called('GET', '/os-aggregates')
|
||||
|
||||
def test_aggregate_cache_images(self):
|
||||
self.run_command(
|
||||
'aggregate-cache-images 1 %s %s' % (
|
||||
FAKE_UUID_1, FAKE_UUID_2),
|
||||
api_version='2.81')
|
||||
body = {
|
||||
'cache': [{'id': FAKE_UUID_1},
|
||||
{'id': FAKE_UUID_2}],
|
||||
}
|
||||
self.assert_called('POST', '/os-aggregates/1/images', body)
|
||||
|
||||
def test_aggregate_cache_images_no_images(self):
|
||||
self.assertRaises(SystemExit,
|
||||
self.run_command,
|
||||
'aggregate-cache-images 1',
|
||||
api_version='2.81')
|
||||
|
||||
def test_aggregate_cache_images_pre281(self):
|
||||
self.assertRaises(SystemExit,
|
||||
self.run_command,
|
||||
'aggregate-cache-images 1 %s %s' % (
|
||||
FAKE_UUID_1, FAKE_UUID_2),
|
||||
api_version='2.80')
|
||||
|
||||
def test_live_migration(self):
|
||||
self.run_command('live-migration sample-server hostname')
|
||||
self.assert_called('POST', '/servers/1234/action',
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
"""Aggregate interface."""
|
||||
|
||||
from novaclient import api_versions
|
||||
from novaclient import base
|
||||
|
||||
|
||||
@ -45,6 +46,10 @@ class Aggregate(base.Resource):
|
||||
"""
|
||||
return self.manager.delete(self)
|
||||
|
||||
@api_versions.wraps("2.81")
|
||||
def cache_images(self, images):
|
||||
return self.manager.cache_images(self, images)
|
||||
|
||||
|
||||
class AggregateManager(base.ManagerWithFind):
|
||||
resource_class = Aggregate
|
||||
@ -103,3 +108,20 @@ class AggregateManager(base.ManagerWithFind):
|
||||
:returns: An instance of novaclient.base.TupleWithMeta
|
||||
"""
|
||||
return self._delete('/os-aggregates/%s' % (base.getid(aggregate)))
|
||||
|
||||
@api_versions.wraps("2.81")
|
||||
def cache_images(self, aggregate, images):
|
||||
"""
|
||||
Request images be cached on a given aggregate.
|
||||
|
||||
:param aggregate: The aggregate to target
|
||||
:param images: A list of image IDs to request caching
|
||||
:returns: An instance of novaclient.base.TupleWithMeta
|
||||
"""
|
||||
body = {
|
||||
'cache': [{'id': base.getid(image)} for image in images],
|
||||
}
|
||||
resp, body = self.api.client.post(
|
||||
"/os-aggregates/%s/images" % base.getid(aggregate),
|
||||
body=body)
|
||||
return self.convert_into_with_meta(body, resp)
|
||||
|
@ -3526,6 +3526,21 @@ def _print_aggregate_details(cs, aggregate):
|
||||
utils.print_list([aggregate], columns, formatters=formatters)
|
||||
|
||||
|
||||
@api_versions.wraps("2.81")
|
||||
@utils.arg(
|
||||
'aggregate', metavar='<aggregate>',
|
||||
help=_('Name or ID of the aggregate.'))
|
||||
@utils.arg(
|
||||
'images', metavar='<image>', nargs='+',
|
||||
help=_('Name or ID of image(s) to cache on the hosts within '
|
||||
'the aggregate.'))
|
||||
def do_aggregate_cache_images(cs, args):
|
||||
"""Request images be cached."""
|
||||
aggregate = _find_aggregate(cs, args.aggregate)
|
||||
images = _find_images(cs, args.images)
|
||||
cs.aggregates.cache_images(aggregate, images)
|
||||
|
||||
|
||||
@utils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||
@utils.arg(
|
||||
'host', metavar='<host>', default=None, nargs='?',
|
||||
|
10
releasenotes/notes/microversion-v2_81-3ddd8e2fc7e45030.yaml
Normal file
10
releasenotes/notes/microversion-v2_81-3ddd8e2fc7e45030.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added support for `microversion 2.81`_ which adds image pre-caching support by
|
||||
aggregate.
|
||||
|
||||
- The ``aggregate-cache-images`` command is added to the CLI
|
||||
- The ``cache_images()`` method is added to the python API binding
|
||||
|
||||
.. _microversion 2.81: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id73
|
Loading…
Reference in New Issue
Block a user