Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-novaclient for 
openSUSE:Factory checked in at 2021-10-27 22:21:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-novaclient (Old)
 and      /work/SRC/openSUSE:Factory/.python-novaclient.new.1890 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-novaclient"

Wed Oct 27 22:21:06 2021 rev:38 rq:927610 version:17.6.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-novaclient/python-novaclient.changes      
2021-05-10 15:39:43.581479209 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-novaclient.new.1890/python-novaclient.changes
    2021-10-27 22:21:20.971203084 +0200
@@ -1,0 +2,20 @@
+Tue Oct 26 21:31:47 UTC 2021 - cloud-de...@suse.de
+
+- update to version 17.6.0
+  - Update master for stable/wallaby
+  - Use importlib instead of imp
+  - Microversion 2.89 - os-volume_attachments
+  - When creating a client, pass the default logger
+  - Refactor constructing request body
+  - Microversion 2.90 - Configurable hostnames
+  - setup.cfg: Replace dashes with underscores
+  - Add Python3 xena unit tests
+  - Use Block Storage API v3 instead of API v2
+  - Use py3 as the default runtime for tox
+  - Add pre-commit
+  - Use well named anchor into the microversion history
+  - tests: Add missing 'nova update' unit tests
+  - Add unit tests for client logger
+  - Change minversion of tox to 3.18.0
+
+-------------------------------------------------------------------

Old:
----
  python-novaclient-17.4.0.tar.gz

New:
----
  python-novaclient-17.6.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-novaclient.spec ++++++
--- /var/tmp/diff_new_pack.2LhM0s/_old  2021-10-27 22:21:21.543203377 +0200
+++ /var/tmp/diff_new_pack.2LhM0s/_new  2021-10-27 22:21:21.547203380 +0200
@@ -17,14 +17,14 @@
 
 
 Name:           python-novaclient
-Version:        17.4.0
+Version:        17.6.0
 Release:        0
 Epoch:          0
 Summary:        Python API and CLI for OpenStack Nova
 License:        Apache-2.0
 Group:          Development/Languages/Python
 URL:            https://docs.openstack.org/python-novaclient
-Source0:        
https://files.pythonhosted.org/packages/source/p/python-novaclient/python-novaclient-17.4.0.tar.gz
+Source0:        
https://files.pythonhosted.org/packages/source/p/python-novaclient/python-novaclient-17.6.0.tar.gz
 BuildRequires:  openssl
 BuildRequires:  openstack-macros
 BuildRequires:  python3-cinderclient
@@ -91,7 +91,7 @@
 %build
 %{py3_build}
 
-PBR_VERSION=17.4.0 %sphinx_build -b html -d doc/build/doctrees doc/source 
doc/build/html
+PBR_VERSION=17.6.0 %sphinx_build -b html -d doc/build/doctrees doc/source 
doc/build/html
 # Fix hidden-file-or-dir warnings
 rm -fr doc/build/html/.doctrees doc/build/html/.buildinfo
 

++++++ _service ++++++
--- /var/tmp/diff_new_pack.2LhM0s/_old  2021-10-27 22:21:21.579203396 +0200
+++ /var/tmp/diff_new_pack.2LhM0s/_new  2021-10-27 22:21:21.579203396 +0200
@@ -1,8 +1,8 @@
 <services>
   <service mode="disabled" name="renderspec">
-    <param 
name="input-template">https://opendev.org/openstack/rpm-packaging/raw/branch/stable/wallaby/openstack/python-novaclient/python-novaclient.spec.j2</param>
+    <param 
name="input-template">https://opendev.org/openstack/rpm-packaging/raw/master/openstack/python-novaclient/python-novaclient.spec.j2</param>
     <param name="output-name">python-novaclient.spec</param>
-    <param 
name="requirements">https://opendev.org/openstack/python-novaclient/raw/branch/stable/wallaby/requirements.txt</param>
+    <param 
name="requirements">https://opendev.org/openstack/python-novaclient/raw/branch/stable/xena/requirements.txt</param>
     <param name="changelog-email">cloud-de...@suse.de</param>
     <param name="changelog-provider">gh,openstack,python-novaclient</param>
   </service>

++++++ python-novaclient-17.4.0.tar.gz -> python-novaclient-17.6.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/.pre-commit-config.yaml 
new/python-novaclient-17.6.0/.pre-commit-config.yaml
--- old/python-novaclient-17.4.0/.pre-commit-config.yaml        1970-01-01 
01:00:00.000000000 +0100
+++ new/python-novaclient-17.6.0/.pre-commit-config.yaml        2021-09-03 
12:18:38.000000000 +0200
@@ -0,0 +1,32 @@
+---
+default_language_version:
+  # force all unspecified python hooks to run python3
+  python: python3
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.0.1
+    hooks:
+      - id: trailing-whitespace
+      - id: mixed-line-ending
+        args: ['--fix', 'lf']
+      - id: check-byte-order-marker
+      - id: check-executables-have-shebangs
+      - id: check-merge-conflict
+      - id: debug-statements
+      - id: check-yaml
+        files: .*\.(yaml|yml)$
+  - repo: https://github.com/Lucas-C/pre-commit-hooks
+    rev: v1.1.10
+    hooks:
+      - id: remove-tabs
+        exclude: '.*\.(svg)$'
+  - repo: local
+    hooks:
+      - id: flake8
+        name: flake8
+        additional_dependencies:
+          - hacking>=3.0.1,<3.1.0
+        language: python
+        entry: flake8
+        files: '^.*\.py$'
+        exclude: '^(doc|releasenotes|tools)/.*$'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/.zuul.yaml 
new/python-novaclient-17.6.0/.zuul.yaml
--- old/python-novaclient-17.4.0/.zuul.yaml     2021-03-11 20:47:21.000000000 
+0100
+++ new/python-novaclient-17.6.0/.zuul.yaml     2021-09-03 12:18:38.000000000 
+0200
@@ -20,7 +20,7 @@
       - lib-forward-testing-python3
       - openstack-cover-jobs
       - openstack-lower-constraints-jobs
-      - openstack-python3-wallaby-jobs
+      - openstack-python3-xena-jobs
       - publish-openstack-docs-pti
       - release-notes-jobs-python3
     check:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/AUTHORS 
new/python-novaclient-17.6.0/AUTHORS
--- old/python-novaclient-17.4.0/AUTHORS        2021-03-11 20:48:00.000000000 
+0100
+++ new/python-novaclient-17.6.0/AUTHORS        2021-09-03 12:19:08.000000000 
+0200
@@ -51,6 +51,7 @@
 Augustina Ragwitz <au...@cpan.org>
 Avishay Traeger <avis...@il.ibm.com>
 Balazs Gibizer <balazs.gibi...@ericsson.com>
