Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-ironicclient for 
openSUSE:Factory checked in at 2026-09-08 16:55:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ironicclient (Old)
 and      /work/SRC/openSUSE:Factory/.python-ironicclient.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-ironicclient"

Tue Sep  8 16:55:14 2026 rev:31 rq:1376088 version:6.3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-ironicclient/python-ironicclient.changes  
2026-08-09 21:37:26.794547162 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-ironicclient.new.1265/python-ironicclient.changes
        2026-09-08 16:57:02.990318348 +0200
@@ -1,0 +2,14 @@
+Mon Sep  7 07:10:38 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 6.3.0:
+  * Add new fields to node history detailed view
+  * Add --disable-ramdisk to runbook set/unset
+  * Remove broken --step option from runbook unset
+  * Remove broken --traits option from runbook create
+  * Add --disable-ramdisk to runbook create
+  * ruff: Enable common checks
+  * Drop unnecessary allowlist_externals
+  * Remove Python 3.10 support
+  * Add openstack-python3-next-jobs job
+
+-------------------------------------------------------------------

Old:
----
  python_ironicclient-6.2.0.tar.gz

New:
----
  python_ironicclient-6.3.0.tar.gz

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

Other differences:
------------------
++++++ python-ironicclient.spec ++++++
--- /var/tmp/diff_new_pack.gBgzHY/_old  2026-09-08 16:57:04.251371176 +0200
+++ /var/tmp/diff_new_pack.gBgzHY/_new  2026-09-08 16:57:04.253371259 +0200
@@ -18,7 +18,7 @@
 
 %global pythons %{primary_python}
 Name:           python-ironicclient
-Version:        6.2.0
+Version:        6.3.0
 Release:        0
 Summary:        Python API and CLI for OpenStack Ironic
 License:        Apache-2.0

++++++ python_ironicclient-6.2.0.tar.gz -> python_ironicclient-6.3.0.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_ironicclient-6.2.0/AUTHORS 
new/python_ironicclient-6.3.0/AUTHORS
--- old/python_ironicclient-6.2.0/AUTHORS       2026-07-02 11:54:35.000000000 
+0200
+++ new/python_ironicclient-6.3.0/AUTHORS       2026-08-26 14:18:17.862646000 
+0200
@@ -171,6 +171,7 @@
 cid <[email protected]>
 deepakmourya <[email protected]>
 dnuka <[email protected]>
+edomfeh <[email protected]>
 ericxiett <[email protected]>
 fpxie <[email protected]>
 ghanshyam <[email protected]>
@@ -194,6 +195,7 @@
 shu-mutou <[email protected]>
 sonu.kumar <[email protected]>
 sunjia <[email protected]>
+ushen <[email protected]>
 venkatamahesh <[email protected]>
 vishal mahajan <[email protected]>
 wangfaxin <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_ironicclient-6.2.0/ChangeLog 
new/python_ironicclient-6.3.0/ChangeLog
--- old/python_ironicclient-6.2.0/ChangeLog     2026-07-02 11:54:35.000000000 
+0200
+++ new/python_ironicclient-6.3.0/ChangeLog     2026-08-26 14:18:17.760645200 
+0200
@@ -1,11 +1,25 @@
 CHANGES
 =======
 
+6.3.0
+-----
+
+* Add new fields to node history detailed view
+* Add --disable-ramdisk to runbook set/unset
+* Remove broken --step option from runbook unset
+* Remove broken --traits option from runbook create
+* Add --disable-ramdisk to runbook create
+* ruff: Enable common checks
+* Drop unnecessary allowlist\_externals
+* Remove Python 3.10 support
+* Add openstack-python3-next-jobs job
+
 6.2.0
 -----
 
 * Treat the API version cache as best-effort
 * Bump openstacksdk lower bound
+* Add portgroup uuid to vif attach OSC client
 * clean up pyproject.toml deprecated and missing entries
 * Stop ignoring override in tests
 * Stop ignoring list-item in tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_ironicclient-6.2.0/PKG-INFO 
new/python_ironicclient-6.3.0/PKG-INFO
--- old/python_ironicclient-6.2.0/PKG-INFO      2026-07-02 11:54:35.792050800 
+0200
+++ new/python_ironicclient-6.3.0/PKG-INFO      2026-08-26 14:18:18.095648000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: python-ironicclient
-Version: 6.2.0
+Version: 6.3.0
 Summary: OpenStack Bare Metal Provisioning API Client Library
 Author-email: OpenStack <[email protected]>
 License-Expression: Apache-2.0
@@ -15,13 +15,12 @@
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3.14
 Classifier: Typing :: Typed
-Requires-Python: >=3.10
+Requires-Python: >=3.11
 Description-Content-Type: text/x-rst
 License-File: LICENSE
 Requires-Dist: pbr>=6.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/ironicclient/common/http.py 
new/python_ironicclient-6.3.0/ironicclient/common/http.py
--- old/python_ironicclient-6.2.0/ironicclient/common/http.py   2026-07-02 
11:53:42.000000000 +0200
+++ new/python_ironicclient-6.3.0/ironicclient/common/http.py   2026-08-26 
14:17:08.345724800 +0200
@@ -42,7 +42,7 @@
 #             
http://specs.openstack.org/openstack/ironic-specs/specs/kilo/api-microversions.html
 # noqa
 #             for full details.
 DEFAULT_VER: str = '1.9'
