Merge "Adding `image delete --store
and
image import info
` commands"
This commit is contained in:
commit
7dc1276f40
@ -18,7 +18,7 @@ image-tag-update,image set --tag <tag>,Update an image with the given tag.
|
||||
image-tasks,,Get tasks associated with image.
|
||||
image-update,image set,Update an existing image.
|
||||
image-upload,,Upload data for a specific image.
|
||||
import-info,,Print import methods available from Glance.
|
||||
import-info,image import info,Show available import methods from Glance.
|
||||
location-add,,Add a location (and related metadata) to an image.
|
||||
location-delete,,Remove locations (and related metadata) from an image.
|
||||
location-update,,Update metadata of an image's location.
|
||||
@ -57,7 +57,7 @@ member-delete,image remove project,Delete image member.
|
||||
member-get,,Show details of an image member
|
||||
member-list,image member list,Describe sharing permissions by image.
|
||||
member-update,image set --accept --reject --status,Update the status of a member for a given image.
|
||||
stores-delete,,Delete image from specific store.
|
||||
stores-delete,image delete --store,Delete image from specific store.
|
||||
stores-info,,Print available backends from Glance.
|
||||
task-create,WONTFIX,Create a new task.
|
||||
task-list,image task list,List tasks you can access.
|
||||
|
|
@ -653,6 +653,13 @@ class DeleteImage(command.Command):
|
||||
nargs="+",
|
||||
help=_("Image(s) to delete (name or ID)"),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--store',
|
||||
metavar='<STORE>',
|
||||
# default=None,
|
||||
dest='store',
|
||||
help=_('Store to delete image(s) from.'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
@ -664,7 +671,18 @@ class DeleteImage(command.Command):
|
||||
image,
|
||||
ignore_missing=False,
|
||||
)
|
||||
image_client.delete_image(image_obj.id)
|
||||
except sdk_exceptions.ResourceNotFound as e:
|
||||
msg = _("Unable to process request: %(e)s") % {'e': e}
|
||||
raise exceptions.CommandError(msg)
|
||||
try:
|
||||
image_client.delete_image(
|
||||
image_obj.id,
|
||||
store=parsed_args.store,
|
||||
ignore_missing=False,
|
||||
)
|
||||
except sdk_exceptions.ResourceNotFound:
|
||||
msg = _("Multi Backend support not enabled.")
|
||||
raise exceptions.CommandError(msg)
|
||||
except Exception as e:
|
||||
del_result += 1
|
||||
msg = _(
|
||||
|
31
openstackclient/image/v2/info.py
Normal file
31
openstackclient/image/v2/info.py
Normal file
@ -0,0 +1,31 @@
|
||||
# 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 osc_lib.cli import format_columns
|
||||
from osc_lib.command import command
|
||||
|
||||
from openstackclient.i18n import _
|
||||
|
||||
|
||||
class ImportInfo(command.ShowOne):
|
||||
_description = _("Show available import methods")
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
image_client = self.app.client_manager.image
|
||||
|
||||
import_info = image_client.get_import_info()
|
||||
import_methods = import_info.import_methods or {}
|
||||
return (
|
||||
('import-methods',),
|
||||
(format_columns.ListColumn(import_methods.get('value', [])),),
|
||||
)
|
30
openstackclient/tests/functional/image/v2/test_info.py
Normal file
30
openstackclient/tests/functional/image/v2/test_info.py
Normal file
@ -0,0 +1,30 @@
|
||||
# Copyright 2023 Red Hat.
|
||||
# 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 openstackclient.tests.functional.image import base
|
||||
|
||||
|
||||
class InfoTests(base.BaseImageTests):
|
||||
"""Functional tests for Info commands"""
|
||||
|
||||
def setUp(self):
|
||||
super(InfoTests, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
|
||||
def test_image_import_info(self):
|
||||
output = self.openstack('image import info', parse_output=True)
|
||||
self.assertIsNotNone(output['import-methods'])
|
@ -41,6 +41,7 @@ class FakeImagev2Client:
|
||||
self.deactivate_image = mock.Mock()
|
||||
self.stage_image = mock.Mock()
|
||||
self.import_image = mock.Mock()
|
||||
self.get_import_info = mock.Mock()
|
||||
|
||||
self.members = mock.Mock()
|
||||
self.add_member = mock.Mock()
|
||||
|
@ -520,7 +520,29 @@ class TestImageDelete(TestImage):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.client.delete_image.assert_called_with(images[0].id)
|
||||
self.client.delete_image.assert_called_with(
|
||||
images[0].id, store=parsed_args.store, ignore_missing=False
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_image_delete_from_store(self):
|
||||
images = self.setup_images_mock(count=1)
|
||||
|
||||
arglist = [
|
||||
images[0].id,
|
||||
'--store',
|
||||
'store1',
|
||||
]
|
||||
verifylist = [('images', [images[0].id]), ('store', 'store1')]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.client.find_image.side_effect = images
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
self.client.delete_image.assert_called_with(
|
||||
images[0].id, store=parsed_args.store, ignore_missing=False
|
||||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_image_delete_multi_images(self):
|
||||
@ -536,10 +558,33 @@ class TestImageDelete(TestImage):
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
|
||||
calls = [mock.call(i.id) for i in images]
|
||||
calls = [
|
||||
mock.call(i.id, store=parsed_args.store, ignore_missing=False)
|
||||
for i in images
|
||||
]
|
||||
self.client.delete_image.assert_has_calls(calls)
|
||||
self.assertIsNone(result)
|
||||
|
||||
def test_image_delete_from_store_without_multi_backend(self):
|
||||
images = self.setup_images_mock(count=1)
|
||||
|
||||
arglist = [images[0].id, '--store', 'store1']
|
||||
verifylist = [('images', [images[0].id]), ('store', 'store1')]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.client.find_image.side_effect = images
|
||||
|
||||
self.client.delete_image.side_effect = sdk_exceptions.ResourceNotFound
|
||||
exc = self.assertRaises(
|
||||
exceptions.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args,
|
||||
)
|
||||
self.assertIn(
|
||||
"Multi Backend support not enabled",
|
||||
str(exc),
|
||||
)
|
||||
|
||||
def test_image_delete_multi_images_exception(self):
|
||||
images = image_fakes.create_images(count=2)
|
||||
arglist = [
|
||||
@ -562,7 +607,10 @@ class TestImageDelete(TestImage):
|
||||
self.assertRaises(
|
||||
exceptions.CommandError, self.cmd.take_action, parsed_args
|
||||
)
|
||||
calls = [mock.call(i.id) for i in images]
|
||||
calls = [
|
||||
mock.call(i.id, store=parsed_args.store, ignore_missing=False)
|
||||
for i in images
|
||||
]
|
||||
self.client.delete_image.assert_has_calls(calls)
|
||||
|
||||
|
||||
|
43
openstackclient/tests/unit/image/v2/test_info.py
Normal file
43
openstackclient/tests/unit/image/v2/test_info.py
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright 2023 Red Hat.
|
||||
# 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 openstackclient.image.v2 import info
|
||||
from openstackclient.tests.unit.image.v2 import fakes as info_fakes
|
||||
|
||||
|
||||
class TestInfo(info_fakes.TestImagev2):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
# Get shortcuts to mocked image client
|
||||
self.client = self.app.client_manager.image
|
||||
|
||||
|
||||
class TestImportInfo(TestInfo):
|
||||
import_info = info_fakes.create_one_import_info()
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
self.client.get_import_info.return_value = self.import_info
|
||||
|
||||
self.cmd = info.ImportInfo(self.app, None)
|
||||
|
||||
def test_import_info(self):
|
||||
arglist = []
|
||||
parsed_args = self.check_parser(self.cmd, arglist, [])
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
self.client.get_import_info.assert_called()
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add ``image import info`` command, allowing users to know available import
|
||||
methods, and `--store` option to ``image delete``, allowing users to delete
|
||||
image from particular store.
|
@ -387,7 +387,7 @@ openstack.image.v2 =
|
||||
image_stage = openstackclient.image.v2.image:StageImage
|
||||
image_task_show = openstackclient.image.v2.task:ShowTask
|
||||
image_task_list = openstackclient.image.v2.task:ListTask
|
||||
image_import = openstackclient.image.v2.image:ImportImage
|
||||
image_import_info = openstackclient.image.v2.info:ImportInfo
|
||||
|
||||
image_metadef_namespace_create = openstackclient.image.v2.metadef_namespaces:CreateMetadefNameSpace
|
||||
image_metadef_namespace_delete = openstackclient.image.v2.metadef_namespaces:DeleteMetadefNameSpace
|
||||
|
Loading…
Reference in New Issue
Block a user