+Balazs Gibizer <balazs.gibi...@est.tech>
 Bartosz G??rski <bartosz.gor...@ntti3.com>
 Bartosz G??rski <bartosz.gor...@nttmcl.com>
 Bartosz G??rski <bart...@codilime.com>
@@ -357,6 +358,7 @@
 Svetlana Shturm <ssht...@mirantis.com>
 Swapnil Kulkarni (coolsvap) <m...@coolsvap.net>
 Sylvain Bauza <sba...@redhat.com>
+Takashi Kajinami <tkaji...@redhat.com>
 Takashi NATSUME <natsume.taka...@lab.ntt.co.jp>
 Takashi Natsume <takanat...@gmail.com>
 Takashi Sogabe <sog...@iij.ad.jp>
@@ -405,6 +407,7 @@
 Yikun Jiang <yikunk...@gmail.com>
 Yongli He <yongli...@intel.com>
 Your Name <heut2...@gmail.com>
+YuehuiLei <leiyue...@inspur.com>
 Yufang Zhang <yufang521...@gmail.com>
 Yunhong, Jiang <yunhong.ji...@intel.com>
 Yuriy Taraday <yorik....@gmail.com>
@@ -469,6 +472,7 @@
 lzyeval <lzye...@gmail.com>
 masumotok <masumo...@nttdata.co.jp>
 melanie witt <melw...@yahoo-inc.com>
+melanie witt <melwi...@gmail.com>
 melwitt <melw...@yahoo-inc.com>
 meretiko <meretikoe...@gmail.com>
 neetu <nut...@gmail.com>
@@ -513,6 +517,7 @@
 zhang-jinnan <ben...@99cloud.net>
 zhang.lei <zhang....@99cloud.net>
 zhangbailin <zhangbai...@inspur.com>
+zhangboye <zhangb...@inspur.com>
 zhangdaolong <zhangdaol...@fiberhome.com>
 zhangjl <zhan...@awcloud.com>
 zhangtralon <zhangchunlo...@huawei.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/ChangeLog 
new/python-novaclient-17.6.0/ChangeLog
--- old/python-novaclient-17.4.0/ChangeLog      2021-03-11 20:48:00.000000000 
+0100
+++ new/python-novaclient-17.6.0/ChangeLog      2021-09-03 12:19:08.000000000 
+0200
@@ -1,6 +1,29 @@
 CHANGES
 =======
 
+17.6.0
+------
+
+* Microversion 2.90 - Configurable hostnames
+* tests: Add missing 'nova update' unit tests
+* Add pre-commit
+* Microversion 2.89 - os-volume\_attachments
+* Use importlib instead of imp
+* Use Block Storage API v3 instead of API v2
+
+17.5.0
+------
+
+* Change minversion of tox to 3.18.0
+* Refactor constructing request body
+* setup.cfg: Replace dashes with underscores
+* Use py3 as the default runtime for tox
+* Add unit tests for client logger
+* When creating a client, pass the default logger
+* Add Python3 xena unit tests
+* Update master for stable/wallaby
+* Use well named anchor into the microversion history
+
 17.4.0
 ------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/PKG-INFO 
new/python-novaclient-17.6.0/PKG-INFO
--- old/python-novaclient-17.4.0/PKG-INFO       2021-03-11 20:48:00.661249600 
+0100
+++ new/python-novaclient-17.6.0/PKG-INFO       2021-09-03 12:19:08.998951000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: python-novaclient
-Version: 17.4.0
+Version: 17.6.0
 Summary: Client library for OpenStack Compute API
 Home-page: https://docs.openstack.org/python-novaclient/latest
 Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/doc/source/cli/nova.rst 
new/python-novaclient-17.6.0/doc/source/cli/nova.rst
--- old/python-novaclient-17.4.0/doc/source/cli/nova.rst        2021-03-11 
20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/doc/source/cli/nova.rst        2021-09-03 
12:18:38.000000000 +0200
@@ -975,6 +975,7 @@
                     [--trusted-image-certificate-id 
<trusted-image-certificate-id>]
                     [--host <host>]
                     [--hypervisor-hostname <hypervisor-hostname>]
+                    [--hostname <hostname>]
                     <name>
 
 Boot a new server.
@@ -1149,6 +1150,12 @@
   Requested hypervisor hostname to create servers. Admin only by default.
   (Supported by API versions '2.74' - '2.latest')
 
+``--hostname <hostname>``
+  Hostname for the instance. This sets the hostname stored in the
+  metadata server: a utility such as cloud-init running on the guest
+  is required to propagate these changes to the guest.
+  (Supported by API versions '2.90' - '2.latest')
+
 .. _nova_clear-password:
 
 nova clear-password
@@ -2885,6 +2892,7 @@
                        [--user-data <user-data>] [--user-data-unset]
                        [--trusted-image-certificate-id 
<trusted-image-certificate-id>]
                        [--trusted-image-certificates-unset]
+                       [--hostname <hostname>]
                        <server> <image>
 
 Shutdown, re-image, and re-boot a server.
@@ -2958,6 +2966,12 @@
   specified with the ``--trusted-image-certificate-id`` option.
   (Supported by API versions '2.63' - '2.latest')
 
+``--hostname <hostname>``
+  New hostname for the instance. This only updates the hostname
+  stored in the metadata server: a utility running on the guest
+  is required to propagate these changes to the guest.
+  (Supported by API versions '2.90' - '2.latest')
+
 .. _nova_refresh-network:
 
 nova refresh-network
@@ -3795,9 +3809,11 @@
 
 .. code-block:: console
 
-   usage: nova update [--name <name>] [--description <description>] <server>
+   usage: nova update [--name <name>] [--description <description>]
+                      [--hostname <hostname>]
+                      <server>
 
-Update the name or the description for a server.
+Update attributes of a server.
 
 **Positional arguments:**
 
@@ -3815,6 +3831,12 @@
   will be removed. (Supported by API versions
   '2.19' - '2.latest')
 
+``--hostname <hostname>``
+  New hostname for the instance. This only updates the hostname
+  stored in the metadata server: a utility running on the guest
+  is required to propagate these changes to the guest.
+  (Supported by API versions '2.90' - '2.latest')
+
 .. _nova_usage:
 
 nova usage
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/novaclient/__init__.py 
new/python-novaclient-17.6.0/novaclient/__init__.py
--- old/python-novaclient-17.4.0/novaclient/__init__.py 2021-03-11 
20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/__init__.py 2021-09-03 
12:18:38.000000000 +0200
@@ -25,4 +25,4 @@
 # when client supported the max version, and bumped sequentially, otherwise
 # the client may break due to server side new version may include some
 # backward incompatible change.