-LAST_KNOWN_API_VERSION: int = 112
+LAST_KNOWN_API_VERSION: int = 115
 LATEST_VERSION: str = '1.{}'.format(LAST_KNOWN_API_VERSION)
 
 LOG: logging.Logger = logging.getLogger(__name__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/ironicclient/osc/v1/baremetal_node.py 
new/python_ironicclient-6.3.0/ironicclient/osc/v1/baremetal_node.py
--- old/python_ironicclient-6.2.0/ironicclient/osc/v1/baremetal_node.py 
2026-07-02 11:53:42.000000000 +0200
+++ new/python_ironicclient-6.3.0/ironicclient/osc/v1/baremetal_node.py 
2026-08-26 14:17:08.354725800 +0200
@@ -2193,6 +2193,11 @@
             help=_("UUID of the baremetal port to attach the VIF to.")
         )
         parser.add_argument(
+            '--portgroup-uuid',
+            metavar='<portgroup-uuid>',
+            help=_("UUID of the baremetal portgroup to attach the VIF to.")
+        )
+        parser.add_argument(
             '--vif-info',
             metavar='<key=value>',
             action='append',
@@ -2209,6 +2214,8 @@
         fields = utils.key_value_pairs_to_dict(parsed_args.vif_info or [])
         if parsed_args.port_uuid:
             fields['port_uuid'] = parsed_args.port_uuid
+        if parsed_args.portgroup_uuid:
+            fields['portgroup_uuid'] = parsed_args.portgroup_uuid
         baremetal_client.node.vif_attach(parsed_args.node, parsed_args.vif_id,
                                          **fields)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/ironicclient/osc/v1/baremetal_runbook.py 
new/python_ironicclient-6.3.0/ironicclient/osc/v1/baremetal_runbook.py
--- old/python_ironicclient-6.2.0/ironicclient/osc/v1/baremetal_runbook.py      
2026-07-02 11:53:42.000000000 +0200
+++ new/python_ironicclient-6.3.0/ironicclient/osc/v1/baremetal_runbook.py      
2026-08-26 14:17:08.355726000 +0200
@@ -59,12 +59,6 @@
             help=_('Description of the runbook.')
         )
         parser.add_argument(
-            '--traits',
-            metavar='<trait>',
-            action='append',
-            help=_('Trait for this runbook. Can be specified multiple times.')
-        )
-        parser.add_argument(
             '--uuid',
             dest='uuid',
             metavar='<uuid>',
@@ -94,6 +88,15 @@
             required=True,
             help=_RUNBOOK_STEPS_HELP
         )
+        parser.add_argument(
+            '--disable-ramdisk',
+            action='store_true',
+            default=None,
+            help=_("ironic-python-agent will not be booted when this "
+                   "runbook is used. Only steps explicitly marked as not "
+                   "requiring ironic-python-agent can be executed with "
+                   "this set.")
+        )
         return parser
 
     def take_action(
@@ -105,19 +108,20 @@
 
         steps = utils.handle_json_arg(parsed_args.steps, 'runbook steps')
 
-        field_list: list[str] = ['name', 'uuid', 'owner', 'public', 'extra']
-
-        # Check if API version supports new fields (description and traits)
+        field_list: list[str] = [
+            'name', 'uuid', 'owner', 'public', 'extra', 'disable_ramdisk',
+        ]
+
+        # Check if API version supports the description field. Note that
+        # traits cannot be set at creation time: the API only accepts them
+        # via the /runbooks/<ident>/traits sub-resource (see the
+        # AddTraitBaremetalRunbook/RemoveTraitBaremetalRunbook commands).
         if utils.check_api_version_support(
                 baremetal_client.current_api_version, "1.112"):
-            field_list.extend(['description', 'traits'])
-        else:
-            if parsed_args.description is not None:
-                raise exc.UnsupportedVersion(
-                    _("--description requires API version 1.112 or later"))
-            if parsed_args.traits is not None:
-                raise exc.UnsupportedVersion(
-                    _("--traits requires API version 1.112 or later"))
+            field_list.append('description')
+        elif parsed_args.description is not None:
+            raise exc.UnsupportedVersion(
+                _("--description requires API version 1.112 or later"))
 
         fields = dict((k, v) for (k, v) in vars(parsed_args).items()
                       if k in field_list and v is not None)
@@ -230,6 +234,15 @@
             help=_('Extra to set on this baremetal runbook '
                    '(repeat option to set multiple extras).'),
         )
+        parser.add_argument(
+            '--disable-ramdisk',
+            dest='disable_ramdisk',
+            nargs='?',
+            const='true',
+            metavar='<disable_ramdisk>',
+            help=_('Whether ironic-python-agent should not be booted when '
+                   'this runbook is used.')
+        )
         return parser
 
     def take_action(self, parsed_args: argparse.Namespace) -> None:
@@ -267,6 +280,14 @@
         if parsed_args.extra:
             properties.extend(utils.args_array_to_patch(
                 'add', ['extra/' + x for x in parsed_args.extra]))
