Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-sushy for openSUSE:Factory checked in at 2026-10-26 10:04:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-sushy (Old) and /work/SRC/openSUSE:Factory/.python-sushy.new.2252680 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sushy" Mon Oct 26 10:04:28 2026 rev:26 rq:1392630 version:5.14.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-sushy/python-sushy.changes 2026-08-22 21:38:45.056816164 +0200 +++ /work/SRC/openSUSE:Factory/.python-sushy.new.2252680/python-sushy.changes 2026-10-26 10:05:31.196596198 +0100 @@ -1,0 +2,14 @@ +Mon Oct 26 07:08:24 UTC 2026 - Dirk Müller <[email protected]> + +- update to 5.14.0: + * Remove note about old pip's behavior + * Skip tempest jobs for more local files + * Add per-job status API to DellJobCollection + * Use lazy registries for TaskMonitor + * Fix accessing PCIe functions when Redfish does not support + them + * Update master for stable/2026.2 + * Read reset types from ResetActionInfo when not listed inline + * Fix get_unfinished_jobs missing non-terminal job states + +------------------------------------------------------------------- Old: ---- sushy-5.13.0.tar.gz New: ---- sushy-5.14.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-sushy.spec ++++++ --- /var/tmp/diff_new_pack.ON7L8N/_old 2026-10-26 10:05:32.760661764 +0100 +++ /var/tmp/diff_new_pack.ON7L8N/_new 2026-10-26 10:05:32.762661848 +0100 @@ -17,7 +17,7 @@ Name: python-sushy -Version: 5.13.0 +Version: 5.14.0 Release: 0 Summary: Python library to communicate with Redfish based systems License: Apache-2.0 ++++++ sushy-5.13.0.tar.gz -> sushy-5.14.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/ChangeLog new/sushy-5.14.0/ChangeLog --- old/sushy-5.13.0/ChangeLog 2026-08-20 17:16:13.098004600 +0200 +++ new/sushy-5.14.0/ChangeLog 2026-10-06 16:46:49.520527600 +0200 @@ -1,6 +1,18 @@ CHANGES ======= +5.14.0 +------ + +* Remove note about old pip's behavior +* Skip tempest jobs for more local files +* Add per-job status API to DellJobCollection +* Use lazy registries for TaskMonitor +* Fix accessing PCIe functions when Redfish does not support them +* Update master for stable/2026.2 +* Read reset types from ResetActionInfo when not listed inline +* Fix get\_unfinished\_jobs missing non-terminal job states + 5.13.0 ------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/PKG-INFO new/sushy-5.14.0/PKG-INFO --- old/sushy-5.13.0/PKG-INFO 2026-08-20 17:16:13.455060700 +0200 +++ new/sushy-5.14.0/PKG-INFO 2026-10-06 16:46:49.774512500 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: sushy -Version: 5.13.0 +Version: 5.14.0 Summary: Sushy is a small Python library to communicate with Redfish based systems Home-page: https://docs.openstack.org/sushy/latest/ Author: OpenStack diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/releasenotes/notes/dell-job-status-api-3f2d835ce01c282e.yaml new/sushy-5.14.0/releasenotes/notes/dell-job-status-api-3f2d835ce01c282e.yaml --- old/sushy-5.13.0/releasenotes/notes/dell-job-status-api-3f2d835ce01c282e.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.14.0/releasenotes/notes/dell-job-status-api-3f2d835ce01c282e.yaml 2026-10-06 16:45:55.755967000 +0200 @@ -0,0 +1,10 @@ +--- +features: + - | + Adds per-job status to the Dell OEM Lifecycle Controller job + collection. Individual jobs can now be read as ``DellJob`` resources + that expose their state and message and report whether the job has + finished and whether it failed, so callers can tell a successful job + from a failed one and see why it failed. Previously only the list of + unfinished job identities was available; ``get_unfinished_jobs()`` + keeps its existing behaviour. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/releasenotes/notes/fix-unfinished-job-states-7c1f4a02e9d83b16.yaml new/sushy-5.14.0/releasenotes/notes/fix-unfinished-job-states-7c1f4a02e9d83b16.yaml --- old/sushy-5.13.0/releasenotes/notes/fix-unfinished-job-states-7c1f4a02e9d83b16.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.14.0/releasenotes/notes/fix-unfinished-job-states-7c1f4a02e9d83b16.yaml 2026-10-06 16:45:55.757965800 +0200 @@ -0,0 +1,32 @@ +--- +fixes: + - | + Fixes ``DellJobCollection.get_unfinished_jobs`` reporting a job as + finished while the Lifecycle Controller was still working on it. The + method matched an allowlist of three "incomplete" states + (``Scheduled``, ``Running`` and ``Paused``), so a job in any other + non-terminal state was silently omitted from the result. This + notably affected ``UserIntervention``, which iDRAC reports for + firmware that has been staged but not yet flashed during POST, and + which is not present in this library's ``JobState`` enumeration at + all. Callers polling for job completion could conclude that a + firmware update had been applied when the flash had not started. The + check is now inverted: only the terminal states listed in + ``sushy.oem.dell.constants.TERMINAL_JOB_STATES`` count as finished, + and any state the library does not recognise is treated as + unfinished. +upgrade: + - | + ``DellJobCollection.get_unfinished_jobs`` now returns jobs in any + non-terminal state rather than only ``Scheduled``, ``Running`` and + ``Paused``. Callers using it to decide whether the BMC is busy will + see it report busy in more situations, which is the intended and + more conservative behaviour. Callers using it to decide whether a + specific job has finished will now get a correct answer for staged + firmware jobs. + - | + ``sushy.oem.dell.constants.INCOMPLETE_JOB_STATES`` is deprecated. It + is an allowlist of only some of the incomplete job states and cannot + be used to determine whether a job has finished. It is retained for + backward compatibility but is no longer used internally; use + ``sushy.oem.dell.constants.TERMINAL_JOB_STATES`` instead. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/releasenotes/notes/pci-empty-96e2fcf1998abc5b.yaml new/sushy-5.14.0/releasenotes/notes/pci-empty-96e2fcf1998abc5b.yaml --- old/sushy-5.13.0/releasenotes/notes/pci-empty-96e2fcf1998abc5b.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.14.0/releasenotes/notes/pci-empty-96e2fcf1998abc5b.yaml 2026-10-06 16:45:55.760964000 +0200 @@ -0,0 +1,11 @@ +--- +fixes: + - | + Fixes Sushy trying to access non-existing ``/empty`` URL when PCIe + functions are not supported by the BMC. MissingAttributeError is raised + instead (as documented). + + The code tries to return an empty collection instead of raising + MissingAttributeError as any other accessors. However, it did not work + in reality. Instead, out-of-band inspection would fail with + ``ResourceNotFoundError: Resource https://<host>/empty not found``. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/releasenotes/notes/reset-action-info-116108027e85e510.yaml new/sushy-5.14.0/releasenotes/notes/reset-action-info-116108027e85e510.yaml --- old/sushy-5.13.0/releasenotes/notes/reset-action-info-116108027e85e510.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.14.0/releasenotes/notes/reset-action-info-116108027e85e510.yaml 2026-10-06 16:45:55.762962800 +0200 @@ -0,0 +1,7 @@ +--- +fixes: + - | + Fixes getting the supported reset types from services that publish them + in an ``ActionInfo`` resource, referenced by the system reset action's + ``@Redfish.ActionInfo`` annotation, instead of annotating them inline. + On such systems every reset type was previously assumed to be supported. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/releasenotes/notes/use-lazy-reg-taskmonitor-3295697c9814d83d.yaml new/sushy-5.14.0/releasenotes/notes/use-lazy-reg-taskmonitor-3295697c9814d83d.yaml --- old/sushy-5.13.0/releasenotes/notes/use-lazy-reg-taskmonitor-3295697c9814d83d.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.14.0/releasenotes/notes/use-lazy-reg-taskmonitor-3295697c9814d83d.yaml 2026-10-06 16:45:55.765961200 +0200 @@ -0,0 +1,5 @@ +--- +fixes: + - | + Postpones Redfish message registries download and processing when accessing + task monitors. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/releasenotes/source/2026.2.rst new/sushy-5.14.0/releasenotes/source/2026.2.rst --- old/sushy-5.13.0/releasenotes/source/2026.2.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.14.0/releasenotes/source/2026.2.rst 2026-10-06 16:45:55.767959800 +0200 @@ -0,0 +1,6 @@ +=========================== +2026.2 Series Release Notes +=========================== + +.. release-notes:: + :branch: stable/2026.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/releasenotes/source/index.rst new/sushy-5.14.0/releasenotes/source/index.rst --- old/sushy-5.13.0/releasenotes/source/index.rst 2026-08-20 17:15:26.833348300 +0200 +++ new/sushy-5.14.0/releasenotes/source/index.rst 2026-10-06 16:45:55.768959300 +0200 @@ -6,6 +6,7 @@ :maxdepth: 1 unreleased + 2026.2 2026.1 2025.2 2025.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/requirements.txt new/sushy-5.14.0/requirements.txt --- old/sushy-5.13.0/requirements.txt 2026-08-20 17:15:26.834350300 +0200 +++ new/sushy-5.14.0/requirements.txt 2026-10-06 16:45:55.769958700 +0200 @@ -2,10 +2,6 @@ # 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. - pbr>=6.0.0 # Apache-2.0 requests>=2.14.2 # Apache-2.0 python-dateutil>=2.7.0 # BSD diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/main.py new/sushy-5.14.0/sushy/main.py --- old/sushy-5.13.0/sushy/main.py 2026-08-20 17:15:26.835352700 +0200 +++ new/sushy-5.14.0/sushy/main.py 2026-10-06 16:45:55.771957600 +0200 @@ -677,4 +677,4 @@ self._conn, task_monitor_uri, redfish_version=self.redfish_version, - registries=self.registries) + registries=self.lazy_registries) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/oem/dell/constants.py new/sushy-5.14.0/sushy/oem/dell/constants.py --- old/sushy-5.13.0/sushy/oem/dell/constants.py 2026-08-20 17:15:26.837356800 +0200 +++ new/sushy-5.14.0/sushy/oem/dell/constants.py 2026-10-06 16:45:55.773956500 +0200 @@ -15,6 +15,27 @@ IDRAC_CONFIG_PENDING = 'LC068' IDRAC_JOB_RUNNING = 'RAC0679' NO_FOREIGN_CONFIG = 'STOR018' +# Job states in which the Lifecycle Controller has stopped working on a +# job: it will make no further progress without a new request. Any other +# state means the job is still in flight, including transient ones such +# as 'Downloading', 'RebootPending' and 'UserIntervention' (which iDRAC +# uses for firmware that is staged but not yet flashed during POST), and +# any state a future iDRAC firmware may introduce. +TERMINAL_JOB_STATES = ['Completed', + 'CompletedWithErrors', + 'Failed', + 'RebootFailed'] + +# The subset of TERMINAL_JOB_STATES in which the job did not do what it +# was asked to: it failed outright, completed only partially, or could +# not be applied because the required reboot failed. +FAILED_JOB_STATES = ['CompletedWithErrors', + 'Failed', + 'RebootFailed'] + +# Deprecated: an allowlist of only some of the incomplete job states, and +# therefore unusable for deciding whether a job has finished. Retained +# for backward compatibility; use TERMINAL_JOB_STATES instead. INCOMPLETE_JOB_STATES = ['Scheduled', 'Running', 'Paused'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/oem/dell/resources/manager/job.py new/sushy-5.14.0/sushy/oem/dell/resources/manager/job.py --- old/sushy-5.13.0/sushy/oem/dell/resources/manager/job.py 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.14.0/sushy/oem/dell/resources/manager/job.py 2026-10-06 16:45:55.774955700 +0200 @@ -0,0 +1,65 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +from sushy.oem.dell import constants +from sushy.resources import base + +LOG = logging.getLogger(__name__) + + +class DellJob(base.ResourceBase): + """A class representing a DellJob. + + Represents the status of a single Lifecycle Controller job, such as a + firmware update or a configuration change, tracked by iDRAC. + """ + + identity = base.Field('Id', required=True) + name = base.Field('Name') + description = base.Field('Description') + job_state = base.Field('JobState') + job_type = base.Field('JobType') + message = base.Field('Message') + message_id = base.Field('MessageId') + percent_complete = base.Field('PercentComplete', adapter=int) + start_time = base.Field('StartTime') + end_time = base.Field('EndTime') + completion_time = base.Field('CompletionTime') + + @property + def is_finished(self): + """Whether the Lifecycle Controller has stopped working on this job. + + A job counts as finished only when it is reported in one of + :py:data:`~sushy.oem.dell.constants.TERMINAL_JOB_STATES`. Any other + state, including one this library does not recognise, means the + job is still in flight. + + :returns: True if the job is in a terminal state, False otherwise. + """ + return self.job_state in constants.TERMINAL_JOB_STATES + + @property + def is_failed(self): + """Whether this job finished without doing what it was asked to. + + True when the job is reported in one of + :py:data:`~sushy.oem.dell.constants.FAILED_JOB_STATES`: it failed, + completed with errors, or its reboot failed. A job that is still + in flight is not failed (yet); check :py:attr:`is_finished` + first to tell the two apart. + + :returns: True if the job ended in a failed state, False otherwise. + """ + return self.job_state in constants.FAILED_JOB_STATES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/oem/dell/resources/manager/job_collection.py new/sushy-5.14.0/sushy/oem/dell/resources/manager/job_collection.py --- old/sushy-5.13.0/sushy/oem/dell/resources/manager/job_collection.py 2026-08-20 17:15:26.839361000 +0200 +++ new/sushy-5.14.0/sushy/oem/dell/resources/manager/job_collection.py 2026-10-06 16:45:55.774955700 +0200 @@ -14,7 +14,7 @@ import logging -from sushy.oem.dell import constants +from sushy.oem.dell.resources.manager import job from sushy.resources import base LOG = logging.getLogger(__name__) @@ -38,18 +38,69 @@ super().__init__( connector, identity, redfish_version, registries) + def get_jobs(self, job_ids=None): + """Get the status of jobs in this collection. + + Performs a single GET of the expanded job collection and builds a + :class:`~sushy.oem.dell.resources.manager.job.DellJob` for each + member from the document that GET already returned, without + issuing any further requests. + + :param job_ids: an optional list of job identities to filter by. + If given, only jobs whose ``Id`` is among them are returned, + preserving the order in which they appear in the collection. + If not given, all jobs in the collection are returned. + :returns: a list of :class:`~sushy.oem.dell.resources.manager. + job.DellJob` instances. + """ + job_expand_uri = f'{self._path}{self._JOB_EXPAND}' + job_response = self._conn.get(job_expand_uri) + data = job_response.json() + jobs = [] + for member in data['Members']: + job_id = member.get('Id') + if job_ids is not None and job_id not in job_ids: + continue + job_path = member.get('@odata.id', f'{self._path}/{job_id}') + jobs.append(job.DellJob( + self._conn, job_path, json_doc=member, + redfish_version=self.redfish_version, + registries=self.registries, root=self.root)) + return jobs + + def get_job(self, job_id): + """Get the status of a single job. + + Unlike :py:meth:`get_jobs`, this performs its own GET of the job + resource rather than reading it out of the collection. + + :param job_id: the identity of the job to fetch. + :returns: a :class:`~sushy.oem.dell.resources.manager.job.DellJob` + instance. + :raises: ResourceNotFoundError if no job with this identity exists. + """ + return job.DellJob( + self._conn, f'{self._path}/{job_id}', + redfish_version=self.redfish_version, + registries=self.registries, root=self.root) + def get_unfinished_jobs(self): """Get the unfinished jobs. + A job counts as finished only when the iDRAC reports it in one of + :py:data:`~sushy.oem.dell.constants.TERMINAL_JOB_STATES`. Every + other state, including states this library does not recognise, is + reported as unfinished so that a job the Lifecycle Controller is + still working on is never mistaken for a completed one. + :returns: A list of unfinished jobs. """ - job_expand_uri = f'{self._path}{self._JOB_EXPAND}' unfinished_jobs = [] - LOG.debug('Getting unfinished jobs...') - job_response = self._conn.get(job_expand_uri) - data = job_response.json() - for job in data['Members']: - if job['JobState'] in constants.INCOMPLETE_JOB_STATES: - unfinished_jobs.append(job['Id']) - LOG.info('Got unfinished jobs') + for dell_job in self.get_jobs(): + if not dell_job.is_finished: + LOG.debug('Job %(id)s is in state %(state)s, treating it ' + 'as unfinished', + {'id': dell_job.identity, + 'state': dell_job.job_state}) + unfinished_jobs.append(dell_job.identity) return unfinished_jobs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/resources/common.py new/sushy-5.14.0/sushy/resources/common.py --- old/sushy-5.13.0/sushy/resources/common.py 2026-08-20 17:15:26.858400800 +0200 +++ new/sushy-5.14.0/sushy/resources/common.py 2026-10-06 16:45:55.781951700 +0200 @@ -10,11 +10,16 @@ # License for the specific language governing permissions and limitations # under the License. +import logging + from dateutil import parser +from sushy import exceptions from sushy.resources import base from sushy.resources import constants +LOG = logging.getLogger(__name__) + class IdRefField(base.CompositeField): """Reference to the resource odata identity field.""" @@ -60,10 +65,77 @@ operation_apply_time_support = OperationApplyTimeSupportField() +class ParametersListField(base.ListField): + """The parameters listed by an ActionInfo resource.""" + + name = base.Field('Name') + allowed_values = base.Field('AllowableValues', adapter=list) + + +class ActionInfo(base.ResourceBase): + """The resource an action can point at to describe its parameters. + + Services that do not annotate an action's allowable values on the action + itself link to one of these instead. + """ + + parameters = ParametersListField('Parameters', default=[]) + + @classmethod + def from_uri(cls, resource, uri): + """Fetch the ActionInfo resource an action points at. + + :param resource: the resource the action belongs to, for its + connection to the BMC. + :param uri: the action's ``@Redfish.ActionInfo`` annotation. + :returns: an `ActionInfo`, or None if it cannot be read. + """ + try: + return cls(resource._conn, uri, + redfish_version=resource.redfish_version, + registries=resource.registries, root=resource.root) + + # A service can answer with something not shaped like an ActionInfo, + # which the field machinery raises TypeError rather than SushyError for + except (exceptions.SushyError, TypeError) as exc: + LOG.warning('Could not read the ActionInfo resource at %s: %s', + uri, exc) + return None + + def get_allowable_values(self, parameter): + """Get the values the given parameter accepts. + + :param parameter: name of the parameter, e.g. ``ResetType``. + :returns: a list of allowed values, or None if this resource does not + constrain the parameter. + """ + return next((p.allowed_values for p in self.parameters + if p.name == parameter), None) + + class ResetActionField(ActionField): allowed_values = base.Field('[email protected]', adapter=list) + action_info_uri = base.Field('@Redfish.ActionInfo') + """Where a service publishes the values instead of annotating them.""" + + def get_allowed_values(self, resource): + """Get the reset types this action accepts. + + :param resource: the resource this action belongs to, used to fetch + the ActionInfo resource if the action points at one. + :returns: a list of allowed values, or None if the service does not + make them known. + """ + if self.allowed_values or not self.action_info_uri: + return self.allowed_values + + action_info = ActionInfo.from_uri(resource, self.action_info_uri) + + return (action_info.get_allowable_values('ResetType') + if action_info else None) + class InitializeActionField(ActionField): allowed_values = base.Field('[email protected]', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/resources/system/pcie_device.py new/sushy-5.14.0/sushy/resources/system/pcie_device.py --- old/sushy-5.13.0/sushy/resources/system/pcie_device.py 2026-08-20 17:15:26.872430300 +0200 +++ new/sushy-5.14.0/sushy/resources/system/pcie_device.py 2026-10-06 16:45:55.787948400 +0200 @@ -16,7 +16,6 @@ # Per DMTF DSP0268_2025.2 Section 6.97 PCIeFunction 1.6.0 import logging -from sushy import exceptions from sushy.resources import base from sushy.resources import common from sushy.resources.system import constants as sys_cons @@ -207,18 +206,11 @@ :raises: MissingAttributeError if PCIeFunctions is not supported :returns: PCIeFunctionCollection instance """ - try: - return PCIeFunctionCollection( - self._conn, - utils.get_sub_resource_path_by(self, "PCIeFunctions"), - redfish_version=self.redfish_version, - registries=self.registries, root=self.root) - except exceptions.MissingAttributeError: - # Return empty collection if PCIeFunctions is not supported - return PCIeFunctionCollection( - self._conn, "/empty", - redfish_version=self.redfish_version, - registries=self.registries, root=self.root) + return PCIeFunctionCollection( + self._conn, + utils.get_sub_resource_path_by(self, "PCIeFunctions"), + redfish_version=self.redfish_version, + registries=self.registries, root=self.root) class PCIeDeviceCollection(base.ResourceCollectionBase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/resources/system/system.py new/sushy-5.14.0/sushy/resources/system/system.py --- old/sushy-5.13.0/sushy/resources/system/system.py 2026-08-20 17:15:26.882451300 +0200 +++ new/sushy-5.14.0/sushy/resources/system/system.py 2026-10-06 16:45:55.789947000 +0200 @@ -292,14 +292,15 @@ :returns: A set with the allowed values. """ reset_action = self._get_reset_action_element() + allowed_values = reset_action.get_allowed_values(self) - if not reset_action.allowed_values: + if not allowed_values: LOG.warning('Could not figure out the allowed values for the ' 'reset system action for System %s', self.identity) return set(res_cons.ResetType) return {v for v in res_cons.ResetType - if v.value in reset_action.allowed_values} + if v.value in allowed_values} def reset_system(self, value): """Reset the system. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/tests/oem/dell/unit/json_samples/job.json new/sushy-5.14.0/sushy/tests/oem/dell/unit/json_samples/job.json --- old/sushy-5.13.0/sushy/tests/oem/dell/unit/json_samples/job.json 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.14.0/sushy/tests/oem/dell/unit/json_samples/job.json 2026-10-06 16:45:55.793944800 +0200 @@ -0,0 +1,19 @@ +{ + "@odata.context": "/redfish/v1/$metadata#DellJob.DellJob", + "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Jobs/JID_878623579002", + "@odata.type": "#DellJob.v1_0_2.DellJob", + "CompletionTime": "2024-06-01T15:21:33", + "Description": "Job Instance", + "EndTime": "TIME_NA", + "Id": "JID_878623579002", + "JobState": "Completed", + "JobType": "FirmwareUpdate", + "Message": "Job completed successfully.", + "MessageArgs": [ ], + "[email protected]": 0, + "MessageId": "PR19", + "Name": "Firmware Update: BIOS", + "PercentComplete": 100, + "StartTime": "2024-06-01T15:10:02", + "TargetSettingsURI": null +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/tests/oem/dell/unit/resources/manager/test_job.py new/sushy-5.14.0/sushy/tests/oem/dell/unit/resources/manager/test_job.py --- old/sushy-5.13.0/sushy/tests/oem/dell/unit/resources/manager/test_job.py 1970-01-01 01:00:00.000000000 +0100 +++ new/sushy-5.14.0/sushy/tests/oem/dell/unit/resources/manager/test_job.py 2026-10-06 16:45:55.797942400 +0200 @@ -0,0 +1,72 @@ +# Copyright (c) 2026 Dell Inc. or its subsidiaries. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json +from unittest import mock + +from oslotest.base import BaseTestCase + +from sushy.oem.dell.resources.manager import job + + +class DellJobTestCase(BaseTestCase): + + def setUp(self): + super().setUp() + self.conn = mock.Mock() + with open('sushy/tests/oem/dell/unit/json_samples/' + 'job.json') as f: + mock_response = self.conn.get.return_value + mock_response.json.return_value = json.load(f) + mock_response.status_code = 200 + + self.dell_job = job.DellJob( + self.conn, + '/redfish/v1/Managers/iDRAC.Embedded.1/Jobs/JID_878623579002') + + def test_parse_attributes(self): + self.assertEqual('JID_878623579002', self.dell_job.identity) + self.assertEqual('Firmware Update: BIOS', self.dell_job.name) + self.assertEqual('Job Instance', self.dell_job.description) + self.assertEqual('Completed', self.dell_job.job_state) + self.assertEqual('FirmwareUpdate', self.dell_job.job_type) + self.assertEqual('Job completed successfully.', + self.dell_job.message) + self.assertEqual('PR19', self.dell_job.message_id) + self.assertEqual(100, self.dell_job.percent_complete) + self.assertEqual('2024-06-01T15:10:02', self.dell_job.start_time) + self.assertEqual('TIME_NA', self.dell_job.end_time) + self.assertEqual('2024-06-01T15:21:33', + self.dell_job.completion_time) + + def test_is_finished_and_is_failed(self): + # (job_state, is_finished, is_failed) for every branch of both + # properties: each terminal state, each known non-terminal state, + # a state this library does not know, and no state at all. + cases = [ + ('Completed', True, False), + ('CompletedWithErrors', True, True), + ('Failed', True, True), + ('RebootFailed', True, True), + ('Scheduled', False, False), + ('Running', False, False), + ('UserIntervention', False, False), + ('SomeFutureState', False, False), + (None, False, False), + ] + for state, finished, failed in cases: + with self.subTest(state=state): + self.dell_job.job_state = state + self.assertIs(finished, self.dell_job.is_finished) + self.assertIs(failed, self.dell_job.is_failed) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/tests/oem/dell/unit/resources/manager/test_job_collection.py new/sushy-5.14.0/sushy/tests/oem/dell/unit/resources/manager/test_job_collection.py --- old/sushy-5.13.0/sushy/tests/oem/dell/unit/resources/manager/test_job_collection.py 2026-08-20 17:15:26.910510300 +0200 +++ new/sushy-5.14.0/sushy/tests/oem/dell/unit/resources/manager/test_job_collection.py 2026-10-06 16:45:55.798941900 +0200 @@ -17,11 +17,57 @@ from oslotest.base import BaseTestCase +from sushy import exceptions from sushy.oem.dell.resources.manager import job_collection class DellJobCollectionTestCase(BaseTestCase): + # Every job state iDRAC is known to report that does not mean the + # Lifecycle Controller has stopped working on the job. 'UserIntervention' + # is absent from the JobState enum in + # sushy.oem.dell.resources.taskservice.constants but is reported by + # iDRAC for firmware that is staged and awaiting a POST flash. + NON_TERMINAL_STATES = ['New', + 'Scheduling', + 'Scheduled', + 'ReadyForExecution', + 'Waiting', + 'Downloading', + 'Downloaded', + 'Running', + 'Paused', + 'RebootPending', + 'RebootCompleted', + 'PendingActivation', + 'UserIntervention', + 'Unknown'] + + TERMINAL_STATES = ['Completed', + 'CompletedWithErrors', + 'Failed', + 'RebootFailed'] + + def _set_jobs(self, states): + """Point the mocked connection at a job queue with these states. + + :param states: a list of JobState strings, one per job. A state of + None omits the JobState field entirely. + :returns: the list of job IDs generated, in order. + """ + members = [] + for index, state in enumerate(states): + job = {'@odata.id': '/redfish/v1/Managers/iDRAC.Embedded.1' + '/Jobs/JID_%d' % index, + 'Id': 'JID_%d' % index} + if state is not None: + job['JobState'] = state + members.append(job) + + self.conn.get.return_value.json.return_value = { + 'Id': 'JobQueue', 'Name': 'JobQueue', 'Members': members} + return [job['Id'] for job in members] + def setUp(self): super().setUp() self.conn = mock.Mock() @@ -44,3 +90,95 @@ '/Jobs?$expand=.($levels=1)') self.conn.get.assert_called_with(target_uri) self.assertEqual(expected_unfinished_jobs, actual_unfinished_jobs) + + def test_get_unfinished_jobs_non_terminal_states(self): + expected = self._set_jobs(self.NON_TERMINAL_STATES) + self.assertEqual(expected, self.job_collection.get_unfinished_jobs()) + + def test_get_unfinished_jobs_terminal_states(self): + self._set_jobs(self.TERMINAL_STATES) + self.assertEqual([], self.job_collection.get_unfinished_jobs()) + + def test_get_unfinished_jobs_user_intervention(self): + """A staged firmware job awaiting a POST flash is not finished.""" + self._set_jobs(['UserIntervention']) + self.assertEqual(['JID_0'], + self.job_collection.get_unfinished_jobs()) + + def test_get_unfinished_jobs_unrecognised_state(self): + """An unknown state must not be mistaken for a finished job.""" + self._set_jobs(['SomeFutureIdracState']) + self.assertEqual(['JID_0'], + self.job_collection.get_unfinished_jobs()) + + def test_get_unfinished_jobs_missing_job_state(self): + self._set_jobs([None]) + self.assertEqual(['JID_0'], + self.job_collection.get_unfinished_jobs()) + + def test_get_unfinished_jobs_mixed(self): + self._set_jobs(['Completed', 'UserIntervention', 'Failed', + 'RebootPending']) + self.assertEqual(['JID_1', 'JID_3'], + self.job_collection.get_unfinished_jobs()) + + def test_get_unfinished_jobs_empty_queue(self): + self._set_jobs([]) + self.assertEqual([], self.job_collection.get_unfinished_jobs()) + + def test_get_jobs(self): + self.conn.get.reset_mock() + jobs = self.job_collection.get_jobs() + target_uri = ('/redfish/v1/Managers/iDRAC.Embedded.1' + '/Jobs?$expand=.($levels=1)') + self.conn.get.assert_called_once_with(target_uri) + self.assertEqual(1, len(jobs)) + dell_job = jobs[0] + self.assertEqual('RID_878460711202', dell_job.identity) + self.assertEqual('Reboot3', dell_job.name) + self.assertEqual('Job Instance', dell_job.description) + self.assertEqual('Running', dell_job.job_state) + self.assertEqual('RebootForce', dell_job.job_type) + self.assertEqual('Reboot is complete.', dell_job.message) + self.assertEqual('RED030', dell_job.message_id) + self.assertEqual(100, dell_job.percent_complete) + self.assertEqual('TIME_NOW', dell_job.start_time) + self.assertEqual('TIME_NA', dell_job.end_time) + self.assertEqual('2020-04-25T15:21:33', dell_job.completion_time) + self.assertFalse(dell_job.is_finished) + + def test_get_jobs_filters_by_job_ids(self): + expected = self._set_jobs( + ['Completed', 'UserIntervention', 'Failed', 'RebootPending']) + self.conn.get.reset_mock() + jobs = self.job_collection.get_jobs( + job_ids=[expected[3], expected[1]]) + self.assertEqual([expected[1], expected[3]], + [dell_job.identity for dell_job in jobs]) + self.conn.get.assert_called_once() + + def test_get_jobs_member_without_id_raises(self): + # Id is a required field of DellJob, so a member lacking it is a + # malformed response and surfaces as such rather than being + # silently dropped. + base_uri = '/redfish/v1/Managers/iDRAC.Embedded.1/Jobs' + no_id_member = { + '@odata.id': base_uri + '/JID_0', 'JobState': 'Completed'} + self.conn.get.return_value.json.return_value = { + 'Id': 'JobQueue', 'Name': 'JobQueue', + 'Members': [no_id_member]} + self.assertRaises(exceptions.MissingAttributeError, + self.job_collection.get_jobs) + + def test_get_job(self): + with open('sushy/tests/oem/dell/unit/json_samples/' + 'job.json') as f: + self.conn.get.return_value.json.return_value = json.load(f) + self.conn.get.reset_mock() + dell_job = self.job_collection.get_job('JID_878623579002') + target_uri = ('/redfish/v1/Managers/iDRAC.Embedded.1' + '/Jobs/JID_878623579002') + self.conn.get.assert_called_once_with(path=target_uri) + self.assertEqual('JID_878623579002', dell_job.identity) + self.assertEqual('Completed', dell_job.job_state) + self.assertTrue(dell_job.is_finished) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/tests/unit/resources/system/test_pcie_device.py new/sushy-5.14.0/sushy/tests/unit/resources/system/test_pcie_device.py --- old/sushy-5.13.0/sushy/tests/unit/resources/system/test_pcie_device.py 2026-08-20 17:15:26.950594400 +0200 +++ new/sushy-5.14.0/sushy/tests/unit/resources/system/test_pcie_device.py 2026-10-06 16:45:55.816931500 +0200 @@ -13,6 +13,7 @@ import json from unittest import mock +from sushy import exceptions from sushy.resources import constants as res_cons from sushy.resources.system import constants as sys_cons from sushy.resources.system import pcie_device @@ -327,17 +328,9 @@ @mock.patch.object(pcie_device, 'PCIeFunctionCollection', autospec=True) @mock.patch('sushy.utils.get_sub_resource_path_by', autospec=True) def test_pcie_functions_missing_attribute( - self, mock_get_path, mock_collection): - from sushy import exceptions - # Simulate MissingAttributeError when PCIeFunctions is not supported + self, mock_get_path, mock_collection): mock_get_path.side_effect = exceptions.MissingAttributeError( attribute='PCIeFunctions', resource=self.pcie_dev._path) - _ = self.pcie_dev.pcie_functions - # Should create empty collection - - mock_collection.assert_called_once_with( - self.pcie_dev._conn, "/empty", - redfish_version=self.pcie_dev.redfish_version, - registries=self.pcie_dev.registries, - root=self.pcie_dev.root) + with self.assertRaises(exceptions.MissingAttributeError): + self.pcie_dev.pcie_functions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy/tests/unit/resources/system/test_system.py new/sushy-5.14.0/sushy/tests/unit/resources/system/test_system.py --- old/sushy-5.13.0/sushy/tests/unit/resources/system/test_system.py 2026-08-20 17:15:26.953600600 +0200 +++ new/sushy-5.14.0/sushy/tests/unit/resources/system/test_system.py 2026-10-06 16:45:55.817931000 +0200 @@ -108,7 +108,8 @@ parser.parse('2016-03-07T14:44:30-05:05')}, attributes.get('maintenance_window')) self.assertEqual( - {'reset': {'allowed_values': + {'reset': {'action_info_uri': None, + 'allowed_values': ['On', 'ForceOff', 'GracefulShutdown', 'GracefulRestart', 'ForceRestart', 'Nmi', 'ForceOn', 'PushPowerButton'], @@ -207,6 +208,58 @@ self.assertIsInstance(values, set) self.assertEqual(1, mock_log.call_count) + def _use_action_info(self, action_info=None, error=None): + """Move the allowed values into a separate ActionInfo resource. + + :returns: the URI the reset action now points at. + """ + uri = '/redfish/v1/Systems/437XR1138R2/ResetActionInfo' + action = self.json_doc['Actions']['#ComputerSystem.Reset'] + action.pop('[email protected]', None) + action['@Redfish.ActionInfo'] = uri + + def _get(path=None, **kwargs): + if path == uri and error: + raise error + response = mock.Mock() + response.headers = {'Allow': 'GET,HEAD'} + response.json.return_value = (action_info if path == uri + else self.json_doc) + return response + + self.conn.get.side_effect = _get + self.sys_inst.refresh(force=True) + + return uri + + def test_get_allowed_reset_system_values_from_action_info(self): + self._use_action_info( + {'Parameters': [{'Name': 'ResetType', + 'AllowableValues': ['ForceOff', + 'GracefulShutdown', + 'On', 'ForceRestart']}]}) + + values = self.sys_inst.get_allowed_reset_system_values() + + self.assertEqual({sushy.ResetType.FORCE_OFF, + sushy.ResetType.GRACEFUL_SHUTDOWN, + sushy.ResetType.ON, + sushy.ResetType.FORCE_RESTART}, values) + + def test_get_allowed_reset_system_values_action_info_unusable(self): + fallback = set(sushy.ResetType) + + for action_info, error in ( + (None, exceptions.ConnectionError(url='/x', error='boom')), + ({'Parameters': 'not a list of parameters'}, None)): + uri = self._use_action_info(action_info, error) + self.conn.get.reset_mock() + + self.assertEqual( + fallback, self.sys_inst.get_allowed_reset_system_values()) + # the fallback came from trying the ActionInfo, not ignoring it + self.conn.get.assert_called_once_with(path=uri) + def test_reset_action_operation_apply_time_support(self): support = self.sys_inst._actions.reset.operation_apply_time_support self.assertIsNotNone(support) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy.egg-info/PKG-INFO new/sushy-5.14.0/sushy.egg-info/PKG-INFO --- old/sushy-5.13.0/sushy.egg-info/PKG-INFO 2026-08-20 17:16:13.159014200 +0200 +++ new/sushy-5.14.0/sushy.egg-info/PKG-INFO 2026-10-06 16:46:49.575524300 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: sushy -Version: 5.13.0 +Version: 5.14.0 Summary: Sushy is a small Python library to communicate with Redfish based systems Home-page: https://docs.openstack.org/sushy/latest/ Author: OpenStack diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy.egg-info/SOURCES.txt new/sushy-5.14.0/sushy.egg-info/SOURCES.txt --- old/sushy-5.13.0/sushy.egg-info/SOURCES.txt 2026-08-20 17:16:13.291035000 +0200 +++ new/sushy-5.14.0/sushy.egg-info/SOURCES.txt 2026-10-06 16:46:49.654519600 +0200 @@ -88,6 +88,7 @@ releasenotes/notes/cisco-c845a-transfer-protocol-fix-3791162410459a33.yaml releasenotes/notes/config-server-side-retries-d16824019bd709a2.yaml releasenotes/notes/decouple-boot-params-c75e80f5951abb12.yaml +releasenotes/notes/dell-job-status-api-3f2d835ce01c282e.yaml releasenotes/notes/deprecate-system-leds-f1a72422c53d281e.yaml releasenotes/notes/disable-conn-pooling-3456782afe56ac94.yaml releasenotes/notes/do-not-offer-compression-encoding-884ca8a7458cb096.yaml @@ -120,6 +121,7 @@ releasenotes/notes/fix-subprocessors-3b619434dba4636d.yaml releasenotes/notes/fix-taskmonitor-init-calls-in-volume-module-0f8a747acd0cfe3f.yaml releasenotes/notes/fix-to-close-session-on-dealloc-c3687d4dcb1441b8.yaml +releasenotes/notes/fix-unfinished-job-states-7c1f4a02e9d83b16.yaml releasenotes/notes/fix-update-service-constants-b8c3f48ccee6ce1f.yaml releasenotes/notes/fix-use-headers-for-options-736940b87c06c189.yaml releasenotes/notes/fix-virtual-media-fallback-15a559414a65c014.yaml @@ -147,6 +149,7 @@ releasenotes/notes/more-transferprotocoltype-739ce8bdedbcb51c.yaml releasenotes/notes/no-passwords-295207ac891d27ab.yaml releasenotes/notes/non-default-language-registries-f73bdecc98ba2cc8.yaml +releasenotes/notes/pci-empty-96e2fcf1998abc5b.yaml releasenotes/notes/property-missing-7602c421ec177e9a.yaml releasenotes/notes/raise-error-on-async-task-failure-b67c7bc189a4d6ca.yaml releasenotes/notes/re-raise-1fe9f912691e893e.yaml @@ -159,6 +162,7 @@ releasenotes/notes/remove-py310-d8d686ad11a67432.yaml releasenotes/notes/remove-py38-6eebcd268c6f8e37.yaml releasenotes/notes/remove-py39-9d9717edf25353f8.yaml +releasenotes/notes/reset-action-info-116108027e85e510.yaml releasenotes/notes/retry-if-transferprototype-missing-9cae57f3ecf470a9.yaml releasenotes/notes/retry-ilo-not-ready-error-0b4dce882282eaac.yaml releasenotes/notes/retry-on-missing-managedby-b2a5240eab8b4262.yaml @@ -180,6 +184,7 @@ releasenotes/notes/sushy-system-virtualmedia-7a61bd77780f7b0e.yaml releasenotes/notes/update-apply-time-support-53c5445b58cd3b42.yaml releasenotes/notes/update_sushy_models-9b8ea0350eb4d4d0.yaml +releasenotes/notes/use-lazy-reg-taskmonitor-3295697c9814d83d.yaml releasenotes/notes/use-sessions-url-from-root-8b8eca57dc450705.yaml releasenotes/notes/use-settingsobject-if-supported-12a332f9905d64ce.yaml releasenotes/notes/vmedia-1.4.0-9957460fed59d85c.yaml @@ -194,6 +199,7 @@ releasenotes/source/2025.1.rst releasenotes/source/2025.2.rst releasenotes/source/2026.1.rst +releasenotes/source/2026.2.rst releasenotes/source/conf.py releasenotes/source/index.rst releasenotes/source/pike.rst @@ -235,6 +241,7 @@ sushy/oem/dell/resources/manager/__init__.py sushy/oem/dell/resources/manager/constants.py sushy/oem/dell/resources/manager/idrac_card_service.py +sushy/oem/dell/resources/manager/job.py sushy/oem/dell/resources/manager/job_collection.py sushy/oem/dell/resources/manager/job_service.py sushy/oem/dell/resources/manager/lifecycle_service.py @@ -346,6 +353,7 @@ sushy/tests/oem/dell/unit/json_samples/export_configuration_idrac.json sushy/tests/oem/dell/unit/json_samples/export_configuration_nic_bios.json sushy/tests/oem/dell/unit/json_samples/idrac_card_service.json +sushy/tests/oem/dell/unit/json_samples/job.json sushy/tests/oem/dell/unit/json_samples/job_collection_expanded.json sushy/tests/oem/dell/unit/json_samples/job_service.json sushy/tests/oem/dell/unit/json_samples/lifecycle_service.json @@ -360,6 +368,7 @@ sushy/tests/oem/dell/unit/resources/__init__.py sushy/tests/oem/dell/unit/resources/manager/__init__.py sushy/tests/oem/dell/unit/resources/manager/test_idrac_card_service.py +sushy/tests/oem/dell/unit/resources/manager/test_job.py sushy/tests/oem/dell/unit/resources/manager/test_job_collection.py sushy/tests/oem/dell/unit/resources/manager/test_job_service.py sushy/tests/oem/dell/unit/resources/manager/test_lifecycle_service.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/sushy.egg-info/pbr.json new/sushy-5.14.0/sushy.egg-info/pbr.json --- old/sushy-5.13.0/sushy.egg-info/pbr.json 2026-08-20 17:16:13.173016300 +0200 +++ new/sushy-5.14.0/sushy.egg-info/pbr.json 2026-10-06 16:46:49.575524300 +0200 @@ -1 +1 @@ -{"git_version": "f13efd9", "is_release": true} \ No newline at end of file +{"git_version": "b7917f5", "is_release": true} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/test-requirements.txt new/sushy-5.14.0/test-requirements.txt --- old/sushy-5.13.0/test-requirements.txt 2026-08-20 17:15:26.956606900 +0200 +++ new/sushy-5.14.0/test-requirements.txt 2026-10-06 16:45:55.820929000 +0200 @@ -1,7 +1,3 @@ -# 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. - # unit tests coverage!=4.4,>=4.0 # Apache-2.0 oslotest>=3.2.0 # Apache-2.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sushy-5.13.0/zuul.d/sushy-jobs.yaml new/sushy-5.14.0/zuul.d/sushy-jobs.yaml --- old/sushy-5.13.0/zuul.d/sushy-jobs.yaml 2026-08-20 17:15:26.956606900 +0200 +++ new/sushy-5.14.0/zuul.d/sushy-jobs.yaml 2026-10-06 16:45:55.820929000 +0200 @@ -1,9 +1,16 @@ - job: name: sushy-tempest-bios-redfish-pxe parent: ironic-tempest-bios-redfish-pxe - irrelevant-files: + irrelevant-files: &irrelevant_files - ^.*\.rst$ + - ^tox\.ini$ + - ^LICENSE$ + - ^\.coveragerc$ + - ^\/.gitconfig$ + - ^\/.gitreview$ + - ^\.mailmap$ - ^\.pre-commit-config\.yaml$ + - ^\.stestr.conf$ - ^doc/.*$ - ^test-requirements.txt$ - ^sushy/tests/.*$ @@ -13,11 +20,6 @@ - job: name: sushy-tempest-uefi-redfish-vmedia parent: ironic-tempest-uefi-redfish-vmedia - irrelevant-files: - - ^.*\.rst$ - - ^\.pre-commit-config\.yaml$ - - ^doc/.*$ - - ^test-requirements.txt$ - - ^sushy/tests/.*$ + irrelevant-files: *irrelevant_files required-projects: - openstack/sushy