-API_MAX_VERSION = api_versions.APIVersion("2.88")
+API_MAX_VERSION = api_versions.APIVersion("2.90")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/novaclient/tests/functional/base.py 
new/python-novaclient-17.6.0/novaclient/tests/functional/base.py
--- old/python-novaclient-17.4.0/novaclient/tests/functional/base.py    
2021-03-11 20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/tests/functional/base.py    
2021-09-03 12:18:38.000000000 +0200
@@ -13,7 +13,7 @@
 import os
 import time
 
-from cinderclient.v2 import client as cinderclient
+from cinderclient.v3 import client as cinderclient
 import fixtures
 from glanceclient import client as glanceclient
 from keystoneauth1.exceptions import discovery as discovery_exc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/novaclient/tests/unit/test_client.py 
new/python-novaclient-17.6.0/novaclient/tests/unit/test_client.py
--- old/python-novaclient-17.4.0/novaclient/tests/unit/test_client.py   
2021-03-11 20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/tests/unit/test_client.py   
2021-09-03 12:18:38.000000000 +0200
@@ -124,3 +124,15 @@
         self.assertNotEqual(original_kwargs, actual_kwargs)
         self.assertEqual({}, actual_kwargs)
         self.assertTrue(mock_warnings.warn.called)
+
+
+class ClientTest(utils.TestCase):
+
+    def test_logger(self):
+        client = novaclient.client.Client('2.1', logger=mock.sentinel.logger)
+        self.assertEqual(mock.sentinel.logger, client.logger)
+        self.assertEqual(mock.sentinel.logger, client.client.logger)
+        client = novaclient.client.Client('2.1')
+        self.assertEqual('novaclient.v2.client', client.logger.name)
+        self.assertIsNotNone(client.client.logger)
+        self.assertEqual('novaclient.v2.client', client.client.logger.name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/novaclient/tests/unit/test_discover.py 
new/python-novaclient-17.6.0/novaclient/tests/unit/test_discover.py
--- old/python-novaclient-17.4.0/novaclient/tests/unit/test_discover.py 
2021-03-11 20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/tests/unit/test_discover.py 
2021-09-03 12:18:38.000000000 +0200
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import imp
+import importlib
 import inspect
 from unittest import mock
 
@@ -31,7 +31,8 @@
         def mock_mgr():
             fake_ep = mock.Mock()
             fake_ep.name = 'foo'
-            fake_ep.module = imp.new_module('foo')
+            module_spec = importlib.machinery.ModuleSpec('foo', None)
+            fake_ep.module = importlib.util.module_from_spec(module_spec)
             fake_ep.load.return_value = fake_ep.module
             fake_ext = extension.Extension(
                 name='foo',
@@ -52,10 +53,14 @@
     def test_discover_extensions(self):
 
         def mock_discover_via_python_path():
-            yield 'foo', imp.new_module('foo')
+            module_spec = importlib.machinery.ModuleSpec('foo', None)
+            module = importlib.util.module_from_spec(module_spec)
+            yield 'foo', module
 
         def mock_discover_via_entry_points():
-            yield 'baz', imp.new_module('baz')
+            module_spec = importlib.machinery.ModuleSpec('baz', None)
+            module = importlib.util.module_from_spec(module_spec)
+            yield 'baz', module
 
         @mock.patch.object(client,
                            '_discover_via_python_path',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/novaclient/tests/unit/v2/fakes.py 
new/python-novaclient-17.6.0/novaclient/tests/unit/v2/fakes.py
--- old/python-novaclient-17.4.0/novaclient/tests/unit/v2/fakes.py      
2021-03-11 20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/tests/unit/v2/fakes.py      
2021-09-03 12:18:38.000000000 +0200
@@ -2408,6 +2408,9 @@
     def delete_servers_1234_migrations_1(self):
         return (202, {}, None)
 
+    def put_servers_1234(self, **kw):
+        return (201, {}, None)
+
     def put_servers_1234_tags_tag(self, **kw):
         return (201, {}, None)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/novaclient/tests/unit/v2/test_servers.py 
new/python-novaclient-17.6.0/novaclient/tests/unit/v2/test_servers.py
--- old/python-novaclient-17.4.0/novaclient/tests/unit/v2/test_servers.py       
2021-03-11 20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/tests/unit/v2/test_servers.py       
2021-09-03 12:18:38.000000000 +0200
@@ -1905,3 +1905,90 @@
         self.cs.api_version = api_versions.APIVersion('2.77')
         s = self.cs.servers.get(1234)
         self.assertRaises(exceptions.VersionNotFoundForAPIMethod, s.topology)
+
+
+class ServersV290Test(ServersV278Test):
+
+    api_version = '2.90'
+
+    def test_create_server_with_hostname(self):
+        self.cs.servers.create(
+            name='My server',
+            image=1,
+            flavor=1,
+            nics='auto',
+            hostname='new-hostname',
+        )
+        self.assert_called(
+            'POST', '/servers',
+            {
+                'server': {
+                    'flavorRef': '1',
+                    'imageRef': '1',
+                    'max_count': 1,
+                    'min_count': 1,
+                    'name': 'My server',
+                    'networks': 'auto',
+                    'hostname': 'new-hostname'
+                },
+            }
+        )
+
+    def test_create_server_with_hostname_pre_290_fails(self):
+        self.cs.api_version = api_versions.APIVersion('2.89')
+        ex = self.assertRaises(
+            exceptions.UnsupportedAttribute,
+            self.cs.servers.create,
+            name='My server',
+            image=1,
+            flavor=1,
+            nics='auto',
+            hostname='new-hostname')
+        self.assertIn(
+            "'hostname' argument is only allowed since microversion 2.90",
+            str(ex))
+
+    def test_rebuild_server_with_hostname(self):
+        s = self.cs.servers.get(1234)
+        ret = s.rebuild(image="1", hostname='new-hostname')
+        self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST)
+        self.assert_called(
+            'POST', '/servers/1234/action',
+            {
+                'rebuild': {
+                    'imageRef': '1',
+                    'hostname': 'new-hostname',
+                },
+            },
+        )
+
+    def test_rebuild_server_with_hostname_pre_290_fails(self):
+        self.cs.api_version = api_versions.APIVersion('2.89')
+        ex = self.assertRaises(
+            exceptions.UnsupportedAttribute,
+            self.cs.servers.rebuild,
+            '1234', fakes.FAKE_IMAGE_UUID_1,
+            hostname='new-hostname')
+        self.assertIn('hostname', str(ex))
+
+    def test_update_server_with_hostname(self):
+        s = self.cs.servers.get(1234)
+
+        s.update(hostname='new-hostname')
+        self.assert_called(
+            'PUT', '/servers/1234',
+            {
+                'server': {
+                    'hostname': 'new-hostname',
+                },
+            },
+        )
+
+    def test_update_with_hostname_pre_290_fails(self):
+        self.cs.api_version = api_versions.APIVersion('2.89')
+        s = self.cs.servers.get(1234)
+        ex = self.assertRaises(
+            TypeError,
+            s.update,
+            hostname='new-hostname')
+        self.assertIn('hostname', str(ex))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/novaclient/tests/unit/v2/test_shell.py 
new/python-novaclient-17.6.0/novaclient/tests/unit/v2/test_shell.py
--- old/python-novaclient-17.4.0/novaclient/tests/unit/v2/test_shell.py 
2021-03-11 20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/tests/unit/v2/test_shell.py 
2021-09-03 12:18:38.000000000 +0200
@@ -1502,6 +1502,34 @@
         self.assertRaises(SystemExit, self.run_command,
                           cmd, api_version='2.73')
 
+    def test_boot_with_hostname(self):
+        self.run_command(
+            'boot --flavor 1 --image %s '
+            '--hostname my-hostname --nic auto '
+            'some-server' % FAKE_UUID_1,
+            api_version='2.90')
+        self.assert_called_anytime(
+            'POST', '/servers',
+            {'server': {
+                'flavorRef': '1',
+                'name': 'some-server',
+                'imageRef': FAKE_UUID_1,
+                'min_count': 1,
+                'max_count': 1,
+                'networks': 'auto',
+                'hostname': 'my-hostname',
+            }},
+        )
+
+    def test_boot_with_hostname_pre_v290(self):
+        cmd = (
+            'boot --flavor 1 --image %s --nic auto '
+            '--hostname my-hostname some-server' % FAKE_UUID_1
+        )
+        self.assertRaises(
+            SystemExit, self.run_command,
+            cmd, api_version='2.89')
+
     def test_flavor_list(self):
         out, _ = self.run_command('flavor-list')
         self.assert_called_anytime('GET', '/flavors/detail')
@@ -2258,6 +2286,31 @@
         self.assertNotIn('server_groups', out)
         self.assertNotIn('a67359fb-d397-4697-88f1-f55e3ee7c499', out)
 
+    def test_rebuild_with_hostname(self):
+        self.run_command(
+            'rebuild sample-server %s --hostname new-hostname' % FAKE_UUID_1,
+            api_version='2.90')
+        self.assert_called('GET', '/servers?name=sample-server', pos=0)
+        self.assert_called('GET', '/servers/1234', pos=1)
+        self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2)
+        self.assert_called(
+            'POST', '/servers/1234/action',
+            {
+                'rebuild': {
+                    'imageRef': FAKE_UUID_1,
+                    'description': None,
+                    'hostname': 'new-hostname',
+                },
+            },
+            pos=3)
+        self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4)
+
+    def test_rebuild_with_hostname_pre_v290(self):
+        self.assertRaises(
+            SystemExit, self.run_command,
+            'rebuild sample-server %s --hostname hostname' % FAKE_UUID_1,
+            api_version='2.89')
+
     def test_start(self):
         self.run_command('start sample-server')
         self.assert_called('POST', '/servers/1234/action', {'os-start': None})