+        if parsed_args.disable_ramdisk is not None:
+            to_bool = utils.bool_argument_value(
+                '--disable-ramdisk', parsed_args.disable_ramdisk,
+                strict=True)
+            disable_ramdisk = [
+                "disable_ramdisk=%s" % json.dumps(to_bool)]
+            properties.extend(
+                utils.args_array_to_patch('add', disable_ramdisk))
 
         if properties:
             baremetal_client.runbook.update(parsed_args.runbook,
@@ -312,19 +333,18 @@
             help=_('Unset owner of a runbook.')
         )
         parser.add_argument(
-            "--step",
-            metavar="<key>",
-            action='append',
-            help=_('Step to unset on this baremetal runbook '
-                   '(repeat option to unset multiple steps).'),
-        )
-        parser.add_argument(
             "--extra",
             metavar="<key>",
             action='append',
             help=_('Extra to unset on this baremetal runbook '
                    '(repeat option to unset multiple extras).'),
         )
+        parser.add_argument(
+            '--disable-ramdisk',
+            dest='disable_ramdisk',
+            action='store_true',
+            help=_('Unset disable_ramdisk of a runbook.')
+        )
 
         return parser
 
@@ -339,7 +359,7 @@
         supports_new_fields = utils.check_api_version_support(
             baremetal_client.current_api_version, "1.112")
 
-        for field in ['name', 'owner', 'public']:
+        for field in ['name', 'owner', 'public', 'disable_ramdisk']:
             if getattr(parsed_args, field):
                 properties.extend(utils.args_array_to_patch('remove', [field]))
 
@@ -354,9 +374,6 @@
         if parsed_args.extra:
             properties.extend(utils.args_array_to_patch('remove',
                               ['extra/' + x for x in parsed_args.extra]))
-        if parsed_args.step:
-            properties.extend(utils.args_array_to_patch('remove',
-                              ['step/' + x for x in parsed_args.step]))
 
         if properties:
             baremetal_client.runbook.update(parsed_args.runbook,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/ironicclient/osc/v1/baremetal_volume_target.py 
new/python_ironicclient-6.3.0/ironicclient/osc/v1/baremetal_volume_target.py
--- 
old/python_ironicclient-6.2.0/ironicclient/osc/v1/baremetal_volume_target.py    
    2026-07-02 11:53:42.000000000 +0200
+++ 
new/python_ironicclient-6.3.0/ironicclient/osc/v1/baremetal_volume_target.py    
    2026-08-26 14:17:08.356726200 +0200
@@ -92,7 +92,7 @@
     def take_action(
         self, parsed_args: argparse.Namespace,
     ) -> tuple[tuple[str, ...], tuple[Any, ...]]:
-        self.log.debug("take_action(%s)" % parsed_args)
+        self.log.debug("take_action(%s)", parsed_args)
         manager = self.app.client_manager
         baremetal_client = manager.baremetal
 
@@ -222,7 +222,7 @@
     def take_action(
         self, parsed_args: argparse.Namespace,
     ) -> tuple[Sequence[str], Iterable[Any]]:
-        self.log.debug("take_action(%s)" % parsed_args)
+        self.log.debug("take_action(%s)", parsed_args)
         manager = self.app.client_manager
         client = manager.baremetal
 
@@ -248,7 +248,7 @@
             columns = resource.fields
             params['fields'] = columns
 
-        self.log.debug("params(%s)" % params)
+        self.log.debug("params(%s)", params)
         data = client.volume_target.list(**params)
 
         data = oscutils.sort_items(data, parsed_args.sort)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/ironicclient/tests/unit/osc/v1/fakes.py 
new/python_ironicclient-6.3.0/ironicclient/tests/unit/osc/v1/fakes.py
--- old/python_ironicclient-6.2.0/ironicclient/tests/unit/osc/v1/fakes.py       
2026-07-02 11:53:42.000000000 +0200
+++ new/python_ironicclient-6.3.0/ironicclient/tests/unit/osc/v1/fakes.py       
2026-08-26 14:17:08.365727200 +0200
@@ -254,11 +254,13 @@
 baremetal_runbook_extra = {'key1': 'value1', 'key2': 'value2'}
 baremetal_runbook_description = ''
 baremetal_runbook_traits = []
+baremetal_runbook_disable_ramdisk = False
 RUNBOOK = {
     'uuid': baremetal_runbook_uuid,
     'name': baremetal_runbook_name,
     'description': baremetal_runbook_description,
     'traits': baremetal_runbook_traits,
+    'disable_ramdisk': baremetal_runbook_disable_ramdisk,
     'owner': baremetal_runbook_owner,
     'public': baremetal_runbook_public,
     'steps': baremetal_runbook_steps,
@@ -281,6 +283,10 @@
         'event_type': 'purring',
         'conductor': 'lap-conductor',
         'user': '0191',
+        'project': 'test-project',
+        'state': 'active',
+        'target_provision_state': 'available',
+        'duration_seconds': 300,
         'links': {'href': 'url', 'rel': 'self'},
     }
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/ironicclient/tests/unit/osc/v1/test_baremetal_node.py
 
new/python_ironicclient-6.3.0/ironicclient/tests/unit/osc/v1/test_baremetal_node.py
--- 
old/python_ironicclient-6.2.0/ironicclient/tests/unit/osc/v1/test_baremetal_node.py
 2026-07-02 11:53:42.000000000 +0200
+++ 
new/python_ironicclient-6.3.0/ironicclient/tests/unit/osc/v1/test_baremetal_node.py
 2026-08-26 14:17:08.369727600 +0200
@@ -4523,6 +4523,19 @@
         self.baremetal_mock.node.vif_attach.assert_called_once_with(
             'node_uuid', 'aaa-aaa', port_uuid='fake-port-uuid')
 
+    def test_baremetal_vif_attach_portgroup_uuid(self) -> None:
+        arglist = ['node_uuid', 'aaa-aaa', '--portgroup-uuid',
+                   'fake-portgroup-uuid']
+        verifylist = [('node', 'node_uuid'),
+                      ('vif_id', 'aaa-aaa'),
+                      ('portgroup_uuid', 'fake-portgroup-uuid')]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        self.cmd.take_action(parsed_args)
+
+        self.baremetal_mock.node.vif_attach.assert_called_once_with(
+            'node_uuid', 'aaa-aaa', portgroup_uuid='fake-portgroup-uuid')
+
 
 class TestVifDetach(TestBaremetal):
     def setUp(self) -> None:
@@ -4885,9 +4898,12 @@
             'node_uuid', True)
         expected_columns = ('uuid', 'created_at', 'severity',
                             'event_type', 'event',
-                            'conductor', 'user')
+                            'conductor', 'user',
+                            'project', 'state',
+                            'target_provision_state', 'duration_seconds')
         expected_data = (('abcdef1', 'time', 'info', 'purring', 'meow',
-                          'lap-conductor', '0191'),)
+                          'lap-conductor', '0191', 'test-project', 'active',
+                          'available', 300),)
         self.assertEqual(expected_columns, columns)
         self.assertEqual(expected_data, tuple(data))
 
