diff --git a/doc/source/command-objects/image.rst b/doc/source/command-objects/image.rst index 257414242d..b62f6e0b01 100644 --- a/doc/source/command-objects/image.rst +++ b/doc/source/command-objects/image.rst @@ -193,7 +193,7 @@ Save an image locally image set --------- -*Only supported for Image v1* +*Image v1, v2* Set image properties @@ -252,6 +252,8 @@ Set image properties Size of image data (in bytes) + *Image version 1 only.* + .. option:: --protected Prevent image from being deleted @@ -272,38 +274,94 @@ Set image properties Upload image to this store + *Image version 1 only.* + .. option:: --location Download image from an existing URL + *Image version 1 only.* + .. option:: --copy-from Copy image from the data store (similar to --location) + *Image version 1 only.* + .. option:: --file Upload image from local file + *Image version 1 only.* + .. option:: --volume Update image with a volume + *Image version 1 only.* + .. option:: --force Force image update if volume is in use (only meaningful with --volume) + *Image version 1 only.* + .. option:: --checksum Image hash used for verification + *Image version 1 only.* + .. option:: --stdin Allow to read image data from standard input + *Image version 1 only.* + .. option:: --property Set a property on this image (repeat for multiple values) + *Image version 1 only.* + +.. option:: --architecture + + Operating system Architecture + + .. versionadded:: 2 + +.. option:: --ramdisk-id + + ID of image stored in Glance that should be used as + the ramdisk when booting an AMI-style image + + .. versionadded:: 2 + +.. option:: --os-distro + + Common name of operating system distribution + + .. versionadded:: 2 + +.. option:: --os-version + + Operating system version as specified by the distributor + + .. versionadded:: 2 + +.. option:: --kernel-id + + ID of image in Glance that should be used as the + kernel when booting an AMI-style image + + .. versionadded:: 2 + +.. option:: --instance-uuid + + ID of instance used to create this image + + .. versionadded:: 2 + .. describe:: Image to modify (name or ID) diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py index 4c019db64a..a8a0c1090b 100644 --- a/openstackclient/image/v2/image.py +++ b/openstackclient/image/v2/image.py @@ -25,6 +25,7 @@ from cliff import show from glanceclient.common import utils as gc_utils from openstackclient.api import utils as api_utils +from openstackclient.common import exceptions from openstackclient.common import parseractions from openstackclient.common import utils from openstackclient.identity import common @@ -336,9 +337,22 @@ class SetImage(show.ShowOne): """Set image properties""" log = logging.getLogger(__name__ + ".SetImage") + deadopts = ('size', 'store', 'location', 'copy-from', 'checksum') def get_parser(self, prog_name): parser = super(SetImage, self).get_parser(prog_name) + # TODO(bunting): There are additional arguments that v1 supported + # --size - does not exist in v2 + # --store - does not exist in v2 + # --location - maybe location add? + # --copy-from - does not exist in v2 + # --file - should be able to upload file + # --volume - needs adding + # --force - needs adding + # --checksum - maybe could be done client side + # --stdin - could be implemented + # --property - needs adding + # --tags - needs adding parser.add_argument( "image", metavar="", @@ -354,12 +368,28 @@ class SetImage(show.ShowOne): metavar="", help="Operating system Architecture" ) - parser.add_argument( + protected_group = parser.add_mutually_exclusive_group() + protected_group.add_argument( "--protected", - dest="protected", action="store_true", help="Prevent image from being deleted" ) + protected_group.add_argument( + "--unprotected", + action="store_true", + help="Allow image to be deleted (default)" + ) + public_group = parser.add_mutually_exclusive_group() + public_group.add_argument( + "--public", + action="store_true", + help="Image is accessible to the public", + ) + public_group.add_argument( + "--private", + action="store_true", + help="Image is inaccessible to the public (default)", + ) parser.add_argument( "--instance-uuid", metavar="", @@ -372,12 +402,11 @@ class SetImage(show.ShowOne): help="Minimum disk size needed to boot image, in gigabytes" ) visibility_choices = ["public", "private"] - parser.add_argument( + public_group.add_argument( "--visibility", metavar="", choices=visibility_choices, - help="Scope of image accessibility. Valid values: %s" - % visibility_choices + help=argparse.SUPPRESS ) help_msg = ("ID of image in Glance that should be used as the kernel" " when booting an AMI-style image") @@ -432,12 +461,25 @@ class SetImage(show.ShowOne): choices=container_choices, help=help_msg ) + for deadopt in self.deadopts: + parser.add_argument( + "--%s" % deadopt, + metavar="<%s>" % deadopt, + dest=deadopt.replace('-', '_'), + help=argparse.SUPPRESS + ) return parser def take_action(self, parsed_args): self.log.debug("take_action(%s)", parsed_args) image_client = self.app.client_manager.image + for deadopt in self.deadopts: + if getattr(parsed_args, deadopt.replace('-', '_'), None): + raise exceptions.CommandError( + "ERROR: --%s was given, which is an Image v1 option" + " that is no longer supported in Image v2" % deadopt) + kwargs = {} copy_attrs = ('architecture', 'container_format', 'disk_format', 'file', 'kernel_id', 'locations', 'name', @@ -451,10 +493,21 @@ class SetImage(show.ShowOne): # Only include a value in kwargs for attributes that are # actually present on the command line kwargs[attr] = val + + # Handle exclusive booleans with care + # Avoid including attributes in kwargs if an option is not + # present on the command line. These exclusive booleans are not + # a single value for the pair of options because the default must be + # to do nothing when no options are present as opposed to always + # setting a default. if parsed_args.protected: kwargs['protected'] = True - else: + if parsed_args.unprotected: kwargs['protected'] = False + if parsed_args.public: + kwargs['visibility'] = 'public' + if parsed_args.private: + kwargs['visibility'] = 'private' if not kwargs: self.log.warning("No arguments specified") diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py index bfb9476518..0c4aad2768 100644 --- a/openstackclient/tests/image/v2/test_image.py +++ b/openstackclient/tests/image/v2/test_image.py @@ -527,8 +527,7 @@ class TestImageSet(TestImage): 'name': 'new-name', 'owner': 'new-owner', 'min_disk': 2, - 'min_ram': 4, - 'protected': False + 'min_ram': 4 } # ImageManager.update(image, **kwargs) self.images_mock.update.assert_called_with(