Hello community, here is the log from the commit of package python-glanceclient for openSUSE:Factory checked in at 2020-06-05 20:10:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-glanceclient (Old) and /work/SRC/openSUSE:Factory/.python-glanceclient.new.3606 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-glanceclient" Fri Jun 5 20:10:10 2020 rev:32 rq:803562 version:3.1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-glanceclient/python-glanceclient.changes 2020-03-24 22:33:03.181110133 +0100 +++ /work/SRC/openSUSE:Factory/.python-glanceclient.new.3606/python-glanceclient.changes 2020-06-05 20:13:01.158281631 +0200 @@ -1,0 +2,27 @@ +Tue May 12 09:55:53 UTC 2020 - cloud-de...@suse.de + +- update to version 3.1.1 + - Replace git.openstack.org URLs with opendev.org URLs + - Remove .zuul.yaml from the list of irrelevant files + - update doc url to new + - Update master for stable/train + - Stop configuring install_command in tox. + - Add release note for glanceclient 3.1.1 + - Remove v1 tests + - Rename releasenotes to reflect correct version + - Add support for multi-store import + - Delete image from specific store + - Update TOX/UPPER_CONSTRAINTS_FILE for stable/ussuri + - Add release note for glanceclient 3.0.0 + - Drop python 2.7 support and testing + - Cleanup session object + - Update .gitreview for stable/ussuri + - setup.cfg: Use better Python 3 hinting + - Pass --all-stores, --allow-failure as bool to API + - Add support for copy-image import method + - Drop support for tempest-full + - Move py35 jobs to latest python3 + - Cleanup py27 support + - Update hacking for Python3 + +------------------------------------------------------------------- Old: ---- python-glanceclient-2.17.0.tar.gz New: ---- python-glanceclient-3.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-glanceclient.spec ++++++ --- /var/tmp/diff_new_pack.e2Rpzw/_old 2020-06-05 20:13:03.170288122 +0200 +++ /var/tmp/diff_new_pack.e2Rpzw/_new 2020-06-05 20:13:03.170288122 +0200 @@ -17,13 +17,13 @@ Name: python-glanceclient -Version: 2.17.0 +Version: 3.1.1 Release: 0 Summary: Python API and CLI for OpenStack Glance License: Apache-2.0 Group: Development/Languages/Python URL: https://launchpad.net/python-glanceclient -Source0: https://files.pythonhosted.org/packages/source/p/python-glanceclient/python-glanceclient-2.17.0.tar.gz +Source0: https://files.pythonhosted.org/packages/source/p/python-glanceclient/python-glanceclient-3.1.1.tar.gz BuildRequires: openstack-macros BuildRequires: python3-PrettyTable >= 0.7.1 BuildRequires: python3-fixtures @@ -82,15 +82,15 @@ This package contains auto-generated documentation. %prep -%autosetup -p1 -n python-glanceclient-2.17.0 +%autosetup -p1 -n python-glanceclient-3.1.1 %py_req_cleanup %build %py3_build # generate html docs -PBR_VERSION=2.17.0 %sphinx_build -b html doc/source doc/build/html -PBR_VERSION=2.17.0 %sphinx_build -b man doc/source doc/build/man +PBR_VERSION=3.1.1 %sphinx_build -b html doc/source doc/build/html +PBR_VERSION=3.1.1 %sphinx_build -b man doc/source doc/build/man # remove the sphinx-build leftovers rm -rf doc/build/html/.{doctrees,buildinfo} rm -rf doc/build/man/.{doctrees,buildinfo} ++++++ _service ++++++ --- /var/tmp/diff_new_pack.e2Rpzw/_old 2020-06-05 20:13:03.198288213 +0200 +++ /var/tmp/diff_new_pack.e2Rpzw/_new 2020-06-05 20:13:03.202288225 +0200 @@ -1,8 +1,8 @@ <services> <service mode="disabled" name="renderspec"> - <param name="input-template">https://raw.githubusercontent.com/openstack/rpm-packaging/stable/train/openstack/python-glanceclient/python-glanceclient.spec.j2</param> + <param name="input-template">https://opendev.org/openstack/rpm-packaging/raw/branch/stable/ussuri/openstack/python-glanceclient/python-glanceclient.spec.j2</param> <param name="output-name">python-glanceclient.spec</param> - <param name="requirements">https://raw.githubusercontent.com/openstack/python-glanceclient/stable/train/requirements.txt</param> + <param name="requirements">https://opendev.org/openstack/python-glanceclient/raw/branch/stable/ussuri/requirements.txt</param> <param name="changelog-email">cloud-de...@suse.de</param> <param name="changelog-provider">gh,openstack,python-glanceclient</param> </service> ++++++ python-glanceclient-2.17.0.tar.gz -> python-glanceclient-3.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/.zuul.yaml new/python-glanceclient-3.1.1/.zuul.yaml --- old/python-glanceclient-2.17.0/.zuul.yaml 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/.zuul.yaml 2020-04-14 00:18:14.000000000 +0200 @@ -1,52 +1,4 @@ - job: - name: glanceclient-dsvm-functional-v1 - parent: devstack-tox-functional - description: | - Devstack-based functional tests for glanceclient - against the Image API v1. - - The Image API v1 is removed from glance in Rocky, but - is still supported by glanceclient until the S cycle, - so we test it against glance stable/queens. - - THIS JOB SHOULD BE REMOVED AT THE BEGINNING OF THE S - CYCLE. - override-checkout: stable/queens - required-projects: - - name: openstack/python-glanceclient - override-checkout: master - timeout: 4200 - vars: - tox_envlist: functional-v1 - devstack_localrc: - GLANCE_V1_ENABLED: true - devstack_services: - # turn off ceilometer - ceilometer-acentral: false - ceilometer-acompute: false - ceilometer-alarm-evaluator: false - ceilometer-alarm-notifier: false - ceilometer-anotification: false - ceilometer-api: false - ceilometer-collector: false - # turn on swift - s-account: true - s-container: true - s-object: true - s-proxy: true - # Hardcode glanceclient path so the job can be run on glance patches - zuul_work_dir: src/opendev.org/openstack/python-glanceclient - irrelevant-files: - - ^doc/.*$ - - ^releasenotes/.*$ - - ^.*\.rst$ - - ^(test-|)requirements.txt$ - - ^lower-constraints.txt$ - - ^setup.cfg$ - - ^tox.ini$ - - ^\.zuul\.yaml$ - -- job: name: glanceclient-dsvm-functional parent: devstack-tox-functional description: | @@ -83,7 +35,6 @@ - ^lower-constraints.txt$ - ^setup.cfg$ - ^tox.ini$ - - ^\.zuul\.yaml$ - job: name: glanceclient-tox-keystone-tips-base @@ -94,20 +45,12 @@ - name: openstack/keystoneauth - job: - name: glanceclient-tox-py27-keystone-tips - parent: glanceclient-tox-keystone-tips-base - description: | - glanceclient py27 unit tests vs. keystone masters - vars: - tox_envlist: py27 - -- job: - name: glanceclient-tox-py35-keystone-tips + name: glanceclient-tox-py3-keystone-tips parent: glanceclient-tox-keystone-tips-base description: | - glanceclient py35 unit tests vs. keystone masters + glanceclient py3 unit tests vs. keystone masters vars: - tox_envlist: py35 + tox_envlist: py3 - job: name: glanceclient-tox-oslo-tips-base @@ -119,20 +62,12 @@ - name: openstack/oslo.utils - job: - name: glanceclient-tox-py27-oslo-tips + name: glanceclient-tox-py3-oslo-tips parent: glanceclient-tox-oslo-tips-base description: | - glanceclient py27 unit tests vs. oslo masters + glanceclient py3 unit tests vs. oslo masters vars: - tox_envlist: py27 - -- job: - name: glanceclient-tox-py35-oslo-tips - parent: glanceclient-tox-oslo-tips-base - description: | - glanceclient py35 unit tests vs. oslo masters - vars: - tox_envlist: py35 + tox_envlist: py3 - job: name: glanceclient-dsvm-functional-py3 @@ -144,21 +79,17 @@ - project: templates: - check-requirements - - lib-forward-testing - lib-forward-testing-python3 - openstack-cover-jobs - openstack-lower-constraints-jobs - - openstack-python-jobs - - openstack-python3-train-jobs + - openstack-python3-ussuri-jobs - publish-openstack-docs-pti - release-notes-jobs-python3 check: jobs: - - glanceclient-dsvm-functional-v1 - glanceclient-dsvm-functional gate: jobs: - - glanceclient-dsvm-functional-v1 - glanceclient-dsvm-functional periodic: jobs: @@ -174,13 +105,9 @@ # to define these jobs in the openstack/project-config repo. # That would make us less agile in adjusting these tests, so we # aren't doing that either. - - glanceclient-tox-py27-keystone-tips: - branches: master - - glanceclient-tox-py35-keystone-tips: - branches: master - - glanceclient-tox-py27-oslo-tips: + - glanceclient-tox-py3-keystone-tips: branches: master - - glanceclient-tox-py35-oslo-tips: + - glanceclient-tox-py3-oslo-tips: branches: master experimental: jobs: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/AUTHORS new/python-glanceclient-3.1.1/AUTHORS --- old/python-glanceclient-2.17.0/AUTHORS 2019-09-13 17:04:44.000000000 +0200 +++ new/python-glanceclient-3.1.1/AUTHORS 2020-04-14 00:19:04.000000000 +0200 @@ -9,6 +9,7 @@ Alessio Ababilov <aababi...@griddynamics.com> Alex Gaynor <alex.gay...@gmail.com> Alex Meade <mr.alex.me...@gmail.com> +Alex Schultz <aschu...@redhat.com> Alexander Bashmakov <alexander.bashma...@intel.com> Alexander Tivelkov <ativel...@mirantis.com> Alexey Galkin <agal...@mirantis.com> @@ -49,6 +50,7 @@ Cyril Roelandt <cyril.roela...@enovance.com> Cyril Roelandt <cy...@redhat.com> Dan Prince <dpri...@redhat.com> +Daniel Bengtsson <dbe...@redhat.com> Danny Al-Gaaf <danny.al-g...@bisect.de> Dao Cong Tien <tie...@vn.fujitsu.com> Darja Shakhray <dshakh...@mirantis.com> @@ -86,6 +88,8 @@ Gabe Westmaas <gabe.westm...@rackspace.com> Gabriel Hurley <gabr...@strikeawe.com> Georges Dubus <georges.du...@numergy.com> +Ghanshyam <gm...@ghanshyammann.com> +Ghanshyam Mann <gm...@ghanshyammann.com> Ghe Rivero <ghe.riv...@hp.com> Gorka Eguileor <gegui...@redhat.com> Haikel Guemar <hgue...@fedoraproject.org> @@ -238,6 +242,7 @@ liuqing <jing.liuq...@99cloud.net> llg8212 <lilin...@huawei.com> lrqrun <lrq...@gmail.com> +lvxianguo <lvxian...@inspur.com> m.benchcha...@cloudbau.de <m.benchcha...@cloudbau.de> mouad benchchaoui <m.benchcha...@cloudbau.de> pawnesh.kumar <pawnesh.ku...@nectechnologies.in> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/ChangeLog new/python-glanceclient-3.1.1/ChangeLog --- old/python-glanceclient-2.17.0/ChangeLog 2019-09-13 17:04:44.000000000 +0200 +++ new/python-glanceclient-3.1.1/ChangeLog 2020-04-14 00:19:04.000000000 +0200 @@ -1,10 +1,43 @@ CHANGES ======= +3.1.1 +----- + +* Add release note for glanceclient 3.1.1 +* Pass --all-stores, --allow-failure as bool to API +* Update TOX/UPPER\_CONSTRAINTS\_FILE for stable/ussuri +* Update .gitreview for stable/ussuri + +3.1.0 +----- + +* Rename releasenotes to reflect correct version +* Add release note for glanceclient 3.0.0 +* Cleanup py27 support +* Update hacking for Python3 +* Delete image from specific store +* Remove .zuul.yaml from the list of irrelevant files + +3.0.0 +----- + +* Add support for copy-image import method +* Add support for multi-store import +* setup.cfg: Use better Python 3 hinting +* Remove v1 tests +* Drop support for tempest-full +* Move py35 jobs to latest python3 +* Drop python 2.7 support and testing +* Stop configuring install\_command in tox +* Update master for stable/train + 2.17.0 ------ * Add release note for glanceclient 2.17.0 +* Replace git.openstack.org URLs with opendev.org URLs +* Cleanup session object * Trivial: fix image format typo * Correcting typo in shell.py - enviroment to environment * Bump openstackdocstheme to 1.20.0 @@ -48,6 +81,7 @@ * add python 3.6 unit test job * switch documentation job to new PTI * import zuul job settings from project-config +* update doc url to new * Remove team diversity tags note in README * Update reno for stable/rocky * Skip quote '=' for token header diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/PKG-INFO new/python-glanceclient-3.1.1/PKG-INFO --- old/python-glanceclient-2.17.0/PKG-INFO 2019-09-13 17:04:44.000000000 +0200 +++ new/python-glanceclient-3.1.1/PKG-INFO 2020-04-14 00:19:04.000000000 +0200 @@ -1,6 +1,6 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.2 Name: python-glanceclient -Version: 2.17.0 +Version: 3.1.1 Summary: OpenStack Image API Client Library Home-page: https://docs.openstack.org/python-glanceclient/latest/ Author: OpenStack @@ -34,7 +34,7 @@ This is a client library for Glance built on the OpenStack Images API. It provides a Python API (the ``glanceclient`` module) and a command-line tool (``glance``). This library fully supports the v1 Images API, while support for the v2 API is in progress. - Development takes place via the usual OpenStack processes as outlined in the `developer guide <https://docs.openstack.org/infra/manual/developers.html>`_. The master repository is in `Git <https://git.openstack.org/cgit/openstack/python-glanceclient>`_. + Development takes place via the usual OpenStack processes as outlined in the `developer guide <https://docs.openstack.org/infra/manual/developers.html>`_. The master repository is in `Git <https://opendev.org/openstack/python-glanceclient>`_. See release notes and more at `<https://docs.openstack.org/python-glanceclient/latest/>`_. @@ -53,7 +53,7 @@ .. _Launchpad project: https://launchpad.net/python-glanceclient .. _Blueprints: https://blueprints.launchpad.net/python-glanceclient .. _Bugs: https://bugs.launchpad.net/python-glanceclient - .. _Source: https://git.openstack.org/cgit/openstack/python-glanceclient + .. _Source: https://opendev.org/openstack/python-glanceclient .. _How to Contribute: https://docs.openstack.org/infra/manual/developers.html .. _Specs: https://specs.openstack.org/openstack/glance-specs/ .. _Release notes: https://docs.openstack.org/releasenotes/python-glanceclient @@ -68,8 +68,9 @@ Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Requires-Python: >=3.6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/README.rst new/python-glanceclient-3.1.1/README.rst --- old/python-glanceclient-2.17.0/README.rst 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/README.rst 2020-04-14 00:18:14.000000000 +0200 @@ -26,7 +26,7 @@ This is a client library for Glance built on the OpenStack Images API. It provides a Python API (the ``glanceclient`` module) and a command-line tool (``glance``). This library fully supports the v1 Images API, while support for the v2 API is in progress. -Development takes place via the usual OpenStack processes as outlined in the `developer guide <https://docs.openstack.org/infra/manual/developers.html>`_. The master repository is in `Git <https://git.openstack.org/cgit/openstack/python-glanceclient>`_. +Development takes place via the usual OpenStack processes as outlined in the `developer guide <https://docs.openstack.org/infra/manual/developers.html>`_. The master repository is in `Git <https://opendev.org/openstack/python-glanceclient>`_. See release notes and more at `<https://docs.openstack.org/python-glanceclient/latest/>`_. @@ -45,7 +45,7 @@ .. _Launchpad project: https://launchpad.net/python-glanceclient .. _Blueprints: https://blueprints.launchpad.net/python-glanceclient .. _Bugs: https://bugs.launchpad.net/python-glanceclient -.. _Source: https://git.openstack.org/cgit/openstack/python-glanceclient +.. _Source: https://opendev.org/openstack/python-glanceclient .. _How to Contribute: https://docs.openstack.org/infra/manual/developers.html .. _Specs: https://specs.openstack.org/openstack/glance-specs/ .. _Release notes: https://docs.openstack.org/releasenotes/python-glanceclient diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/doc/requirements.txt new/python-glanceclient-3.1.1/doc/requirements.txt --- old/python-glanceclient-2.17.0/doc/requirements.txt 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/doc/requirements.txt 2020-04-14 00:18:14.000000000 +0200 @@ -3,6 +3,5 @@ # process, which may cause wedges in the gate later. openstackdocstheme>=1.20.0 # Apache-2.0 reno>=2.5.0 # Apache-2.0 -sphinx!=1.6.6,!=1.6.7,>=1.6.2,<2.0.0;python_version=='2.7' # BSD -sphinx!=1.6.6,!=1.6.7,!=2.1.0,>=1.6.2;python_version>='3.4' # BSD +sphinx!=1.6.6,!=1.6.7,!=2.1.0,>=1.6.2 # BSD sphinxcontrib-apidoc>=0.2.0 # BSD diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/glanceclient/common/http.py new/python-glanceclient-3.1.1/glanceclient/common/http.py --- old/python-glanceclient-2.17.0/glanceclient/common/http.py 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/glanceclient/common/http.py 2020-04-14 00:18:14.000000000 +0200 @@ -177,12 +177,21 @@ if kwargs.get('insecure', False) is True: self.session.verify = False else: - if kwargs.get('cacert', None) is not '': + if kwargs.get('cacert', None) != '': self.session.verify = kwargs.get('cacert', True) self.session.cert = (kwargs.get('cert_file'), kwargs.get('key_file')) + def __del__(self): + if self.session: + try: + self.session.close() + except Exception as e: + LOG.exception(e) + finally: + self.session = None + @staticmethod def parse_endpoint(endpoint): return netutils.urlsplit(endpoint) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/glanceclient/tests/functional/v1/test_readonly_glance.py new/python-glanceclient-3.1.1/glanceclient/tests/functional/v1/test_readonly_glance.py --- old/python-glanceclient-2.17.0/glanceclient/tests/functional/v1/test_readonly_glance.py 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/glanceclient/tests/functional/v1/test_readonly_glance.py 2020-04-14 00:18:14.000000000 +0200 @@ -52,7 +52,7 @@ commands = [] cmds_start = lines.index('Positional arguments:') cmds_end = lines.index('Optional arguments:') - command_pattern = re.compile('^ {4}([a-z0-9\-\_]+)') + command_pattern = re.compile(r'^ {4}([a-z0-9\-\_]+)') for line in lines[cmds_start:cmds_end]: match = command_pattern.match(line) if match: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/glanceclient/tests/functional/v2/test_readonly_glance.py new/python-glanceclient-3.1.1/glanceclient/tests/functional/v2/test_readonly_glance.py --- old/python-glanceclient-2.17.0/glanceclient/tests/functional/v2/test_readonly_glance.py 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/glanceclient/tests/functional/v2/test_readonly_glance.py 2020-04-14 00:18:14.000000000 +0200 @@ -72,7 +72,7 @@ commands = [] cmds_start = lines.index('Positional arguments:') cmds_end = lines.index('Optional arguments:') - command_pattern = re.compile('^ {4}([a-z0-9\-\_]+)') + command_pattern = re.compile(r'^ {4}([a-z0-9\-\_]+)') for line in lines[cmds_start:cmds_end]: match = command_pattern.match(line) if match: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/glanceclient/tests/unit/test_http.py new/python-glanceclient-3.1.1/glanceclient/tests/unit/test_http.py --- old/python-glanceclient-2.17.0/glanceclient/tests/unit/test_http.py 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/glanceclient/tests/unit/test_http.py 2020-04-14 00:18:14.000000000 +0200 @@ -367,11 +367,11 @@ self.assertTrue(mock_log.called, 'LOG.debug never called') self.assertTrue(mock_log.call_args[0], 'LOG.debug called with no arguments') - hd_regex = ".*\s-H\s+'\s*%s\s*:\s*%s\s*'.*" % (hd_name, hd_val) + hd_regex = r".*\s-H\s+'\s*%s\s*:\s*%s\s*'.*" % (hd_name, hd_val) self.assertThat(mock_log.call_args[0][0], matchers.MatchesRegex(hd_regex), 'header not found in curl command') - body_regex = ".*\s-d\s+'%s'\s.*" % body + body_regex = r".*\s-d\s+'%s'\s.*" % body self.assertThat(mock_log.call_args[0][0], matchers.MatchesRegex(body_regex), 'body not found in curl command') @@ -390,12 +390,12 @@ needles = {'key': key, 'cert': cert, 'cacert': cacert} for option, value in needles.items(): if value: - regex = ".*\s--%s\s+('%s'|%s).*" % (option, value, value) + regex = r".*\s--%s\s+('%s'|%s).*" % (option, value, value) self.assertThat(mock_log.call_args[0][0], matchers.MatchesRegex(regex), 'no --%s option in curl command' % option) else: - regex = ".*\s--%s\s+.*" % option + regex = r".*\s--%s\s+.*" % option self.assertThat(mock_log.call_args[0][0], matchers.Not(matchers.MatchesRegex(regex)), 'unexpected --%s option in curl command' % @@ -421,7 +421,7 @@ self.assertTrue(mock_log.call_args[0], 'LOG.debug called with no arguments') self.assertThat(mock_log.call_args[0][0], - matchers.MatchesRegex('.*\s-k\s.*'), + matchers.MatchesRegex(r'.*\s-k\s.*'), 'no -k option in curl command') @mock.patch('glanceclient.common.http.LOG.debug') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/glanceclient/tests/unit/v2/test_metadefs_namespaces.py new/python-glanceclient-3.1.1/glanceclient/tests/unit/v2/test_metadefs_namespaces.py --- old/python-glanceclient-2.17.0/glanceclient/tests/unit/v2/test_metadefs_namespaces.py 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/glanceclient/tests/unit/v2/test_metadefs_namespaces.py 2020-04-14 00:18:14.000000000 +0200 @@ -58,6 +58,7 @@ return ns + data_fixtures = { "/v2/metadefs/namespaces?limit=20": { "GET": ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/glanceclient/tests/unit/v2/test_metadefs_objects.py new/python-glanceclient-3.1.1/glanceclient/tests/unit/v2/test_metadefs_objects.py --- old/python-glanceclient-2.17.0/glanceclient/tests/unit/v2/test_metadefs_objects.py 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/glanceclient/tests/unit/v2/test_metadefs_objects.py 2020-04-14 00:18:14.000000000 +0200 @@ -58,6 +58,7 @@ return obj + data_fixtures = { "/v2/metadefs/namespaces/%s/objects" % NAMESPACE1: { "GET": ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/glanceclient/tests/unit/v2/test_shell_v2.py new/python-glanceclient-3.1.1/glanceclient/tests/unit/v2/test_shell_v2.py --- old/python-glanceclient-2.17.0/glanceclient/tests/unit/v2/test_shell_v2.py 2019-09-13 17:03:31.000000000 +0200 +++ new/python-glanceclient-3.1.1/glanceclient/tests/unit/v2/test_shell_v2.py 2020-04-14 00:18:14.000000000 +0200 @@ -55,6 +55,8 @@ 'locations': {'type': 'string'}, 'copy_from': {'type': 'string'}}} return original_schema_args(my_schema_getter, omit) + + utils.schema_args = schema_args from glanceclient.v2 import shell as test_shell # noqa @@ -842,7 +844,7 @@ import_info_response = {'import-methods': { 'type': 'array', 'description': 'Import methods available.', - 'value': ['glance-direct', 'web-download']}} + 'value': ['glance-direct', 'web-download', 'copy-image']}} def _mock_utils_exit(self, msg): sys.exit(msg) @@ -871,6 +873,111 @@ mock_utils_exit.assert_called_once_with(expected_msg) @mock.patch('glanceclient.common.utils.exit') + def test_neg_image_create_via_import_copy_image( + self, mock_utils_exit): + expected_msg = ("Import method 'copy-image' cannot be used " + "while creating the image.") + mock_utils_exit.side_effect = self._mock_utils_exit + my_args = self.base_args.copy() + my_args.update( + {'id': 'IMG-01', 'import_method': 'copy-image'}) + args = self._make_args(my_args) + + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + mocked_info.return_value = self.import_info_response + try: + test_shell.do_image_create_via_import(self.gc, args) + self.fail("utils.exit should have been called") + except SystemExit: + pass + mock_utils_exit.assert_called_once_with(expected_msg) + + @mock.patch('glanceclient.common.utils.exit') + def test_neg_image_create_via_import_stores_all_stores_specified( + self, mock_utils_exit): + expected_msg = ('Only one of --store, --stores and --all-stores can ' + 'be provided') + mock_utils_exit.side_effect = self._mock_utils_exit + my_args = self.base_args.copy() + my_args.update( + {'id': 'IMG-01', 'import_method': 'glance-direct', + 'stores': 'file1,file2', 'os_all_stores': True, + 'file': 'some.mufile', + 'disk_format': 'raw', + 'container_format': 'bare', + }) + args = self._make_args(my_args) + + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + mocked_info.return_value = self.import_info_response + try: + test_shell.do_image_create_via_import(self.gc, args) + self.fail("utils.exit should have been called") + except SystemExit: + pass + mock_utils_exit.assert_called_once_with(expected_msg) + + @mock.patch('glanceclient.common.utils.exit') + @mock.patch('sys.stdin', autospec=True) + def test_neg_image_create_via_import_stores_without_file( + self, mock_stdin, mock_utils_exit): + expected_msg = ('--stores option should only be provided with --file ' + 'option or stdin for the glance-direct import method.') + mock_utils_exit.side_effect = self._mock_utils_exit + mock_stdin.isatty = lambda: True + my_args = self.base_args.copy() + my_args.update( + {'id': 'IMG-01', 'import_method': 'glance-direct', + 'stores': 'file1,file2', + 'disk_format': 'raw', + 'container_format': 'bare', + }) + args = self._make_args(my_args) + + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + with mock.patch.object(self.gc.images, + 'get_stores_info') as mocked_stores_info: + mocked_stores_info.return_value = self.stores_info_response + mocked_info.return_value = self.import_info_response + try: + test_shell.do_image_create_via_import(self.gc, args) + self.fail("utils.exit should have been called") + except SystemExit: + pass + mock_utils_exit.assert_called_once_with(expected_msg) + + @mock.patch('glanceclient.common.utils.exit') + @mock.patch('sys.stdin', autospec=True) + def test_neg_image_create_via_import_all_stores_without_file( + self, mock_stdin, mock_utils_exit): + expected_msg = ('--all-stores option should only be provided with ' + '--file option or stdin for the glance-direct import ' + 'method.') + mock_utils_exit.side_effect = self._mock_utils_exit + mock_stdin.isatty = lambda: True + my_args = self.base_args.copy() + my_args.update( + {'id': 'IMG-01', 'import_method': 'glance-direct', + 'os_all_stores': True, + 'disk_format': 'raw', + 'container_format': 'bare', + }) + args = self._make_args(my_args) + + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + mocked_info.return_value = self.import_info_response + try: + test_shell.do_image_create_via_import(self.gc, args) + self.fail("utils.exit should have been called") + except SystemExit: + pass + mock_utils_exit.assert_called_once_with(expected_msg) + + @mock.patch('glanceclient.common.utils.exit') @mock.patch('os.access') @mock.patch('sys.stdin', autospec=True) def test_neg_image_create_via_import_no_file_and_stdin_with_store( @@ -1084,6 +1191,60 @@ mock_utils_exit.assert_called_once_with(expected_msg) @mock.patch('glanceclient.common.utils.exit') + def test_neg_image_create_via_import_stores_without_uri( + self, mock_utils_exit): + expected_msg = ('--stores option should only be provided with --uri ' + 'option for the web-download import method.') + mock_utils_exit.side_effect = self._mock_utils_exit + my_args = self.base_args.copy() + my_args.update( + {'id': 'IMG-01', 'import_method': 'web-download', + 'stores': 'file1,file2', + 'disk_format': 'raw', + 'container_format': 'bare', + }) + args = self._make_args(my_args) + + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + with mock.patch.object(self.gc.images, + 'get_stores_info') as mocked_stores_info: + mocked_stores_info.return_value = self.stores_info_response + mocked_info.return_value = self.import_info_response + try: + test_shell.do_image_create_via_import(self.gc, args) + self.fail("utils.exit should have been called") + except SystemExit: + pass + mock_utils_exit.assert_called_once_with(expected_msg) + + @mock.patch('glanceclient.common.utils.exit') + def test_neg_image_create_via_import_all_stores_without_uri( + self, mock_utils_exit): + expected_msg = ('--all-stores option should only be provided with ' + '--uri option for the web-download import ' + 'method.') + mock_utils_exit.side_effect = self._mock_utils_exit + my_args = self.base_args.copy() + my_args.update( + {'id': 'IMG-01', 'import_method': 'web-download', + 'os_all_stores': True, + 'disk_format': 'raw', + 'container_format': 'bare', + }) + args = self._make_args(my_args) + + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + mocked_info.return_value = self.import_info_response + try: + test_shell.do_image_create_via_import(self.gc, args) + self.fail("utils.exit should have been called") + except SystemExit: + pass + mock_utils_exit.assert_called_once_with(expected_msg) + + @mock.patch('glanceclient.common.utils.exit') @mock.patch('sys.stdin', autospec=True) def test_neg_image_create_via_import_web_download_no_uri_with_file( self, mock_stdin, mock_utils_exit): @@ -1785,7 +1946,8 @@ mock_import.return_value = None test_shell.do_image_import(self.gc, args) mock_import.assert_called_once_with( - 'IMG-01', 'glance-direct', None, backend=None) + 'IMG-01', 'glance-direct', None, backend=None, + all_stores=None, allow_failure=True, stores=None) def test_image_import_web_download(self): args = self._make_args( @@ -1803,7 +1965,9 @@ test_shell.do_image_import(self.gc, args) mock_import.assert_called_once_with( 'IMG-01', 'web-download', - 'http://example.com/image.qcow', backend=None) + 'http://example.com/image.qcow', + all_stores=None, allow_failure=True, + backend=None, stores=None) @mock.patch('glanceclient.common.utils.print_image') def test_image_import_no_print_image(self, mocked_utils_print_image): @@ -1821,9 +1985,108 @@ mock_import.return_value = None test_shell.do_image_import(self.gc, args) mock_import.assert_called_once_with( - 'IMG-02', 'glance-direct', None, backend=None) + 'IMG-02', 'glance-direct', None, stores=None, + all_stores=None, allow_failure=True, backend=None) mocked_utils_print_image.assert_not_called() + @mock.patch('glanceclient.common.utils.print_image') + @mock.patch('glanceclient.v2.shell._validate_backend') + def test_image_import_multiple_stores(self, mocked_utils_print_image, + msvb): + args = self._make_args( + {'id': 'IMG-02', 'uri': None, 'import_method': 'glance-direct', + 'from_create': False, 'stores': 'site1,site2'}) + with mock.patch.object(self.gc.images, 'image_import') as mock_import: + with mock.patch.object(self.gc.images, 'get') as mocked_get: + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + mocked_get.return_value = {'status': 'uploading', + 'container_format': 'bare', + 'disk_format': 'raw'} + mocked_info.return_value = self.import_info_response + mock_import.return_value = None + test_shell.do_image_import(self.gc, args) + mock_import.assert_called_once_with( + 'IMG-02', 'glance-direct', None, all_stores=None, + allow_failure=True, stores=['site1', 'site2'], + backend=None) + + @mock.patch('glanceclient.common.utils.print_image') + @mock.patch('glanceclient.v2.shell._validate_backend') + def test_image_import_copy_image(self, mocked_utils_print_image, + msvb): + args = self._make_args( + {'id': 'IMG-02', 'uri': None, 'import_method': 'copy-image', + 'from_create': False, 'stores': 'file1,file2'}) + with mock.patch.object(self.gc.images, 'image_import') as mock_import: + with mock.patch.object(self.gc.images, 'get') as mocked_get: + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + mocked_get.return_value = {'status': 'active', + 'container_format': 'bare', + 'disk_format': 'raw'} + mocked_info.return_value = self.import_info_response + mock_import.return_value = None + test_shell.do_image_import(self.gc, args) + mock_import.assert_called_once_with( + 'IMG-02', 'copy-image', None, all_stores=None, + allow_failure=True, stores=['file1', 'file2'], + backend=None) + + @mock.patch('glanceclient.common.utils.exit') + def test_neg_image_import_copy_image_not_active( + self, mock_utils_exit): + expected_msg = ("The 'copy-image' import method can only be used on " + "an image with status 'active'.") + mock_utils_exit.side_effect = self._mock_utils_exit + args = self._make_args( + {'id': 'IMG-02', 'uri': None, 'import_method': 'copy-image', + 'disk_format': 'raw', + 'container_format': 'bare', + 'from_create': False, 'stores': 'file1,file2'}) + with mock.patch.object( + self.gc.images, + 'get_stores_info') as mocked_stores_info: + with mock.patch.object(self.gc.images, 'get') as mocked_get: + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + + mocked_stores_info.return_value = self.stores_info_response + mocked_get.return_value = {'status': 'uploading', + 'container_format': 'bare', + 'disk_format': 'raw'} + mocked_info.return_value = self.import_info_response + try: + test_shell.do_image_import(self.gc, args) + self.fail("utils.exit should have been called") + except SystemExit: + pass + mock_utils_exit.assert_called_once_with(expected_msg) + + @mock.patch('glanceclient.common.utils.exit') + def test_neg_image_import_stores_all_stores_not_specified( + self, mock_utils_exit): + expected_msg = ("Provide either --stores or --all-stores for " + "'copy-image' import method.") + mock_utils_exit.side_effect = self._mock_utils_exit + my_args = self.base_args.copy() + my_args.update( + {'id': 'IMG-01', 'import_method': 'copy-image', + 'disk_format': 'raw', + 'container_format': 'bare', + }) + args = self._make_args(my_args) + + with mock.patch.object(self.gc.images, + 'get_import_info') as mocked_info: + mocked_info.return_value = self.import_info_response + try: + test_shell.do_image_import(self.gc, args) + self.fail("utils.exit should have been called") + except SystemExit: + pass + mock_utils_exit.assert_called_once_with(expected_msg) + def test_image_download(self): args = self._make_args( {'id': 'IMG-01', 'file': 'test', 'progress': True, @@ -1905,6 +2168,29 @@ mocked_utils_exit.assert_called_once_with() @mock.patch.object(utils, 'exit') + def test_do_image_delete_from_store_not_found(self, mocked_utils_exit): + args = argparse.Namespace(id='image1', store='store1') + with mock.patch.object(self.gc.images, + 'delete_from_store') as mocked_delete: + mocked_delete.side_effect = exc.HTTPNotFound + + test_shell.do_stores_delete(self.gc, args) + + self.assertEqual(1, mocked_delete.call_count) + mocked_utils_exit.assert_called_once_with('Multi Backend support ' + 'is not enabled or ' + 'Image/store not found.') + + def test_do_image_delete_from_store(self): + args = argparse.Namespace(id='image1', store='store1') + with mock.patch.object(self.gc.images, + 'delete_from_store') as mocked_delete: + test_shell.do_stores_delete(self.gc, args) + + mocked_delete.assert_called_once_with('store1', + 'image1') + + @mock.patch.object(utils, 'exit') @mock.patch.object(utils, 'print_err') def test_do_image_delete_with_forbidden_ids(self, mocked_print_err, mocked_utils_exit): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/glanceclient/v2/images.py new/python-glanceclient-3.1.1/glanceclient/v2/images.py --- old/python-glanceclient-2.17.0/glanceclient/v2/images.py 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/glanceclient/v2/images.py 2020-04-14 00:18:14.000000000 +0200 @@ -303,6 +303,14 @@ return body, resp @utils.add_req_id_to_object() + def delete_from_store(self, store_id, image_id): + """Delete image data from specific store.""" + url = ('/v2/stores/%(store)s/%(image)s' % {'store': store_id, + 'image': image_id}) + resp, body = self.http_client.delete(url) + return body, resp + + @utils.add_req_id_to_object() def stage(self, image_id, image_data, image_size=None): """Upload the data to image staging. @@ -318,13 +326,22 @@ @utils.add_req_id_to_object() def image_import(self, image_id, method='glance-direct', uri=None, - backend=None): + backend=None, stores=None, allow_failure=True, + all_stores=None): """Import Image via method.""" headers = {} url = '/v2/images/%s/import' % image_id data = {'method': {'name': method}} + if stores: + data['stores'] = stores + if allow_failure: + data['all_stores_must_succeed'] = False if backend is not None: headers['x-image-meta-store'] = backend + if all_stores: + data['all_stores'] = True + if allow_failure: + data['all_stores_must_succeed'] = False if uri: if method == 'web-download': diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/glanceclient/v2/resource_type_schema.py new/python-glanceclient-3.1.1/glanceclient/v2/resource_type_schema.py --- old/python-glanceclient-2.17.0/glanceclient/v2/resource_type_schema.py 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/glanceclient/v2/resource_type_schema.py 2020-04-14 00:18:14.000000000 +0200 @@ -25,8 +25,8 @@ "name": { "type": "string", "description": "Resource type names should be aligned with Heat " - "resource types whenever possible: http://docs." - "openstack.org/developer/heat/template_guide/" + "resource types whenever possible: https://docs." + "openstack.org/heat/latest/template_guide/" "openstack.html", "maxLength": 80 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/glanceclient/v2/shell.py new/python-glanceclient-3.1.1/glanceclient/v2/shell.py --- old/python-glanceclient-2.17.0/glanceclient/v2/shell.py 2019-09-13 17:03:31.000000000 +0200 +++ new/python-glanceclient-3.1.1/glanceclient/v2/shell.py 2020-04-14 00:18:14.000000000 +0200 @@ -150,6 +150,28 @@ @utils.arg('--store', metavar='<STORE>', default=utils.env('OS_IMAGE_STORE', default=None), help='Backend store to upload image to.') +@utils.arg('--stores', metavar='<STORES>', + default=utils.env('OS_IMAGE_STORES', default=None), + help=_('Stores to upload image to if multi-stores import ' + 'available. Comma separated list. Available stores can be ' + 'listed with "stores-info" call.')) +@utils.arg('--all-stores', type=strutils.bool_from_string, + metavar='[True|False]', + default=None, + dest='os_all_stores', + help=_('"all-stores" can be ued instead of "stores"-list to ' + 'indicate that image should be imported into all available ' + 'stores.')) +@utils.arg('--allow-failure', type=strutils.bool_from_string, + metavar='[True|False]', + dest='os_allow_failure', + default=utils.env('OS_IMAGE_ALLOW_FAILURE', default=True), + help=_('Indicator if all stores listed (or available) must ' + 'succeed. "True" by default meaning that we allow some ' + 'stores to fail and the status can be monitored from the ' + 'image metadata. If this is set to "False" the import will ' + 'be reverted should any of the uploads fail. Only usable ' + 'with "stores" or "all-stores".')) @utils.on_data_require_fields(DATA_FIELDS) def do_image_create_via_import(gc, args): """EXPERIMENTAL: Create a new image via image import. @@ -188,6 +210,10 @@ if args.import_method is None and (file_name or using_stdin): args.import_method = 'glance-direct' + if args.import_method == 'copy-image': + utils.exit("Import method 'copy-image' cannot be used " + "while creating the image.") + # determine whether the requested import method is valid import_methods = gc.images.get_import_info().get('import-methods') if args.import_method and args.import_method not in import_methods.get( @@ -198,9 +224,21 @@ # determine if backend is valid backend = None - if args.store: + stores = getattr(args, "stores", None) + all_stores = getattr(args, "os_all_stores", None) + + if (args.store and (stores or all_stores)) or (stores and all_stores): + utils.exit("Only one of --store, --stores and --all-stores can be " + "provided") + elif args.store: backend = args.store + # determine if backend is valid _validate_backend(backend, gc) + elif stores: + stores = str(stores).split(',') + for store in stores: + # determine if backend is valid + _validate_backend(store, gc) # make sure we have all and only correct inputs for the requested method if args.import_method is None: @@ -211,6 +249,14 @@ if backend and not (file_name or using_stdin): utils.exit("--store option should only be provided with --file " "option or stdin for the glance-direct import method.") + if stores and not (file_name or using_stdin): + utils.exit("--stores option should only be provided with --file " + "option or stdin for the glance-direct import method.") + if all_stores and not (file_name or using_stdin): + utils.exit("--all-stores option should only be provided with " + "--file option or stdin for the glance-direct import " + "method.") + if args.uri: utils.exit("You cannot specify a --uri with the glance-direct " "import method.") @@ -227,6 +273,12 @@ if backend and not args.uri: utils.exit("--store option should only be provided with --uri " "option for the web-download import method.") + if stores and not args.uri: + utils.exit("--stores option should only be provided with --uri " + "option for the web-download import method.") + if all_stores and not args.uri: + utils.exit("--all-stores option should only be provided with " + "--uri option for the web-download import method.") if not args.uri: utils.exit("URI is required for web-download import method. " "Please use '--uri <uri>'.") @@ -246,6 +298,7 @@ args.size = None do_image_stage(gc, args) args.from_create = True + args.stores = stores do_image_import(gc, args) image = gc.images.get(args.id) finally: @@ -503,6 +556,24 @@ utils.print_dict(stores_info) +@utils.arg('id', metavar='<IMAGE_ID>', help=_('ID of image to update.')) +@utils.arg('--store', metavar='<STORE_ID>', required=True, + help=_('Store to delete image from.')) +def do_stores_delete(gc, args): + """Delete image from specific store.""" + try: + gc.images.delete_from_store(args.store, args.id) + except exc.HTTPNotFound: + utils.exit('Multi Backend support is not enabled or Image/store not ' + 'found.') + except (exc.HTTPForbidden, exc.HTTPException) as e: + msg = ("Unable to delete image '%s' from store '%s'. (%s)" % ( + args.id, + args.store, + e)) + utils.exit(msg) + + @utils.arg('--allow-md5-fallback', action='store_true', default=utils.env('OS_IMAGE_ALLOW_MD5_FALLBACK', default=False), help=_('If os_hash_algo and os_hash_value properties are available ' @@ -617,19 +688,56 @@ @utils.arg('--store', metavar='<STORE>', default=utils.env('OS_IMAGE_STORE', default=None), help='Backend store to upload image to.') +@utils.arg('--stores', metavar='<STORES>', + default=utils.env('OS_IMAGE_STORES', default=None), + help='Stores to upload image to if multi-stores import available.') +@utils.arg('--all-stores', type=strutils.bool_from_string, + metavar='[True|False]', + default=None, + dest='os_all_stores', + help=_('"all-stores" can be ued instead of "stores"-list to ' + 'indicate that image should be imported all available ' + 'stores.')) +@utils.arg('--allow-failure', type=strutils.bool_from_string, + metavar='[True|False]', + dest='os_allow_failure', + default=utils.env('OS_IMAGE_ALLOW_FAILURE', default=True), + help=_('Indicator if all stores listed (or available) must ' + 'succeed. "True" by default meaning that we allow some ' + 'stores to fail and the status can be monitored from the ' + 'image metadata. If this is set to "False" the import will ' + 'be reverted should any of the uploads fail. Only usable ' + 'with "stores" or "all-stores".')) def do_image_import(gc, args): """Initiate the image import taskflow.""" - backend = None - if args.store: - backend = args.store + backend = getattr(args, "store", None) + stores = getattr(args, "stores", None) + all_stores = getattr(args, "os_all_stores", None) + allow_failure = getattr(args, "os_allow_failure", True) + + if not getattr(args, 'from_create', False): + if (args.store and (stores or all_stores)) or (stores and all_stores): + utils.exit("Only one of --store, --stores and --all-stores can be " + "provided") + elif args.store: + backend = args.store + # determine if backend is valid + _validate_backend(backend, gc) + elif stores: + stores = str(stores).split(',') + # determine if backend is valid - _validate_backend(backend, gc) + if stores: + for store in stores: + _validate_backend(store, gc) if getattr(args, 'from_create', False): # this command is being called "internally" so we can skip # validation -- just do the import and get out of here gc.images.image_import(args.id, args.import_method, args.uri, - backend=backend) + backend=backend, + stores=stores, all_stores=all_stores, + allow_failure=allow_failure) return # do input validation @@ -649,6 +757,10 @@ utils.exit("Import method should be 'web-download' if URI is " "provided.") + if args.import_method == 'copy-image' and not (stores or all_stores): + utils.exit("Provide either --stores or --all-stores for " + "'copy-image' import method.") + # check image properties image = gc.images.get(args.id) container_format = image.get('container_format') @@ -666,10 +778,16 @@ if image_status != 'queued': utils.exit("The 'web-download' import method can only be applied " "to an image in status 'queued'") + if args.import_method == 'copy-image': + if image_status != 'active': + utils.exit("The 'copy-image' import method can only be used on " + "an image with status 'active'.") # finally, do the import gc.images.image_import(args.id, args.import_method, args.uri, - backend=backend) + backend=backend, + stores=stores, all_stores=all_stores, + allow_failure=allow_failure) image = gc.images.get(args.id) utils.print_image(image) @@ -722,15 +840,15 @@ @utils.arg('tag_value', metavar='<TAG_VALUE>', help=_('Value of the tag.')) def do_image_tag_update(gc, args): - """Update an image with the given tag.""" - if not (args.image_id and args.tag_value): - utils.exit('Unable to update tag. Specify image_id and tag_value') - else: - gc.image_tags.update(args.image_id, args.tag_value) - image = gc.images.get(args.image_id) - image = [image] - columns = ['ID', 'Tags'] - utils.print_list(image, columns) + """Update an image with the given tag.""" + if not (args.image_id and args.tag_value): + utils.exit('Unable to update tag. Specify image_id and tag_value') + else: + gc.image_tags.update(args.image_id, args.tag_value) + image = gc.images.get(args.image_id) + image = [image] + columns = ['ID', 'Tags'] + utils.print_list(image, columns) @utils.arg('image_id', metavar='<IMAGE_ID>', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/lower-constraints.txt new/python-glanceclient-3.1.1/lower-constraints.txt --- old/python-glanceclient-2.17.0/lower-constraints.txt 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/lower-constraints.txt 2020-04-14 00:18:14.000000000 +0200 @@ -13,9 +13,7 @@ extras==1.0.0 fasteners==0.7.0 fixtures==3.0.0 -flake8==2.5.5 future==0.16.0 -hacking==0.12.0 idna==2.6 imagesize==0.7.1 iso8601==0.1.11 @@ -45,11 +43,9 @@ oslo.utils==3.33.0 paramiko==2.0.0 pbr==2.0.0 -pep8==1.5.7 prettytable==0.7.1 pyasn1==0.1.8 pycparser==2.18 -pyflakes==0.8.1 Pygments==2.2.0 pyinotify==0.9.6 pyOpenSSL==17.1.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/python_glanceclient.egg-info/PKG-INFO new/python-glanceclient-3.1.1/python_glanceclient.egg-info/PKG-INFO --- old/python-glanceclient-2.17.0/python_glanceclient.egg-info/PKG-INFO 2019-09-13 17:04:44.000000000 +0200 +++ new/python-glanceclient-3.1.1/python_glanceclient.egg-info/PKG-INFO 2020-04-14 00:19:04.000000000 +0200 @@ -1,6 +1,6 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.2 Name: python-glanceclient -Version: 2.17.0 +Version: 3.1.1 Summary: OpenStack Image API Client Library Home-page: https://docs.openstack.org/python-glanceclient/latest/ Author: OpenStack @@ -34,7 +34,7 @@ This is a client library for Glance built on the OpenStack Images API. It provides a Python API (the ``glanceclient`` module) and a command-line tool (``glance``). This library fully supports the v1 Images API, while support for the v2 API is in progress. - Development takes place via the usual OpenStack processes as outlined in the `developer guide <https://docs.openstack.org/infra/manual/developers.html>`_. The master repository is in `Git <https://git.openstack.org/cgit/openstack/python-glanceclient>`_. + Development takes place via the usual OpenStack processes as outlined in the `developer guide <https://docs.openstack.org/infra/manual/developers.html>`_. The master repository is in `Git <https://opendev.org/openstack/python-glanceclient>`_. See release notes and more at `<https://docs.openstack.org/python-glanceclient/latest/>`_. @@ -53,7 +53,7 @@ .. _Launchpad project: https://launchpad.net/python-glanceclient .. _Blueprints: https://blueprints.launchpad.net/python-glanceclient .. _Bugs: https://bugs.launchpad.net/python-glanceclient - .. _Source: https://git.openstack.org/cgit/openstack/python-glanceclient + .. _Source: https://opendev.org/openstack/python-glanceclient .. _How to Contribute: https://docs.openstack.org/infra/manual/developers.html .. _Specs: https://specs.openstack.org/openstack/glance-specs/ .. _Release notes: https://docs.openstack.org/releasenotes/python-glanceclient @@ -68,8 +68,9 @@ Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Requires-Python: >=3.6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/python_glanceclient.egg-info/SOURCES.txt new/python-glanceclient-3.1.1/python_glanceclient.egg-info/SOURCES.txt --- old/python-glanceclient-2.17.0/python_glanceclient.egg-info/SOURCES.txt 2019-09-13 17:04:44.000000000 +0200 +++ new/python-glanceclient-3.1.1/python_glanceclient.egg-info/SOURCES.txt 2020-04-14 00:19:04.000000000 +0200 @@ -116,11 +116,17 @@ releasenotes/notes/.placeholder releasenotes/notes/2.16.0_Release-43ebe06b74a272ba.yaml releasenotes/notes/2.17.0_Release-c67392be3b428d10.yaml +releasenotes/notes/3.1.0_Release-1337ddc753b88905.yaml +releasenotes/notes/3.1.1_Release-a452f4709d7d9a7d.yaml releasenotes/notes/bp-use-keystoneauth-e12f300e58577b13.yaml +releasenotes/notes/copy-existing-image-619b7e6bc3394446.yaml +releasenotes/notes/del_from_store-2d807c3038283907.yaml +releasenotes/notes/drop-py-2-7-f10417b8d1dd38fb.yaml releasenotes/notes/headers-encoding-bug-rocky-889ccd885a9cc4e8.yaml releasenotes/notes/hidden-images-support-9e2277ad62bf0d31.yaml releasenotes/notes/http-headers-per-rfc-8187-aafa3199f863be81.yaml releasenotes/notes/log-request-id-e7f67a23a0ed5c7b.yaml +releasenotes/notes/multi-store-import-45d05a6193ef2c04.yaml releasenotes/notes/multi-store-support-acc7ad0e7e8b6f99.yaml releasenotes/notes/multihash-download-verification-596e91bf7b68e7db.yaml releasenotes/notes/multihash-filter-ef2a48dc48fae9dc.yaml @@ -140,6 +146,7 @@ releasenotes/source/queens.rst releasenotes/source/rocky.rst releasenotes/source/stein.rst +releasenotes/source/train.rst releasenotes/source/unreleased.rst releasenotes/source/_static/.placeholder releasenotes/source/_templates/.placeholder diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/python_glanceclient.egg-info/pbr.json new/python-glanceclient-3.1.1/python_glanceclient.egg-info/pbr.json --- old/python-glanceclient-2.17.0/python_glanceclient.egg-info/pbr.json 2019-09-13 17:04:44.000000000 +0200 +++ new/python-glanceclient-3.1.1/python_glanceclient.egg-info/pbr.json 2020-04-14 00:19:04.000000000 +0200 @@ -1 +1 @@ -{"git_version": "40c19aa", "is_release": true} \ No newline at end of file +{"git_version": "1d8fa3d", "is_release": true} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/releasenotes/notes/3.1.0_Release-1337ddc753b88905.yaml new/python-glanceclient-3.1.1/releasenotes/notes/3.1.0_Release-1337ddc753b88905.yaml --- old/python-glanceclient-2.17.0/releasenotes/notes/3.1.0_Release-1337ddc753b88905.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-glanceclient-3.1.1/releasenotes/notes/3.1.0_Release-1337ddc753b88905.yaml 2020-04-14 00:18:14.000000000 +0200 @@ -0,0 +1,25 @@ +--- +prelude: | + This version of python-glanceclient finalizes client-side support for + the Glance import image in multiple stores, copy existing image in + multiple stores and delete image from single store. +fixes: + - | + Bug 1838694: glanceclient doesn't cleanup session it creates if one is not provided + + .. _1838694: https://bugs.launchpad.net/python-glanceclient/+bug/1838694 +upgrade: + - | + The following Command Line Interface calls now take ``--stores``, + ``--all-stores`` and ``--allow-failure`` option: + + * ``glance image-create-via-import`` + * ``glance image-import`` + + The value for ``--stores`` option is a list of store identifiers. The + list of available stores may be obtained from the ``glance stores-info`` + command. + + The value for ``--all-stores`` option could be True or False. + + The value for ``--allow-failure`` option could be True or False. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/releasenotes/notes/3.1.1_Release-a452f4709d7d9a7d.yaml new/python-glanceclient-3.1.1/releasenotes/notes/3.1.1_Release-a452f4709d7d9a7d.yaml --- old/python-glanceclient-2.17.0/releasenotes/notes/3.1.1_Release-a452f4709d7d9a7d.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-glanceclient-3.1.1/releasenotes/notes/3.1.1_Release-a452f4709d7d9a7d.yaml 2020-04-14 00:18:14.000000000 +0200 @@ -0,0 +1,10 @@ +--- +prelude: | + This version of python-glanceclient fixes an important issue where under + some circumstances the client was not sending information of the + appropriate data type when contacting the Image Service API. +fixes: + - | + Bug 1871674_: Pass boolean instead of string for --all-stores, --allow-failure options + + .. _1871674: https://code.launchpad.net/bugs/1871674 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/releasenotes/notes/copy-existing-image-619b7e6bc3394446.yaml new/python-glanceclient-3.1.1/releasenotes/notes/copy-existing-image-619b7e6bc3394446.yaml --- old/python-glanceclient-2.17.0/releasenotes/notes/copy-existing-image-619b7e6bc3394446.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-glanceclient-3.1.1/releasenotes/notes/copy-existing-image-619b7e6bc3394446.yaml 2020-04-14 00:18:14.000000000 +0200 @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support for copy-image import method which will copy existing + images into multiple stores. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/releasenotes/notes/del_from_store-2d807c3038283907.yaml new/python-glanceclient-3.1.1/releasenotes/notes/del_from_store-2d807c3038283907.yaml --- old/python-glanceclient-2.17.0/releasenotes/notes/del_from_store-2d807c3038283907.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-glanceclient-3.1.1/releasenotes/notes/del_from_store-2d807c3038283907.yaml 2020-04-14 00:18:14.000000000 +0200 @@ -0,0 +1,4 @@ +--- +features: + - | + Support for deleting the image data from single store. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/releasenotes/notes/drop-py-2-7-f10417b8d1dd38fb.yaml new/python-glanceclient-3.1.1/releasenotes/notes/drop-py-2-7-f10417b8d1dd38fb.yaml --- old/python-glanceclient-2.17.0/releasenotes/notes/drop-py-2-7-f10417b8d1dd38fb.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-glanceclient-3.1.1/releasenotes/notes/drop-py-2-7-f10417b8d1dd38fb.yaml 2020-04-14 00:18:14.000000000 +0200 @@ -0,0 +1,6 @@ +--- +upgrade: + - | + Python 2.7 support has been dropped. Last release of python-glanceclient + to support py2.7 is OpenStack Train. The minimum version of Python now + supported by python-glanceclient is Python 3.6. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/releasenotes/notes/multi-store-import-45d05a6193ef2c04.yaml new/python-glanceclient-3.1.1/releasenotes/notes/multi-store-import-45d05a6193ef2c04.yaml --- old/python-glanceclient-2.17.0/releasenotes/notes/multi-store-import-45d05a6193ef2c04.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-glanceclient-3.1.1/releasenotes/notes/multi-store-import-45d05a6193ef2c04.yaml 2020-04-14 00:18:14.000000000 +0200 @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support for multi-store import where user can import + image into multiple backend stores with single command. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/releasenotes/notes/pike-relnote-2c77b01aa8799f35.yaml new/python-glanceclient-3.1.1/releasenotes/notes/pike-relnote-2c77b01aa8799f35.yaml --- old/python-glanceclient-2.17.0/releasenotes/notes/pike-relnote-2c77b01aa8799f35.yaml 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/releasenotes/notes/pike-relnote-2c77b01aa8799f35.yaml 2020-04-14 00:18:14.000000000 +0200 @@ -70,7 +70,7 @@ may now be specified_ by setting the value of the ``OS_PROFILE`` environment variable. - .. _removed: https://git.openstack.org/cgit/openstack/python-glanceclient/commit/?id=28c003dc1179ddb3124fd30c6f525dd341ae9213 + .. _removed: https://opendev.org/openstack/python-glanceclient/commit/28c003dc1179ddb3124fd30c6f525dd341ae9213 .. _inoperative: https://specs.openstack.org/openstack/glance-specs/specs/liberty/approved/remove-special-client-ssl-handling.html - .. _optimization: https://git.openstack.org/cgit/openstack/python-glanceclient/commit/?id=1df55dd952fe52c1c1fc2583326d017275b01ddc - .. _specified: https://git.openstack.org/cgit/openstack/python-glanceclient/commit/?id=c0f88d5fc0fd947319e022cfeba21bcb15635316 + .. _optimization: https://opendev.org/openstack/python-glanceclient/commit/1df55dd952fe52c1c1fc2583326d017275b01ddc + .. _specified: https://opendev.org/openstack/python-glanceclient/commit/c0f88d5fc0fd947319e022cfeba21bcb15635316 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/releasenotes/source/earlier.rst new/python-glanceclient-3.1.1/releasenotes/source/earlier.rst --- old/python-glanceclient-2.17.0/releasenotes/source/earlier.rst 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/releasenotes/source/earlier.rst 2020-04-14 00:18:14.000000000 +0200 @@ -107,14 +107,14 @@ * 5e85d61 cleanup openstack-common.conf and sync updated files * 1432701_: Add parameter 'changes-since' for image-list of v1 -.. _remcustssl: https://review.openstack.org/#/c/187674 +.. _remcustssl: https://review.opendev.org/#/c/187674 .. _1309272: https://bugs.launchpad.net/python-glanceclient/+bug/1309272 .. _1481729: https://bugs.launchpad.net/python-glanceclient/+bug/1481729 .. _1477910: https://bugs.launchpad.net/python-glanceclient/+bug/1477910 .. _1475769: https://bugs.launchpad.net/python-glanceclient/+bug/1475769 .. _1479020: https://bugs.launchpad.net/python-glanceclient/+bug/1479020 .. _1433637: https://bugs.launchpad.net/python-glanceclient/+bug/1433637 -.. _metatags: https://review.openstack.org/#/c/179674/ +.. _metatags: https://review.opendev.org/#/c/179674/ .. _1472234: https://bugs.launchpad.net/python-glanceclient/+bug/1472234 .. _1473454: https://bugs.launchpad.net/python-cinderclient/+bug/1473454 .. _1468485: https://bugs.launchpad.net/python-glanceclient/+bug/1468485 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/releasenotes/source/index.rst new/python-glanceclient-3.1.1/releasenotes/source/index.rst --- old/python-glanceclient-2.17.0/releasenotes/source/index.rst 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/releasenotes/source/index.rst 2020-04-14 00:18:14.000000000 +0200 @@ -6,6 +6,7 @@ :maxdepth: 1 unreleased + train stein rocky queens diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/releasenotes/source/train.rst new/python-glanceclient-3.1.1/releasenotes/source/train.rst --- old/python-glanceclient-2.17.0/releasenotes/source/train.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-glanceclient-3.1.1/releasenotes/source/train.rst 2020-04-14 00:18:14.000000000 +0200 @@ -0,0 +1,6 @@ +=================================== + Train Series Release Notes +=================================== + +.. release-notes:: + :branch: stable/train diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/setup.cfg new/python-glanceclient-3.1.1/setup.cfg --- old/python-glanceclient-2.17.0/setup.cfg 2019-09-13 17:04:44.000000000 +0200 +++ new/python-glanceclient-3.1.1/setup.cfg 2020-04-14 00:19:04.000000000 +0200 @@ -7,6 +7,7 @@ author = OpenStack author-email = openstack-disc...@lists.openstack.org home-page = https://docs.openstack.org/python-glanceclient/latest/ +python-requires = >=3.6 classifier = Development Status :: 5 - Production/Stable Environment :: Console @@ -16,8 +17,8 @@ License :: OSI Approved :: Apache Software License Operating System :: POSIX :: Linux Programming Language :: Python - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 + Programming Language :: Python :: Implementation :: CPython + Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 @@ -26,17 +27,10 @@ packages = glanceclient -[global] -setup-hooks = - pbr.hooks.setup_hook - [entry_points] console_scripts = glance = glanceclient.shell:main -[wheel] -universal = 1 - [egg_info] tag_build = tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/setup.py new/python-glanceclient-3.1.1/setup.py --- old/python-glanceclient-2.17.0/setup.py 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/setup.py 2020-04-14 00:18:14.000000000 +0200 @@ -13,17 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT import setuptools -# In python < 2.7.4, a lazy loading of package `pbr` will break -# setuptools if some other modules registered functions in `atexit`. -# solution from: http://bugs.python.org/issue15881#msg170215 -try: - import multiprocessing # noqa -except ImportError: - pass - setuptools.setup( setup_requires=['pbr>=2.0.0'], pbr=True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/test-requirements.txt new/python-glanceclient-3.1.1/test-requirements.txt --- old/python-glanceclient-2.17.0/test-requirements.txt 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/test-requirements.txt 2020-04-14 00:18:14.000000000 +0200 @@ -2,7 +2,7 @@ # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. -hacking>=1.1.0,<1.2.0 # Apache-2.0 +hacking>=3.0,<3.1.0 # Apache-2.0 coverage!=4.4,>=4.0 # Apache-2.0 mock>=2.0.0 # BSD diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-glanceclient-2.17.0/tox.ini new/python-glanceclient-3.1.1/tox.ini --- old/python-glanceclient-2.17.0/tox.ini 2019-09-13 17:03:25.000000000 +0200 +++ new/python-glanceclient-3.1.1/tox.ini 2020-04-14 00:18:14.000000000 +0200 @@ -1,17 +1,15 @@ [tox] -envlist = py27,py37,pep8 +envlist = py37,pep8 minversion = 2.0 skipsdist = True [testenv] usedevelop = True -install_command = pip install {opts} {packages} -setenv = VIRTUAL_ENV={envdir} - OS_STDOUT_NOCAPTURE=False +setenv = OS_STDOUT_NOCAPTURE=False OS_STDERR_NOCAPTURE=False deps = - -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} + -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/ussuri} -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt commands = stestr run --slowest {posargs} @@ -39,18 +37,6 @@ bash tools/fix_ca_bundle.sh stestr run --slowest {posargs} -[testenv:functional-v1] -# TODO(rosmaita): remove this testenv at the beginning -# of the 'S' cycle -setenv = - OS_TEST_PATH = ./glanceclient/tests/functional/v1 - OS_TESTENV_NAME = {envname} -whitelist_externals = - bash -commands = - bash tools/fix_ca_bundle.sh - stestr run --slowest {posargs} - [testenv:cover] basepython = python3 setenv = @@ -70,14 +56,15 @@ [testenv:releasenotes] basepython = python3 deps = - -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} + -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/ussuri} -r{toxinidir}/doc/requirements.txt commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html [flake8] # E731 skipped as assign a lambda expression -ignore = E731,F403,F812,F821 +# W504 line break after binary operator +ignore = E731,F403,F812,F821,W504 show-source = True exclude = .venv*,.tox,dist,*egg,build,.git,doc,*lib/python*,.update-venv