@@ -4912,9 +4928,12 @@
         self.baremetal_mock.node.get_history_event.assert_called_once_with(
             'node_uuid', 'event_uuid')
         expected_columns = ('uuid', 'created_at', 'severity', 'event',
-                            'event_type', 'conductor', 'user')
+                            'event_type', 'conductor', 'user', 'project',
+                            'state', 'target_provision_state',
+                            'duration_seconds')
         expected_data = ('abcdef1', 'time', 'info', 'meow', 'purring',
-                         'lap-conductor', '0191')
+                         'lap-conductor', '0191', 'test-project', 'active',
+                         'available', 300)
 
         self.assertEqual(expected_columns, columns)
         self.assertEqual(expected_data, tuple(data))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/ironicclient/tests/unit/osc/v1/test_baremetal_runbook.py
 
new/python_ironicclient-6.3.0/ironicclient/tests/unit/osc/v1/test_baremetal_runbook.py
--- 
old/python_ironicclient-6.2.0/ironicclient/tests/unit/osc/v1/test_baremetal_runbook.py
      2026-07-02 11:53:42.000000000 +0200
+++ 
new/python_ironicclient-6.3.0/ironicclient/tests/unit/osc/v1/test_baremetal_runbook.py
      2026-08-26 14:17:08.370727800 +0200
@@ -15,6 +15,7 @@
 
 import copy
 import json
+from typing import Any
 from unittest import mock
 
 from osc_lib.tests import utils as osctestutils
@@ -131,6 +132,21 @@
                           self.cmd, arglist, verifylist)
         self.assertFalse(self.baremetal_mock.runbook.create.called)
 
+    def test_baremetal_runbook_create_no_traits_option(self) -> None:
+        # Traits cannot be supplied at creation time; the API only accepts
+        # them via the /runbooks/<ident>/traits sub-resource.
+        arglist = [
+            '--name', baremetal_fakes.baremetal_runbook_name,
+            '--steps', baremetal_fakes.baremetal_runbook_steps,
+            '--traits', 'CUSTOM_FOO',
+        ]
+        verifylist: list[tuple[str, Any]] = []
+
+        self.assertRaises(osctestutils.ParserException,
+                          self.check_parser,
+                          self.cmd, arglist, verifylist)
+        self.assertFalse(self.baremetal_mock.runbook.create.called)
+
     def test_baremetal_runbook_create_public_false(self) -> None:
         arglist = [
             '--name', baremetal_fakes.baremetal_runbook_name,
@@ -153,6 +169,28 @@
         }
         self.baremetal_mock.runbook.create.assert_called_once_with(**expected)
 
