diff --git a/containers/ironic/patches/0001-pass-along-physical_network-to-neutron-from-the-bare.patch b/containers/ironic/patches/0001-pass-along-physical_network-to-neutron-from-the-bare.patch index ff361d6e3..d1d46a67f 100644 --- a/containers/ironic/patches/0001-pass-along-physical_network-to-neutron-from-the-bare.patch +++ b/containers/ironic/patches/0001-pass-along-physical_network-to-neutron-from-the-bare.patch @@ -1,7 +1,7 @@ -From 386faaeaf4a900c4c4591fae4e735164a0f38b45 Mon Sep 17 00:00:00 2001 +From 1b26fa5dad6ce2ad8ac959188e98cd951aee099d Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Wed, 22 Oct 2025 12:58:41 -0500 -Subject: [PATCH 1/8] pass along physical_network to neutron from the baremetal +Subject: [PATCH 1/7] pass along physical_network to neutron from the baremetal port When plugging a baremetal port in using the 'neutron' interface, send diff --git a/containers/ironic/patches/0002-Add-SKU-field-to-Redfish-inspection.patch b/containers/ironic/patches/0002-Add-SKU-field-to-Redfish-inspection.patch index b58c42925..29aa13f6b 100644 --- a/containers/ironic/patches/0002-Add-SKU-field-to-Redfish-inspection.patch +++ b/containers/ironic/patches/0002-Add-SKU-field-to-Redfish-inspection.patch @@ -1,7 +1,7 @@ -From 2ce4304ad46bd37c526740d3a05544aa8cdd2937 Mon Sep 17 00:00:00 2001 +From e7be4c17b8d9119b3beaa926853feb3d6076e475 Mon Sep 17 00:00:00 2001 From: Nidhi Rai Date: Thu, 11 Sep 2025 17:05:22 +0530 -Subject: [PATCH 2/8] Add SKU field to Redfish inspection +Subject: [PATCH 2/7] Add SKU field to Redfish inspection Collect SKU (Service Tag) from Redfish ComputerSystem and include it in system_vendor inventory data. @@ -19,12 +19,12 @@ The change: Change-Id: I6623fd33b356d6149001c43a7179297a7c8568d8 Signed-off-by: Nidhi Rai --- - ironic/drivers/modules/redfish/inspect.py | 6 ++++++ - .../unit/drivers/modules/redfish/test_inspect.py | 12 ++++++++++++ - 2 files changed, 18 insertions(+) + ironic/drivers/modules/redfish/inspect.py | 6 ++++++ + .../unit/drivers/modules/redfish/test_inspect.py | 11 +++++++++++ + 2 files changed, 17 insertions(+) diff --git a/ironic/drivers/modules/redfish/inspect.py b/ironic/drivers/modules/redfish/inspect.py -index eb0345fd0..59c3ce2b0 100644 +index df1ff9a91..69f0f0c09 100644 --- a/ironic/drivers/modules/redfish/inspect.py +++ b/ironic/drivers/modules/redfish/inspect.py @@ -158,6 +158,12 @@ class RedfishInspect(base.InspectInterface): @@ -41,22 +41,21 @@ index eb0345fd0..59c3ce2b0 100644 inventory['system_vendor'] = system_vendor diff --git a/ironic/tests/unit/drivers/modules/redfish/test_inspect.py b/ironic/tests/unit/drivers/modules/redfish/test_inspect.py -index 798e4fe87..c81fb3934 100644 +index 733a2beab..162998e33 100644 --- a/ironic/tests/unit/drivers/modules/redfish/test_inspect.py +++ b/ironic/tests/unit/drivers/modules/redfish/test_inspect.py -@@ -139,6 +139,10 @@ class RedfishInspectTestCase(db_base.DbTestCase): - +@@ -140,6 +140,9 @@ class RedfishInspectTestCase(db_base.DbTestCase): system_mock.manufacturer = 'Sushy Emulator' + system_mock.model = 'PowerEdge R1234' + system_mock.sku = 'DELL123456' + + system_mock.uuid = '12345678-1234-1234-1234-12345' -+ + return system_mock - def test_get_properties(self): -@@ -185,12 +189,18 @@ class RedfishInspectTestCase(db_base.DbTestCase): - expected_product_name = 'System1' +@@ -187,12 +190,18 @@ class RedfishInspectTestCase(db_base.DbTestCase): + expected_product_name = 'PowerEdge R1234' expected_serial_number = '123456' expected_manufacturer = 'Sushy Emulator' + expected_sku = 'DELL123456' @@ -74,8 +73,8 @@ index 798e4fe87..c81fb3934 100644 expected_interfaces = [{'mac_address': '00:11:22:33:44:55', 'name': 'NIC.Integrated.1-1'}, -@@ -700,6 +710,8 @@ class RedfishInspectTestCase(db_base.DbTestCase): - system_mock.name = None +@@ -702,6 +711,8 @@ class RedfishInspectTestCase(db_base.DbTestCase): + system_mock.model = None system_mock.serial_number = None system_mock.manufacturer = None + system_mock.sku = None diff --git a/containers/ironic/patches/0004-hack-for-scheduling-purposes-ignore-ports-with-categ.patch b/containers/ironic/patches/0003-hack-for-scheduling-purposes-ignore-ports-with-categ.patch similarity index 93% rename from containers/ironic/patches/0004-hack-for-scheduling-purposes-ignore-ports-with-categ.patch rename to containers/ironic/patches/0003-hack-for-scheduling-purposes-ignore-ports-with-categ.patch index 5b49a234e..e8efd93c4 100644 --- a/containers/ironic/patches/0004-hack-for-scheduling-purposes-ignore-ports-with-categ.patch +++ b/containers/ironic/patches/0003-hack-for-scheduling-purposes-ignore-ports-with-categ.patch @@ -1,7 +1,7 @@ -From 0d800dfef4ab8516406c068835de2e4e52905dd9 Mon Sep 17 00:00:00 2001 +From 0812e66dd4b52cfb917d2593a8f3efd67922b98a Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Tue, 13 Jan 2026 11:08:04 -0600 -Subject: [PATCH 4/8] hack: for scheduling purposes ignore ports with category +Subject: [PATCH 3/7] hack: for scheduling purposes ignore ports with category storage We want to ignore ports that are in category storage for being eligible diff --git a/containers/ironic/patches/0005-feat-skip-invalid-mac-addr-interfaces-in-redfish-ins.patch b/containers/ironic/patches/0004-feat-skip-invalid-mac-addr-interfaces-in-redfish-ins.patch similarity index 95% rename from containers/ironic/patches/0005-feat-skip-invalid-mac-addr-interfaces-in-redfish-ins.patch rename to containers/ironic/patches/0004-feat-skip-invalid-mac-addr-interfaces-in-redfish-ins.patch index d10f47ba3..4451cb6fe 100644 --- a/containers/ironic/patches/0005-feat-skip-invalid-mac-addr-interfaces-in-redfish-ins.patch +++ b/containers/ironic/patches/0004-feat-skip-invalid-mac-addr-interfaces-in-redfish-ins.patch @@ -1,7 +1,7 @@ -From da011a985fce208c3ad4eeb13d635323b1cbfc8d Mon Sep 17 00:00:00 2001 +From 5fde08ae5631dfeb078ae40838b91c416a422f0f Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Tue, 13 Jan 2026 11:49:05 -0600 -Subject: [PATCH 5/8] feat: skip invalid mac addr interfaces in redfish inspect +Subject: [PATCH 4/7] feat: skip invalid mac addr interfaces in redfish inspect add speed Refactor the redfish interfaces inspection by moving it to its own @@ -78,7 +78,7 @@ index 69f0f0c09..9786c9f46 100644 # NOTE(JayF): Checking truthiness here is better than checking for None # because if we have an empty list, we'll raise a diff --git a/ironic/tests/unit/drivers/modules/redfish/test_inspect.py b/ironic/tests/unit/drivers/modules/redfish/test_inspect.py -index c81fb3934..4b8d08217 100644 +index 162998e33..e8c3e01d7 100644 --- a/ironic/tests/unit/drivers/modules/redfish/test_inspect.py +++ b/ironic/tests/unit/drivers/modules/redfish/test_inspect.py @@ -108,6 +108,7 @@ class RedfishInspectTestCase(db_base.DbTestCase): @@ -97,7 +97,7 @@ index c81fb3934..4b8d08217 100644 eth_interface_mock2.status.state = sushy.STATE_DISABLED eth_interface_mock2.status.health = sushy.HEALTH_OK -@@ -203,9 +205,11 @@ class RedfishInspectTestCase(db_base.DbTestCase): +@@ -204,9 +206,11 @@ class RedfishInspectTestCase(db_base.DbTestCase): system_vendor['system_uuid']) expected_interfaces = [{'mac_address': '00:11:22:33:44:55', diff --git a/containers/ironic/patches/0006-Add-Redfish-LLDP-data-collection-support-to-the-Redf.patch b/containers/ironic/patches/0005-Add-Redfish-LLDP-data-collection-support-to-the-Redf.patch similarity index 99% rename from containers/ironic/patches/0006-Add-Redfish-LLDP-data-collection-support-to-the-Redf.patch rename to containers/ironic/patches/0005-Add-Redfish-LLDP-data-collection-support-to-the-Redf.patch index a1ac229f2..c5903f23e 100644 --- a/containers/ironic/patches/0006-Add-Redfish-LLDP-data-collection-support-to-the-Redf.patch +++ b/containers/ironic/patches/0005-Add-Redfish-LLDP-data-collection-support-to-the-Redf.patch @@ -1,7 +1,7 @@ -From 6433e8653d0337bdd147bea957f812d4fac239cc Mon Sep 17 00:00:00 2001 +From 3f55e9dc63060cfa6ceed23f96f1f42dede6014f Mon Sep 17 00:00:00 2001 From: Nidhi Rai Date: Thu, 20 Nov 2025 19:01:05 +0530 -Subject: [PATCH 6/8] Add Redfish LLDP data collection support to the Redfish +Subject: [PATCH 5/7] Add Redfish LLDP data collection support to the Redfish inspection interface. - _collect_lldp_data(): Collects LLDP data from Redfish NetworkAdapter Ports via Sushy library, walking the Chassis/NetworkAdapter/Port hierarchy @@ -224,10 +224,10 @@ index 9786c9f46..aa492ebc6 100644 + else: + return getattr(lldp_receive, attr_name, None) diff --git a/ironic/tests/unit/drivers/modules/redfish/test_inspect.py b/ironic/tests/unit/drivers/modules/redfish/test_inspect.py -index 4b8d08217..1e0aad17d 100644 +index e8c3e01d7..ac9a7e795 100644 --- a/ironic/tests/unit/drivers/modules/redfish/test_inspect.py +++ b/ironic/tests/unit/drivers/modules/redfish/test_inspect.py -@@ -733,6 +733,283 @@ class RedfishInspectTestCase(db_base.DbTestCase): +@@ -734,6 +734,283 @@ class RedfishInspectTestCase(db_base.DbTestCase): self.assertEqual(expected_properties, task.driver.inspect._get_pxe_port_macs(task)) diff --git a/containers/ironic/patches/0007-Add-LLDP-collect-for-DRAC-Redfish-inspection.patch b/containers/ironic/patches/0006-Add-LLDP-collect-for-DRAC-Redfish-inspection.patch similarity index 99% rename from containers/ironic/patches/0007-Add-LLDP-collect-for-DRAC-Redfish-inspection.patch rename to containers/ironic/patches/0006-Add-LLDP-collect-for-DRAC-Redfish-inspection.patch index b7e18122d..3573bd7b1 100644 --- a/containers/ironic/patches/0007-Add-LLDP-collect-for-DRAC-Redfish-inspection.patch +++ b/containers/ironic/patches/0006-Add-LLDP-collect-for-DRAC-Redfish-inspection.patch @@ -1,7 +1,7 @@ -From 9b08080ef4676d4700d14b3ee44f1b10cdd320df Mon Sep 17 00:00:00 2001 +From b313441094d5e6484e03c5e35a4a7cf44e877d45 Mon Sep 17 00:00:00 2001 From: Nidhi Rai Date: Thu, 11 Dec 2025 19:59:04 +0530 -Subject: [PATCH 7/8] Add LLDP collect for DRAC Redfish inspection +Subject: [PATCH 6/7] Add LLDP collect for DRAC Redfish inspection The implementation collects LLDP data from Dell OEM SwitchConnection endpoints and falls back to standard Redfish LLDP collection when Dell specific data is unavailable. diff --git a/containers/ironic/patches/0009-kubernetes-console-provider.patch b/containers/ironic/patches/0007-Add-a-kubernetes-provider-for-console-container.patch similarity index 89% rename from containers/ironic/patches/0009-kubernetes-console-provider.patch rename to containers/ironic/patches/0007-Add-a-kubernetes-provider-for-console-container.patch index b3586be21..087d4e070 100644 --- a/containers/ironic/patches/0009-kubernetes-console-provider.patch +++ b/containers/ironic/patches/0007-Add-a-kubernetes-provider-for-console-container.patch @@ -1,75 +1,40 @@ -commit 5d44ecd6e39588d509129efd26f6eaafba5c5bb4 -Author: Steve Baker -Date: Fri Oct 3 11:16:53 2025 +1300 +From 3856f2183a4e568eb4f05aa561c8626eb80241c0 Mon Sep 17 00:00:00 2001 +From: Steve Baker +Date: Fri, 3 Oct 2025 11:16:53 +1300 +Subject: [PATCH 7/7] Add a kubernetes provider for console container - Add a kubernetes provider for console container +A new ``ironic.console.container`` provider is added called +``kubernetes`` which allows Ironic conductor to manage console +containers as Kubernetes pods. The kubernetes resources are defined in +the template file configured by ``[vnc]kubernetes_container_template`` +and the default template creates one secret to store the app info, and +one pod to run the console container. - A new ``ironic.console.container`` provider is added called - ``kubernetes`` which allows Ironic conductor to manage console - containers as Kubernetes pods. The kubernetes resources are defined in - the template file configured by ``[vnc]kubernetes_container_template`` - and the default template creates one secret to store the app info, and - one pod to run the console container. +It is expected that Ironic conductor is deployed inside the kubernetes +cluster. The associated service account will need roles and bindings +which allow it to manage the required resources (with the default +template this will be secrets and pods). - It is expected that Ironic conductor is deployed inside the kubernetes - cluster. The associated service account will need roles and bindings - which allow it to manage the required resources (with the default - template this will be secrets and pods). +This provider holds the assumption that ironic-novnc will be deployed in +the same kubernetes cluster, and so can connect to the VNC servers via +the pod's ``status.hostIP``. - This provider holds the assumption that ironic-novnc will be deployed in - the same kubernetes cluster, and so can connect to the VNC servers via - the pod's ``status.hostIP``. +Assisted-By: gemini +Change-Id: Ib91f7d7c15be51d68ebf886e44efaf191a14437b +Signed-off-by: Steve Baker +--- + doc/source/install/graphical-console.rst | 67 +- + ironic/conf/vnc.py | 23 +- + .../ironic-console-pod.yaml.template | 45 ++ + ironic/console/container/kubernetes.py | 307 +++++++ + .../container/test_console_container.py | 764 +++++++++++++++++- + .../notes/console-k8s-b4aee1bb1d3d0a65.yaml | 18 + + setup.cfg | 1 + + 7 files changed, 1216 insertions(+), 9 deletions(-) + create mode 100644 ironic/console/container/ironic-console-pod.yaml.template + create mode 100644 ironic/console/container/kubernetes.py + create mode 100644 releasenotes/notes/console-k8s-b4aee1bb1d3d0a65.yaml - Assisted-By: gemini - Change-Id: Ib91f7d7c15be51d68ebf886e44efaf191a14437b - Signed-off-by: Steve Baker - - Updated to apply cleanly on 2025.2 (marek.skrobacki) - -diff --git a/ironic/conf/vnc.py b/ironic/conf/vnc.py -index 6a7c27900..41365e5f8 100644 ---- a/ironic/conf/vnc.py -+++ b/ironic/conf/vnc.py -@@ -99,11 +99,14 @@ opts = [ - '"systemd" manages containers as systemd units via podman ' - 'Quadlet support. The default is "fake" which returns an ' - 'unusable VNC host and port. This needs to be changed if enabled ' -- 'is True'), -+ 'is True. ' -+ '"kubernetes" manages containers as pods using template driven ' -+ 'resource creation.'), - cfg.StrOpt( - 'console_image', - mutable=True, -- help='Container image reference for the "systemd" console container ' -+ help='Container image reference for the "systemd" and ' -+ '"kubernetes" console container ' - 'provider, and any other out-of-tree provider which requires a ' - 'configurable image reference.'), - cfg.StrOpt( -@@ -127,6 +130,22 @@ opts = [ - 'have no authentication or encryption so they also should not ' - 'be exposed to public access. Additionally, the containers ' - 'need to be able to access BMC management endpoints. '), -+ cfg.StrOpt( -+ 'kubernetes_container_template', -+ default=os.path.join( -+ '$pybasedir', -+ 'console/container/ironic-console-pod.yaml.template'), -+ mutable=True, -+ help='For the kubernetes provider, path to the template for defining ' -+ 'the console resources. The default template creates one Secret ' -+ 'to store the app info, and one Pod to run a console ' -+ 'container. A custom template must include namespace metadata, ' -+ 'and must define labels which can be used as a delete-all ' -+ 'selector.'), -+ cfg.IntOpt('kubernetes_pod_timeout', -+ default=120, -+ help='For the kubernetes provider, the time (in seconds) to ' -+ 'wait for the console pod to start.'), - cfg.StrOpt( - 'ssl_cert_file', - help="Certificate file to use when starting the server securely."), diff --git a/ironic/console/container/ironic-console-pod.yaml.template b/ironic/console/container/ironic-console-pod.yaml.template new file mode 100644 index 000000000..05770bcf6 @@ -436,7 +401,7 @@ index 000000000..35dfab261 + selector = self._labels_to_selector(labels) + self._delete(kind, namespace, selector=selector) diff --git a/ironic/tests/unit/console/container/test_console_container.py b/ironic/tests/unit/console/container/test_console_container.py -index 64c85870e..229b1df12 100644 +index 64c85870e..62c5c6f31 100644 --- a/ironic/tests/unit/console/container/test_console_container.py +++ b/ironic/tests/unit/console/container/test_console_container.py @@ -11,9 +11,12 @@ @@ -452,16 +417,15 @@ index 64c85870e..229b1df12 100644 from oslo_concurrency import processutils from oslo_config import cfg -@@ -22,6 +25,8 @@ from ironic.common import console_factory +@@ -22,6 +25,7 @@ from ironic.common import console_factory from ironic.common import exception from ironic.common import utils from ironic.console.container import fake +from ironic.console.container import kubernetes -+from ironic.console.container import systemd from ironic.tests import base CONF = cfg.CONF -@@ -146,8 +151,8 @@ class TestSystemdConsoleContainer(base.TestCase): +@@ -146,8 +150,8 @@ class TestSystemdConsoleContainer(base.TestCase): @mock.patch.object(utils, 'execute', autospec=True) def test__host_port(self, mock_exec): @@ -472,7 +436,7 @@ index 64c85870e..229b1df12 100644 self.assertEqual( ('192.0.2.1', 33819), self.provider._host_port(container) -@@ -323,3 +328,759 @@ WantedBy=default.target""", f.read()) +@@ -323,3 +327,759 @@ WantedBy=default.target""", f.read()) mock_exec.reset_mock() self.provider.stop_all_containers() mock_exec.assert_not_called() @@ -1232,15 +1196,5 @@ index 64c85870e..229b1df12 100644 + ), + ] + ) -diff --git ironic-32.0.1.dev54.dist-info/entry_points.txt ironic-32.0.1.dev54.dist-info/entry_points.txt -index 29c3decfc..4c886a0f6 100644 ---- a/ironic-32.0.1.dev54.dist-info/entry_points.txt -+++ b/ironic-32.0.1.dev54.dist-info/entry_points.txt -@@ -10,6 +10,7 @@ - [ironic.console.container] - fake = ironic.console.container.fake:FakeConsoleContainer - systemd = ironic.console.container.systemd:SystemdConsoleContainer -+kubernetes = ironic.console.container.kubernetes:KubernetesConsoleContainer - - [ironic.database.migration_backend] - sqlalchemy = ironic.db.sqlalchemy.migration +-- +2.50.1 (Apple Git-155) diff --git a/containers/ironic/patches/0008-fix-port-endpoints-did-not-return-vendor-and-categor.patch b/containers/ironic/patches/0008-fix-port-endpoints-did-not-return-vendor-and-categor.patch deleted file mode 100644 index e6462f066..000000000 --- a/containers/ironic/patches/0008-fix-port-endpoints-did-not-return-vendor-and-categor.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3c5765088cb7469892214692b26175bc1668f4b6 Mon Sep 17 00:00:00 2001 -From: Doug Goldstein -Date: Tue, 13 Jan 2026 13:44:42 -0600 -Subject: [PATCH 8/8] fix: port endpoints did not return vendor and category - and fix docs - -The port API endpoints were not returning the vendor and category fields -when they should have been. A number of places the api-ref was incorrect -and missed adding information about the vendor and category fields but -other fields were omitted as well. - -Change-Id: Iaa19c384556b4c7453141c14ea76700c6ecae05d -Signed-off-by: Doug Goldstein ---- - ironic/api/controllers/v1/port.py | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/ironic/api/controllers/v1/port.py b/ironic/api/controllers/v1/port.py -index 1480e836b..5b1e8cc44 100644 ---- a/ironic/api/controllers/v1/port.py -+++ b/ironic/api/controllers/v1/port.py -@@ -166,6 +166,8 @@ def convert_with_links(rpc_port, fields=None, sanitize=True): - 'node_uuid', - 'name', - 'description', -+ 'vendor', -+ 'category', - ) - ) - if rpc_port.portgroup_id: --- -2.50.1 (Apple Git-155) diff --git a/containers/ironic/patches/series b/containers/ironic/patches/series index 93f105373..193d6834d 100644 --- a/containers/ironic/patches/series +++ b/containers/ironic/patches/series @@ -3,10 +3,8 @@ #ironic 0001-pass-along-physical_network-to-neutron-from-the-bare.patch 0002-Add-SKU-field-to-Redfish-inspection.patch -0003-fix-redfish-inspect-system-product-name.patch -0004-hack-for-scheduling-purposes-ignore-ports-with-categ.patch -0005-feat-skip-invalid-mac-addr-interfaces-in-redfish-ins.patch -0006-Add-Redfish-LLDP-data-collection-support-to-the-Redf.patch -0007-Add-LLDP-collect-for-DRAC-Redfish-inspection.patch -0008-fix-port-endpoints-did-not-return-vendor-and-categor.patch -0009-kubernetes-console-provider.patch +0003-hack-for-scheduling-purposes-ignore-ports-with-categ.patch +0004-feat-skip-invalid-mac-addr-interfaces-in-redfish-ins.patch +0005-Add-Redfish-LLDP-data-collection-support-to-the-Redf.patch +0006-Add-LLDP-collect-for-DRAC-Redfish-inspection.patch +0007-Add-a-kubernetes-provider-for-console-container.patch diff --git a/python/ironic-understack/pyproject.toml b/python/ironic-understack/pyproject.toml index 74bda2a10..102357419 100644 --- a/python/ironic-understack/pyproject.toml +++ b/python/ironic-understack/pyproject.toml @@ -16,6 +16,10 @@ dependencies = [ "understack-flavor-matcher", ] +# REMOVE ME: delete this once we move away from patching a venv or we upgrade to a newer ironic base version +[project.entry-points."ironic.console.container"] +kubernetes = "ironic.console.container.kubernetes:KubernetesConsoleContainer" + [project.entry-points."ironic.inspection.hooks"] resource-class = "ironic_understack.resource_class:ResourceClassHook" update-baremetal-port = "ironic_understack.inspect_hook_update_baremetal_ports:InspectHookUpdateBaremetalPorts"