From 00eebaf5bc5ff7a383a8ed085098abc24c8a2e74 Mon Sep 17 00:00:00 2001 From: TerryHowe Date: Tue, 18 Aug 2015 10:09:46 -0600 Subject: [PATCH 1/5] Override the debug default and help text Cliff sets the default debug value to False and this makes it impossible to override debug with OCC. If we set the default to None, we can override debug in clouds.yaml. Also, OSC changes the meaning of --debug, so modify the help text. Change-Id: I5e6680b2286cd7f55afe4b083fae5f8a4a9567a2 Closes-Bug: #1483378 --- openstackclient/shell.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openstackclient/shell.py b/openstackclient/shell.py index a8b5ac4c88..566a7cd9f0 100644 --- a/openstackclient/shell.py +++ b/openstackclient/shell.py @@ -79,6 +79,10 @@ class OpenStackShell(app.App): help.HelpCommand.auth_required = False complete.CompleteCommand.auth_required = False + # Slight change to the meaning of --debug + self.DEFAULT_DEBUG_VALUE = None + self.DEFAULT_DEBUG_HELP = 'Set debug logging and traceback on errors.' + super(OpenStackShell, self).__init__( description=__doc__.strip(), version=openstackclient.__version__, From 9e6f99e2ab4763c5288e5e876dee2708d0ddc273 Mon Sep 17 00:00:00 2001 From: Andrey Kurilin Date: Fri, 11 Sep 2015 16:23:54 +0300 Subject: [PATCH 2/5] Use `discover_extensions` for novaclient novaclien v2.26.0 includes `discover_extensions` method, which returns list of all nova extensions based of version. Such method allows us to reduce imports of novaclient's modules and construct novaclient instance simpler. Change-Id: Idbe3ed275fb4a7e3918b11669dcfad47b8de4fb9 --- openstackclient/compute/client.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/openstackclient/compute/client.py b/openstackclient/compute/client.py index 8ac5f32416..23a4decaab 100644 --- a/openstackclient/compute/client.py +++ b/openstackclient/compute/client.py @@ -34,13 +34,8 @@ _compute_api_version = None def make_client(instance): """Returns a compute service client.""" - # Defer client imports until we actually need them + # Defer client import until we actually need them from novaclient import client as nova_client - from novaclient import extension - try: - from novaclient.v2.contrib import list_extensions - except ImportError: - from novaclient.v1_1.contrib import list_extensions if _compute_api_version is not None: version = _compute_api_version @@ -52,7 +47,8 @@ def make_client(instance): # Set client http_log_debug to True if verbosity level is high enough http_log_debug = utils.get_effective_log_level() <= logging.DEBUG - extensions = [extension.Extension('list_extensions', list_extensions)] + extensions = [ext for ext in nova_client.discover_extensions(version) + if ext.name == "list_extensions"] # Remember interface only if it is set kwargs = utils.build_kwargs_dict('endpoint_type', instance._interface) From 8faabb3bbaa199cce8a52d6e6ed40b15e4a3a000 Mon Sep 17 00:00:00 2001 From: NiallBunting Date: Tue, 22 Sep 2015 09:59:30 +0000 Subject: [PATCH 3/5] Glance `image set` Resolve Fracturing Currently `image set` uses the new api, where other parts of osc the old api is used. This deprecates the v2 api in favour of the v1 to maintain the same commands across osc. However the functionality now remains there as people could now be using this functionality. This also adds the --unprotected argument, as in the previous version if --protected was not supplied it would just make the argument --unprotected without the users explicit consent. The patch also fixes the documentation for image set as it was outdated. Change-Id: I990d20332c80165102badef7ac94ddbeb7824950 Closes-Bug: 1498092 --- doc/source/command-objects/image.rst | 60 +++++++++++++++++- openstackclient/image/v2/image.py | 65 ++++++++++++++++++-- openstackclient/tests/image/v2/test_image.py | 3 +- 3 files changed, 119 insertions(+), 9 deletions(-) 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( From 0e89d084343bcda55db737c3286a17ec695befaf Mon Sep 17 00:00:00 2001 From: Steve Martinelli Date: Thu, 24 Sep 2015 11:50:46 -0400 Subject: [PATCH 4/5] docs: pip install -e needs an argument The arguments to install the development branch is incorrect, since the -e option needs a directory to look for setup.py in. Change-Id: Icfe402e7b79a50ddc885c7eadb6c323c27e36ef3 --- doc/source/developing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/developing.rst b/doc/source/developing.rst index 90f0900ab0..c41fbf3472 100644 --- a/doc/source/developing.rst +++ b/doc/source/developing.rst @@ -113,4 +113,4 @@ or .. code-block:: bash - $ pip install -e + $ pip install -e . From 599905e51217aee686f5738ee778257a0fc1d6cc Mon Sep 17 00:00:00 2001 From: Dean Troyer Date: Wed, 30 Sep 2015 14:47:10 -0500 Subject: [PATCH 5/5] Release notes 1.7.1 Change-Id: Ia0bd230385c2a324b8ca5f5e586b748b5ea915f9 --- doc/source/releases.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/source/releases.rst b/doc/source/releases.rst index 526b1635c7..582f5843da 100644 --- a/doc/source/releases.rst +++ b/doc/source/releases.rst @@ -2,6 +2,12 @@ Release Notes ============= +1.7.1 (30 Sep 2015) +=================== + +* Image v2 lookup issues + Bug `1501362 `_ + 1.7.0 (22 Sep 2015) ===================