+    def test_baremetal_runbook_create_disable_ramdisk(self) -> None:
+        arglist = [
+            '--name', baremetal_fakes.baremetal_runbook_name,
+            '--steps', baremetal_fakes.baremetal_runbook_steps,
+            '--disable-ramdisk',
+        ]
+        verifylist = [
+            ('name', baremetal_fakes.baremetal_runbook_name),
+            ('steps', baremetal_fakes.baremetal_runbook_steps),
+            ('disable_ramdisk', True),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+        self.cmd.take_action(parsed_args)
+
+        expected = {
+            'name': baremetal_fakes.baremetal_runbook_name,
+            'steps': json.loads(baremetal_fakes.baremetal_runbook_steps),
+            'disable_ramdisk': True,
+        }
+        self.baremetal_mock.runbook.create.assert_called_once_with(**expected)
+
 
 class TestShowBaremetalRunbook(TestBaremetalRunbook):
     def setUp(self) -> None:
@@ -182,6 +220,7 @@
 
         collist = (
             'description',
+            'disable_ramdisk',
             'extra',
             'name',
             'owner',
@@ -193,6 +232,7 @@
 
         datalist = (
             baremetal_fakes.baremetal_runbook_description,
+            baremetal_fakes.baremetal_runbook_disable_ramdisk,
             baremetal_fakes.baremetal_runbook_extra,
             baremetal_fakes.baremetal_runbook_name,
             baremetal_fakes.baremetal_runbook_owner,
@@ -257,6 +297,36 @@
             baremetal_fakes.baremetal_runbook_uuid,
             [{'path': '/steps', 'value': expected_steps, 'op': 'add'}])
 
+    def test_baremetal_runbook_set_disable_ramdisk(self) -> None:
+        arglist = [
+            baremetal_fakes.baremetal_runbook_uuid,
+            '--disable-ramdisk']
+        verifylist = [
+            ('runbook', baremetal_fakes.baremetal_runbook_uuid),
+            ('disable_ramdisk', 'true')]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        self.cmd.take_action(parsed_args)
+        self.baremetal_mock.runbook.update.assert_called_once_with(
+            baremetal_fakes.baremetal_runbook_uuid,
+            [{'path': '/disable_ramdisk', 'value': True, 'op': 'add'}])
+
+    def test_baremetal_runbook_set_disable_ramdisk_false(self) -> None:
+        arglist = [
+            baremetal_fakes.baremetal_runbook_uuid,
+            '--disable-ramdisk', 'false']
+        verifylist = [
+            ('runbook', baremetal_fakes.baremetal_runbook_uuid),
+            ('disable_ramdisk', 'false')]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        self.cmd.take_action(parsed_args)
+        self.baremetal_mock.runbook.update.assert_called_once_with(
+            baremetal_fakes.baremetal_runbook_uuid,
+            [{'path': '/disable_ramdisk', 'value': False, 'op': 'add'}])
+
     def test_baremetal_runbook_set_no_options(self) -> None:
         arglist = []
         verifylist = []
@@ -308,6 +378,31 @@
             [{'path': '/extra/key1', 'op': 'remove'},
              {'path': '/extra/key2', 'op': 'remove'}])
 
+    def test_baremetal_runbook_unset_disable_ramdisk(self) -> None:
+        arglist = [
+            baremetal_fakes.baremetal_runbook_uuid, '--disable-ramdisk']
+        verifylist = [('runbook',
+                       baremetal_fakes.baremetal_runbook_uuid),
+                      ('disable_ramdisk', True)]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        self.cmd.take_action(parsed_args)
+        self.baremetal_mock.runbook.update.assert_called_once_with(
+            baremetal_fakes.baremetal_runbook_uuid,
+            [{'path': '/disable_ramdisk', 'op': 'remove'}])
+
+    def test_baremetal_runbook_unset_no_step_option(self) -> None:
+        # --step was removed: the API has no way to remove an individual
+        # step from a runbook, only to replace the whole 'steps' list.
+        arglist = [baremetal_fakes.baremetal_runbook_uuid, '--step', 'key1']
+        verifylist: list[tuple[str, Any]] = []
+
+        self.assertRaises(osctestutils.ParserException,
+                          self.check_parser,
+                          self.cmd, arglist, verifylist)
+        self.assertFalse(self.baremetal_mock.runbook.update.called)
+
     def test_baremetal_runbook_unset_no_options(self) -> None:
         arglist = []
         verifylist = []
@@ -436,6 +531,7 @@
                    'name',
                    'description',
                    'traits',
+                   'disable_ramdisk',
                    'owner',
                    'public',
                    'steps',
@@ -449,6 +545,7 @@
             baremetal_fakes.baremetal_runbook_name,
             baremetal_fakes.baremetal_runbook_description,
             baremetal_fakes.baremetal_runbook_traits,
+            baremetal_fakes.baremetal_runbook_disable_ramdisk,
             baremetal_fakes.baremetal_runbook_owner,
             baremetal_fakes.baremetal_runbook_public,
             baremetal_fakes.baremetal_runbook_steps,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/ironicclient/tests/unit/v1/test_runbook.py 
new/python_ironicclient-6.3.0/ironicclient/tests/unit/v1/test_runbook.py
--- old/python_ironicclient-6.2.0/ironicclient/tests/unit/v1/test_runbook.py    
2026-07-02 11:53:42.000000000 +0200
+++ new/python_ironicclient-6.3.0/ironicclient/tests/unit/v1/test_runbook.py    
2026-08-26 14:17:08.391730500 +0200
@@ -38,6 +38,9 @@
 
 CREATE_RUNBOOK_WITH_UUID = copy.deepcopy(RUNBOOK)
 
+CREATE_RUNBOOK_WITH_DISABLE_RAMDISK = copy.deepcopy(CREATE_RUNBOOK)
+CREATE_RUNBOOK_WITH_DISABLE_RAMDISK['disable_ramdisk'] = True
+
 UPDATED_RUNBOOK = copy.deepcopy(RUNBOOK)
 NEW_NAME = 'CUSTOM_RUNBOOK3'
 UPDATED_RUNBOOK['name'] = NEW_NAME
@@ -292,6 +295,15 @@
         ]
         self.assertEqual(expect, self.api.calls)
         self.assertTrue(runbook)