@@ -2395,6 +2448,54 @@
         self.assert_called('POST', '/servers/1234/action',
                            {'migrate': {'host': 'target-host'}})
 
+    def test_update(self):
+        self.run_command('update --name new-name sample-server')
+        expected_put_body = {
+            "server": {
+                "name": "new-name"
+            }
+        }
+        self.assert_called('GET', '/servers/1234', pos=-2)
+        self.assert_called('PUT', '/servers/1234', expected_put_body, pos=-1)
+
+    def test_update_with_description(self):
+        self.run_command(
+            'update --description new-description sample-server',
+            api_version='2.19')
+        expected_put_body = {
+            "server": {
+                "description": "new-description"
+            }
+        }
+        self.assert_called('GET', '/servers/1234', pos=-2)
+        self.assert_called('PUT', '/servers/1234', expected_put_body, pos=-1)
+
+    def test_update_with_description_pre_v219(self):
+        self.assertRaises(
+            SystemExit,
+            self.run_command,
+            'update --description new-description sample-server',
+            api_version='2.18')
+
+    def test_update_with_hostname(self):
+        self.run_command(
+            'update --hostname new-hostname sample-server',
+            api_version='2.90')
+        expected_put_body = {
+            "server": {
+                "hostname": "new-hostname"
+            }
+        }
+        self.assert_called('GET', '/servers/1234', pos=-2)
+        self.assert_called('PUT', '/servers/1234', expected_put_body, pos=-1)
+
+    def test_update_with_hostname_pre_v290(self):
+        self.assertRaises(
+            SystemExit,
+            self.run_command,
+            'update --hostname new-hostname sample-server',
+            api_version='2.89')
+
     def test_resize(self):
         self.run_command('resize sample-server 1')
         self.assert_called('POST', '/servers/1234/action',
@@ -3994,6 +4095,24 @@
         self.assert_called('GET', '/servers/1234/os-volume_attachments')
         self.assertIn('DELETE ON TERMINATION', out)
 
+    def test_volume_attachments_pre_v2_89(self):
+        out = self.run_command(
+            'volume-attachments 1234', api_version='2.88')[0]
+        self.assert_called('GET', '/servers/1234/os-volume_attachments')
+        # We can't assert just ID here as it's part of various other fields
+        self.assertIn('| ID', out)
+        self.assertNotIn('ATTACHMENT ID', out)
+        self.assertNotIn('BDM UUID', out)
+
+    def test_volume_attachments_v2_89(self):
+        out = self.run_command(
+            'volume-attachments 1234', api_version='2.89')[0]
+        self.assert_called('GET', '/servers/1234/os-volume_attachments')
+        # We can't assert just ID here as it's part of various other fields
+        self.assertNotIn('| ID', out)
+        self.assertIn('ATTACHMENT ID', out)
+        self.assertIn('BDM UUID', out)
+
     def test_volume_attach_with_delete_on_termination_pre_v2_79(self):
         self.assertRaises(
             SystemExit, self.run_command,
@@ -4577,6 +4696,7 @@
             84,  # There are no version-wrapped shell method changes for this.
             86,  # doesn't require any changes in novaclient.
             87,  # doesn't require any changes in novaclient.
+            89,  # There are no version-wrapped shell method changes for this.
         ])
         versions_supported = set(range(0,
                                  novaclient.API_MAX_VERSION.ver_minor + 1))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/novaclient/v2/client.py 
