Implement tripleo container image delete command
This patch implements the tripleo container image delete command. Change-Id: I1f028e9ea14f6f5a9fe6ccf608be08b9fd569b9e
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
With the new podman container setup comes an Apache served local image
|
||||
registry.
|
||||
|
||||
`openstack tripleo container image delete` allows you to maintain those
|
||||
images, and remove those that are no longer required.
|
||||
|
||||
@@ -103,6 +103,7 @@ openstack.tripleoclient.v1 =
|
||||
overcloud_ffwd-upgrade_converge = tripleoclient.v1.overcloud_ffwd_upgrade:FFWDUpgradeConverge
|
||||
overcloud_execute = tripleoclient.v1.overcloud_execute:RemoteExecute
|
||||
overcloud_generate_fencing = tripleoclient.v1.overcloud_parameters:GenerateFencingParameters
|
||||
tripleo_container_image_delete = tripleoclient.v1.container_image:TripleOContainerImageDelete
|
||||
tripleo_container_image_list = tripleoclient.v1.container_image:TripleOContainerImageList
|
||||
tripleo_container_image_prepare = tripleoclient.v1.container_image:TripleOImagePrepare
|
||||
tripleo_container_image_prepare_default = tripleoclient.v1.container_image:TripleOImagePrepareDefault
|
||||
|
||||
@@ -23,6 +23,8 @@ import sys
|
||||
import tempfile
|
||||
import yaml
|
||||
|
||||
from osc_lib import exceptions as oscexc
|
||||
|
||||
from tripleo_common.image import image_uploader
|
||||
from tripleo_common.image import kolla_builder
|
||||
from tripleoclient.tests.v1.test_plugin import TestPluginV1
|
||||
@@ -80,6 +82,46 @@ class TestContainerImageUpload(TestPluginV1):
|
||||
mock_manager.return_value.upload.assert_called_once_with()
|
||||
|
||||
|
||||
class TestContainerImageDelete(TestPluginV1):
|
||||
|
||||
def setUp(self):
|
||||
super(TestContainerImageDelete, self).setUp()
|
||||
self.cmd = container_image.TripleOContainerImageDelete(self.app, None)
|
||||
|
||||
@mock.patch('tripleo_common.image.image_uploader.ImageUploadManager')
|
||||
def test_oserror(self, mock_manager):
|
||||
|
||||
arglist = ['-y', 'foo']
|
||||
verifylist = [('yes', True),
|
||||
('image_to_delete', 'foo')]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
# mock manager object
|
||||
mock_mgr = mock.Mock()
|
||||
mock_manager.return_value = mock_mgr
|
||||
|
||||
# mock uploader object
|
||||
mock_uploader = mock.Mock()
|
||||
mock_mgr.uploader.return_value = mock_uploader
|
||||
|
||||
# mock return url object from uploader._image_to_url
|
||||
mock_url = mock.Mock()
|
||||
mock_url.geturl.return_value = 'munged-reg-url'
|
||||
|
||||
mock_uploader._image_to_url.return_value = mock_url
|
||||
|
||||
# mock return session object from uploader.authenticate
|
||||
mock_session = mock.Mock()
|
||||
mock_uploader.authenticate.return_value = mock_session
|
||||
|
||||
mock_uploader.delete.side_effect = OSError('Errno 13')
|
||||
self.assertRaises(oscexc.CommandError,
|
||||
self.cmd.take_action,
|
||||
parsed_args)
|
||||
mock_uploader.delete.assert_called_once_with('foo',
|
||||
session=mock_session)
|
||||
|
||||
|
||||
class TestContainerImageList(TestPluginV1):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
@@ -511,6 +511,72 @@ class DiscoverImageTag(command.Command):
|
||||
))
|
||||
|
||||
|
||||
class TripleOContainerImageDelete(command.Command):
|
||||
"""Delete specified image from registry."""
|
||||
|
||||
auth_required = False
|
||||
log = logging.getLogger(__name__ + ".TripleoContainerImageDelete")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(TripleOContainerImageDelete, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
"--registry-url",
|
||||
dest="registry_url",
|
||||
metavar='<registry url>',
|
||||
default=image_uploader.get_undercloud_registry(),
|
||||
help=_("URL of registry images are to be listed from in the "
|
||||
"form <fqdn>:<port>.")
|
||||
)
|
||||
parser.add_argument(
|
||||
dest="image_to_delete",
|
||||
metavar='<image to delete>',
|
||||
help=_("Full URL of image to be deleted in the "
|
||||
"form <fqdn>:<port>/path/to/image")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--username",
|
||||
dest="username",
|
||||
metavar='<username>',
|
||||
help=_("Username for image registry.")
|
||||
)
|
||||
parser.add_argument(
|
||||
"--password",
|
||||
dest="password",
|
||||
metavar='<password>',
|
||||
help=_("Password for image registry.")
|
||||
)
|
||||
parser.add_argument(
|
||||
'-y', '--yes',
|
||||
help=_('Skip yes/no prompt (assume yes).'),
|
||||
default=False,
|
||||
action="store_true")
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
|
||||
if not parsed_args.yes:
|
||||
confirm = utils.prompt_user_for_confirmation(
|
||||
message=_("Are you sure you want to delete this image "
|
||||
"[y/N]? "),
|
||||
logger=self.log)
|
||||
if not confirm:
|
||||
raise oscexc.CommandError("Action not confirmed, exiting.")
|
||||
|
||||
manager = image_uploader.ImageUploadManager()
|
||||
uploader = manager.uploader('python')
|
||||
url = uploader._image_to_url(parsed_args.registry_url)
|
||||
session = uploader.authenticate(url, parsed_args.username,
|
||||
parsed_args.password)
|
||||
|
||||
try:
|
||||
uploader.delete(parsed_args.image_to_delete, session=session)
|
||||
except OSError as e:
|
||||
self.log.error("Unable to remove due to permissions. "
|
||||
"Please prefix command with sudo.")
|
||||
raise oscexc.CommandError(e)
|
||||
|
||||
|
||||
class TripleOContainerImageList(command.Lister):
|
||||
"""List images discovered in registry."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user