+
+    def test_create_with_disable_ramdisk(self) -> None:
+        runbook = self.mgr.create(**CREATE_RUNBOOK_WITH_DISABLE_RAMDISK)
+        expect = [
+            ('POST', '/v1/runbooks', {},
+             CREATE_RUNBOOK_WITH_DISABLE_RAMDISK),
+        ]
+        self.assertEqual(expect, self.api.calls)
+        self.assertTrue(runbook)
 
     def test_delete(self) -> None:
         self.mgr.delete(runbook_id=RUNBOOK['uuid'])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/ironicclient/v1/resource_fields.py 
new/python_ironicclient-6.3.0/ironicclient/v1/resource_fields.py
--- old/python_ironicclient-6.2.0/ironicclient/v1/resource_fields.py    
2026-07-02 11:53:42.000000000 +0200
+++ new/python_ironicclient-6.3.0/ironicclient/v1/resource_fields.py    
2026-08-26 14:17:08.403732000 +0200
@@ -71,6 +71,7 @@
         'driver': 'Driver',
         'driver_info': 'Driver Info',
         'driver_internal_info': 'Driver Internal Info',
+        'duration_seconds': 'Duration (seconds)',
         'drivers': 'Drivers',
         'enabled_bios_interfaces': 'Enabled BIOS Interfaces',
         'enabled_boot_interfaces': 'Enabled Boot Interfaces',
@@ -111,6 +112,7 @@
         'node_uuid': 'Node UUID',
         'owner': 'Owner',
         'power_state': 'Power State',
+        'project': 'Project',
         'properties': 'Properties',
         'protected': 'Protected',
         'protected_reason': 'Protected Reason',
@@ -168,6 +170,7 @@
         'health': 'Health',
         'public': 'Public',
         'disable_power_off': 'Disable Power Off',
+        'disable_ramdisk': 'Disable Ramdisk',
         'priority': 'Priority',
         'sensitive': 'Sensitive',
         'phase': 'Phase',
@@ -644,6 +647,7 @@
      'name',
      'description',
      'traits',
+     'disable_ramdisk',
      'owner',
      'public',
      'steps',
@@ -674,7 +678,11 @@
      'event_type',
      'event',
      'conductor',