new/python-novaclient-17.6.0/novaclient/v2/client.py
--- old/python-novaclient-17.4.0/novaclient/v2/client.py        2021-03-11 
20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/v2/client.py        2021-09-03 
12:18:38.000000000 +0200
@@ -192,7 +192,7 @@
             endpoint_type=endpoint_type,
             http_log_debug=http_log_debug,
             insecure=insecure,
-            logger=logger,
+            logger=self.logger,
             os_cache=self.os_cache,
             password=password,
             project_domain_id=project_domain_id,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/novaclient/v2/servers.py 
new/python-novaclient-17.6.0/novaclient/v2/servers.py
--- old/python-novaclient-17.4.0/novaclient/v2/servers.py       2021-03-11 
20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/v2/servers.py       2021-09-03 
12:18:38.000000000 +0200
@@ -67,17 +67,17 @@
     @api_versions.wraps("2.0", "2.18")
     def update(self, name=None):
         """
-        Update the name for this server.
+        Update attributes of this server.
 
         :param name: Update the server's name.
         :returns: :class:`Server`
         """
         return self.manager.update(self, name=name)
 
-    @api_versions.wraps("2.19")
+    @api_versions.wraps("2.19", "2.89")
     def update(self, name=None, description=None):
         """
-        Update the name and the description for this server.
+        Update attributes of this server.
 
         :param name: Update the server's name.
         :param description: Update the server's description.
@@ -88,6 +88,23 @@
             update_kwargs["description"] = description
         return self.manager.update(self, **update_kwargs)
 
+    @api_versions.wraps("2.90")
+    def update(self, name=None, description=None, hostname=None):
+        """
+        Update attributes of this server.
+
+        :param name: Update the server's name.
+        :param description: Update the server's description.
+        :param hostname: Update the server's hostname.
+        :returns: :class:`Server`
+        """
+        update_kwargs = {"name": name}
+        if description is not None:
+            update_kwargs["description"] = description
+        if hostname is not None:
+            update_kwargs["hostname"] = hostname
+        return self.manager.update(self, **update_kwargs)
+
     def get_console_output(self, length=None):
         """
         Get text console log output from Server.
@@ -704,7 +721,7 @@
               config_drive=None, admin_pass=None, disk_config=None,
               access_ip_v4=None, access_ip_v6=None, description=None,
               tags=None, trusted_image_certificates=None,
-              host=None, hypervisor_hostname=None, **kwargs):
+              host=None, hypervisor_hostname=None, hostname=None, **kwargs):
         """
         Create (boot) a new server.
         """
@@ -833,6 +850,9 @@
         if hypervisor_hostname:
             body['server']['hypervisor_hostname'] = hypervisor_hostname
 
+        if hostname:
+            body['server']['hostname'] = hostname
+
         return self._create('/servers', body, response_key,
                             return_raw=return_raw, **kwargs)
 
@@ -1318,10 +1338,8 @@
                config_drive=None, disk_config=None, admin_pass=None,
                access_ip_v4=None, access_ip_v6=None,
                trusted_image_certificates=None,
-               host=None, hypervisor_hostname=None,
+               host=None, hypervisor_hostname=None, hostname=None,
                **kwargs):
-        # TODO(anthony): indicate in doc string if param is an extension
-        # and/or optional
         """
         Create (boot) a new server.
 
@@ -1390,6 +1408,8 @@
                      (allowed since microversion 2.74)
         :param hypervisor_hostname: requested hypervisor hostname to create
                                     servers (allowed since microversion 2.74)
+        :param hostname: requested hostname of server (allowed since
+                         microversion 2.90)
         """
         if not min_count:
             min_count = 1
@@ -1453,6 +1473,10 @@
             raise exceptions.UnsupportedAttribute(
                 "hypervisor_hostname", "2.74")
 
+        hostname_microversion = api_versions.APIVersion("2.90")
+        if hostname and self.api_version < hostname_microversion:
+            raise exceptions.UnsupportedAttribute("hostname", "2.90")
+
         boot_kwargs = dict(
             meta=meta, files=files, userdata=userdata,
             reservation_id=reservation_id, min_count=min_count,
@@ -1463,7 +1487,7 @@
             access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6,
             trusted_image_certificates=trusted_image_certificates,
             host=host, hypervisor_hostname=hypervisor_hostname,
-            **kwargs)
+            hostname=hostname, **kwargs)
 
         if block_device_mapping:
             boot_kwargs['block_device_mapping'] = block_device_mapping
@@ -1479,10 +1503,11 @@
     @api_versions.wraps("2.0", "2.18")
     def update(self, server, name=None):
         """
-        Update the name for a server.
+        Update attributes of a server.
 
         :param server: The :class:`Server` (or its ID) to update.
         :param name: Update the server's name.
+        :returns: :class:`Server`
         """
         if name is None:
             return
@@ -1495,15 +1520,16 @@
 
         return self._update("/servers/%s" % base.getid(server), body, "server")
 
-    @api_versions.wraps("2.19")
+    @api_versions.wraps("2.19", "2.89")
     def update(self, server, name=None, description=None):
         """
-        Update the name or the description for a server.
+        Update attributes of a server.
 
         :param server: The :class:`Server` (or its ID) to update.
         :param name: Update the server's name.
         :param description: Update the server's description. If it equals to
             empty string(i.g. ""), the server description will be removed.
+        :returns: :class:`Server`
         """
         if name is None and description is None:
             return
@@ -1518,6 +1544,36 @@
 
         return self._update("/servers/%s" % base.getid(server), body, "server")
 
+    @api_versions.wraps("2.90")
+    def update(self, server, name=None, description=None, hostname=None):
+        """
+        Update attributes of a server.
+
+        :param server: The :class:`Server` (or its ID) to update.
+        :param name: Update the server's name.
+        :param description: Update the server's description. If it equals to
+            empty string(i.g. ""), the server description will be removed.
+        :param hostname: Update the server's hostname as recorded by the
+            metadata service. Note that a separate utility running on the
+            guest will be necessary to reflect these changes in the guest
+            itself.
+        :returns: :class:`Server`
+        """
+        if name is None and description is None and hostname is None:
+            return
+
+        body = {"server": {}}
+        if name:
+            body["server"]["name"] = name
+        if description == "":
+            body["server"]["description"] = None
+        elif description:
+            body["server"]["description"] = description
+        if hostname:
+            body["server"]["hostname"] = hostname
+
+        return self._update("/servers/%s" % base.getid(server), body, "server")
+
     def change_password(self, server, password):
         """
         Update the password for a server.
@@ -1548,6 +1604,7 @@
         """
         return self._action('reboot', server, {'type': reboot_type})
 
+    # TODO(stephenfin): Expand out kwargs
     def rebuild(self, server, image, password=None, disk_config=None,
                 preserve_ephemeral=False, name=None, meta=None, files=None,
                 **kwargs):
