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
 


Reply via email to