-     'user']
+     'user',
+     'project',
+     'state',
+     'target_provision_state',
+     'duration_seconds']
 )
 
 SHARD_RESOURCE = Resource(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_ironicclient-6.2.0/ironicclient/v1/runbook.py 
new/python_ironicclient-6.3.0/ironicclient/v1/runbook.py
--- old/python_ironicclient-6.2.0/ironicclient/v1/runbook.py    2026-07-02 
11:53:42.000000000 +0200
+++ new/python_ironicclient-6.3.0/ironicclient/v1/runbook.py    2026-08-26 
14:17:08.404732000 +0200
@@ -29,8 +29,8 @@
 class RunbookManager(base.CreateManager[Runbook]):
     resource_class: type[Runbook] = Runbook
     _creation_attributes: list[str] = [
-        'description', 'extra', 'name', 'owner', 'public', 'steps',
-        'traits', 'uuid',
+        'description', 'disable_ramdisk', 'extra', 'name', 'owner', 'public',
+        'steps', 'uuid',
     ]
     _resource_name: str = 'runbooks'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_ironicclient-6.2.0/pyproject.toml 
new/python_ironicclient-6.3.0/pyproject.toml
--- old/python_ironicclient-6.2.0/pyproject.toml        2026-07-02 
11:53:42.000000000 +0200
+++ new/python_ironicclient-6.3.0/pyproject.toml        2026-08-26 
14:17:08.407732500 +0200
@@ -11,7 +11,7 @@
 readme = {file = "README.rst", content-type = "text/x-rst"}
 license = "Apache-2.0"
 dynamic = ["version", "dependencies"]
-requires-python = ">=3.10"
+requires-python = ">=3.11"
 classifiers = [
   "Development Status :: 5 - Production/Stable",
   "Environment :: OpenStack",
@@ -21,7 +21,6 @@
   "Programming Language :: Python",
   "Programming Language :: Python :: 3",
   "Programming Language :: Python :: 3 :: Only",
-  "Programming Language :: Python :: 3.10",
   "Programming Language :: Python :: 3.11",
   "Programming Language :: Python :: 3.12",
   "Programming Language :: Python :: 3.13",
@@ -211,3 +210,14 @@
 disallow_untyped_defs = true
 disallow_subclassing_any = false
 disable_error_code = ["import-untyped"]
+
+[tool.ruff]
+line-length = 79
+
+[tool.ruff.lint]
+select = [
+    "E",        # pycodestyle (error)
+    "F",        # pyflakes
+    "G",        # flake8-logging-format
+    "LOG",      # flake8-logging
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/python_ironicclient.egg-info/PKG-INFO 
new/python_ironicclient-6.3.0/python_ironicclient.egg-info/PKG-INFO
--- old/python_ironicclient-6.2.0/python_ironicclient.egg-info/PKG-INFO 
2026-07-02 11:54:35.000000000 +0200
+++ new/python_ironicclient-6.3.0/python_ironicclient.egg-info/PKG-INFO 
2026-08-26 14:18:17.880646200 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: python-ironicclient
-Version: 6.2.0
+Version: 6.3.0
 Summary: OpenStack Bare Metal Provisioning API Client Library
 Author-email: OpenStack <[email protected]>
 License-Expression: Apache-2.0
@@ -15,13 +15,12 @@
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3 :: Only
-Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3.14
 Classifier: Typing :: Typed
-Requires-Python: >=3.10
+Requires-Python: >=3.11
 Description-Content-Type: text/x-rst
 License-File: LICENSE
 Requires-Dist: pbr>=6.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/python_ironicclient.egg-info/SOURCES.txt 
new/python_ironicclient-6.3.0/python_ironicclient.egg-info/SOURCES.txt
--- old/python_ironicclient-6.2.0/python_ironicclient.egg-info/SOURCES.txt      
2026-07-02 11:54:35.000000000 +0200
+++ new/python_ironicclient-6.3.0/python_ironicclient.egg-info/SOURCES.txt      
2026-08-26 14:18:17.976647000 +0200
@@ -155,6 +155,7 @@
 releasenotes/notes/add-node-description-support-6efd0882eaa0c788.yaml
 releasenotes/notes/add-node-health-fields-support-c8f3d2a9b7e4f1a5.yaml
 releasenotes/notes/add-node-history-b9b9beeb0200f185.yaml
+releasenotes/notes/add-node-history-fields-v1115-e81b2785f0cd89e2.yaml
 releasenotes/notes/add-node-inventory-74e856c019cfa7e2.yaml
 releasenotes/notes/add-node-lessee-c36409eb0415f75d.yaml
 releasenotes/notes/add-node-owner-c2dce5a6075ce2b7.yaml
@@ -293,11 +294,16 @@
 releasenotes/notes/remove-ironic-command-5c9f7bc4946996e0.yaml
 releasenotes/notes/remove-llc-short-arg-89c7443acc6c54a4.yaml
 releasenotes/notes/remove-port-create-l-option-08ce0a3fc3e48d59.yaml
+releasenotes/notes/remove-py310-0bbd70865f78c373.yaml
 releasenotes/notes/remove-py39-4dcb7e79fa3d6f66.yaml
 releasenotes/notes/remove-states-field-0242960d121a09a7.yaml
 releasenotes/notes/reset-interface-bbd7a612242db399.yaml
 releasenotes/notes/reset-interfaces-bec227bf933fea59.yaml
 
releasenotes/notes/retry-on-keystone-auth-retriable-failures-91c08b9f8bdab7f3.yaml
+releasenotes/notes/runbook-create-remove-traits-5a8b82fac5a57567.yaml
+releasenotes/notes/runbook-disable-ramdisk-511a0d673dac3f7b.yaml
+releasenotes/notes/runbook-set-unset-disable-ramdisk-eda9599a16b94d29.yaml
+releasenotes/notes/runbook-unset-remove-step-447d9731a552fb48.yaml
 releasenotes/notes/session-client-endpoint-override-20f1d822b4430afa.yaml
 releasenotes/notes/session-create-092172964afdb71b.yaml
 
releasenotes/notes/show-required-arguments-in-help-commands-of-node-create-port-create-b213bb28bcc94743.yaml
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/python_ironicclient.egg-info/pbr.json 
new/python_ironicclient-6.3.0/python_ironicclient.egg-info/pbr.json
--- old/python_ironicclient-6.2.0/python_ironicclient.egg-info/pbr.json 
2026-07-02 11:54:35.000000000 +0200
+++ new/python_ironicclient-6.3.0/python_ironicclient.egg-info/pbr.json 
2026-08-26 14:18:17.879646300 +0200
@@ -1 +1 @@
-{"git_version": "c68d9f8", "is_release": true}
\ No newline at end of file
+{"git_version": "8f37f71", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/releasenotes/notes/add-node-history-fields-v1115-e81b2785f0cd89e2.yaml
 
new/python_ironicclient-6.3.0/releasenotes/notes/add-node-history-fields-v1115-e81b2785f0cd89e2.yaml
--- 
old/python_ironicclient-6.2.0/releasenotes/notes/add-node-history-fields-v1115-e81b2785f0cd89e2.yaml
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/python_ironicclient-6.3.0/releasenotes/notes/add-node-history-fields-v1115-e81b2785f0cd89e2.yaml
        2026-08-26 14:17:08.413733200 +0200
@@ -0,0 +1,4 @@
+features:
+  - |
+    Adds ``state``, ``target_provision_state``, and ``duration_seconds``
+    in detailed node history responses starting with API microversion 1.115.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/releasenotes/notes/remove-py310-0bbd70865f78c373.yaml
 
new/python_ironicclient-6.3.0/releasenotes/notes/remove-py310-0bbd70865f78c373.yaml
--- 
old/python_ironicclient-6.2.0/releasenotes/notes/remove-py310-0bbd70865f78c373.yaml
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/python_ironicclient-6.3.0/releasenotes/notes/remove-py310-0bbd70865f78c373.yaml
 2026-08-26 14:17:08.435736000 +0200
@@ -0,0 +1,5 @@
+---
+upgrade:
+  - |
+    Support for Python 3.10 has been removed. Now Python 3.11 is the minimum
+    version supported.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/releasenotes/notes/runbook-create-remove-traits-5a8b82fac5a57567.yaml
 
new/python_ironicclient-6.3.0/releasenotes/notes/runbook-create-remove-traits-5a8b82fac5a57567.yaml
--- 
old/python_ironicclient-6.2.0/releasenotes/notes/runbook-create-remove-traits-5a8b82fac5a57567.yaml
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/python_ironicclient-6.3.0/releasenotes/notes/runbook-create-remove-traits-5a8b82fac5a57567.yaml
 2026-08-26 14:17:08.437736300 +0200
@@ -0,0 +1,7 @@
+---
+fixes:
+  - |
+    Removes ``--traits`` from ``openstack baremetal runbook create``.
+    Ironic has never accepted traits in the create request body; use
+    ``openstack baremetal runbook trait add/remove`` instead. Passing
+    ``--traits`` to ``runbook create`` always resulted in a ``400``.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/releasenotes/notes/runbook-disable-ramdisk-511a0d673dac3f7b.yaml
 
new/python_ironicclient-6.3.0/releasenotes/notes/runbook-disable-ramdisk-511a0d673dac3f7b.yaml
--- 
old/python_ironicclient-6.2.0/releasenotes/notes/runbook-disable-ramdisk-511a0d673dac3f7b.yaml
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/python_ironicclient-6.3.0/releasenotes/notes/runbook-disable-ramdisk-511a0d673dac3f7b.yaml
      2026-08-26 14:17:08.438736400 +0200
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Adds ``--disable-ramdisk`` to ``openstack baremetal runbook create``,
+    matching the field ironic's runbook resource already supports. Also
+    shown by ``runbook show`` and ``runbook list --long``.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/releasenotes/notes/runbook-set-unset-disable-ramdisk-eda9599a16b94d29.yaml
 
new/python_ironicclient-6.3.0/releasenotes/notes/runbook-set-unset-disable-ramdisk-eda9599a16b94d29.yaml
--- 
old/python_ironicclient-6.2.0/releasenotes/notes/runbook-set-unset-disable-ramdisk-eda9599a16b94d29.yaml
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/python_ironicclient-6.3.0/releasenotes/notes/runbook-set-unset-disable-ramdisk-eda9599a16b94d29.yaml
    2026-08-26 14:17:08.440736500 +0200
@@ -0,0 +1,7 @@
+---
+features:
+  - |
+    Adds ``--disable-ramdisk`` to ``openstack baremetal runbook set``
+    and ``runbook unset``, so the field can be changed after creation.
+    Requires an ironic fix allowing ``disable_ramdisk`` to be patched;
+    without it, these options fail server-side.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python_ironicclient-6.2.0/releasenotes/notes/runbook-unset-remove-step-447d9731a552fb48.yaml
 
new/python_ironicclient-6.3.0/releasenotes/notes/runbook-unset-remove-step-447d9731a552fb48.yaml
--- 
old/python_ironicclient-6.2.0/releasenotes/notes/runbook-unset-remove-step-447d9731a552fb48.yaml
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/python_ironicclient-6.3.0/releasenotes/notes/runbook-unset-remove-step-447d9731a552fb48.yaml
    2026-08-26 14:17:08.440736500 +0200
@@ -0,0 +1,8 @@
+---
+fixes:
+  - |
+    Removes ``--step`` from ``openstack baremetal runbook unset``. It
+    generated a patch path (``/step/<key>``) that ironic always
+    rejected: the allowed field is the plural ``steps`` list, not a
+    per-step key, and there's no way to remove a single step by name.
+    Use ``runbook set --steps`` to replace the full list instead.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_ironicclient-6.2.0/tox.ini 
new/python_ironicclient-6.3.0/tox.ini
--- old/python_ironicclient-6.2.0/tox.ini       2026-07-02 11:53:42.000000000 
+0200
+++ new/python_ironicclient-6.3.0/tox.ini       2026-08-26 14:17:08.449737800 
+0200
@@ -24,7 +24,6 @@
 commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html 
releasenotes/source releasenotes/build/html
 
 [testenv:pep8]
-allowlist_externals = pre-commit
 deps = pre-commit
 commands = pre-commit run --all-files --show-diff-on-failure {posargs}
 
@@ -67,17 +66,16 @@
     make -C doc/build/pdf
 
 [flake8]
-ignore = W503
+# We only enable the hacking (H) checks
+select = H
 exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools
 # [H106] Don't put vim configuration in source files.
 # [H203] Use assertIs(Not)None to check for None.
 # [H204] Use assert(Not)Equal to check for equality.
 # [H205] Use assert(Greater|Less)(Equal) for comparison.
 # [H210] Require 'autospec', 'spec', or 'spec_set' in 
mock.patch/mock.patch.object calls
-# [H904] Delay string interpolations at logging calls.
-enable-extensions=H106,H203,H204,H205,H210,H904
+enable-extensions=H106,H203,H204,H205,H210
 filename = *.py
-import-order-style = pep8
 application-import-names = ironicclient
 
 [hacking]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python_ironicclient-6.2.0/zuul.d/project.yaml 
new/python_ironicclient-6.3.0/zuul.d/project.yaml
--- old/python_ironicclient-6.2.0/zuul.d/project.yaml   2026-07-02 
11:53:42.000000000 +0200
+++ new/python_ironicclient-6.3.0/zuul.d/project.yaml   2026-08-26 
14:17:08.451737900 +0200
@@ -3,6 +3,7 @@
       - check-requirements
       - openstack-cover-jobs
       - openstack-python3-jobs
+      - openstack-python3-next-jobs
       - openstackclient-plugin-jobs
       - publish-openstack-docs-pti
       - release-notes-jobs-python3

Reply via email to