@@ -1555,34 +1612,36 @@
         Rebuild -- shut down and then re-image -- a server.
 
         :param server: The :class:`Server` (or its ID) to share onto.
-        :param image: the :class:`Image` (or its ID) to re-image with.
-        :param password: string to set as password on the rebuilt server.
-        :param disk_config: partitioning mode to use on the rebuilt server.
-                            Valid values are 'AUTO' or 'MANUAL'
+        :param image: The :class:`Image` (or its ID) to re-image with.
+        :param password: String to set as password on the rebuilt server.
+        :param disk_config: Partitioning mode to use on the rebuilt server.
+            Valid values are 'AUTO' or 'MANUAL'
         :param preserve_ephemeral: If True, request that any ephemeral device
             be preserved when rebuilding the instance. Defaults to False.
         :param name: Something to name the server.
         :param meta: A dict of arbitrary key/value metadata to store for this
-                     server. Both keys and values must be <=255 characters.
+            server. Both keys and values must be <=255 characters.
         :param files: A dict of files to overwrite on the server upon boot.
-                      Keys are file names (i.e. ``/etc/passwd``) and values
-                      are the file contents (either as a string or as a
-                      file-like object). A maximum of five entries is allowed,
-                      and each file must be 10k or less.
-                      (deprecated starting with microversion 2.57)
-        :param description: optional description of the server (allowed since
-                            microversion 2.19)
-        :param key_name: optional key pair name for rebuild operation; passing
-                         None will unset the key for the server instance
-                         (starting from microversion 2.54)
-        :param userdata: optional user data to pass to be exposed by the
-                         metadata server; this can be a file type object as
-                         well or a string. If None is specified, the existing
-                         user_data is unset.
-                         (starting from microversion 2.57)
+            Keys are file names (i.e. ``/etc/passwd``) and values are the file
+            contents (either as a string or as a file-like object). A maximum
+            of five entries is allowed, and each file must be 10k or less.
+            (deprecated starting with microversion 2.57)
+        :param description: Optional description of the server. If None is
+            specified, the existing description will be unset.
+            (starting from microversion 2.19)
+        :param key_name: Optional key pair name for rebuild operation. If None
+            is specified, the existing key will be unset.
+            (starting from microversion 2.54)
+        :param userdata: Optional user data to pass to be exposed by the
+            metadata server; this can be a file type object as well or a
+            string. If None is specified, the existing user_data is unset.
+            (starting from microversion 2.57)
         :param trusted_image_certificates: A list of trusted certificate IDs
-                         or None to unset/reset the servers trusted image
-                         certificates (allowed since microversion 2.63)
+            or None to unset/reset the servers trusted image certificates
+            (starting from microversion 2.63)
+        :param hostname: Optional hostname to configure for the instance. If
+            None is specified, the existing hostname will be unset.
+            (starting from microversion 2.90)
         :returns: :class:`Server`
         """
         descr_microversion = api_versions.APIVersion("2.19")
@@ -1612,6 +1671,12 @@
             raise exceptions.UnsupportedAttribute("trusted_image_certificates",
                                                   "2.63")
 
+        if (
+            'hostname' in kwargs and
+            self.api_version < api_versions.APIVersion("2.90")
+        ):
+            raise exceptions.UnsupportedAttribute('hostname', '2.90')
+
         body = {'imageRef': base.getid(image)}
         if password is not None:
             body['adminPass'] = password
@@ -1628,6 +1693,8 @@
         if "trusted_image_certificates" in kwargs:
             body["trusted_image_certificates"] = kwargs[
                 "trusted_image_certificates"]
+        if "hostname" in kwargs:
+            body["hostname"] = kwargs["hostname"]
         if meta:
             body['metadata'] = meta
         if files:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/novaclient/v2/shell.py 
new/python-novaclient-17.6.0/novaclient/v2/shell.py
--- old/python-novaclient-17.4.0/novaclient/v2/shell.py 2021-03-11 
20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/v2/shell.py 2021-09-03 
12:18:38.000000000 +0200
@@ -532,8 +532,10 @@
     if include_files:
         boot_kwargs['files'] = files
 
-    if ('trusted_image_certificates' in args and
-            args.trusted_image_certificates):
+    if (
+        'trusted_image_certificates' in args and
+        args.trusted_image_certificates
+    ):
         boot_kwargs['trusted_image_certificates'] = (
             args.trusted_image_certificates)
     elif utils.env('OS_TRUSTED_IMAGE_CERTIFICATE_IDS'):
@@ -545,6 +547,9 @@
                 "OS_TRUSTED_IMAGE_CERTIFICATE_IDS",
                 "2.63")
 
+    if 'hostname' in args and args.hostname:
+        boot_kwargs['hostname'] = args.hostname
+
     return boot_args, boot_kwargs
 
 
@@ -970,6 +975,14 @@
     help=_('Requested hypervisor hostname to create servers. Admin only by '
            'default.'),
     start_version="2.74")
+@utils.arg(
+    '--hostname',
+    help=_(
+        'Hostname for the instance. This sets the hostname stored in the '
+        'metadata server: a utility such as cloud-init running on the guest '
+        'is required to propagate these changes to the guest.'
+    ),
+    start_version='2.90')
 def do_boot(cs, args):
     """Boot a new server."""
     boot_args, boot_kwargs = _boot(cs, args)
@@ -2031,6 +2044,14 @@
     help=_("Unset trusted_image_certificates in the server. Cannot be "
            "specified with the '--trusted-image-certificate-id' option."),
     start_version="2.63")
+@utils.arg(
+    '--hostname',
+    help=_(
+        'New hostname for the instance. This only updates the hostname '
+        'stored in the metadata server: a utility running on the guest '
+        'is required to propagate these changes to the guest.'
+    ),
+    start_version='2.90')
 def do_rebuild(cs, args):
     """Shutdown, re-image, and re-boot a server."""
     server = _find_server(cs, args.server)
@@ -2121,6 +2142,9 @@
             "OS_TRUSTED_IMAGE_CERTIFICATE_IDS",
             "2.63")
 
+    if 'hostname' in args and args.hostname is not None:
+        kwargs['hostname'] = args.hostname
+
     server = server.rebuild(image, _password, **kwargs)
     _print_server(cs, args, server)
 
@@ -2145,6 +2169,14 @@
     help=_('New description for the server. If it equals to empty string '
            '(i.g. ""), the server description will be removed.'),
     start_version="2.19")
+@utils.arg(
+    '--hostname',
+    help=_(
+        'New hostname for the instance. This only updates the hostname '
+        'stored in the metadata server: a utility running on the guest '
+        'is required to propagate these changes to the guest.'
+    ),
+    start_version='2.90')
 def do_update(cs, args):
     """Update the name or the description for a server."""
     update_kwargs = {}
@@ -2152,6 +2184,8 @@
         update_kwargs["name"] = args.name
     if "description" in args and args.description is not None:
         update_kwargs["description"] = args.description
+    if "hostname" in args and args.hostname is not None:
+        update_kwargs["hostname"] = args.hostname
     _find_server(cs, args.server).update(**update_kwargs)
 
 
@@ -2800,6 +2834,10 @@
     _translate_volume_attachments_keys(volumes)
     # Microversion >= 2.70 returns the tag value.
     fields = ['ID', 'DEVICE', 'SERVER ID', 'VOLUME ID']
+    if cs.api_version >= api_versions.APIVersion('2.89'):
+        fields.remove('ID')
+        fields.append('ATTACHMENT ID')
+        fields.append('BDM UUID')
     if cs.api_version >= api_versions.APIVersion('2.70'):
         fields.append('TAG')
     # Microversion >= 2.79 returns the delete_on_termination value.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/novaclient/v2/volumes.py 
new/python-novaclient-17.6.0/novaclient/v2/volumes.py
--- old/python-novaclient-17.4.0/novaclient/v2/volumes.py       2021-03-11 
20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/novaclient/v2/volumes.py       2021-09-03 
12:18:38.000000000 +0200
@@ -39,6 +39,20 @@
     """
     resource_class = Volume
 
