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 2023-03-07 16:49:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-ironicclient (Old) and /work/SRC/openSUSE:Factory/.python-ironicclient.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-ironicclient" Tue Mar 7 16:49:47 2023 rev:24 rq:1069832 version:5.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-ironicclient/python-ironicclient.changes 2022-06-19 21:11:59.442226681 +0200 +++ /work/SRC/openSUSE:Factory/.python-ironicclient.new.31432/python-ironicclient.changes 2023-03-07 16:50:24.349607145 +0100 @@ -1,0 +2,32 @@ +Tue Mar 7 06:59:00 UTC 2023 - cloud-de...@suse.de + +- update to version 5.1.0 + - Fix tox4 error + - Add support for fields in drivers CLI + - CI: Removing ironic job queue + - No longer override install_command in tox.ini + - Update master for stable/yoga + - Fix wrong assertion methods + - Avoid using 'foo' as invalid JSON test data + - Add Python3 yoga unit tests + - Updating python testing classifier as per Yoga testing runtime + - Add Python3 zed unit tests + - Update master for stable/zed + - Validate path when passing a config-drive + - Improve description of "node boot mode set" + - remove unicode from code + - Add node history support + - Made `baremetal <command> --help` display command specific help. + - Update master for stable/xena + - Test python 3.6 for distributions compatibility + - Fix CI + - Remove unused check_python_version + - Add Python3 antelope unit tests + - Drop lower-constraints.txt and its testing + - Fix logging in the baremetal CLI + - The Python 3.6 and Python 3.7 Support has been dropped since zed + - Fix references to ironicclient classes and methods + - Fix distribution compatability for configdrive build + - Use only Yoga tests + +------------------------------------------------------------------- Old: ---- python-ironicclient-4.8.0.tar.gz New: ---- python-ironicclient-5.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-ironicclient.spec ++++++ --- /var/tmp/diff_new_pack.In9dN6/_old 2023-03-07 16:50:25.105611123 +0100 +++ /var/tmp/diff_new_pack.In9dN6/_new 2023-03-07 16:50:25.105611123 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-ironicclient # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,13 +17,13 @@ Name: python-ironicclient -Version: 4.8.0 +Version: 5.1.0 Release: 0 Summary: Python API and CLI for OpenStack Ironic License: Apache-2.0 Group: Development/Languages/Python URL: https://docs.openstack.org/python-ironicclient -Source0: https://files.pythonhosted.org/packages/source/p/python-ironicclient/python-ironicclient-4.8.0.tar.gz +Source0: https://files.pythonhosted.org/packages/source/p/python-ironicclient/python-ironicclient-5.1.0.tar.gz BuildRequires: openstack-macros BuildRequires: python3-Babel BuildRequires: python3-PyYAML >= 3.13 @@ -88,13 +88,13 @@ This package contains auto-generated documentation. %prep -%autosetup -p1 -n python-ironicclient-4.8.0 +%autosetup -p1 -n python-ironicclient-5.1.0 %py_req_cleanup %build %{py3_build} -PBR_VERSION=4.8.0 %sphinx_build -b html doc/source doc/build/html +PBR_VERSION=5.1.0 %sphinx_build -b html doc/source doc/build/html # remove the sphinx-build leftovers rm -rf doc/build/html/.{doctrees,buildinfo} @@ -102,7 +102,7 @@ %{py3_install} %check -python3 -m stestr.cli run +%{openstack_stestr_run} %files -n python3-ironicclient %license LICENSE ++++++ python-ironicclient-4.8.0.tar.gz -> python-ironicclient-5.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/AUTHORS new/python-ironicclient-5.1.0/AUTHORS --- old/python-ironicclient-4.8.0/AUTHORS 2021-08-31 15:09:07.000000000 +0200 +++ new/python-ironicclient-5.1.0/AUTHORS 2023-02-17 11:38:39.000000000 +0100 @@ -36,6 +36,7 @@ Doug Hellmann <d...@doughellmann.com> Eric Fried <efr...@us.ibm.com> Eric Fried <openst...@fried.cc> +Felix Huettner <felix.huettner@mail.schwarz> Flavio Percoco <flape...@gmail.com> Florian Fuchs <flfu...@redhat.com> Galyna Zholtkevych <gzholtkev...@mirantis.com> @@ -59,6 +60,7 @@ Jamie Lennox <jamielen...@gmail.com> Jamie Lennox <jamielen...@redhat.com> Jason <jasonander...@uchicago.edu> +Jay Faulkner <j...@jvf.cc> Jeremy Stanley <fu...@yuggoth.org> Jim Rollenhagen <j...@jimrollenhagen.com> John L. Villalovos <john.l.villalo...@intel.com> @@ -81,6 +83,7 @@ Luong Anh Tuan <tua...@vn.fujitsu.com> M V P Nitesh <m.nit...@nectechnologies.in> Madhuri Kumari <madhuri.kum...@intel.com> +Mahnoor Asghar <masghar.bese15se...@seecs.edu.pk> Marc Aubry <mau...@internap.com> Mario Villaplana <mario.villapl...@gmail.com> Mark Goddard <m...@stackhpc.com> @@ -103,6 +106,7 @@ OpenStack Release Bot <infra-r...@openstack.org> Pavlo Shchelokovskyy <pshchelokovs...@mirantis.com> Pavlo Shchelokovskyy <shchelokovs...@gmail.com> +Pierre Riteau <pie...@stackhpc.com> Rakesh H S <r...@hp.com> Ramakrishnan G <ramesh...@gmail.com> Riccardo Pittau <elfosa...@gmail.com> @@ -121,7 +125,11 @@ Shuquan Huang <huang.shuq...@99cloud.net> Sinval Vieira <sinvalnet...@gmail.com> SofiiaAndriichenko <sandriiche...@mirantis.com> +Steve Baker <sba...@redhat.com> Steve Martinelli <steve...@ca.ibm.com> +Tadeas Kot <t...@redhat.com> +Takashi Kajinami <tkaji...@redhat.com> +Takashi Natsume <takanat...@gmail.com> Tang Chen <chen.t...@easystack.cn> Tang Chen <tangc...@cn.fujitsu.com> Tao Li <litao3...@126.com> @@ -174,6 +182,7 @@ venkatamahesh <venkatamaheshko...@gmail.com> vishal mahajan <vishal.maha...@nectechnologies.in> wangfaxin <wangfa...@inspur.com> +wangjiaqi07 <wangjiaq...@inspur.com> wu.chunyang <wu.chuny...@99cloud.net> wu.chunyang <wuchuny...@yovole.com> wu.shiming <wushim...@yovole.com> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ChangeLog new/python-ironicclient-5.1.0/ChangeLog --- old/python-ironicclient-4.8.0/ChangeLog 2021-08-31 15:09:07.000000000 +0200 +++ new/python-ironicclient-5.1.0/ChangeLog 2023-02-17 11:38:38.000000000 +0100 @@ -1,6 +1,57 @@ CHANGES ======= +5.1.0 +----- + +* Fix tox4 error +* No longer override install\_command in tox.ini +* Fix wrong assertion methods +* Add Python3 antelope unit tests +* Update master for stable/zed +* remove unicode from code + +5.0.1 +----- + +* Remove unused check\_python\_version + +5.0.0 +----- + +* The Python 3.6 and Python 3.7 Support has been dropped since zed +* Drop lower-constraints.txt and its testing +* Fix logging in the baremetal CLI +* CI: Removing ironic job queue +* Fix CI +* Add Python3 zed unit tests +* Update master for stable/yoga +* Avoid using 'foo' as invalid JSON test data + +4.11.0 +------ + + +4.10.0 +------ + +* Improve description of "node boot mode set" +* Use only Yoga tests +* Updating python testing classifier as per Yoga testing runtime +* Add node history support +* Test python 3.6 for distributions compatibility +* Made \`baremetal <command> --help\` display command specific help +* Fix references to ironicclient classes and methods + +4.9.0 +----- + +* Fix distribution compatability for configdrive build +* Add Python3 yoga unit tests +* Update master for stable/xena +* Add support for fields in drivers CLI +* Validate path when passing a config-drive + 4.8.0 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/PKG-INFO new/python-ironicclient-5.1.0/PKG-INFO --- old/python-ironicclient-4.8.0/PKG-INFO 2021-08-31 15:09:07.817825600 +0200 +++ new/python-ironicclient-5.1.0/PKG-INFO 2023-02-17 11:38:39.215122500 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: python-ironicclient -Version: 4.8.0 +Version: 5.1.0 Summary: OpenStack Bare Metal Provisioning API Client Library Home-page: https://docs.openstack.org/python-ironicclient/latest/ Author: OpenStack @@ -103,9 +103,8 @@ Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 -Requires-Python: >=3.6 +Classifier: Programming Language :: Python :: 3.9 +Requires-Python: >=3.8 Provides-Extra: cli Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/doc/source/api_v1.rst new/python-ironicclient-5.1.0/doc/source/api_v1.rst --- old/python-ironicclient-4.8.0/doc/source/api_v1.rst 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/doc/source/api_v1.rst 2023-02-17 11:37:51.000000000 +0100 @@ -8,24 +8,26 @@ Bare Metal Provisioning Service. For example, to manipulate nodes, you interact with an -`ironicclient.v1.node`_ object. +:py:class:`ironicclient.v1.node.Node` object. You obtain access to nodes via attributes of the -`ironicclient.v1.client.Client`_ object. +:py:class:`ironicclient.v1.client.Client` object. Usage ===== Get a Client object ------------------- -First, create an `ironicclient.v1.client.Client`_ instance by passing your -credentials to `ironicclient.client.get_client()`_. By default, the -Bare Metal Provisioning system is configured so that only administrators +First, create an :py:class:`ironicclient.v1.client.Client` instance by passing +your credentials to :py:meth:`ironicclient.client.get_client()`. By default, +the Bare Metal Provisioning system is configured so that only administrators (users with 'admin' role) have access. .. note:: - Explicit instantiation of `ironicclient.v1.client.Client`_ may cause - errors since it doesn't verify provided arguments, using - `ironicclient.client.get_client()` is preferred way to get client object. + + Explicit instantiation of :py:class:`ironicclient.v1.client.Client` may + cause errors since it doesn't verify provided arguments, using + :py:meth:`ironicclient.client.get_client()` is preferred way to get client + object. There are two different sets of credentials that can be used:: @@ -81,15 +83,16 @@ Perform ironic operations ------------------------- -Once you have an ironic `Client`_, you can perform various tasks:: +Once you have an :py:class:`ironicclient.v1.client.Client`, you can perform +various tasks:: >>> ironic.driver.list() # list of drivers >>> ironic.node.list() # list of nodes >>> ironic.node.get(node_uuid) # information about a particular node -When the `Client`_ needs to propagate an exception, it will usually -raise an instance subclassed from -`ironicclient.exc.BaseException`_ or `ironicclient.exc.ClientException`_. +When the Client needs to propagate an exception, it will usually raise an +instance subclassed from +:py:class:`ironicclient.common.apiclient.exceptions.ClientException`. Refer to the modules themselves, for more details. @@ -97,10 +100,3 @@ ==================== * :ref:`modindex` - -.. _ironicclient.v1.node: api/ironicclient.v1.node.html#ironicclient.v1.node.Node -.. _ironicclient.v1.client.Client: api/ironicclient.v1.client.html#ironicclient.v1.client.Client -.. _Client: api/ironicclient.v1.client.html#ironicclient.v1.client.Client -.. _ironicclient.client.get_client(): api/ironicclient.client.html#ironicclient.client.get_client -.. _ironicclient.exc.BaseException: api/ironicclient.exc.html#ironicclient.exc.BaseException -.. _ironicclient.exc.ClientException: api/ironicclient.exc.html#ironicclient.exc.ClientException diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/doc/source/conf.py new/python-ironicclient-5.1.0/doc/source/conf.py --- old/python-ironicclient-4.8.0/doc/source/conf.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/doc/source/conf.py 2023-02-17 11:37:51.000000000 +0100 @@ -36,7 +36,7 @@ master_doc = 'index' # General information about the project. -copyright = u'OpenStack Foundation' +copyright = 'OpenStack Foundation' # A list of ignored prefixes for module index sorting. modindex_common_prefix = ['ironicclient.'] @@ -77,8 +77,8 @@ ( 'index', 'doc-python-ironicclient.tex', - u'Python Ironic Client Documentation', - u'OpenStack LLC', + 'Python Ironic Client Documentation', + 'OpenStack LLC', 'manual' ), ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/common/http.py new/python-ironicclient-5.1.0/ironicclient/common/http.py --- old/python-ironicclient-4.8.0/ironicclient/common/http.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/common/http.py 2023-02-17 11:37:51.000000000 +0100 @@ -37,7 +37,7 @@ # http://specs.openstack.org/openstack/ironic-specs/specs/kilo/api-microversions.html # noqa # for full details. DEFAULT_VER = '1.9' -LAST_KNOWN_API_VERSION = 76 +LAST_KNOWN_API_VERSION = 78 LATEST_VERSION = '1.{}'.format(LAST_KNOWN_API_VERSION) LOG = logging.getLogger(__name__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/common/utils.py new/python-ironicclient-5.1.0/ironicclient/common/utils.py --- old/python-ironicclient-4.8.0/ironicclient/common/utils.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/common/utils.py 2023-02-17 11:37:51.000000000 +0100 @@ -267,20 +267,30 @@ with tempfile.NamedTemporaryFile() as tmpfile: with tempfile.NamedTemporaryFile() as tmpzipfile: publisher = 'ironicclient-configdrive 0.1' - try: - p = subprocess.Popen(['genisoimage', '-o', tmpfile.name, - '-ldots', '-allow-lowercase', - '-allow-multidot', '-l', - '-publisher', publisher, - '-quiet', '-J', - '-r', '-V', 'config-2', - path], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - except OSError as e: + # NOTE(toabctl): Luckily, genisoimage, mkisofs and xorrisofs + # understand the same parameters which are currently used. + cmds = ['genisoimage', 'mkisofs', 'xorrisofs'] + for c in cmds: + try: + p = subprocess.Popen([c, '-o', tmpfile.name, + '-ldots', '-allow-lowercase', + '-allow-multidot', '-l', + '-publisher', publisher, + '-quiet', '-J', + '-r', '-V', 'config-2', + path], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + except OSError as e: + error = e + else: + error = None + break + if error: raise exc.CommandError( _('Error generating the config drive. Make sure the ' - '"genisoimage" tool is installed. Error: %s') % e) + '"genisoimage", "mkisofs", or "xorriso" tool is ' + 'installed. Error: %s') % error) stdout, stderr = p.communicate() if p.returncode != 0: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/osc/v1/baremetal_driver.py new/python-ironicclient-5.1.0/ironicclient/osc/v1/baremetal_driver.py --- old/python-ironicclient-4.8.0/ironicclient/osc/v1/baremetal_driver.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/osc/v1/baremetal_driver.py 2023-02-17 11:37:51.000000000 +0100 @@ -12,8 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. # - - +import itertools import logging from osc_lib.command import command @@ -39,11 +38,23 @@ help='Type of driver ("classic" or "dynamic"). ' 'The default is to list all of them.' ) - parser.add_argument( + display_group = parser.add_mutually_exclusive_group() + display_group.add_argument( '--long', action='store_true', default=None, help="Show detailed information about the drivers.") + display_group.add_argument( + '--fields', + nargs='+', + dest='fields', + metavar='<field>', + action='append', + default=[], + choices=res_fields.DRIVER_DETAILED_RESOURCE.fields, + help=_("One or more node fields. Only these fields will be " + "fetched from the server. Can not be used when '--long' " + "is specified.")) return parser def take_action(self, parsed_args): @@ -55,6 +66,12 @@ if parsed_args.long: labels = res_fields.DRIVER_DETAILED_RESOURCE.labels columns = res_fields.DRIVER_DETAILED_RESOURCE.fields + elif parsed_args.fields: + fields = itertools.chain.from_iterable(parsed_args.fields) + resource = res_fields.Resource(list(fields)) + columns = resource.fields + labels = resource.labels + params['fields'] = columns else: labels = res_fields.DRIVER_RESOURCE.labels columns = res_fields.DRIVER_RESOURCE.fields @@ -213,13 +230,26 @@ 'driver', metavar='<driver>', help=_('Name of the driver.')) + parser.add_argument( + '--fields', + nargs='+', + dest='fields', + metavar='<field>', + action='append', + default=[], + choices=res_fields.DRIVER_DETAILED_RESOURCE.fields, + help=_("One or more node fields. Only these fields will be " + "fetched from the server.")) return parser def take_action(self, parsed_args): self.log.debug("take_action(%s)", parsed_args) baremetal_client = self.app.client_manager.baremetal - driver = baremetal_client.driver.get(parsed_args.driver)._info + fields = list(itertools.chain.from_iterable(parsed_args.fields)) + fields = fields if fields else None + driver = baremetal_client.driver.get(parsed_args.driver, + fields=fields)._info driver.pop("links", None) driver.pop("properties", None) # For list-type properties, show the values as comma separated diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/osc/v1/baremetal_node.py new/python-ironicclient-5.1.0/ironicclient/osc/v1/baremetal_node.py --- old/python-ironicclient-4.8.0/ironicclient/osc/v1/baremetal_node.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/osc/v1/baremetal_node.py 2023-02-17 11:37:51.000000000 +0100 @@ -243,7 +243,7 @@ class BootmodeSetBaremetalNode(command.Command): - """Set boot mode for baremetal node""" + """Set the boot mode for the next baremetal node deployment""" log = logging.getLogger(__name__ + ".BootmodeSetBaremetalNode") @@ -2131,3 +2131,77 @@ parsed_args.node, parsed_args.setting_name) setting.pop("links", None) return self.dict2columns(setting) + + +class NodeHistoryList(command.Lister): + """Get history events for a baremetal node.""" + + log = logging.getLogger(__name__ + ".NodeHistoryList") + + def get_parser(self, prog_name): + parser = super(NodeHistoryList, self).get_parser(prog_name) + + parser.add_argument( + 'node', + metavar='<node>', + help=_("Name or UUID of the node.") + ) + parser.add_argument( + '--long', + default=False, + help=_("Show detailed information about the BIOS settings."), + action='store_true') + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)", parsed_args) + + baremetal_client = self.app.client_manager.baremetal + if parsed_args.long: + labels = res_fields.NODE_HISTORY_DETAILED_RESOURCE.labels + fields = res_fields.NODE_HISTORY_DETAILED_RESOURCE.fields + else: + labels = res_fields.NODE_HISTORY_RESOURCE.labels + fields = res_fields.NODE_HISTORY_RESOURCE.fields + + data = baremetal_client.node.get_history_list( + parsed_args.node, + parsed_args.long) + + return (labels, + (oscutils.get_dict_properties(s, fields) for s in data)) + + +class NodeHistoryEventGet(command.ShowOne): + """Get history event for a baremetal node.""" + + log = logging.getLogger(__name__ + ".NodeHistoryEventGet") + + def get_parser(self, prog_name): + parser = super(NodeHistoryEventGet, self).get_parser(prog_name) + + parser.add_argument( + 'node', + metavar='<node>', + help=_("Name or UUID of the node.") + ) + + parser.add_argument( + 'event', + metavar='<event>', + help=_("UUID of the event.") + ) + + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)", parsed_args) + + baremetal_client = self.app.client_manager.baremetal + + data = baremetal_client.node.get_history_event( + parsed_args.node, + parsed_args.event) + data.pop('links') + + return self.dict2columns(data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/shell.py new/python-ironicclient-5.1.0/ironicclient/shell.py --- old/python-ironicclient-4.8.0/ironicclient/shell.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/shell.py 2023-02-17 11:37:51.000000000 +0100 @@ -137,7 +137,8 @@ self.config = os_config.OpenStackConfig(override_defaults=_DEFAULTS) super(App, self).__init__(description=_DESCRIPTION, version=str(version_info), - command_manager=mgr) + command_manager=mgr, + deferred_help=True) def build_option_parser(self, description, version, argparse_kwargs=None): parser = super(App, self).build_option_parser( @@ -169,21 +170,35 @@ ) return parser + # This is the openstacksdk default value + _STREAM_FORMAT = '%(asctime)s %(levelname)s: %(name)s %(message)s' + def _configure_ironic_logging(self): - openstack.enable_logging(debug=self.options.debug) - # NOTE(dtantsur): I wish logging.basicConfig worked.. but it does not. + debug_enabled = self.options.debug or self.options.verbose_level > 1 + + openstack.enable_logging(debug=debug_enabled, stream=sys.stderr, + format_template=self._STREAM_FORMAT, + # No fancy formatting if debug is off + format_stream=debug_enabled) + # NOTE(dtantsur): prevent openstack logging from appearing again in the + # cliff handlers + for name in ('openstack', 'keystoneauth'): + logger = logging.getLogger(name) + logger.propagate = False + + # NOTE(dtantsur): I wish logging.basicConfig worked, but at this point + # cliff has already started configuring logging. for name in ('ironicclient', 'ironic_inspector_client'): logger = logging.getLogger(name) logger.setLevel( - logging.DEBUG if self.options.debug else logging.WARNING) - # warnings are already configured by something else, only configure + logging.DEBUG if debug_enabled else logging.WARNING) + # warnings are already configured by cliff, only configure # debug logging for ironic. - if not logger.handlers and self.options.debug: - handler = logging.StreamHandler() - handler.setFormatter(logging.Formatter( - # This is the openstacksdk default value - '%(asctime)s %(levelname)s: %(name)s %(message)s')) + if not logger.handlers and debug_enabled: + handler = logging.StreamHandler(stream=sys.stderr) + handler.setFormatter(logging.Formatter(self._STREAM_FORMAT)) logger.addHandler(handler) + logger.propagate = False def initialize_app(self, argv): super(App, self).initialize_app(argv) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/tests/unit/common/test_utils.py new/python-ironicclient-5.1.0/ironicclient/tests/unit/common/test_utils.py --- old/python-ironicclient-4.8.0/ironicclient/tests/unit/common/test_utils.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/tests/unit/common/test_utils.py 2023-02-17 11:37:51.000000000 +0100 @@ -265,6 +265,20 @@ '-quiet', '-J', '-r', '-V', 'config-2', mock.ANY] + self.mkisofs_cmd = ['mkisofs', '-o', mock.ANY, + '-ldots', '-allow-lowercase', + '-allow-multidot', '-l', + '-publisher', 'ironicclient-configdrive 0.1', + '-quiet', '-J', '-r', '-V', + 'config-2', mock.ANY] + + self.xorrisofs_cmd = ['xorrisofs', '-o', mock.ANY, + '-ldots', '-allow-lowercase', + '-allow-multidot', '-l', + '-publisher', 'ironicclient-configdrive 0.1', + '-quiet', '-J', '-r', '-V', + 'config-2', mock.ANY] + def test_make_configdrive(self, mock_popen): fake_process = mock.Mock(returncode=0) fake_process.communicate.return_value = ('', '') @@ -278,6 +292,24 @@ stdout=subprocess.PIPE) fake_process.communicate.assert_called_once_with() + def test_make_configdrive_fallsback(self, mock_popen): + fake_process = mock.Mock(returncode=0) + fake_process.communicate.return_value = ('', '') + mock_popen.side_effect = iter([OSError('boom'), + OSError('boom'), + fake_process]) + with utils.tempdir() as dirname: + utils.make_configdrive(dirname) + mock_popen.assert_has_calls([ + mock.call(self.genisoimage_cmd, stderr=subprocess.PIPE, + stdout=subprocess.PIPE), + mock.call(self.mkisofs_cmd, stderr=subprocess.PIPE, + stdout=subprocess.PIPE), + mock.call(self.xorrisofs_cmd, stderr=subprocess.PIPE, + stdout=subprocess.PIPE) + ]) + fake_process.communicate.assert_called_once_with() + @mock.patch.object(os, 'access', autospec=True) def test_make_configdrive_non_readable_dir(self, mock_access, mock_popen): mock_access.return_value = False @@ -292,9 +324,14 @@ self.assertRaises(exc.CommandError, utils.make_configdrive, 'fake-dir') mock_access.assert_called_once_with('fake-dir', os.R_OK) - mock_popen.assert_called_once_with(self.genisoimage_cmd, - stderr=subprocess.PIPE, - stdout=subprocess.PIPE) + mock_popen.assert_has_calls([ + mock.call(self.genisoimage_cmd, stderr=subprocess.PIPE, + stdout=subprocess.PIPE), + mock.call(self.mkisofs_cmd, stderr=subprocess.PIPE, + stdout=subprocess.PIPE), + mock.call(self.xorrisofs_cmd, stderr=subprocess.PIPE, + stdout=subprocess.PIPE) + ]) @mock.patch.object(os, 'access', autospec=True) def test_make_configdrive_non_zero_returncode(self, mock_access, @@ -340,7 +377,7 @@ self.assertEqual(json.loads(cleansteps), steps) def test_handle_json_or_file_arg_bad_json(self): - cleansteps = 'foo' + cleansteps = '{foo invalid: json{' self.assertRaisesRegex(exc.InvalidAttribute, 'is not a file and cannot be parsed as JSON', utils.handle_json_or_file_arg, cleansteps) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/tests/unit/osc/v1/fakes.py new/python-ironicclient-5.1.0/ironicclient/tests/unit/osc/v1/fakes.py --- old/python-ironicclient-4.8.0/ironicclient/tests/unit/osc/v1/fakes.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/tests/unit/osc/v1/fakes.py 2023-02-17 11:37:51.000000000 +0100 @@ -229,6 +229,18 @@ 'steps': baremetal_deploy_template_steps, 'extra': baremetal_deploy_template_extra, } +NODE_HISTORY = [ + { + 'uuid': 'abcdef1', + 'created_at': 'time', + 'severity': 'info', + 'event': 'meow', + 'event_type': 'purring', + 'conductor': 'lap-conductor', + 'user': '0191', + 'links': {'href': 'url', 'rel': 'self'}, + } +] class TestBaremetal(utils.TestCommand): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/tests/unit/osc/v1/test_baremetal_deploy_template.py new/python-ironicclient-5.1.0/ironicclient/tests/unit/osc/v1/test_baremetal_deploy_template.py --- old/python-ironicclient-4.8.0/ironicclient/tests/unit/osc/v1/test_baremetal_deploy_template.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/tests/unit/osc/v1/test_baremetal_deploy_template.py 2023-02-17 11:37:51.000000000 +0100 @@ -316,7 +316,7 @@ self.cmd.take_action(parsed_args) args = ['zzz-zzzzzz-zzzz', 'fakename'] - self.baremetal_mock.deploy_template.delete.has_calls( + self.baremetal_mock.deploy_template.delete.assert_has_calls( [mock.call(x) for x in args]) self.assertEqual( 2, self.baremetal_mock.deploy_template.delete.call_count) @@ -333,7 +333,7 @@ parsed_args) args = ['zzz-zzzzzz-zzzz', 'badname'] - self.baremetal_mock.deploy_template.delete.has_calls( + self.baremetal_mock.deploy_template.delete.assert_has_calls( [mock.call(x) for x in args]) self.assertEqual( 2, self.baremetal_mock.deploy_template.delete.call_count) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/tests/unit/osc/v1/test_baremetal_driver.py new/python-ironicclient-5.1.0/ironicclient/tests/unit/osc/v1/test_baremetal_driver.py --- old/python-ironicclient-4.8.0/ironicclient/tests/unit/osc/v1/test_baremetal_driver.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/tests/unit/osc/v1/test_baremetal_driver.py 2023-02-17 11:37:51.000000000 +0100 @@ -146,6 +146,69 @@ ),) self.assertEqual(datalist, tuple(data)) + def test_baremetal_driver_list_fields(self): + arglist = [ + '--fields', 'name', 'hosts' + ] + verifylist = [ + ('fields', [['name', 'hosts']]) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + + kwargs = { + 'driver_type': None, + 'detail': None, + 'fields': ('name', 'hosts') + } + + self.baremetal_mock.driver.list.assert_called_with(**kwargs) + + def test_baremetal_driver_list_fields_multiple(self): + arglist = [ + '--fields', 'name', + '--fields', 'hosts', 'type' + ] + verifylist = [ + ('fields', [['name'], ['hosts', 'type']]) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + + kwargs = { + 'driver_type': None, + 'detail': None, + 'fields': ('name', 'hosts', 'type') + } + + self.baremetal_mock.driver.list.assert_called_with(**kwargs) + + def test_baremetal_driver_list_invalid_fields(self): + arglist = [ + '--fields', 'name', 'invalid' + ] + verifylist = [ + ('fields', [['name', 'invalid']]) + ] + self.assertRaises(oscutils.ParserException, + self.check_parser, + self.cmd, arglist, verifylist) + + def test_baremetal_driver_list_fields_with_long(self): + arglist = [ + '--fields', 'name', 'hosts', + '--long' + ] + verifylist = [ + ('fields', [['name', 'invalid']]), + ('long', True) + ] + self.assertRaises(oscutils.ParserException, + self.check_parser, + self.cmd, arglist, verifylist) + class TestListBaremetalDriverProperty(TestBaremetalDriver): @@ -362,7 +425,7 @@ columns, data = self.cmd.take_action(parsed_args) args = ['fakedrivername'] - self.baremetal_mock.driver.get.assert_called_with(*args) + self.baremetal_mock.driver.get.assert_called_with(*args, fields=None) self.assertFalse(self.baremetal_mock.driver.properties.called) collist = ('default_bios_interface', 'default_boot_interface', @@ -419,4 +482,55 @@ self.assertRaises(oscutils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_baremetal_driver_show_fields(self): + arglist = [ + 'fakedrivername', + '--fields', 'name', 'hosts' + ] + verifylist = [ + ('driver', 'fakedrivername'), + ('fields', [['name', 'hosts']]) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + args = ['fakedrivername'] + fields = ['name', 'hosts'] + self.baremetal_mock.driver.get.assert_called_with(*args, fields=fields) + self.assertFalse(self.baremetal_mock.driver.properties.called) + + def test_baremetal_driver_show_fields_multiple(self): + arglist = [ + 'fakedrivername', + '--fields', 'name', + '--fields', 'hosts', 'type' + ] + verifylist = [ + ('driver', 'fakedrivername'), + ('fields', [['name'], ['hosts', 'type']]) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + args = ['fakedrivername'] + fields = ['name', 'hosts', 'type'] + self.baremetal_mock.driver.get.assert_called_with(*args, fields=fields) + self.assertFalse(self.baremetal_mock.driver.properties.called) + + def test_baremetal_driver_show_invalid_fields(self): + arglist = [ + 'fakedrivername', + '--fields', 'name', 'invalid' + ] + verifylist = [ + ('driver', 'fakedrivername'), + ('fields', [['name', 'invalid']]) + ] + + self.assertRaises(oscutils.ParserException, + self.check_parser, self.cmd, arglist, verifylist) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/tests/unit/osc/v1/test_baremetal_node.py new/python-ironicclient-5.1.0/ironicclient/tests/unit/osc/v1/test_baremetal_node.py --- old/python-ironicclient-4.8.0/ironicclient/tests/unit/osc/v1/test_baremetal_node.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/tests/unit/osc/v1/test_baremetal_node.py 2023-02-17 11:37:51.000000000 +0100 @@ -4188,3 +4188,59 @@ 'node_uuid', 'bios_name_1') expected_data = ('bios_name_1', 'bios_value_1') self.assertEqual(expected_data, tuple(data)) + + +class TestNodeHistoryEventList(TestBaremetal): + def setUp(self): + super(TestNodeHistoryEventList, self).setUp() + + self.baremetal_mock.node.get_history_list.return_value = ( + baremetal_fakes.NODE_HISTORY) + + # Get the command object to test + self.cmd = baremetal_node.NodeHistoryList(self.app, None) + + def test_baremetal_node_history_list(self): + arglist = ['node_uuid', '--long'] + verifylist = [('node', 'node_uuid'), ('long', True)] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.baremetal_mock.node.get_history_list.assert_called_once_with( + 'node_uuid', True) + expected_columns = ('UUID', 'Created At', 'Severity', + 'Event Origin Type', 'Description of the event', + 'Conductor', 'User') + expected_data = (('abcdef1', 'time', 'info', 'purring', 'meow', + 'lap-conductor', '0191'),) + self.assertEqual(expected_columns, columns) + self.assertEqual(expected_data, tuple(data)) + + +class TestNodeHistoryEventGet(TestBaremetal): + def setUp(self): + super(TestNodeHistoryEventGet, self).setUp() + + self.baremetal_mock.node.get_history_event.return_value = ( + baremetal_fakes.NODE_HISTORY[0]) + + # Get the command object to test + self.cmd = baremetal_node.NodeHistoryEventGet(self.app, None) + + def test_baremetal_node_history_list(self): + arglist = ['node_uuid', 'event_uuid'] + verifylist = [('node', 'node_uuid'), ('event', 'event_uuid')] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.baremetal_mock.node.get_history_event.assert_called_once_with( + 'node_uuid', 'event_uuid') + expected_columns = ('conductor', 'created_at', 'event', 'event_type', + 'severity', 'user', 'uuid') + expected_data = ('lap-conductor', 'time', 'meow', 'purring', 'info', + '0191', 'abcdef1') + + self.assertEqual(expected_columns, columns) + self.assertEqual(expected_data, tuple(data)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/tests/unit/v1/test_driver.py new/python-ironicclient-5.1.0/ironicclient/tests/unit/v1/test_driver.py --- old/python-ironicclient-4.8.0/ironicclient/tests/unit/v1/test_driver.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/tests/unit/v1/test_driver.py 2023-02-17 11:37:51.000000000 +0100 @@ -77,6 +77,13 @@ {'drivers': [DRIVER1]}, ), }, + '/v1/drivers/?fields=name,hosts': + { + 'GET': ( + {}, + {'drivers': [DRIVER1]} + ) + }, '/v1/drivers/%s' % DRIVER1['name']: { 'GET': ( @@ -84,6 +91,13 @@ DRIVER1 ), }, + '/v1/drivers/%s?fields=name,hosts' % DRIVER1['name']: + { + 'GET': ( + {}, + DRIVER1, + ), + }, '/v1/drivers/%s/properties' % DRIVER2['name']: { 'GET': ( @@ -136,6 +150,24 @@ self.assertEqual(DRIVER1, driver_attr) + def test_driver_list_fields(self): + drivers = self.mgr.list(fields=['name', 'hosts']) + expect = [ + ('GET', '/v1/drivers/?fields=name,hosts', {}, None), + ] + self.assertEqual(expect, self.api.calls) + self.assertThat(drivers, matchers.HasLength(1)) + + def test_driver_show_fields(self): + driver_ = self.mgr.get(DRIVER1['name'], fields=['name', 'hosts']) + expect = [ + ('GET', '/v1/drivers/%s?fields=name,hosts' % + DRIVER1['name'], {}, None) + ] + self.assertEqual(expect, self.api.calls) + self.assertEqual(DRIVER1['name'], driver_.name) + self.assertEqual(DRIVER1['hosts'], driver_.hosts) + def test_driver_properties(self): properties = self.mgr.properties(DRIVER2['name']) expect = [ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/tests/unit/v1/test_node.py new/python-ironicclient-5.1.0/ironicclient/tests/unit/v1/test_node.py --- old/python-ironicclient-4.8.0/ironicclient/tests/unit/v1/test_node.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/tests/unit/v1/test_node.py 2023-02-17 11:37:51.000000000 +0100 @@ -1556,7 +1556,7 @@ def test_node_set_provision_state_with_configdrive(self): target_state = 'active' self.mgr.set_provision_state(NODE1['uuid'], target_state, - configdrive='foo') + configdrive=b'foo') body = {'target': target_state, 'configdrive': 'foo'} expect = [ ('PUT', '/v1/nodes/%s/states/provision' % NODE1['uuid'], {}, body), @@ -1616,6 +1616,16 @@ ] self.assertEqual(expect, self.api.calls) + def test_node_set_provision_state_fails_missing_dir_or_file(self): + target_state = 'active' + + with common_utils.tempdir() as dirname: + self.assertRaisesRegex(ValueError, + 'Config drive', + self.mgr.set_provision_state, + NODE1['uuid'], target_state, + configdrive=dirname + "/thisdoesnotexist") + def test_node_set_provision_state_with_cleansteps(self): cleansteps = [{"step": "upgrade", "interface": "deploy"}] target_state = 'clean' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/v1/driver.py new/python-ironicclient-5.1.0/ironicclient/v1/driver.py --- old/python-ironicclient-4.8.0/ironicclient/v1/driver.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/v1/driver.py 2023-02-17 11:37:51.000000000 +0100 @@ -28,7 +28,7 @@ _resource_name = 'drivers' def list(self, driver_type=None, detail=None, os_ironic_api_version=None, - global_request_id=None): + global_request_id=None, fields=None): """Retrieve a list of drivers. :param driver_type: Optional, string to filter the drivers by type. @@ -41,13 +41,22 @@ the request. If not specified, the client's default is used. :param global_request_id: String containing global request ID header value (in form "req-<UUID>") to use for the request. + :param fields: Optional, a list with a specified set of fields + of the resource to be returned. Can not be used + when 'detail' is set. :returns: A list of drivers. """ + filters = [] + if detail and fields: + raise exc.InvalidAttribute(_("Can't fetch a subset of fields " + "with 'detail' set")) if driver_type is not None: filters.append('type=%s' % driver_type) if detail is not None: filters.append('detail=%s' % detail) + if fields is not None: + filters.append('fields=%s' % ','.join(fields)) path = '' if filters: @@ -57,8 +66,8 @@ global_request_id=global_request_id) def get(self, driver_name, os_ironic_api_version=None, - global_request_id=None): - return self._get(resource_id=driver_name, + global_request_id=None, fields=None): + return self._get(resource_id=driver_name, fields=fields, os_ironic_api_version=os_ironic_api_version, global_request_id=global_request_id) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/v1/node.py new/python-ironicclient-5.1.0/ironicclient/v1/node.py --- old/python-ironicclient-4.8.0/ironicclient/v1/node.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/v1/node.py 2023-02-17 11:37:51.000000000 +0100 @@ -714,12 +714,16 @@ path = "%s/states/provision" % node_uuid body = {'target': state} if configdrive: - if not isinstance(configdrive, dict): + if isinstance(configdrive, str): if os.path.isfile(configdrive): with open(configdrive, 'rb') as f: configdrive = f.read() - if os.path.isdir(configdrive): + elif os.path.isdir(configdrive): configdrive = utils.make_configdrive(configdrive) + else: + raise ValueError('Config drive seems to refer to a file ' + 'or directory but this file/directory ' + 'does not exist: %s.' % configdrive) if isinstance(configdrive, bytes): try: @@ -1008,3 +1012,56 @@ '%(state)s, the current state is %(actual)s', {'node': node_ident, 'state': expected_state, 'actual': node.provision_state}) + + def get_history_list(self, + node_ident, + detail=False, + os_ironic_api_version=None, + global_request_id=None): + """Get node history event list. + + Provides the ability to query a node event history list from + the API and return the API response to the caller. + + Requires API version 1.78. + + :param node_ident: The name or UUID of the node. + :param detail: If detailed data should be returned in the + event list entry. Default False. + :param os_ironic_api_version: String version (e.g. "1.35") to use for + the request. If not specified, the client's default is used. + :param global_request_id: String containing global request ID header + value (in form "req-<UUID>") to use for the request. + """ + path = "%s/history" % node_ident + + if detail: + path = path + '/detail' + + return self._list_primitives( + self._path(path), 'history', + os_ironic_api_version=os_ironic_api_version, + global_request_id=global_request_id) + + def get_history_event(self, + node_ident, + event, + os_ironic_api_version=None, + global_request_id=None): + """Get a single event record for a node. + + Provides the ability to request, and return + a node's single vent hisotyr entry. + + :param node_ident: The name or UUID of the node. + :param event: The UUID of the event entry as listed + in the node event history list. + :param os_ironic_api_version: String version (e.g. "1.35") to use for + the request. If not specified, the client's default is used. + :param global_request_id: String containing global request ID header + value (in form "req-<UUID>") to use for the request. + """ + path = "%s/history/%s" % (node_ident, event) + return self._get_as_dict( + path, os_ironic_api_version=os_ironic_api_version, + global_request_id=global_request_id) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/ironicclient/v1/resource_fields.py new/python-ironicclient-5.1.0/ironicclient/v1/resource_fields.py --- old/python-ironicclient-4.8.0/ironicclient/v1/resource_fields.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/ironicclient/v1/resource_fields.py 2023-02-17 11:37:51.000000000 +0100 @@ -79,6 +79,8 @@ 'enabled_storage_interfaces': 'Enabled Storage Interfaces', 'enabled_vendor_interfaces': 'Enabled Vendor Interfaces', 'extra': 'Extra', + 'event': 'Description of the event', + 'event_type': 'Event Origin Type', 'hostname': 'Hostname', 'hosts': 'Active host(s)', 'http_methods': 'Supported HTTP methods', @@ -140,8 +142,10 @@ 'raid_interface': 'RAID Interface', 'rescue_interface': 'Rescue Interface', 'storage_interface': 'Storage Interface', + 'severity': 'Severity', 'unique': 'Unique', 'upper_bound': 'Upper Bound', + 'user': 'User', 'vendor_interface': 'Vendor Interface', 'standalone_ports_supported': 'Standalone Ports Supported', 'physical_network': 'Physical Network', @@ -570,3 +574,21 @@ 'name', ], ) + + +NODE_HISTORY_RESOURCE = Resource( + ['uuid', + 'created_at', + 'severity', + 'event'] +) + +NODE_HISTORY_DETAILED_RESOURCE = Resource( + ['uuid', + 'created_at', + 'severity', + 'event_type', + 'event', + 'conductor', + 'user'] +) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/lower-constraints.txt new/python-ironicclient-5.1.0/lower-constraints.txt --- old/python-ironicclient-4.8.0/lower-constraints.txt 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/lower-constraints.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,25 +0,0 @@ -PyYAML==3.13 -appdirs==1.3.0 -cliff==2.8.0 -coverage==4.0 -ddt==1.0.1 -dogpile.cache==0.8.0 -fixtures==3.0.0 -jsonschema==3.2.0 -keystoneauth1==3.11.0 -openstacksdk==0.18.0 -osc-lib==2.0.0 -oslo.config==6.3.0 -oslo.log==3.36.0 -oslo.utils==3.33.0 -oslotest==3.2.0 -pbr==2.0.0 -python-cinderclient==7.2.1 -python-novaclient==9.0.0 -python-openstackclient==3.12.0 -requests-mock==1.2.0 -requests==2.14.2 -stestr==1.0.0 -stevedore==1.20.0 -tempest==25.0.0 -testtools==2.2.0 \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/python_ironicclient.egg-info/PKG-INFO new/python-ironicclient-5.1.0/python_ironicclient.egg-info/PKG-INFO --- old/python-ironicclient-4.8.0/python_ironicclient.egg-info/PKG-INFO 2021-08-31 15:09:07.000000000 +0200 +++ new/python-ironicclient-5.1.0/python_ironicclient.egg-info/PKG-INFO 2023-02-17 11:38:39.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: python-ironicclient -Version: 4.8.0 +Version: 5.1.0 Summary: OpenStack Bare Metal Provisioning API Client Library Home-page: https://docs.openstack.org/python-ironicclient/latest/ Author: OpenStack @@ -103,9 +103,8 @@ Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 -Requires-Python: >=3.6 +Classifier: Programming Language :: Python :: 3.9 +Requires-Python: >=3.8 Provides-Extra: cli Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/python_ironicclient.egg-info/SOURCES.txt new/python-ironicclient-5.1.0/python_ironicclient.egg-info/SOURCES.txt --- old/python-ironicclient-4.8.0/python_ironicclient.egg-info/SOURCES.txt 2021-08-31 15:09:07.000000000 +0200 +++ new/python-ironicclient-5.1.0/python_ironicclient.egg-info/SOURCES.txt 2023-02-17 11:38:39.000000000 +0100 @@ -6,7 +6,6 @@ LICENSE README.rst bindep.txt -lower-constraints.txt requirements.txt setup.cfg setup.py @@ -151,6 +150,7 @@ releasenotes/notes/add-conductor-cli-233249ebc9d5a5f3.yaml releasenotes/notes/add-create-command-3df5efbbecc33276.yaml releasenotes/notes/add-deploy-steps-arg-0b127e29c8cf976d.yaml +releasenotes/notes/add-driver-cli-fields-selector-b0f527eb5f6fb2a9.yaml releasenotes/notes/add-environment-variable-to-specify-version-cache-timeout-dfa5f6d4af0ea1d3.yaml releasenotes/notes/add-events-support-53c461d28abf010b.yaml releasenotes/notes/add-is-smartnic-port-attr-ed46d887aec276ed.yaml @@ -161,6 +161,7 @@ releasenotes/notes/add-node-boot-mode-08ac768649a2fc93.yaml releasenotes/notes/add-node-boot-mode-set-9746b45aa3f80fe8.yaml releasenotes/notes/add-node-description-support-6efd0882eaa0c788.yaml +releasenotes/notes/add-node-history-b9b9beeb0200f185.yaml releasenotes/notes/add-node-lessee-c36409eb0415f75d.yaml releasenotes/notes/add-node-owner-c2dce5a6075ce2b7.yaml releasenotes/notes/add-node-resource-class-6040d1d6c734522c.yaml @@ -179,6 +180,7 @@ releasenotes/notes/add_api_versions-a59e5b6899833c33.yaml releasenotes/notes/add_automated_clean_field-d2a0c824a4e90bf4.yaml releasenotes/notes/add_retired_field-6ec9f97c7c2f86ec.yaml +releasenotes/notes/address-cross-distro-iso-tools-006711c9f150037a.yaml releasenotes/notes/allocation-api-5f13082a8b36d788.yaml releasenotes/notes/allocation-backfill-4d4e51af2f787a72.yaml releasenotes/notes/allow-allocation-update-b4fb715045ab40a2.yaml @@ -221,6 +223,7 @@ releasenotes/notes/latest-default-41fdcc49701c4d70.yaml releasenotes/notes/latest-renegotiation-55daa01b3fc261be.yaml releasenotes/notes/list-nodes-by-driver-b1e1e1018077089b.yaml +releasenotes/notes/logging-9c452e4869d80de9.yaml releasenotes/notes/manual-clean-09f6b49df7d2513f.yaml releasenotes/notes/missing-session-cc11e62dc966b4e0.yaml releasenotes/notes/negative-wrap-fix-4197e91b2ecfb722.yaml @@ -306,6 +309,9 @@ releasenotes/source/ussuri.rst releasenotes/source/victoria.rst releasenotes/source/wallaby.rst +releasenotes/source/xena.rst +releasenotes/source/yoga.rst +releasenotes/source/zed.rst releasenotes/source/_static/.placeholder releasenotes/source/_templates/.placeholder tools/__init__.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/python_ironicclient.egg-info/entry_points.txt new/python-ironicclient-5.1.0/python_ironicclient.egg-info/entry_points.txt --- old/python-ironicclient-4.8.0/python_ironicclient.egg-info/entry_points.txt 2021-08-31 15:09:07.000000000 +0200 +++ new/python-ironicclient-5.1.0/python_ironicclient.egg-info/entry_points.txt 2023-02-17 11:38:39.000000000 +0100 @@ -44,6 +44,8 @@ baremetal_node_create = ironicclient.osc.v1.baremetal_node:CreateBaremetalNode baremetal_node_delete = ironicclient.osc.v1.baremetal_node:DeleteBaremetalNode baremetal_node_deploy = ironicclient.osc.v1.baremetal_node:DeployBaremetalNode +baremetal_node_history_get = ironicclient.osc.v1.baremetal_node:NodeHistoryEventGet +baremetal_node_history_list = ironicclient.osc.v1.baremetal_node:NodeHistoryList baremetal_node_inject_nmi = ironicclient.osc.v1.baremetal_node:InjectNmiBaremetalNode baremetal_node_inspect = ironicclient.osc.v1.baremetal_node:InspectBaremetalNode baremetal_node_list = ironicclient.osc.v1.baremetal_node:ListBaremetalNode diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/python_ironicclient.egg-info/pbr.json new/python-ironicclient-5.1.0/python_ironicclient.egg-info/pbr.json --- old/python-ironicclient-4.8.0/python_ironicclient.egg-info/pbr.json 2021-08-31 15:09:07.000000000 +0200 +++ new/python-ironicclient-5.1.0/python_ironicclient.egg-info/pbr.json 2023-02-17 11:38:39.000000000 +0100 @@ -1 +1 @@ -{"git_version": "b5df386", "is_release": true} \ No newline at end of file +{"git_version": "f945974", "is_release": true} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/releasenotes/notes/add-driver-cli-fields-selector-b0f527eb5f6fb2a9.yaml new/python-ironicclient-5.1.0/releasenotes/notes/add-driver-cli-fields-selector-b0f527eb5f6fb2a9.yaml --- old/python-ironicclient-4.8.0/releasenotes/notes/add-driver-cli-fields-selector-b0f527eb5f6fb2a9.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-ironicclient-5.1.0/releasenotes/notes/add-driver-cli-fields-selector-b0f527eb5f6fb2a9.yaml 2023-02-17 11:37:51.000000000 +0100 @@ -0,0 +1,9 @@ +--- +features: + - | + Adds support for fields selector in driver cli. + See `story 1674775 + <https://storyboard.openstack.org/#!/story/1674775>`_. + + * ``openstack baremetal driver list --fields <field> [<field> ...]`` + * ``openstack baremetal driver show <driver_name> --fields <field> [<field> ...]`` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/releasenotes/notes/add-node-history-b9b9beeb0200f185.yaml new/python-ironicclient-5.1.0/releasenotes/notes/add-node-history-b9b9beeb0200f185.yaml --- old/python-ironicclient-4.8.0/releasenotes/notes/add-node-history-b9b9beeb0200f185.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-ironicclient-5.1.0/releasenotes/notes/add-node-history-b9b9beeb0200f185.yaml 2023-02-17 11:37:51.000000000 +0100 @@ -0,0 +1,9 @@ +--- +features: + - | + Adds support for API version ``1.78`` and "node history" functionality + allowing users to query a list of events, and retrieve a single history + event from a baremetal node. + - Adds ``get_history_list`` and ``get_history_event`` methods to the python + client library. These methods allow operators to query recorded node event + information from an ironic API, where supported and enabled. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/releasenotes/notes/address-cross-distro-iso-tools-006711c9f150037a.yaml new/python-ironicclient-5.1.0/releasenotes/notes/address-cross-distro-iso-tools-006711c9f150037a.yaml --- old/python-ironicclient-4.8.0/releasenotes/notes/address-cross-distro-iso-tools-006711c9f150037a.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-ironicclient-5.1.0/releasenotes/notes/address-cross-distro-iso-tools-006711c9f150037a.yaml 2023-02-17 11:37:51.000000000 +0100 @@ -0,0 +1,7 @@ +--- +fixes: + - | + Embedded configuration drive generation support has been updated to + support ``mkisofs`` and ``xorrisofs`` in adition to the previously + supported ``genisoimage`` utility. This is as distributions such as + Debian and OpenSUSE do not ship ``genisoimage``. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/releasenotes/notes/logging-9c452e4869d80de9.yaml new/python-ironicclient-5.1.0/releasenotes/notes/logging-9c452e4869d80de9.yaml --- old/python-ironicclient-4.8.0/releasenotes/notes/logging-9c452e4869d80de9.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/python-ironicclient-5.1.0/releasenotes/notes/logging-9c452e4869d80de9.yaml 2023-02-17 11:37:51.000000000 +0100 @@ -0,0 +1,9 @@ +--- +fixes: + - | + OpenStackSDK log messages are no longer sent to stdout and no longer break + parsing the output. + - | + The logging configuration now respects the ``--verbose`` flag. + - | + Some warnings are no longer duplicated. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/releasenotes/source/conf.py new/python-ironicclient-5.1.0/releasenotes/source/conf.py --- old/python-ironicclient-4.8.0/releasenotes/source/conf.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/releasenotes/source/conf.py 2023-02-17 11:37:51.000000000 +0100 @@ -61,8 +61,8 @@ master_doc = 'index' # General information about the project. -project = u'Ironic Client Release Notes' -copyright = u'2015, Ironic Developers' +project = 'Ironic Client Release Notes' +copyright = '2015, Ironic Developers' # Release notes are version independent. # The short X.Y version. @@ -208,8 +208,8 @@ # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'IronicClientReleaseNotes.tex', - u'Ironic Client Release Notes Documentation', - u'Ironic Developers', 'manual'), + 'Ironic Client Release Notes Documentation', + 'Ironic Developers', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -239,8 +239,8 @@ # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'ironicclientreleasenotes', - u'Ironic Client Release Notes Documentation', - [u'Ironic Developers'], 1) + 'Ironic Client Release Notes Documentation', + ['Ironic Developers'], 1) ] # If true, show URL addresses after external links. @@ -254,8 +254,8 @@ # dir menu entry, description, category) texinfo_documents = [ ('index', 'IronicClientReleaseNotes', - u'Ironic Client Release Notes Documentation', - u'Ironic Developers', 'IronicClientReleaseNotes', + 'Ironic Client Release Notes Documentation', + 'Ironic Developers', 'IronicClientReleaseNotes', 'Bare metal provisioning service client.', 'Miscellaneous'), ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/releasenotes/source/index.rst new/python-ironicclient-5.1.0/releasenotes/source/index.rst --- old/python-ironicclient-4.8.0/releasenotes/source/index.rst 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/releasenotes/source/index.rst 2023-02-17 11:37:51.000000000 +0100 @@ -6,6 +6,9 @@ :maxdepth: 1 unreleased + zed + yoga + xena wallaby victoria ussuri diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/releasenotes/source/xena.rst new/python-ironicclient-5.1.0/releasenotes/source/xena.rst --- old/python-ironicclient-4.8.0/releasenotes/source/xena.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-ironicclient-5.1.0/releasenotes/source/xena.rst 2023-02-17 11:37:51.000000000 +0100 @@ -0,0 +1,6 @@ +========================= +Xena Series Release Notes +========================= + +.. release-notes:: + :branch: stable/xena diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/releasenotes/source/yoga.rst new/python-ironicclient-5.1.0/releasenotes/source/yoga.rst --- old/python-ironicclient-4.8.0/releasenotes/source/yoga.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-ironicclient-5.1.0/releasenotes/source/yoga.rst 2023-02-17 11:37:51.000000000 +0100 @@ -0,0 +1,6 @@ +========================= +Yoga Series Release Notes +========================= + +.. release-notes:: + :branch: stable/yoga diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/releasenotes/source/zed.rst new/python-ironicclient-5.1.0/releasenotes/source/zed.rst --- old/python-ironicclient-4.8.0/releasenotes/source/zed.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/python-ironicclient-5.1.0/releasenotes/source/zed.rst 2023-02-17 11:37:51.000000000 +0100 @@ -0,0 +1,6 @@ +======================== +Zed Series Release Notes +======================== + +.. release-notes:: + :branch: stable/zed diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/requirements.txt new/python-ironicclient-5.1.0/requirements.txt --- old/python-ironicclient-4.8.0/requirements.txt 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/requirements.txt 2023-02-17 11:37:51.000000000 +0100 @@ -1,3 +1,7 @@ +# Requirements lower bounds listed here are our best effort to keep them up to +# date but we do not test them so no guarantee of having them all correct. If +# you find any incorrect lower bounds, let us know or propose a fix. + # The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/setup.cfg new/python-ironicclient-5.1.0/setup.cfg --- old/python-ironicclient-4.8.0/setup.cfg 2021-08-31 15:09:07.817825600 +0200 +++ new/python-ironicclient-5.1.0/setup.cfg 2023-02-17 11:38:39.215122500 +0100 @@ -5,7 +5,7 @@ author = OpenStack author_email = openstack-disc...@lists.openstack.org home_page = https://docs.openstack.org/python-ironicclient/latest/ -python_requires = >=3.6 +python_requires = >=3.8 classifier = Environment :: OpenStack Intended Audience :: Information Technology @@ -16,9 +16,8 @@ Programming Language :: Python :: Implementation :: CPython Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 [files] packages = ironicclient @@ -69,6 +68,8 @@ baremetal_node_create = ironicclient.osc.v1.baremetal_node:CreateBaremetalNode baremetal_node_delete = ironicclient.osc.v1.baremetal_node:DeleteBaremetalNode baremetal_node_deploy = ironicclient.osc.v1.baremetal_node:DeployBaremetalNode + baremetal_node_history_list = ironicclient.osc.v1.baremetal_node:NodeHistoryList + baremetal_node_history_get = ironicclient.osc.v1.baremetal_node:NodeHistoryEventGet baremetal_node_inspect = ironicclient.osc.v1.baremetal_node:InspectBaremetalNode baremetal_node_list = ironicclient.osc.v1.baremetal_node:ListBaremetalNode baremetal_node_maintenance_set = ironicclient.osc.v1.baremetal_node:MaintenanceSetBaremetalNode diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/tools/install_venv_common.py new/python-ironicclient-5.1.0/tools/install_venv_common.py --- old/python-ironicclient-4.8.0/tools/install_venv_common.py 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/tools/install_venv_common.py 2023-02-17 11:37:51.000000000 +0100 @@ -16,16 +16,12 @@ """Provides methods needed by installation script for OpenStack development virtual environments. -Since this script is used to bootstrap a virtualenv from the system's Python -environment, it should be kept strictly compatible with Python 3.6. - Synced in from openstack-common """ import optparse import os import subprocess -import sys class InstallVenv(object): @@ -44,10 +40,6 @@ print(message % args, file=sys.stderr) sys.exit(1) - def check_python_version(self): - if sys.version_info < (3, 6): - self.die("Need Python Version >= 3.6") - def run_command_with_code(self, cmd, redirect_output=True, check_exit_code=True): """Runs a command in an out-of-process shell. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/tox.ini new/python-ironicclient-5.1.0/tox.ini --- old/python-ironicclient-4.8.0/tox.ini 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/tox.ini 2023-02-17 11:37:51.000000000 +0100 @@ -1,7 +1,6 @@ [tox] minversion = 3.18.0 envlist = py3,pep8 -skipsdist = True ignore_basepython_conflict=true [testenv] @@ -12,7 +11,6 @@ # .stestr.conf uses TESTS_DIR TESTS_DIR=./ironicclient/tests/unit usedevelop = True -install_command = pip install {opts} {packages} deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/requirements.txt @@ -91,9 +89,3 @@ [hacking] import_exceptions = testtools.matchers, ironicclient.common.i18n - -[testenv:lower-constraints] -deps = - -c{toxinidir}/lower-constraints.txt - -r{toxinidir}/test-requirements.txt - -r{toxinidir}/requirements.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/zuul.d/ironicclient-jobs.yaml new/python-ironicclient-5.1.0/zuul.d/ironicclient-jobs.yaml --- old/python-ironicclient-4.8.0/zuul.d/ironicclient-jobs.yaml 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/zuul.d/ironicclient-jobs.yaml 2023-02-17 11:37:51.000000000 +0100 @@ -41,5 +41,4 @@ - openstack/python-ironicclient vars: devstack_localrc: - IRONIC_DEFAULT_BOOT_OPTION: netboot EBTABLES_RACE_FIX: True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-ironicclient-4.8.0/zuul.d/project.yaml new/python-ironicclient-5.1.0/zuul.d/project.yaml --- old/python-ironicclient-4.8.0/zuul.d/project.yaml 2021-08-31 15:08:24.000000000 +0200 +++ new/python-ironicclient-5.1.0/zuul.d/project.yaml 2023-02-17 11:37:51.000000000 +0100 @@ -2,8 +2,7 @@ templates: - check-requirements - openstack-cover-jobs - - openstack-lower-constraints-master-branch-jobs - - openstack-python3-xena-jobs + - openstack-python3-antelope-jobs - openstackclient-plugin-jobs - publish-openstack-docs-pti - release-notes-jobs-python3 @@ -12,7 +11,6 @@ - ironicclient-functional - ironicclient-tempest gate: - queue: ironic jobs: - ironicclient-functional - ironicclient-tempest