Add image re/deactivate commands

This change allows admins to deactivate and reactivate their
images. Currently this has to be done with the REST api or the
glanceclient.

This change introduces `--deactivate` and `--activate` for the `image
set` command.

This requires glanceclient 1.2.0. Which got bumped here:
https://review.openstack.org/#/c/257512/

Change-Id: I476c44a0343cdc92d58ddc93fb06470242de2345
Depends-On: I2c370c6bf6ff664d94d756cc76aaa983fbdb8869
Closes-Bug: 1516661
This commit is contained in:
NiallBunting 2015-12-14 14:28:45 +00:00
parent 1ee5191cec
commit b3943d7142
3 changed files with 101 additions and 2 deletions

View File

@ -243,6 +243,7 @@ Set image properties
[--os-distro <os-distro>]
[--os-version <os-version>]
[--ramdisk-id <ramdisk-id>]
[--activate|--deactivate]
<image>
.. option:: --name <name>
@ -387,6 +388,18 @@ Set image properties
.. versionadded:: 2
.. option:: --activate
Activate the image.
.. versionadded:: 2
.. option:: --deactivate
Deactivate the image.
.. versionadded:: 2
.. describe:: <image>
Image to modify (name or ID)

View File

@ -693,6 +693,17 @@ class SetImage(command.Command):
metavar="<ramdisk-id>",
help="ID of ramdisk image used to boot this disk image",
)
deactivate_group = parser.add_mutually_exclusive_group()
deactivate_group.add_argument(
"--deactivate",
action="store_true",
help="Deactivate the image",
)
deactivate_group.add_argument(
"--activate",
action="store_true",
help="Activate the image",
)
for deadopt in self.deadopts:
parser.add_argument(
"--%s" % deadopt,
@ -745,18 +756,35 @@ class SetImage(command.Command):
if parsed_args.private:
kwargs['visibility'] = 'private'
if not kwargs:
# Checks if anything that requires getting the image
if not (kwargs or parsed_args.deactivate or parsed_args.activate):
self.log.warning("No arguments specified")
return {}, {}
image = utils.find_resource(
image_client.images, parsed_args.image)
if parsed_args.deactivate:
image_client.images.deactivate(image.id)
activation_status = "deactivated"
if parsed_args.activate:
image_client.images.reactivate(image.id)
activation_status = "activated"
# Check if need to do the actual update
if not kwargs:
return {}, {}
if parsed_args.tags:
# Tags should be extended, but duplicates removed
kwargs['tags'] = list(set(image.tags).union(set(parsed_args.tags)))
image = image_client.images.update(image.id, **kwargs)
try:
image = image_client.images.update(image.id, **kwargs)
except Exception as e:
if activation_status is not None:
print("Image %s was %s." % (image.id, activation_status))
raise e
class ShowImage(show.ShowOne):

View File

@ -838,6 +838,64 @@ class TestImageSet(TestImage):
**kwargs
)
def test_image_set_activate(self):
arglist = [
'--tag', 'test-tag',
'--activate',
image_fakes.image_name,
]
verifylist = [
('tags', ['test-tag']),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
self.cmd.take_action(parsed_args)
kwargs = {
'tags': ['test-tag'],
}
self.images_mock.reactivate.assert_called_with(
image_fakes.image_id,
)
# ImageManager.update(image, **kwargs)
self.images_mock.update.assert_called_with(
image_fakes.image_id,
**kwargs
)
def test_image_set_deactivate(self):
arglist = [
'--tag', 'test-tag',
'--deactivate',
image_fakes.image_name,
]
verifylist = [
('tags', ['test-tag']),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# DisplayCommandBase.take_action() returns two tuples
self.cmd.take_action(parsed_args)
kwargs = {
'tags': ['test-tag'],
}
self.images_mock.deactivate.assert_called_with(
image_fakes.image_id,
)
# ImageManager.update(image, **kwargs)
self.images_mock.update.assert_called_with(
image_fakes.image_id,
**kwargs
)
def test_image_set_tag_merge(self):
old_image = copy.copy(image_fakes.IMAGE)
old_image['tags'] = ['old1', 'new2']