+    @staticmethod
+    def _get_request_body_for_create(volume_id, device=None, tag=None,
+                                     delete_on_termination=False):
+        body = {'volumeAttachment': {'volumeId': volume_id}}
+        if device is not None:
+            body['volumeAttachment']['device'] = device
+        if tag is not None:
+            body['volumeAttachment']['tag'] = tag
+        if delete_on_termination:
+            body['volumeAttachment']['delete_on_termination'] = (
+                delete_on_termination)
+
+        return body
+
     @api_versions.wraps("2.0", "2.48")
     def create_server_volume(self, server_id, volume_id, device=None):
         """
@@ -49,11 +63,10 @@
         :param device: The device name (optional)
         :rtype: :class:`Volume`
         """
-        body = {'volumeAttachment': {'volumeId': volume_id}}
-        if device is not None:
-            body['volumeAttachment']['device'] = device
-        return self._create("/servers/%s/os-volume_attachments" % server_id,
-                            body, "volumeAttachment")
+        return self._create(
+            "/servers/%s/os-volume_attachments" % server_id,
+            VolumeManager._get_request_body_for_create(volume_id, device),
+            "volumeAttachment")
 
     @api_versions.wraps("2.49", "2.78")
     def create_server_volume(self, server_id, volume_id, device=None,
@@ -67,13 +80,10 @@
         :param tag: The tag (optional)
         :rtype: :class:`Volume`
         """
-        body = {'volumeAttachment': {'volumeId': volume_id}}
-        if device is not None:
-            body['volumeAttachment']['device'] = device
-        if tag is not None:
-            body['volumeAttachment']['tag'] = tag
-        return self._create("/servers/%s/os-volume_attachments" % server_id,
-                            body, "volumeAttachment")
+        return self._create(
+            "/servers/%s/os-volume_attachments" % server_id,
+            VolumeManager._get_request_body_for_create(volume_id, device, tag),
+            "volumeAttachment")
 
     @api_versions.wraps("2.79")
     def create_server_volume(self, server_id, volume_id, device=None,
@@ -90,18 +100,11 @@
                                       (optional).
         :rtype: :class:`Volume`
         """
-        # TODO(mriedem): Move this body construction into a private common
-        # helper method for all versions of create_server_volume to use.
-        body = {'volumeAttachment': {'volumeId': volume_id}}
-        if device is not None:
-            body['volumeAttachment']['device'] = device
-        if tag is not None:
-            body['volumeAttachment']['tag'] = tag
-        if delete_on_termination:
-            body['volumeAttachment']['delete_on_termination'] = (
-                delete_on_termination)
-        return self._create("/servers/%s/os-volume_attachments" % server_id,
-                            body, "volumeAttachment")
+        return self._create(
+            "/servers/%s/os-volume_attachments" % server_id,
+            VolumeManager._get_request_body_for_create(volume_id, device, tag,
+                                                       delete_on_termination),
+            "volumeAttachment")
 
     @api_versions.wraps("2.0", "2.84")
     def update_server_volume(self, server_id, src_volid, dest_volid):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/python_novaclient.egg-info/PKG-INFO 
new/python-novaclient-17.6.0/python_novaclient.egg-info/PKG-INFO
--- old/python-novaclient-17.4.0/python_novaclient.egg-info/PKG-INFO    
2021-03-11 20:48:00.000000000 +0100
+++ new/python-novaclient-17.6.0/python_novaclient.egg-info/PKG-INFO    
2021-09-03 12:19:08.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: python-novaclient
-Version: 17.4.0
+Version: 17.6.0
 Summary: Client library for OpenStack Compute API
 Home-page: https://docs.openstack.org/python-novaclient/latest
 Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/python_novaclient.egg-info/SOURCES.txt 
new/python-novaclient-17.6.0/python_novaclient.egg-info/SOURCES.txt
--- old/python-novaclient-17.4.0/python_novaclient.egg-info/SOURCES.txt 
2021-03-11 20:48:00.000000000 +0100
+++ new/python-novaclient-17.6.0/python_novaclient.egg-info/SOURCES.txt 
2021-09-03 12:19:08.000000000 +0200
@@ -1,5 +1,6 @@
 .coveragerc
 .mailmap
+.pre-commit-config.yaml
 .stestr.conf
 .zuul.yaml
 AUTHORS
@@ -266,7 +267,9 @@
 releasenotes/notes/microversion-v2_81-3ddd8e2fc7e45030.yaml
 releasenotes/notes/microversion-v2_85-230931f88c4f1d52.yaml
 releasenotes/notes/microversion-v2_88-d91136020e3a3621.yaml
+releasenotes/notes/microversion-v2_90-259779668e67dfb5.yaml
 releasenotes/notes/microversion_v2_70-09cbe0933b3a9335.yaml
+releasenotes/notes/microversion_v2_89-af6223273b2bdfb0.yaml
 releasenotes/notes/no-glance-proxy-5c13001a4b13e8ce.yaml
 releasenotes/notes/no-neutron-proxy-18fd54febe939a6b.yaml
 releasenotes/notes/pike-rm-deprecated-img-d58e9ae2d774cbfc.yaml
@@ -314,6 +317,7 @@
 releasenotes/source/unreleased.rst
 releasenotes/source/ussuri.rst
 releasenotes/source/victoria.rst
+releasenotes/source/wallaby.rst
 releasenotes/source/_static/.placeholder
 releasenotes/source/_templates/.placeholder
 releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/python_novaclient.egg-info/pbr.json 
new/python-novaclient-17.6.0/python_novaclient.egg-info/pbr.json
--- old/python-novaclient-17.4.0/python_novaclient.egg-info/pbr.json    
2021-03-11 20:48:00.000000000 +0100
+++ new/python-novaclient-17.6.0/python_novaclient.egg-info/pbr.json    
2021-09-03 12:19:08.000000000 +0200
@@ -1 +1 @@
-{"git_version": "54d4da11", "is_release": true}
\ No newline at end of file
+{"git_version": "8066f8c7", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/releasenotes/notes/microversion-v2_88-d91136020e3a3621.yaml
 
new/python-novaclient-17.6.0/releasenotes/notes/microversion-v2_88-d91136020e3a3621.yaml
--- 
old/python-novaclient-17.4.0/releasenotes/notes/microversion-v2_88-d91136020e3a3621.yaml
    2021-03-11 20:47:21.000000000 +0100
+++ 
new/python-novaclient-17.6.0/releasenotes/notes/microversion-v2_88-d91136020e3a3621.yaml
    2021-09-03 12:18:38.000000000 +0200
@@ -7,7 +7,7 @@
     which is deprecated in 2.88, and the ``/os-hypervisors/{id}`` API, which
     now includes uptime information, based on the microversion.
 
-    .. _microversion 2.88: 
https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id80
+    .. _microversion 2.88: 
https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#microversion-2-88
 deprecations:
   - |
     The ``nova hypervisor-stats`` command and underlying
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/releasenotes/notes/microversion-v2_90-259779668e67dfb5.yaml
 
new/python-novaclient-17.6.0/releasenotes/notes/microversion-v2_90-259779668e67dfb5.yaml
--- 
old/python-novaclient-17.4.0/releasenotes/notes/microversion-v2_90-259779668e67dfb5.yaml
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/python-novaclient-17.6.0/releasenotes/notes/microversion-v2_90-259779668e67dfb5.yaml
    2021-09-03 12:18:38.000000000 +0200
@@ -0,0 +1,13 @@
+---
+features:
+  - |
+    Added support for `microversion 2.90`_. This microversion provides the
+    ability to manually configure the instance ``hostname`` attribute when
+    creating a new instance (``nova boot --hostname HOSTNAME ...``), updating
+    an existing instance (``nova update --hostname HOSTNAME ...``), or
+    rebuilding an existing instance (``nova rebuild --hostname HOSTNAME``).
+    This attribute is published via the metadata service and config drive and
+    can be used by init scripts such as ``cloud-init`` to configure the guest's
+    hostname.
+
+    .. _microversion 2.90: 
https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#microversion-2-90
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/releasenotes/notes/microversion_v2_89-af6223273b2bdfb0.yaml
 
new/python-novaclient-17.6.0/releasenotes/notes/microversion_v2_89-af6223273b2bdfb0.yaml
--- 
old/python-novaclient-17.4.0/releasenotes/notes/microversion_v2_89-af6223273b2bdfb0.yaml
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/python-novaclient-17.6.0/releasenotes/notes/microversion_v2_89-af6223273b2bdfb0.yaml
    2021-09-03 12:18:38.000000000 +0200
@@ -0,0 +1,11 @@
+---
+features:
+  - |
+    Added support for `microversion 2.89`_. This microversion removes the
+    ``id`` field while adding the ``attachment_id`` and ``bdm_uuid`` fields to
+    the responses of ``GET /servers/{server_id}/os-volume_attachments`` and
+    ``GET /servers/{server_id}/os-volume_attachments/{volume_id}`` with these
+    changes reflected in novaclient under the ``nova volume-attachments``
+    command.
+
+    .. _microversion 2.89: 
https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#microversion-2-89
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/releasenotes/source/index.rst 
new/python-novaclient-17.6.0/releasenotes/source/index.rst
--- old/python-novaclient-17.4.0/releasenotes/source/index.rst  2021-03-11 
20:47:21.000000000 +0100
+++ new/python-novaclient-17.6.0/releasenotes/source/index.rst  2021-09-03 
12:18:38.000000000 +0200
@@ -8,6 +8,7 @@
    :maxdepth: 2
 
    unreleased
+   wallaby
    victoria
    ussuri
    train
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-novaclient-17.4.0/releasenotes/source/wallaby.rst 
new/python-novaclient-17.6.0/releasenotes/source/wallaby.rst
--- old/python-novaclient-17.4.0/releasenotes/source/wallaby.rst        
1970-01-01 01:00:00.000000000 +0100
+++ new/python-novaclient-17.6.0/releasenotes/source/wallaby.rst        
2021-09-03 12:18:38.000000000 +0200
@@ -0,0 +1,6 @@
+============================
+Wallaby Series Release Notes
+============================
+
+.. release-notes::
+   :branch: stable/wallaby
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/setup.cfg 
new/python-novaclient-17.6.0/setup.cfg
--- old/python-novaclient-17.4.0/setup.cfg      2021-03-11 20:48:00.661249600 
+0100
+++ new/python-novaclient-17.6.0/setup.cfg      2021-09-03 12:19:08.998951000 
+0200
@@ -1,13 +1,13 @@
 [metadata]
 name = python-novaclient
 summary = Client library for OpenStack Compute API
-description-file = 
+description_file = 
        README.rst
 license = Apache License, Version 2.0
 author = OpenStack
-author-email = openstack-disc...@lists.openstack.org
-home-page = https://docs.openstack.org/python-novaclient/latest
-python-requires = >=3.6
+author_email = openstack-disc...@lists.openstack.org
+home_page = https://docs.openstack.org/python-novaclient/latest
+python_requires = >=3.6
 classifier = 
        Development Status :: 5 - Production/Stable
        Environment :: Console
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-novaclient-17.4.0/tox.ini 
new/python-novaclient-17.6.0/tox.ini
--- old/python-novaclient-17.4.0/tox.ini        2021-03-11 20:47:21.000000000 
+0100
+++ new/python-novaclient-17.6.0/tox.ini        2021-09-03 12:18:38.000000000 
+0200
@@ -1,6 +1,6 @@
 [tox]
-envlist = py38,pep8,docs
-minversion = 3.1
+envlist = py3,pep8,docs
+minversion = 3.18.0
 skipsdist = true
 ignore_basepython_conflict = true
 
@@ -8,7 +8,7 @@
 basepython = python3
 usedevelop = true
 # tox is silly... these need to be separated by a newline....
-whitelist_externals =
+allowlist_externals =
   find
   rm
   make

Reply via email to