Skip to content

Commit 9a30a8a

Browse files
committed
Migrate package metadata from setup.cfg to pyproject.toml
Modernize the packaging configuration by moving all metadata, entry points, and tool configurations from setup.cfg to pyproject.toml following PEP 621 standards. This includes project metadata, classifiers, entry points for extensions and hardware managers, console scripts, and tool configurations. A minimal setup.cfg is retained with only the package name for PBR compatibility, as PBR still requires this file to exist. Also modifies an inspector test which used a precise count of calls to the time module... which is a known problematic pattern. The code has been updated to be more forgiving across python versions and logging configurations such as the difference which can exist between unit tests and coverage test checking where this test was found to be failing in CI. Since this was originally proposed, it looks like another change removed the check entirely, but I've added it back with a slightly more graceful model of asserting that there were calls, just not counting the exact number of calls, asserting at least a minimum number because changes for python ?3.13? also previously had to adjust the count. Assisted-By: Claude Code - Claude Sonnet 4.5 Change-Id: I85209e6cc9a01d6b61527a755e654a9f1844a8e4 Signed-off-by: Julia Kreger <juliaashleykreger@gmail.com>
1 parent f6eb47e commit 9a30a8a

3 files changed

Lines changed: 87 additions & 75 deletions

File tree

ironic_python_agent/tests/unit/test_inspector.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,11 @@ def test_timeout(self, mocked_time, mocked_time_ns, mocked_sleep,
680680
self.assertFalse(inspector.wait_for_dhcp())
681681
mocked_dispatch.assert_called_with('list_network_interfaces')
682682
mocked_sleep.assert_called_once_with(inspector._DHCP_RETRY_INTERVAL)
683+
# time.time() was called 3 times explicitly in wait_for_dhcp(),
684+
# Python 3.13+ uses time.time_ns for logging which varies by logging
685+
# level and coverage configuration, so we cannot assert exact counts
686+
total_time_calls = mocked_time.call_count + mocked_time_ns.call_count
687+
self.assertGreaterEqual(total_time_calls, 3)
683688

684689
def test_disabled(self, mocked_dispatch):
685690
CONF.set_override('inspection_dhcp_wait_timeout', 0)

pyproject.toml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,80 @@
22
requires = ["pbr>=6.0.0", "setuptools>=64.0.0"]
33
build-backend = "pbr.build"
44

5+
[project]
6+
name = "ironic-python-agent"
7+
description = "Ironic Python Agent Ramdisk"
8+
authors = [
9+
{name = "OpenStack", email = "openstack-discuss@lists.openstack.org"},
10+
]
11+
license = {text = "Apache-2.0"}
12+
readme = {file = "README.rst", content-type = "text/x-rst"}
13+
requires-python = ">=3.10"
14+
classifiers = [
15+
"Environment :: OpenStack",
16+
"Intended Audience :: System Administrators",
17+
"Intended Audience :: Information Technology",
18+
"Operating System :: OS Independent",
19+
"Programming Language :: Python",
20+
"Programming Language :: Python :: Implementation :: CPython",
21+
"Programming Language :: Python :: 3 :: Only",
22+
"Programming Language :: Python :: 3",
23+
"Programming Language :: Python :: 3.10",
24+
"Programming Language :: Python :: 3.11",
25+
"Programming Language :: Python :: 3.12",
26+
]
27+
dynamic = ["version", "dependencies"]
28+
29+
[project.urls]
30+
Homepage = "https://docs.openstack.org/ironic-python-agent/"
31+
32+
[project.optional-dependencies]
33+
burnin-network-kazoo = [
34+
"kazoo>=2.8.0",
35+
]
36+
37+
[project.entry-points."oslo.config.opts"]
38+
ironic-python-agent = "ironic_python_agent.config:list_opts"
39+
ironic-python-agent-mdns = "ironic_python_agent.mdns:list_opts"
40+
41+
[project.entry-points."ironic_python_agent.extensions"]
42+
standby = "ironic_python_agent.extensions.standby:StandbyExtension"
43+
clean = "ironic_python_agent.extensions.clean:CleanExtension"
44+
deploy = "ironic_python_agent.extensions.deploy:DeployExtension"
45+
flow = "ironic_python_agent.extensions.flow:FlowExtension"
46+
image = "ironic_python_agent.extensions.image:ImageExtension"
47+
log = "ironic_python_agent.extensions.log:LogExtension"
48+
rescue = "ironic_python_agent.extensions.rescue:RescueExtension"
49+
poll = "ironic_python_agent.extensions.poll:PollExtension"
50+
service = "ironic_python_agent.extensions.service:ServiceExtension"
51+
system = "ironic_python_agent.extensions.system:SystemExtension"
52+
53+
[project.entry-points."ironic_python_agent.hardware_managers"]
54+
generic = "ironic_python_agent.hardware:GenericHardwareManager"
55+
mlnx = "ironic_python_agent.hardware_managers.mlnx:MellanoxDeviceHardwareManager"
56+
cna = "ironic_python_agent.hardware_managers.cna:IntelCnaHardwareManager"
57+
container = "ironic_python_agent.hardware_managers.container:ContainerHardwareManager"
58+
59+
[project.entry-points."ironic_python_agent.inspector.collectors"]
60+
default = "ironic_python_agent.inspector:collect_default"
61+
logs = "ironic_python_agent.inspector:collect_logs"
62+
extra-hardware = "ironic_python_agent.inspector:collect_extra_hardware"
63+
pci-devices = "ironic_python_agent.inspector:collect_pci_devices_info"
64+
numa-topology = "ironic_python_agent.numa_inspector:collect_numa_topology_info"
65+
dmi-decode = "ironic_python_agent.dmi_inspector:collect_dmidecode_info"
66+
lldp = "ironic_python_agent.inspector:collect_lldp"
67+
usb-devices = "ironic_python_agent.inspector:collect_usb_devices"
68+
69+
[project.scripts]
70+
ironic-python-agent = "ironic_python_agent.cmd.agent:run"
71+
ironic-collect-introspection-data = "ironic_python_agent.cmd.inspect:run"
72+
73+
[tool.pbr]
74+
autodoc_index_modules = true
75+
76+
[tool.setuptools]
77+
packages = ["ironic_python_agent"]
78+
579
[tool.ruff]
680
line-length = 79
781

@@ -12,3 +86,8 @@ select = [
1286
"G", # flake8-logging-format
1387
"LOG", # flake8-logging
1488
]
89+
90+
[tool.codespell]
91+
quiet-level = 4
92+
ignore-words-list = "cna,assertin,burnin"
93+
skip = "./releasenotes/build,./venv,./doc/build"

setup.cfg

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,5 @@
1+
# All package metadata has been migrated to pyproject.toml
2+
# This file is kept minimal for PBR compatibility
3+
14
[metadata]
25
name = ironic-python-agent
3-
description_file =
4-
README.rst
5-
author = OpenStack
6-
author_email = openstack-discuss@lists.openstack.org
7-
home_page = https://docs.openstack.org/ironic-python-agent/
8-
summary = Ironic Python Agent Ramdisk
9-
license = Apache-2
10-
python_requires = >=3.10
11-
classifier =
12-
Environment :: OpenStack
13-
Intended Audience :: System Administrators
14-
Intended Audience :: Information Technology
15-
License :: OSI Approved :: Apache Software License
16-
Operating System :: OS Independent
17-
Programming Language :: Python
18-
Programming Language :: Python :: Implementation :: CPython
19-
Programming Language :: Python :: 3 :: Only
20-
Programming Language :: Python :: 3
21-
Programming Language :: Python :: 3.10
22-
Programming Language :: Python :: 3.11
23-
Programming Language :: Python :: 3.12
24-
25-
[files]
26-
packages =
27-
ironic_python_agent
28-
29-
[entry_points]
30-
oslo.config.opts =
31-
ironic-python-agent = ironic_python_agent.config:list_opts
32-
ironic-python-agent-mdns = ironic_python_agent.mdns:list_opts
33-
34-
console_scripts =
35-
ironic-python-agent = ironic_python_agent.cmd.agent:run
36-
ironic-collect-introspection-data = ironic_python_agent.cmd.inspect:run
37-
38-
ironic_python_agent.extensions =
39-
standby = ironic_python_agent.extensions.standby:StandbyExtension
40-
clean = ironic_python_agent.extensions.clean:CleanExtension
41-
deploy = ironic_python_agent.extensions.deploy:DeployExtension
42-
flow = ironic_python_agent.extensions.flow:FlowExtension
43-
image = ironic_python_agent.extensions.image:ImageExtension
44-
log = ironic_python_agent.extensions.log:LogExtension
45-
rescue = ironic_python_agent.extensions.rescue:RescueExtension
46-
poll = ironic_python_agent.extensions.poll:PollExtension
47-
service = ironic_python_agent.extensions.service:ServiceExtension
48-
system = ironic_python_agent.extensions.system:SystemExtension
49-
50-
ironic_python_agent.hardware_managers =
51-
generic = ironic_python_agent.hardware:GenericHardwareManager
52-
mlnx = ironic_python_agent.hardware_managers.mlnx:MellanoxDeviceHardwareManager
53-
cna = ironic_python_agent.hardware_managers.cna:IntelCnaHardwareManager
54-
container = ironic_python_agent.hardware_managers.container:ContainerHardwareManager
55-
56-
ironic_python_agent.inspector.collectors =
57-
default = ironic_python_agent.inspector:collect_default
58-
logs = ironic_python_agent.inspector:collect_logs
59-
extra-hardware = ironic_python_agent.inspector:collect_extra_hardware
60-
pci-devices = ironic_python_agent.inspector:collect_pci_devices_info
61-
numa-topology = ironic_python_agent.numa_inspector:collect_numa_topology_info
62-
dmi-decode = ironic_python_agent.dmi_inspector:collect_dmidecode_info
63-
lldp = ironic_python_agent.inspector:collect_lldp
64-
usb-devices = ironic_python_agent.inspector:collect_usb_devices
65-
66-
[extras]
67-
burnin-network-kazoo =
68-
kazoo>=2.8.0 # Apache-2.0
69-
70-
[codespell]
71-
quiet-level = 4
72-
# Words to ignore:
73-
# cna: Intel CNA card
74-
# assertin: valid method in testing
75-
# burnin: name of our burn in methods
76-
ignore-words-list = cna,assertin,burnin
77-
skip = ./releasenotes/build,./venv,./doc/build

0 commit comments

Comments
 (0)