diff --git a/baremetal-operator-image/Dockerfile b/baremetal-operator-image/Dockerfile index 5d905eb..8647243 100644 --- a/baremetal-operator-image/Dockerfile +++ b/baremetal-operator-image/Dockerfile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -#!BuildTag: %%IMG_PREFIX%%baremetal-operator:%%baremetal-operator_version%%.1 -#!BuildTag: %%IMG_PREFIX%%baremetal-operator:%%baremetal-operator_version%%.1-%RELEASE% +#!BuildTag: %%IMG_PREFIX%%baremetal-operator:%%baremetal-operator_version%%.0 +#!BuildTag: %%IMG_PREFIX%%baremetal-operator:%%baremetal-operator_version%%.0-%RELEASE% ARG SLE_VERSION FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro diff --git a/baremetal-operator/0001-Enable-exhaustive-linter.patch b/baremetal-operator/0001-Enable-exhaustive-linter.patch deleted file mode 100644 index fc24436..0000000 --- a/baremetal-operator/0001-Enable-exhaustive-linter.patch +++ /dev/null @@ -1,163 +0,0 @@ -From f8c1ba1696fd8555e8e94246ec5afa38536fa8bd Mon Sep 17 00:00:00 2001 -From: erjavaskivuori -Date: Thu, 5 Jun 2025 09:49:47 +0000 -Subject: [PATCH 1/5] Enable exhaustive linter - -Enable exhaustive linter to check exhaustiveness of switch statements of enum-like -constants. - -Signed-off-by: erjavaskivuori -(cherry picked from commit a5a81b8717c9e6642ae626ea97933e3615fe11c0) ---- - .golangci.yaml | 4 ++- - .../metal3.io/v1alpha1/baremetalhost_types.go | 1 + - .../metal3.io/baremetalhost_controller.go | 2 ++ - .../metal3.io/host_state_machine.go | 4 +++ - pkg/provisioner/ironic/ironic.go | 26 +++++++++---------- - 5 files changed, 22 insertions(+), 15 deletions(-) - -diff --git a/.golangci.yaml b/.golangci.yaml -index 58e54b31..c758b93c 100644 ---- a/.golangci.yaml -+++ b/.golangci.yaml -@@ -21,7 +21,7 @@ linters: - - errchkjson - #- errname - #- errorlint -- #- exhaustive -+ - exhaustive - - exptostd - - fatcontext - #- forbidigo -@@ -78,6 +78,8 @@ linters: - # Run with --fast=false for more extensive checks - fast: true - linters-settings: -+ exhaustive: -+ default-signifies-exhaustive: true - gosec: - severity: medium - confidence: medium -diff --git a/apis/metal3.io/v1alpha1/baremetalhost_types.go b/apis/metal3.io/v1alpha1/baremetalhost_types.go -index ba1b4333..426a7a89 100644 ---- a/apis/metal3.io/v1alpha1/baremetalhost_types.go -+++ b/apis/metal3.io/v1alpha1/baremetalhost_types.go -@@ -1113,6 +1113,7 @@ func (host *BareMetalHost) OperationMetricForState(operation ProvisioningState) - metric = &history.Provision - case StateDeprovisioning: - metric = &history.Deprovision -+ default: - } - return - } -diff --git a/internal/controller/metal3.io/baremetalhost_controller.go b/internal/controller/metal3.io/baremetalhost_controller.go -index 33310bf7..1998627e 100644 ---- a/internal/controller/metal3.io/baremetalhost_controller.go -+++ b/internal/controller/metal3.io/baremetalhost_controller.go -@@ -586,6 +586,7 @@ func getCurrentImage(host *metal3api.BareMetalHost) *metal3api.Image { - if host.Spec.Image != nil && host.Spec.Image.URL != "" { - return host.Spec.Image.DeepCopy() - } -+ default: - } - return nil - } -@@ -816,6 +817,7 @@ func (r *BareMetalHostReconciler) registerHost(prov provisioner.Provisioner, inf - if info.host.Spec.AutomatedCleaningMode == metal3api.CleaningModeDisabled { - preprovImgFormats = nil - } -+ default: - } - - preprovImg, err := r.getPreprovImage(info, preprovImgFormats) -diff --git a/internal/controller/metal3.io/host_state_machine.go b/internal/controller/metal3.io/host_state_machine.go -index 8b382553..6d88591b 100644 ---- a/internal/controller/metal3.io/host_state_machine.go -+++ b/internal/controller/metal3.io/host_state_machine.go -@@ -107,6 +107,7 @@ func (hsm *hostStateMachine) updateHostStateFrom(initialState metal3api.Provisio - if actionRes := hsm.ensureCapacity(info, hsm.NextState); actionRes != nil { - return actionRes - } -+ default: - } - - info.log.Info("changing provisioning state", -@@ -137,6 +138,7 @@ func (hsm *hostStateMachine) updateHostStateFrom(initialState metal3api.Provisio - info.log.Info("saving boot mode", - "new mode", hsm.Host.Status.Provisioning.BootMode) - } -+ default: - } - } - -@@ -163,6 +165,7 @@ func (hsm *hostStateMachine) checkDelayedHost(info *reconcileInfo) actionResult - if actionRes := hsm.ensureCapacity(info, info.host.Status.Provisioning.State); actionRes != nil { - return actionRes - } -+ default: - } - - return nil -@@ -299,6 +302,7 @@ func (hsm *hostStateMachine) checkDetachedHost(info *reconcileInfo) (result acti - switch info.host.Status.Provisioning.State { - case metal3api.StateProvisioned, metal3api.StateExternallyProvisioned, metal3api.StateReady, metal3api.StateAvailable: - return hsm.Reconciler.detachHost(hsm.Provisioner, info) -+ default: - } - } - if info.host.Status.ErrorType == metal3api.DetachError { -diff --git a/pkg/provisioner/ironic/ironic.go b/pkg/provisioner/ironic/ironic.go -index 9a4b4589..4c4923ad 100644 ---- a/pkg/provisioner/ironic/ironic.go -+++ b/pkg/provisioner/ironic/ironic.go -@@ -335,21 +335,17 @@ func (p *ironicProvisioner) configureImages(data provisioner.ManagementAccessDat - return result, err - } - -+ if data.State == metal3api.StateProvisioning && data.CurrentImage.IsLiveISO() { -+ // Live ISO doesn't need pre-provisioning image -+ return result, nil -+ } -+ -+ if data.State == metal3api.StateDeprovisioning && data.AutomatedCleaningMode == metal3api.CleaningModeDisabled { -+ // No need for pre-provisioning image if cleaning disabled -+ return result, nil -+ } -+ - switch data.State { -- case metal3api.StateProvisioning, -- metal3api.StateDeprovisioning: -- if data.State == metal3api.StateProvisioning { -- if data.CurrentImage.IsLiveISO() { -- // Live ISO doesn't need pre-provisioning image -- return result, nil -- } -- } else { -- if data.AutomatedCleaningMode == metal3api.CleaningModeDisabled { -- // No need for pre-provisioning image if cleaning disabled -- return result, nil -- } -- } -- fallthrough - case metal3api.StateInspecting, - metal3api.StatePreparing: - if deployImageInfo == nil { -@@ -360,6 +356,7 @@ func (p *ironicProvisioner) configureImages(data provisioner.ManagementAccessDat - } - return result, err - } -+ default: - } - - return result, nil -@@ -1724,6 +1721,7 @@ func (p *ironicProvisioner) loadBusyHosts() (hosts map[string]struct{}, err erro - if !strings.Contains(node.BootInterface, "virtual-media") { - hosts[node.Name] = struct{}{} - } -+ default: - } - } - --- -2.50.1 - diff --git a/baremetal-operator/0002-Stop-requiring-DEPLOY_KERNEL-RAMDISK.patch b/baremetal-operator/0002-Stop-requiring-DEPLOY_KERNEL-RAMDISK.patch deleted file mode 100644 index e93c2e0..0000000 --- a/baremetal-operator/0002-Stop-requiring-DEPLOY_KERNEL-RAMDISK.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 509ba92a8ed7303a418c5277f7544db2765c3802 Mon Sep 17 00:00:00 2001 -From: Dmitry Tantsur -Date: Wed, 2 Jul 2025 17:33:46 +0200 -Subject: [PATCH 2/5] Stop requiring DEPLOY_KERNEL/RAMDISK - -Ironic has global configuration that allows specifying them, even -depending on the architecture. Our ironic-image supports that when -IPA downloader is used (and should start supporting explicit variables -too). - -Signed-off-by: Dmitry Tantsur -(cherry picked from commit 0f1ef6cbeb8815f19d853ba5eab1e70c7d85e2ec) ---- - pkg/provisioner/ironic/factory.go | 6 ++---- - pkg/provisioner/ironic/factory_test.go | 9 ++------- - pkg/provisioner/ironic/ironic.go | 10 +++------- - 3 files changed, 7 insertions(+), 18 deletions(-) - -diff --git a/pkg/provisioner/ironic/factory.go b/pkg/provisioner/ironic/factory.go -index 19571eb0..15f636b3 100644 ---- a/pkg/provisioner/ironic/factory.go -+++ b/pkg/provisioner/ironic/factory.go -@@ -114,10 +114,8 @@ func loadConfigFromEnv(havePreprovImgBuilder bool) (ironicConfig, error) { - c.deployRamdiskURL = os.Getenv("DEPLOY_RAMDISK_URL") - c.deployISOURL = os.Getenv("DEPLOY_ISO_URL") - if !havePreprovImgBuilder { -- if c.deployISOURL == "" && -- (c.deployKernelURL == "" || c.deployRamdiskURL == "") { -- return c, errors.New("either DEPLOY_KERNEL_URL and DEPLOY_RAMDISK_URL or DEPLOY_ISO_URL must be set") -- } -+ // NOTE(dtantsur): with a PreprovisioningImage controller, it makes sense to set only the kernel. -+ // Without it, either both or neither must be set. - if (c.deployKernelURL == "" && c.deployRamdiskURL != "") || - (c.deployKernelURL != "" && c.deployRamdiskURL == "") { - return c, errors.New("DEPLOY_KERNEL_URL and DEPLOY_RAMDISK_URL can only be set together") -diff --git a/pkg/provisioner/ironic/factory_test.go b/pkg/provisioner/ironic/factory_test.go -index db47d8b2..0d32eccb 100644 ---- a/pkg/provisioner/ironic/factory_test.go -+++ b/pkg/provisioner/ironic/factory_test.go -@@ -98,24 +98,19 @@ func TestLoadConfigFromEnv(t *testing.T) { - ramdiskURL: "http://ramdisk", - }, - }, -- { -- name: "no deploy info", -- env: EnvFixture{}, -- expectedError: "either DEPLOY_KERNEL_URL and DEPLOY_RAMDISK_URL or DEPLOY_ISO_URL must be set", -- }, - { - name: "only kernel", - env: EnvFixture{ - kernelURL: "http://kernel", - }, -- expectedError: "either DEPLOY_KERNEL_URL and DEPLOY_RAMDISK_URL or DEPLOY_ISO_URL must be set", -+ expectedError: "DEPLOY_KERNEL_URL and DEPLOY_RAMDISK_URL can only be set together", - }, - { - name: "only ramdisk", - env: EnvFixture{ - ramdiskURL: "http://ramdisk", - }, -- expectedError: "either DEPLOY_KERNEL_URL and DEPLOY_RAMDISK_URL or DEPLOY_ISO_URL must be set", -+ expectedError: "DEPLOY_KERNEL_URL and DEPLOY_RAMDISK_URL can only be set together", - expectedImgBuildError: "DEPLOY_RAMDISK_URL requires DEPLOY_KERNEL_URL to be set also", - }, - { -diff --git a/pkg/provisioner/ironic/ironic.go b/pkg/provisioner/ironic/ironic.go -index 4c4923ad..48db865a 100644 ---- a/pkg/provisioner/ironic/ironic.go -+++ b/pkg/provisioner/ironic/ironic.go -@@ -348,14 +348,10 @@ func (p *ironicProvisioner) configureImages(data provisioner.ManagementAccessDat - switch data.State { - case metal3api.StateInspecting, - metal3api.StatePreparing: -- if deployImageInfo == nil { -- if p.config.havePreprovImgBuilder { -- result, err = transientError(provisioner.ErrNeedsPreprovisioningImage) -- } else { -- result, err = operationFailed("no preprovisioning image available") -- } -- return result, err -+ if deployImageInfo == nil && p.config.havePreprovImgBuilder { -+ result, err = transientError(provisioner.ErrNeedsPreprovisioningImage) - } -+ return result, err - default: - } - --- -2.50.1 - diff --git a/baremetal-operator/0003-Remove-DEPLOY_KERNEL_URL-from-deployment-scripts-for.patch b/baremetal-operator/0003-Remove-DEPLOY_KERNEL_URL-from-deployment-scripts-for.patch deleted file mode 100644 index 545ad00..0000000 --- a/baremetal-operator/0003-Remove-DEPLOY_KERNEL_URL-from-deployment-scripts-for.patch +++ /dev/null @@ -1,49 +0,0 @@ -From ea10df866f0fc491cac15ba5005f3b820e1ccecb Mon Sep 17 00:00:00 2001 -From: Dmitry Tantsur -Date: Wed, 2 Jul 2025 17:55:48 +0200 -Subject: [PATCH 3/5] Remove DEPLOY_KERNEL_URL from deployment scripts for main - -Signed-off-by: Dmitry Tantsur -(cherry picked from commit ddcf3d915819b6344f79fbcec3e28250b217a597) ---- - config/default/ironic.env | 2 -- - config/overlays/e2e/ironic.env | 2 -- - config/render/capm3.yaml | 2 -- - 3 files changed, 6 deletions(-) - -diff --git a/config/default/ironic.env b/config/default/ironic.env -index e72cb3c3..3fe36d25 100644 ---- a/config/default/ironic.env -+++ b/config/default/ironic.env -@@ -1,7 +1,5 @@ - HTTP_PORT=6180 - PROVISIONING_INTERFACE=eth2 - DHCP_RANGE=172.22.0.10,172.22.0.100 --DEPLOY_KERNEL_URL=http://172.22.0.2:6180/images/ironic-python-agent.kernel --DEPLOY_RAMDISK_URL=http://172.22.0.2:6180/images/ironic-python-agent.initramfs - IRONIC_ENDPOINT=http://172.22.0.2:6385/v1/ - CACHEURL=http://172.22.0.1/images -diff --git a/config/overlays/e2e/ironic.env b/config/overlays/e2e/ironic.env -index 44147ae0..6f200720 100644 ---- a/config/overlays/e2e/ironic.env -+++ b/config/overlays/e2e/ironic.env -@@ -1,3 +1 @@ --DEPLOY_KERNEL_URL=http://192.168.222.1:6180/images/ironic-python-agent.kernel --DEPLOY_RAMDISK_URL=http://192.168.222.1:6180/images/ironic-python-agent.initramfs - IRONIC_ENDPOINT=https://192.168.222.1:6385/v1/ -diff --git a/config/render/capm3.yaml b/config/render/capm3.yaml -index 42283193..7568288f 100644 ---- a/config/render/capm3.yaml -+++ b/config/render/capm3.yaml -@@ -2510,8 +2510,6 @@ subjects: - apiVersion: v1 - data: - CACHEURL: http://172.22.0.1/images -- DEPLOY_KERNEL_URL: http://172.22.0.2:6180/images/ironic-python-agent.kernel -- DEPLOY_RAMDISK_URL: http://172.22.0.2:6180/images/ironic-python-agent.initramfs - DHCP_RANGE: 172.22.0.10,172.22.0.100 - HTTP_PORT: "6180" - IRONIC_ENDPOINT: http://172.22.0.2:6385/v1/ --- -2.50.1 - diff --git a/baremetal-operator/0004-Refactor-setting-various-Ironic-properties.patch b/baremetal-operator/0004-Refactor-setting-various-Ironic-properties.patch deleted file mode 100644 index abedf04..0000000 --- a/baremetal-operator/0004-Refactor-setting-various-Ironic-properties.patch +++ /dev/null @@ -1,422 +0,0 @@ -From b2e8a1a42c95a3338c9c83a4781ba4744da5ff6a Mon Sep 17 00:00:00 2001 -From: Dmitry Tantsur -Date: Tue, 24 Jun 2025 18:53:42 +0200 -Subject: [PATCH 4/5] Refactor setting various Ironic properties - -Currently, Ironic instance_info and properties fields are populated at -random either in most states or before deployment. While potentially -convenient, it makes it very hard to reason about the code. - -Now, the logic is split into two parts: -1. configureNode (renamed from configureImages) writes fields that are - considered properties of the node itself: CPU architecture, deploy - images, capabilities, etc. -2. getInstanceUpdateOpts (merge of getImageUpdateOptsForNode and - getUpdateOptsForNode) writes fields that are required for deployment - and thus are properties of instance. This includes images, checksums, - runtime capabilities. As an exception, root device hints fall under - this category and thus are now set in instance_info, not properties. - -Signed-off-by: Dmitry Tantsur -(cherry picked from commit 0c70cba38c926c474f4fa129a7e99ef9827d6ce9) ---- - .../metal3.io/baremetalhost_controller.go | 2 +- - pkg/provisioner/ironic/ironic.go | 49 +++++------- - pkg/provisioner/ironic/provision_test.go | 27 +++---- - pkg/provisioner/ironic/register.go | 3 +- - pkg/provisioner/ironic/register_test.go | 78 +------------------ - pkg/provisioner/provisioner.go | 2 +- - 6 files changed, 40 insertions(+), 121 deletions(-) - -diff --git a/internal/controller/metal3.io/baremetalhost_controller.go b/internal/controller/metal3.io/baremetalhost_controller.go -index 1998627e..0d0c9562 100644 ---- a/internal/controller/metal3.io/baremetalhost_controller.go -+++ b/internal/controller/metal3.io/baremetalhost_controller.go -@@ -848,6 +848,7 @@ func (r *BareMetalHostReconciler) registerHost(prov provisioner.Provisioner, inf - PreprovisioningNetworkData: preprovisioningNetworkData, - HasCustomDeploy: hasCustomDeploy(info.host), - DisablePowerOff: info.host.Spec.DisablePowerOff, -+ CPUArchitecture: getHostArchitecture(info.host), - }, - credsChanged, - info.host.Status.ErrorType == metal3api.RegistrationError) -@@ -1271,7 +1272,6 @@ func (r *BareMetalHostReconciler) actionProvisioning(prov provisioner.Provisione - BootMode: info.host.Status.Provisioning.BootMode, - HardwareProfile: hwProf, - RootDeviceHints: info.host.Status.Provisioning.RootDeviceHints.DeepCopy(), -- CPUArchitecture: getHostArchitecture(info.host), - }, forceReboot) - if err != nil { - return actionError{errors.Wrap(err, "failed to provision")} -diff --git a/pkg/provisioner/ironic/ironic.go b/pkg/provisioner/ironic/ironic.go -index 48db865a..b8e6d72b 100644 ---- a/pkg/provisioner/ironic/ironic.go -+++ b/pkg/provisioner/ironic/ironic.go -@@ -311,20 +311,24 @@ func (p *ironicProvisioner) createPXEEnabledNodePort(uuid, macAddress string) er - return nil - } - --func (p *ironicProvisioner) configureImages(data provisioner.ManagementAccessData, ironicNode *nodes.Node, bmcAccess bmc.AccessDetails) (result provisioner.Result, err error) { -+func (p *ironicProvisioner) configureNode(data provisioner.ManagementAccessData, ironicNode *nodes.Node, bmcAccess bmc.AccessDetails) (result provisioner.Result, err error) { - updater := clients.UpdateOptsBuilder(p.log) - - deployImageInfo := setDeployImage(p.config, bmcAccess, data.PreprovisioningImage) - updater.SetDriverInfoOpts(deployImageInfo, ironicNode) - -- // NOTE(dtantsur): It is risky to update image information for active nodes since it may affect the ability to clean up. -- if (data.CurrentImage != nil || data.HasCustomDeploy) && ironicNode.ProvisionState != string(nodes.Active) { -- p.getImageUpdateOptsForNode(ironicNode, data.CurrentImage, data.BootMode, data.HasCustomDeploy, updater) -- } - updater.SetTopLevelOpt("automated_clean", - data.AutomatedCleaningMode != metal3api.CleaningModeDisabled, - ironicNode.AutomatedClean) - -+ opts := clients.UpdateOptsData{ -+ "capabilities": buildCapabilitiesValue(ironicNode, data.BootMode), -+ } -+ if data.CPUArchitecture != "" { -+ opts["cpu_arch"] = data.CPUArchitecture -+ } -+ updater.SetPropertiesOpts(opts, ironicNode) -+ - _, success, result, err := p.tryUpdateNode(ironicNode, updater) - if !success { - return result, err -@@ -656,40 +660,29 @@ func (p *ironicProvisioner) setCustomDeployUpdateOptsForNode(ironicNode *nodes.N - SetTopLevelOpt("deploy_interface", "custom-agent", ironicNode.DeployInterface) - } - --func (p *ironicProvisioner) getImageUpdateOptsForNode(ironicNode *nodes.Node, imageData *metal3api.Image, bootMode metal3api.BootMode, hasCustomDeploy bool, updater *clients.NodeUpdater) { -+func (p *ironicProvisioner) getInstanceUpdateOpts(ironicNode *nodes.Node, data provisioner.ProvisionData) *clients.NodeUpdater { -+ updater := clients.UpdateOptsBuilder(p.log) -+ -+ hasCustomDeploy := data.CustomDeploy != nil && data.CustomDeploy.Method != "" -+ - // instance_uuid - updater.SetTopLevelOpt("instance_uuid", string(p.objectMeta.UID), ironicNode.InstanceUUID) - - updater.SetInstanceInfoOpts(clients.UpdateOptsData{ -- "capabilities": buildInstanceInfoCapabilities(bootMode), -+ "capabilities": buildInstanceInfoCapabilities(data.BootMode), -+ "root_device": devicehints.MakeHintMap(data.RootDeviceHints), - }, ironicNode) - - if hasCustomDeploy { - // Custom deploy process -- p.setCustomDeployUpdateOptsForNode(ironicNode, imageData, updater) -- } else if imageData.IsLiveISO() { -+ p.setCustomDeployUpdateOptsForNode(ironicNode, &data.Image, updater) -+ } else if data.Image.IsLiveISO() { - // Set live-iso format options -- p.setLiveIsoUpdateOptsForNode(ironicNode, imageData, updater) -+ p.setLiveIsoUpdateOptsForNode(ironicNode, &data.Image, updater) - } else { - // Set deploy_interface direct options when not booting a live-iso -- p.setDirectDeployUpdateOptsForNode(ironicNode, imageData, updater) -+ p.setDirectDeployUpdateOptsForNode(ironicNode, &data.Image, updater) - } --} -- --func (p *ironicProvisioner) getUpdateOptsForNode(ironicNode *nodes.Node, data provisioner.ProvisionData) *clients.NodeUpdater { -- updater := clients.UpdateOptsBuilder(p.log) -- -- hasCustomDeploy := data.CustomDeploy != nil && data.CustomDeploy.Method != "" -- p.getImageUpdateOptsForNode(ironicNode, &data.Image, data.BootMode, hasCustomDeploy, updater) -- -- opts := clients.UpdateOptsData{ -- "root_device": devicehints.MakeHintMap(data.RootDeviceHints), -- "capabilities": buildCapabilitiesValue(ironicNode, data.BootMode), -- } -- if data.CPUArchitecture != "" { -- opts["cpu_arch"] = data.CPUArchitecture -- } -- updater.SetPropertiesOpts(opts, ironicNode) - - return updater - } -@@ -792,7 +785,7 @@ func (p *ironicProvisioner) setUpForProvisioning(ironicNode *nodes.Node, data pr - p.log.Info("starting provisioning", "node properties", ironicNode.Properties) - - ironicNode, success, result, err := p.tryUpdateNode(ironicNode, -- p.getUpdateOptsForNode(ironicNode, data)) -+ p.getInstanceUpdateOpts(ironicNode, data)) - if !success { - return result, err - } -diff --git a/pkg/provisioner/ironic/provision_test.go b/pkg/provisioner/ironic/provision_test.go -index 72ee57b7..40c714e9 100644 ---- a/pkg/provisioner/ironic/provision_test.go -+++ b/pkg/provisioner/ironic/provision_test.go -@@ -713,7 +713,7 @@ func TestGetUpdateOptsForNodeWithRootHints(t *testing.T) { - BootMode: metal3api.DefaultBootMode, - RootDeviceHints: host.Status.Provisioning.RootDeviceHints, - } -- patches := prov.getUpdateOptsForNode(ironicNode, provData).Updates -+ patches := prov.getInstanceUpdateOpts(ironicNode, provData).Updates - - t.Logf("patches: %v", patches) - -@@ -723,7 +723,7 @@ func TestGetUpdateOptsForNodeWithRootHints(t *testing.T) { - Value interface{} // the value being passed to ironic (or value associated with the key) - }{ - { -- Path: "/properties/root_device", -+ Path: "/instance_info/root_device", - Value: "userdefined_devicename", - Map: map[string]string{ - "name": "s== userd_devicename", -@@ -807,7 +807,7 @@ func TestGetUpdateOptsForNodeVirtual(t *testing.T) { - BootMode: metal3api.DefaultBootMode, - HardwareProfile: hwProf, - } -- patches := prov.getUpdateOptsForNode(ironicNode, provData).Updates -+ patches := prov.getInstanceUpdateOpts(ironicNode, provData).Updates - - t.Logf("patches: %v", patches) - -@@ -903,9 +903,8 @@ func TestGetUpdateOptsForNodeDell(t *testing.T) { - Image: *host.Spec.Image, - BootMode: metal3api.DefaultBootMode, - HardwareProfile: hwProf, -- CPUArchitecture: "x86_64", - } -- patches := prov.getUpdateOptsForNode(ironicNode, provData).Updates -+ patches := prov.getInstanceUpdateOpts(ironicNode, provData).Updates - - t.Logf("patches: %v", patches) - -@@ -930,10 +929,6 @@ func TestGetUpdateOptsForNodeDell(t *testing.T) { - Path: "/instance_uuid", - Value: "27720611-e5d1-45d3-ba3a-222dcfaa4ca2", - }, -- { -- Path: "/properties/cpu_arch", -- Value: "x86_64", -- }, - } - - for _, e := range expected { -@@ -971,7 +966,7 @@ func TestGetUpdateOptsForNodeLiveIso(t *testing.T) { - Image: *host.Spec.Image, - BootMode: metal3api.DefaultBootMode, - } -- patches := prov.getUpdateOptsForNode(ironicNode, provData).Updates -+ patches := prov.getInstanceUpdateOpts(ironicNode, provData).Updates - - t.Logf("patches: %v", patches) - -@@ -1038,7 +1033,7 @@ func TestGetUpdateOptsForNodeImageToLiveIso(t *testing.T) { - Image: *host.Spec.Image, - BootMode: metal3api.DefaultBootMode, - } -- patches := prov.getUpdateOptsForNode(ironicNode, provData).Updates -+ patches := prov.getInstanceUpdateOpts(ironicNode, provData).Updates - - t.Logf("patches: %v", patches) - -@@ -1116,7 +1111,7 @@ func TestGetUpdateOptsForNodeLiveIsoToImage(t *testing.T) { - Image: *host.Spec.Image, - BootMode: metal3api.DefaultBootMode, - } -- patches := prov.getUpdateOptsForNode(ironicNode, provData).Updates -+ patches := prov.getInstanceUpdateOpts(ironicNode, provData).Updates - - t.Logf("patches: %v", patches) - -@@ -1188,7 +1183,7 @@ func TestGetUpdateOptsForNodeCustomDeploy(t *testing.T) { - BootMode: metal3api.DefaultBootMode, - CustomDeploy: host.Spec.CustomDeploy, - } -- patches := prov.getUpdateOptsForNode(ironicNode, provData).Updates -+ patches := prov.getInstanceUpdateOpts(ironicNode, provData).Updates - - t.Logf("patches: %v", patches) - -@@ -1245,7 +1240,7 @@ func TestGetUpdateOptsForNodeCustomDeployWithImage(t *testing.T) { - BootMode: metal3api.DefaultBootMode, - CustomDeploy: host.Spec.CustomDeploy, - } -- patches := prov.getUpdateOptsForNode(ironicNode, provData).Updates -+ patches := prov.getInstanceUpdateOpts(ironicNode, provData).Updates - - t.Logf("patches: %v", patches) - -@@ -1312,7 +1307,7 @@ func TestGetUpdateOptsForNodeImageToCustomDeploy(t *testing.T) { - BootMode: metal3api.DefaultBootMode, - CustomDeploy: host.Spec.CustomDeploy, - } -- patches := prov.getUpdateOptsForNode(ironicNode, provData).Updates -+ patches := prov.getInstanceUpdateOpts(ironicNode, provData).Updates - - t.Logf("patches: %v", patches) - -@@ -1405,7 +1400,7 @@ func TestGetUpdateOptsForNodeSecureBoot(t *testing.T) { - BootMode: metal3api.UEFISecureBoot, - HardwareProfile: hwProf, - } -- patches := prov.getUpdateOptsForNode(ironicNode, provData).Updates -+ patches := prov.getInstanceUpdateOpts(ironicNode, provData).Updates - - t.Logf("patches: %v", patches) - -diff --git a/pkg/provisioner/ironic/register.go b/pkg/provisioner/ironic/register.go -index 390e463f..9a600189 100644 ---- a/pkg/provisioner/ironic/register.go -+++ b/pkg/provisioner/ironic/register.go -@@ -220,7 +220,7 @@ func (p *ironicProvisioner) Register(data provisioner.ManagementAccessData, cred - fallthrough - - default: -- result, err = p.configureImages(data, ironicNode, bmcAccess) -+ result, err = p.configureNode(data, ironicNode, bmcAccess) - return result, provID, err - } - } -@@ -246,6 +246,7 @@ func (p *ironicProvisioner) enrollNode(data provisioner.ManagementAccessData, bm - DisablePowerOff: &data.DisablePowerOff, - Properties: map[string]interface{}{ - "capabilities": buildCapabilitiesValue(nil, data.BootMode), -+ "cpu_arch": data.CPUArchitecture, - }, - } - -diff --git a/pkg/provisioner/ironic/register_test.go b/pkg/provisioner/ironic/register_test.go -index e6c302b5..8e524dad 100644 ---- a/pkg/provisioner/ironic/register_test.go -+++ b/pkg/provisioner/ironic/register_test.go -@@ -72,7 +72,7 @@ func TestRegisterMACOptional(t *testing.T) { - assert.Equal(t, "", result.ErrorMessage) - } - --func TestRegisterCreateNodeNoImage(t *testing.T) { -+func TestRegisterCreateNode(t *testing.T) { - // Create a host without a bootMACAddress and with a BMC that - // does not require one. - host := makeHost() -@@ -146,79 +146,6 @@ func TestRegisterCreateNodeOldInspection(t *testing.T) { - assert.Equal(t, "inspector", createdNode.InspectInterface) - } - --func TestRegisterCreateWithImage(t *testing.T) { -- // Create a host with Image specified in the Spec -- host := makeHost() -- host.Status.Provisioning.ID = "" // so we don't lookup by uuid -- host.Spec.Image.URL = "theimagefoo" -- host.Spec.Image.Checksum = "thechecksumxyz" -- host.Spec.Image.ChecksumType = "auto" -- -- var createdNode *nodes.Node -- -- createCallback := func(node nodes.Node) { -- createdNode = &node -- } -- -- ironic := testserver.NewIronic(t).WithDrivers().CreateNodes(createCallback).NoNode(host.Namespace + nameSeparator + host.Name).NoNode(host.Name) -- ironic.AddDefaultResponse("/v1/nodes/node-0", "PATCH", http.StatusOK, "{}") -- ironic.Start() -- defer ironic.Stop() -- -- auth := clients.AuthConfig{Type: clients.NoAuth} -- prov, err := newProvisionerWithSettings(host, bmc.Credentials{}, nullEventPublisher, ironic.Endpoint(), auth) -- if err != nil { -- t.Fatalf("could not create provisioner: %s", err) -- } -- -- result, provID, err := prov.Register(provisioner.ManagementAccessData{CurrentImage: host.Spec.Image.DeepCopy()}, false, false) -- if err != nil { -- t.Fatalf("error from Register: %s", err) -- } -- assert.Equal(t, "", result.ErrorMessage) -- assert.Equal(t, createdNode.UUID, provID) -- assert.Equal(t, "", createdNode.DeployInterface) -- updates, _ := ironic.GetLastRequestFor("/v1/nodes/node-0", http.MethodPatch) -- assert.Contains(t, updates, "/instance_info/image_source") -- assert.Contains(t, updates, host.Spec.Image.URL) -- assert.Contains(t, updates, "/instance_info/image_checksum") -- assert.Contains(t, updates, host.Spec.Image.Checksum) --} -- --func TestRegisterCreateWithLiveIso(t *testing.T) { -- // Create a host with Image specified in the Spec -- host := makeHostLiveIso() -- host.Status.Provisioning.ID = "" // so we don't lookup by uuid -- -- var createdNode *nodes.Node -- -- createCallback := func(node nodes.Node) { -- createdNode = &node -- } -- -- ironic := testserver.NewIronic(t).WithDrivers().CreateNodes(createCallback).NoNode(host.Namespace + nameSeparator + host.Name).NoNode(host.Name) -- ironic.AddDefaultResponse("/v1/nodes/node-0", "PATCH", http.StatusOK, "{}") -- ironic.Start() -- defer ironic.Stop() -- -- auth := clients.AuthConfig{Type: clients.NoAuth} -- prov, err := newProvisionerWithSettings(host, bmc.Credentials{}, nullEventPublisher, ironic.Endpoint(), auth) -- if err != nil { -- t.Fatalf("could not create provisioner: %s", err) -- } -- -- result, provID, err := prov.Register(provisioner.ManagementAccessData{CurrentImage: host.Spec.Image.DeepCopy()}, false, false) -- if err != nil { -- t.Fatalf("error from Register: %s", err) -- } -- assert.Equal(t, "", result.ErrorMessage) -- assert.Equal(t, createdNode.UUID, provID) -- assert.Equal(t, "ramdisk", createdNode.DeployInterface) -- updates, _ := ironic.GetLastRequestFor("/v1/nodes/node-0", http.MethodPatch) -- assert.Contains(t, updates, "/instance_info/boot_iso") -- assert.Contains(t, updates, host.Spec.Image.URL) --} -- - func TestRegisterExistingNode(t *testing.T) { - // Create a host without a bootMACAddress and with a BMC that - // does not require one. -@@ -342,6 +269,7 @@ func TestRegisterExistingNodeContinue(t *testing.T) { - "test_password": "******", // ironic returns a placeholder - "test_port": "42", - }, -+ Properties: map[string]interface{}{"capabilities": ""}, - }).NodeUpdate(nodes.Node{ - UUID: "uuid", - }) -@@ -521,6 +449,7 @@ func TestRegisterExistingSteadyStateNoUpdate(t *testing.T) { - DeployInterface: imageType.DeployInterface, - InstanceInfo: imageType.InstanceInfo, - DriverInfo: imageType.DriverInfo, -+ Properties: map[string]interface{}{"capabilities": ""}, - }).NodeUpdate(nodes.Node{ - UUID: "uuid", - }) -@@ -577,6 +506,7 @@ func TestRegisterExistingNodeWaiting(t *testing.T) { - "test_password": "******", // ironic returns a placeholder - "test_port": "42", - }, -+ Properties: map[string]interface{}{"capabilities": ""}, - } - ironic := testserver.NewIronic(t).CreateNodes(createCallback).Node(node).NodeUpdate(nodes.Node{ - UUID: "uuid", -diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go -index faddd0fd..e2018e63 100644 ---- a/pkg/provisioner/provisioner.go -+++ b/pkg/provisioner/provisioner.go -@@ -82,6 +82,7 @@ type ManagementAccessData struct { - PreprovisioningNetworkData string - HasCustomDeploy bool - DisablePowerOff bool -+ CPUArchitecture string - } - - type AdoptData struct { -@@ -122,7 +123,6 @@ type ProvisionData struct { - HardwareProfile profile.Profile - RootDeviceHints *metal3api.RootDeviceHints - CustomDeploy *metal3api.CustomDeploy -- CPUArchitecture string - } - - type HTTPHeaders []map[string]string --- -2.50.1 - diff --git a/baremetal-operator/0005-Provide-inline-docs-for-node-configuration-calls.patch b/baremetal-operator/0005-Provide-inline-docs-for-node-configuration-calls.patch deleted file mode 100644 index 7a2ee61..0000000 --- a/baremetal-operator/0005-Provide-inline-docs-for-node-configuration-calls.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 5419f8d95306efed8667936156d8081c21e068ed Mon Sep 17 00:00:00 2001 -From: Dmitry Tantsur -Date: Wed, 9 Jul 2025 14:02:23 +0200 -Subject: [PATCH 5/5] Provide inline docs for node configuration calls - -Signed-off-by: Dmitry Tantsur -(cherry picked from commit 778d9342747aefc8079f1ccaa6a14f83b26f28ff) ---- - pkg/provisioner/ironic/ironic.go | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/pkg/provisioner/ironic/ironic.go b/pkg/provisioner/ironic/ironic.go -index b8e6d72b..166d929c 100644 ---- a/pkg/provisioner/ironic/ironic.go -+++ b/pkg/provisioner/ironic/ironic.go -@@ -311,6 +311,10 @@ func (p *ironicProvisioner) createPXEEnabledNodePort(uuid, macAddress string) er - return nil - } - -+// configureNode configures Node properties that are not related to any specific provisioning phase. -+// It populates the AutomatedClean field, as well as capabilities and architecture in Properties. -+// It also calls setDeployImage to populate IPA parameters in DriverInfo and -+// checks if the required PreprovisioningImage is provided and ready. - func (p *ironicProvisioner) configureNode(data provisioner.ManagementAccessData, ironicNode *nodes.Node, bmcAccess bmc.AccessDetails) (result provisioner.Result, err error) { - updater := clients.UpdateOptsBuilder(p.log) - -@@ -426,6 +430,8 @@ func setExternalURL(p *ironicProvisioner, driverInfo map[string]interface{}) map - return driverInfo - } - -+// setDeployImage configures the IPA ramdisk parameters in the Node's DriverInfo. -+// It can use either the provided PreprovisioningImage or the global configuration from ironicConfig. - func setDeployImage(config ironicConfig, accessDetails bmc.AccessDetails, hostImage *provisioner.PreprovisioningImage) clients.UpdateOptsData { - deployImageInfo := clients.UpdateOptsData{ - deployKernelKey: nil, -@@ -660,6 +666,7 @@ func (p *ironicProvisioner) setCustomDeployUpdateOptsForNode(ironicNode *nodes.N - SetTopLevelOpt("deploy_interface", "custom-agent", ironicNode.DeployInterface) - } - -+// getInstanceUpdateOpts constructs InstanceInfo options required to provision a Node in Ironic. - func (p *ironicProvisioner) getInstanceUpdateOpts(ironicNode *nodes.Node, data provisioner.ProvisionData) *clients.NodeUpdater { - updater := clients.UpdateOptsBuilder(p.log) - --- -2.50.1 - diff --git a/baremetal-operator/_service b/baremetal-operator/_service index a15e872..e4b8c26 100644 --- a/baremetal-operator/_service +++ b/baremetal-operator/_service @@ -2,7 +2,7 @@ https://github.com/metal3-io/baremetal-operator git - v0.10.2 + v0.11.2 _auto_ @PARENT_TAG@ enable diff --git a/baremetal-operator/baremetal-operator.spec b/baremetal-operator/baremetal-operator.spec index 8cf0824..40b82f6 100644 --- a/baremetal-operator/baremetal-operator.spec +++ b/baremetal-operator/baremetal-operator.spec @@ -17,19 +17,13 @@ Name: baremetal-operator -Version: 0.10.2 +Version: 0.11.2 Release: 0 Summary: Implements a Kubernetes API for managing bare metal hosts License: Apache-2.0 URL: https://github.com/metal3-io/baremetal-operator Source: baremetal-operator-%{version}.tar Source1: vendor.tar.gz -# Patches related to multi-architecture support, upstream PRs #2506 #2559 #2537 -Patch0: 0001-Enable-exhaustive-linter.patch -Patch1: 0002-Stop-requiring-DEPLOY_KERNEL-RAMDISK.patch -Patch2: 0003-Remove-DEPLOY_KERNEL_URL-from-deployment-scripts-for.patch -Patch3: 0004-Refactor-setting-various-Ironic-properties.patch -Patch4: 0005-Provide-inline-docs-for-node-configuration-calls.patch BuildRequires: golang(API) = 1.24 ExcludeArch: s390 diff --git a/ironic-image/Dockerfile b/ironic-image/Dockerfile index 09b96a3..285f3f1 100644 --- a/ironic-image/Dockerfile +++ b/ironic-image/Dockerfile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -#!BuildTag: %%IMG_PREFIX%%ironic:29.0.4.4 -#!BuildTag: %%IMG_PREFIX%%ironic:29.0.4.4-%RELEASE% +#!BuildTag: %%IMG_PREFIX%%ironic:32.0.0.0 +#!BuildTag: %%IMG_PREFIX%%ironic:32.0.0.0-%RELEASE% ARG SLE_VERSION FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro @@ -81,7 +81,7 @@ RUN cp /bin/ironic-readiness /bin/ironic-liveness COPY ironic-config/inspector.ipxe.j2 ironic-config/httpd-ironic-api.conf.j2 \ ironic-config/ipxe_config.template ironic-config/dnsmasq.conf.j2 \ - /tmp/ + /templates/ # IRONIC # RUN cp /usr/share/ipxe/undionly.kpxe /tftpboot/undionly.kpxe @@ -105,8 +105,8 @@ RUN rm /etc/ironic/ironic.conf.d/010-ironic.conf # Custom httpd config, removes all but the bare minimum needed modules COPY ironic-config/httpd.conf.j2 /etc/httpd/conf/ COPY ironic-config/httpd-modules.conf /etc/httpd/conf.modules.d/ -COPY ironic-config/apache2-vmedia.conf.j2 /tmp/httpd-vmedia.conf.j2 -COPY ironic-config/apache2-ipxe.conf.j2 /tmp/httpd-ipxe.conf.j2 +COPY ironic-config/apache2-vmedia.conf.j2 /templates/httpd-vmedia.conf.j2 +COPY ironic-config/apache2-ipxe.conf.j2 /templates/httpd-ipxe.conf.j2 # configure non-root user and set relevant permissions RUN configure-nonroot.sh && rm -f /bin/configure-nonroot.sh diff --git a/ironic-image/ironic-config/apache2-ipxe.conf.j2 b/ironic-image/ironic-config/apache2-ipxe.conf.j2 index ae19139..cd1e27d 100644 --- a/ironic-image/ironic-config/apache2-ipxe.conf.j2 +++ b/ironic-image/ironic-config/apache2-ipxe.conf.j2 @@ -11,26 +11,17 @@ Listen [::]:{{ env.IPXE_TLS_PORT }} SSLCertificateFile {{ env.IPXE_CERT_FILE }} SSLCertificateKeyFile {{ env.IPXE_KEY_FILE }} + DocumentRoot "/shared/html" - Order Allow,Deny - Allow from all + Options Indexes FollowSymLinks + Require all granted - - Order Deny,Allow - Deny from all + + Require all denied + + + SSLRequireSSL + + - - - SSLRequireSSL - - - SSLRequireSSL - - - SSLRequireSSL - - - SSLRequireSSL - - diff --git a/ironic-image/ironic-config/apache2-vmedia.conf.j2 b/ironic-image/ironic-config/apache2-vmedia.conf.j2 index 3abb7c4..0366e95 100644 --- a/ironic-image/ironic-config/apache2-vmedia.conf.j2 +++ b/ironic-image/ironic-config/apache2-vmedia.conf.j2 @@ -24,18 +24,16 @@ Listen [::]:{{ env.VMEDIA_TLS_PORT }} SSLHonorCipherOrder on {% endif %} - - Options Indexes FollowSymLinks - AllowOverride None - Require all granted + + Require all denied - Options Indexes FollowSymLinks - AllowOverride None Require all granted + + + SSLRequireSSL + + - - SSLRequireSSL - diff --git a/ironic-image/ironic-config/dnsmasq.conf.j2 b/ironic-image/ironic-config/dnsmasq.conf.j2 index f216fed..305c776 100644 --- a/ironic-image/ironic-config/dnsmasq.conf.j2 +++ b/ironic-image/ironic-config/dnsmasq.conf.j2 @@ -11,14 +11,8 @@ port={{ env.DNS_PORT }} {%- if env.DHCP_RANGE | length %} log-dhcp dhcp-range={{ env.DHCP_RANGE }} - -# It can be used when setting DNS or GW variables. -{%- if env["GATEWAY_IP"] is undefined %} -# Disable default router(s) -dhcp-option=3 -{% else %} -dhcp-option=option{% if ":" in env["GATEWAY_IP"] %}6{% endif %}:router,{{ env["GATEWAY_IP"] }} {% endif %} + {%- if env["DNS_IP"] is undefined %} # Disable DNS over provisioning network dhcp-option=6 @@ -26,31 +20,31 @@ dhcp-option=6 dhcp-option=option{% if ":" in env["DNS_IP"] %}6{% endif %}:dns-server,{{ env["DNS_IP"] }} {% endif %} +{# Network boot options for IPv4 and IPv6 #} {%- if env.IPV == "4" or env.IPV is undefined %} # IPv4 Configuration: dhcp-match=ipxe,175 -# Client is already running iPXE; move to next stage of chainloading -{%- if env.IPXE_TLS_SETUP == "true" %} -# iPXE with (U)EFI -dhcp-boot=tag:efi,tag:ipxe,{{ env.IRONIC_HTTP_URL }}/custom-ipxe/snponly.efi -# iPXE with BIOS -dhcp-boot=tag:ipxe,{{ env.IRONIC_HTTP_URL }}/custom-ipxe/undionly.kpxe + +{# Set the router or disable it. Setting router is IPv4 specific, in v6 there #} +{# are router advertisements that do the same thing. #} +{%- if env["GATEWAY_IP"] is undefined %} +# Disable default router(s) +dhcp-option=3 {% else %} -dhcp-boot=tag:ipxe,{{ env.IRONIC_HTTP_URL }}/boot.ipxe +dhcp-option=option:router,{{ env["GATEWAY_IP"] }} {% endif %} # Note: Need to test EFI booting dhcp-match=set:efi,option:client-arch,7 dhcp-match=set:efi,option:client-arch,9 dhcp-match=set:efi,option:client-arch,11 -# Client is PXE booting over EFI without iPXE ROM; send EFI version of iPXE chainloader do the same also if iPXE ROM boots but TLS is enabled -{%- if env.IPXE_TLS_SETUP == "true" %} -dhcp-boot=tag:efi,tag:ipxe,snponly.efi +# Client is (i)PXE booting on EFI machine +dhcp-boot=tag:efi,/snponly.efi,{{ env.IRONIC_IP }} +# Client is running (i)PXE on BIOS machine +dhcp-boot=tag:!efi,/undionly.kpxe,{{ env.IRONIC_IP }} +{%- if env.IPXE_TLS_SETUP != "true" %} +dhcp-boot=tag:ipxe,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/boot.ipxe {% endif %} -dhcp-boot=tag:efi,tag:!ipxe,snponly.efi - -# Client is running PXE over BIOS; send BIOS version of iPXE chainloader -dhcp-boot=/undionly.kpxe,{{ env.IRONIC_IP }} {% endif %} {% if env.IPV == "6" %} @@ -60,22 +54,12 @@ ra-param={{ env.PROVISIONING_INTERFACE }},0,0 dhcp-vendorclass=set:pxe6,enterprise:343,PXEClient dhcp-userclass=set:ipxe6,iPXE -dhcp-option=tag:pxe6,option6:bootfile-url,{{ env.IRONIC_TFTP_URL }}/snponly.efi +# Client is (i)PXE booting on EFI machine +dhcp-option=tag:efi,option6:bootfile-url,{{ env.IRONIC_URL_HOST }}/snponly.efi +# Client is running (i)PXE on BIOS machine +dhcp-option=tag:!efi,option6:bootfile-url,{{ env.IRONIC_URL_HOST }}/undionly.kpxe +{%- if env.IPXE_TLS_SETUP != "true" %} dhcp-option=tag:ipxe6,option6:bootfile-url,{{ env.IRONIC_HTTP_URL }}/boot.ipxe - -# It can be used when setting DNS or GW variables. -{%- if env["GATEWAY_IP"] is undefined %} -# Disable default router(s) -dhcp-option=3 -{% else %} -dhcp-option=3,{{ env["GATEWAY_IP"] }} -{% endif %} -{%- if env["DNS_IP"] is undefined %} -# Disable DNS over provisioning network -dhcp-option=6 -{% else %} -dhcp-option=6,{{ env["DNS_IP"] }} -{% endif %} {% endif %} {% endif %} diff --git a/ironic-image/ironic-config/httpd-ironic-api.conf.j2 b/ironic-image/ironic-config/httpd-ironic-api.conf.j2 index ba28640..600848f 100644 --- a/ironic-image/ironic-config/httpd-ironic-api.conf.j2 +++ b/ironic-image/ironic-config/httpd-ironic-api.conf.j2 @@ -29,6 +29,20 @@ Listen [{{ env.IRONIC_IPV6 }}]:{{ env.IRONIC_LISTEN_PORT }} {% endif %} {% endif %} + DocumentRoot "/shared/html" + + + Require all denied + + + + Require all granted + + + # Exclude /images from proxying + ProxyPass "/images" ! + ProxyPassReverse "/images" ! + {% if env.IRONIC_PRIVATE_PORT == "unix" %} ProxyPass "/" "unix:/shared/ironic.sock|http://127.0.0.1/" ProxyPassReverse "/" "unix:/shared/ironic.sock|http://127.0.0.1/" @@ -51,6 +65,7 @@ Listen [{{ env.IRONIC_IPV6 }}]:{{ env.IRONIC_LISTEN_PORT }} SSLCertificateKeyFile {{ env.IRONIC_KEY_FILE }} {% endif %} + {% if "IRONIC_HTPASSWD" in env and env.IRONIC_HTPASSWD | length %} AuthType Basic @@ -67,4 +82,9 @@ Listen [{{ env.IRONIC_IPV6 }}]:{{ env.IRONIC_LISTEN_PORT }} Require all granted + + + Require all granted + + diff --git a/ironic-image/ironic-config/httpd-modules.conf b/ironic-image/ironic-config/httpd-modules.conf index adde4d8..e5b5169 100644 --- a/ironic-image/ironic-config/httpd-modules.conf +++ b/ironic-image/ironic-config/httpd-modules.conf @@ -8,8 +8,6 @@ LoadModule authz_core_module /usr/lib64/apache2/mod_authz_core.so LoadModule ssl_module /usr/lib64/apache2/mod_ssl.so LoadModule env_module /usr/lib64/apache2/mod_env.so LoadModule proxy_module /usr/lib64/apache2/mod_proxy.so -LoadModule proxy_ajp_module /usr/lib64/apache2/mod_proxy_ajp.so -LoadModule proxy_balancer_module /usr/lib64/apache2/mod_proxy_balancer.so LoadModule proxy_http_module /usr/lib64/apache2/mod_proxy_http.so LoadModule slotmem_shm_module /usr/lib64/apache2/mod_slotmem_shm.so LoadModule headers_module /usr/lib64/apache2/mod_headers.so diff --git a/ironic-image/ironic-config/httpd.conf.j2 b/ironic-image/ironic-config/httpd.conf.j2 index 7c7106d..f4a35f8 100644 --- a/ironic-image/ironic-config/httpd.conf.j2 +++ b/ironic-image/ironic-config/httpd.conf.j2 @@ -22,18 +22,43 @@ Group ironic-suse DocumentRoot "/shared/html" +{%- if env.IPXE_TLS_SETUP | lower == "true" %} + Options Indexes FollowSymLinks + Require all denied +{%- else %} Options Indexes FollowSymLinks - AllowOverride None Require all granted +{%- endif %} -{%- if env.HTTPD_SERVE_NODE_IMAGES | lower == "true" %} + +{%- if env.IRONIC_VMEDIA_TLS_SETUP | lower == "true" %} + Require all denied +{%- else %} + Require all granted +{%- endif %} + + +{%- set serve_img = env.HTTPD_SERVE_NODE_IMAGES | lower %} +{%- set image_tls = env.IRONIC_TLS_SETUP | lower %} Options Indexes FollowSymLinks AllowOverride None +{%- if serve_img == "true" and image_tls != "true" %} Require all granted +{%- else %} + Require all denied +{%- endif %} + + +{%- if env.IPXE_TLS_SETUP | lower == "true" %} + Require all denied +{%- else %} + Require all granted +{%- endif %} + -{% endif %} + DirectoryIndex index.html @@ -70,7 +95,7 @@ AddDefaultCharset UTF-8 MIMEMagicFile conf/magic -PidFile /var/tmp/httpd.pid +PidFile {{ env.IRONIC_TMP_DATA_DIR }}/httpd.pid # EnableSendfile directive could speed up deployments but it could also cause # issues depending on the underlying file system, to learn more: diff --git a/ironic-image/ironic-config/ironic.conf.j2 b/ironic-image/ironic-config/ironic.conf.j2 index 686738e..d03b8d1 100644 --- a/ironic-image/ironic-config/ironic.conf.j2 +++ b/ironic-image/ironic-config/ironic.conf.j2 @@ -4,19 +4,19 @@ debug = true default_deploy_interface = direct default_inspect_interface = agent default_network_interface = noop -enabled_bios_interfaces = no-bios,redfish,idrac-redfish,irmc,ilo -enabled_boot_interfaces = ipxe,ilo-ipxe,pxe,ilo-pxe,fake,redfish-virtual-media,idrac-redfish-virtual-media,ilo-virtual-media,redfish-https +enabled_bios_interfaces = no-bios,redfish,idrac-redfish,irmc +enabled_boot_interfaces = ipxe,pxe,fake,redfish-virtual-media,idrac-redfish-virtual-media,redfish-https enabled_deploy_interfaces = direct,fake,ramdisk,custom-agent enabled_firmware_interfaces = no-firmware,fake,redfish # NOTE(dtantsur): when changing this, make sure to update the driver # dependencies in Dockerfile. -enabled_hardware_types = ipmi,idrac,irmc,fake-hardware,redfish,manual-management,ilo,ilo5 -enabled_inspect_interfaces = agent,irmc,fake,redfish,ilo -enabled_management_interfaces = ipmitool,irmc,fake,redfish,idrac-redfish,ilo,ilo5,noop +enabled_hardware_types = ipmi,idrac,irmc,fake-hardware,redfish,manual-management +enabled_inspect_interfaces = agent,irmc,fake,redfish +enabled_management_interfaces = ipmitool,irmc,fake,redfish,idrac-redfish,noop enabled_network_interfaces = noop -enabled_power_interfaces = ipmitool,irmc,fake,redfish,idrac-redfish,ilo -enabled_raid_interfaces = no-raid,irmc,agent,fake,redfish,idrac-redfish,ilo5 -enabled_vendor_interfaces = no-vendor,ipmitool,idrac-redfish,redfish,ilo,fake +enabled_power_interfaces = ipmitool,irmc,fake,redfish,idrac-redfish +enabled_raid_interfaces = no-raid,irmc,agent,fake,redfish,idrac-redfish +enabled_vendor_interfaces = no-vendor,ipmitool,idrac-redfish,redfish,fake {% if env.IRONIC_EXPOSE_JSON_RPC | lower == "true" %} rpc_transport = json-rpc {% else %} @@ -33,7 +33,6 @@ my_ipv6 = {{ env.IRONIC_IPV6 }} {% endif %} host = {{ env.IRONIC_CONDUCTOR_HOST }} -tempdir = {{ env.IRONIC_TMP_DATA_DIR }} # If a path to a certificate is defined, use that first for webserver {% if env.WEBSERVER_CACERT_FILE %} @@ -48,6 +47,10 @@ isolinux_bin = /usr/share/syslinux/isolinux.bin # the ESP provided in [conductor]bootloader. grub_config_path = EFI/BOOT/grub.cfg +# NOTE(hroyrh): updating the default temp directory to fix device cross links +# errors when hard linking +tempdir = /shared/tmp + [agent] deploy_logs_collect = always deploy_logs_local_path = /shared/log/ironic/deploy @@ -86,11 +89,6 @@ network_data_schema = /etc/ironic/network-data-schema-empty.json automated_clean = {{ env.IRONIC_AUTOMATED_CLEAN }} # NOTE(dtantsur): keep aligned with [pxe]boot_retry_timeout below. deploy_callback_timeout = 4800 -send_sensor_data = {{ env.SEND_SENSOR_DATA }} -# NOTE(TheJulia): Do not lower this value below 120 seconds. -# Power state is checked every 60 seconds and BMC activity should -# be avoided more often than once every sixty seconds. -send_sensor_data_interval = 160 bootloader_by_arch = {{ env.BOOTLOADER_BY_ARCH }} verify_step_priority_override = management.clear_job_queue:90 # We don't use this feature, and it creates an additional load on the database @@ -112,6 +110,9 @@ deploy_ramdisk_by_arch = {{ env.DEPLOY_RAMDISK_BY_ARCH }} {% if env.DISABLE_DEEP_IMAGE_INSPECTION | lower == "true" %} disable_deep_image_inspection = True {% endif %} +# Allowed path for file:// links: ipa-downloader uses /shared/html/images, +# while the bootloader configuration above refers to /templates. +file_url_allowed_paths = /shared/html/images,/templates [database] {% if env.IRONIC_USE_MARIADB | lower == "true" %} @@ -131,6 +132,7 @@ erase_devices_priority = 0 http_root = /shared/html/ http_url = {% if env.VMEDIA_TLS_PORT %}{{ env.IRONIC_HTTPS_VMEDIA_URL }}{% else %}{{ env.IRONIC_HTTP_URL }}{% endif %} fast_track = {{ env.IRONIC_FAST_TRACK }} +iso_master_path = /shared/html/master_iso_images {% if env.IRONIC_BOOT_ISO_SOURCE %} ramdisk_image_download_source = {{ env.IRONIC_BOOT_ISO_SOURCE }} {% endif %} @@ -194,6 +196,7 @@ cipher_suite_versions = 3,17 auth_strategy = http_basic http_basic_auth_user_file = {{ env.IRONIC_RPC_HTPASSWD_FILE }} host_ip = {{ env.IRONIC_HOST_IP }} +port = {{ env.IRONIC_JSON_RPC_PORT }} {% if env.IRONIC_TLS_SETUP == "true" %} use_ssl = true cafile = {{ env.IRONIC_CACERT_FILE }} @@ -204,6 +207,26 @@ insecure = {{ env.IRONIC_INSECURE }} [nova] send_power_notifications = false +# Sections (oslo_messaging_notifications, sensor_data, metrics) required for sensor data collection using ironic-prometheus-exporter (IPE): +{% if env.SEND_SENSOR_DATA | lower == "true" %} +[oslo_messaging_notifications] +driver = prometheus_exporter +location = /shared/ironic_prometheus_exporter +transport_url = fake:// + +[sensor_data] +send_sensor_data = {{ env.SEND_SENSOR_DATA }} +# NOTE(TheJulia): Do not lower this value below 120 seconds. +# Power state is checked every 60 seconds and BMC activity should +# be avoided more often than once every sixty seconds. +interval = 160 +# Additional sensor_data options can be configured via OS_ environment variables: +# https://docs.openstack.org/ironic/latest/configuration/config.html#sensor-data + +[metrics] +backend = collector +{% endif %} + [pxe] # NOTE(dtantsur): keep this value at least 3x lower than # [conductor]deploy_callback_timeout so that at least some retries happen. @@ -221,19 +244,22 @@ enable_netboot_fallback = true # Enable the fallback path to in-band inspection ipxe_fallback_script = inspector.ipxe {% if env.IPXE_TLS_SETUP | lower == "true" %} -ipxe_config_template = /tmp/ipxe_config.template +ipxe_config_template = /templates/ipxe_config.template {% endif %} [redfish] use_swift = false kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.ENABLE_FIPS_IPA %}fips={{ env.ENABLE_FIPS_IPA|trim }}{% endif %} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes net.ifnames={{ '0' if env.PREDICTABLE_NIC_NAMES == 'false' else '1' }} - -[ilo] -kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.ENABLE_FIPS_IPA %}fips={{ env.ENABLE_FIPS_IPA|trim }}{% endif %} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes net.ifnames={{ '0' if env.PREDICTABLE_NIC_NAMES == 'false' else '1' }} -use_web_server_for_images = true +{% if env.BMC_TLS_ENABLED == "true" %} +# idrac uses the same options as the redfish driver +verify_ca = {{ env.BMC_CACERT_FILE }} +{% endif %} [irmc] kernel_append_params = nofb nomodeset vga=normal ipa-insecure={{ env.IPA_INSECURE }} {% if env.ENABLE_FIPS_IPA %}fips={{ env.ENABLE_FIPS_IPA|trim }}{% endif %} {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} systemd.journald.forward_to_console=yes net.ifnames={{ '0' if env.PREDICTABLE_NIC_NAMES == 'false' else '1' }} +{% if env.BMC_TLS_ENABLED == "true" %} +verify_ca = {{ env.BMC_CACERT_FILE }} +{% endif %} [service_catalog] endpoint_override = {{ env.IRONIC_BASE_URL }} @@ -243,3 +269,8 @@ endpoint_override = {{ env.IRONIC_BASE_URL }} cert_file = {{ env.IRONIC_CERT_FILE }} key_file = {{ env.IRONIC_KEY_FILE }} {% endif %} + +[oci] +{% if env.IRONIC_OCI_AUTH_CONFIG is defined %} +authentication_config = {{ env.IRONIC_OCI_AUTH_CONFIG }} +{% endif %} diff --git a/ironic-image/scripts/auth-common.sh b/ironic-image/scripts/auth-common.sh index b9526d4..a7c1133 100644 --- a/ironic-image/scripts/auth-common.sh +++ b/ironic-image/scripts/auth-common.sh @@ -40,6 +40,10 @@ fi IRONIC_CONFIG="${IRONIC_CONF_DIR}/ironic.conf" +if [[ -z "${IRONIC_OCI_AUTH_CONFIG:-}" ]] && [[ -f "/auth/oci.json" ]]; then + export IRONIC_OCI_AUTH_CONFIG="/auth/oci.json" +fi + configure_json_rpc_auth() { if [[ "${IRONIC_EXPOSE_JSON_RPC}" != "true" ]]; then diff --git a/ironic-image/scripts/configure-ironic.sh b/ironic-image/scripts/configure-ironic.sh index 508f4d0..41b872e 100755 --- a/ironic-image/scripts/configure-ironic.sh +++ b/ironic-image/scripts/configure-ironic.sh @@ -18,8 +18,6 @@ export IRONIC_ENABLE_VLAN_INTERFACES=${IRONIC_ENABLE_VLAN_INTERFACES:-${IRONIC_I # shellcheck disable=SC1091 . /bin/auth-common.sh -export HTTP_PORT=${HTTP_PORT:-80} - if [[ "${IRONIC_USE_MARIADB}" == true ]]; then if [[ -z "${MARIADB_PASSWORD:-}" ]]; then echo "FATAL: IRONIC_USE_MARIADB requires password, mount a secret under /auth/mariadb" @@ -130,6 +128,8 @@ echo 'Options set from Environment variables' env | grep "^OS_" || true mkdir -p /shared/html +mkdir -p /shared/tmp +mkdir -p /shared/ironic_prometheus_exporter if [[ -f /proc/sys/crypto/fips_enabled ]]; then ENABLE_FIPS_IPA=$(cat /proc/sys/crypto/fips_enabled) diff --git a/ironic-image/scripts/ironic-common.sh b/ironic-image/scripts/ironic-common.sh index 0def24c..0ddc8bc 100644 --- a/ironic-image/scripts/ironic-common.sh +++ b/ironic-image/scripts/ironic-common.sh @@ -25,6 +25,11 @@ export IRONIC_GEN_CERT_DIR="${CUSTOM_DATA_DIR}/auto_gen_certs" export IRONIC_TMP_DATA_DIR="${CUSTOM_DATA_DIR}/tmp" export PROBE_CONF_DIR="${CUSTOM_CONFIG_DIR}/probes" +export HTTP_PORT=${HTTP_PORT:-80} +# NOTE(elfosardo): the default port for json_rpc in ironic is 8089, but +# we need to use a different port to avoid conflicts with other services +export IRONIC_JSON_RPC_PORT=${IRONIC_JSON_RPC_PORT:-6189} + mkdir -p "${IRONIC_CONF_DIR}" "${PROBE_CONF_DIR}" "${HTTPD_CONF_DIR}" \ "${HTTPD_CONF_DIR_D}" "${DNSMASQ_CONF_DIR}" "${DNSMASQ_TEMP_DIR}" \ "${IRONIC_DB_DIR}" "${IRONIC_GEN_CERT_DIR}" "${DNSMASQ_DATA_DIR}" \ diff --git a/ironic-image/scripts/rundnsmasq b/ironic-image/scripts/rundnsmasq index 28174d0..4192624 100755 --- a/ironic-image/scripts/rundnsmasq +++ b/ironic-image/scripts/rundnsmasq @@ -7,7 +7,6 @@ set -eux # shellcheck disable=SC1091 . /bin/tls-common.sh -export HTTP_PORT=${HTTP_PORT:-80} DNSMASQ_EXCEPT_INTERFACE=${DNSMASQ_EXCEPT_INTERFACE:-lo} export DNS_PORT=${DNS_PORT:-0} @@ -36,7 +35,7 @@ fi # Template and write dnsmasq.conf # we template via /tmp as sed otherwise creates temp files in /etc directory # where we can't write -python3.13 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' <"/tmp/dnsmasq.conf.j2" >"${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf" +python3.13 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' <"/templates/dnsmasq.conf.j2" >"${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf" for iface in $(echo "$DNSMASQ_EXCEPT_INTERFACE" | tr ',' ' '); do sed -i -e "/^interface=.*/ a\except-interface=${iface}" "${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf" diff --git a/ironic-image/scripts/runhttpd b/ironic-image/scripts/runhttpd index c094689..d6375f0 100755 --- a/ironic-image/scripts/runhttpd +++ b/ironic-image/scripts/runhttpd @@ -5,7 +5,6 @@ . /bin/ironic-common.sh . /bin/auth-common.sh -export HTTP_PORT=${HTTP_PORT:-80} export VMEDIA_TLS_PORT=${VMEDIA_TLS_PORT:-8083} export IRONIC_REVERSE_PROXY_SETUP=${IRONIC_REVERSE_PROXY_SETUP:-false} @@ -36,7 +35,7 @@ fi export INSPECTOR_EXTRA_ARGS # Copy files to shared mount -render_j2_config /tmp/inspector.ipxe.j2 /shared/html/inspector.ipxe +render_j2_config /templates/inspector.ipxe.j2 /shared/html/inspector.ipxe # cp -r /etc/httpd/* "${HTTPD_DIR}" if [[ -f "${HTTPD_CONF_DIR}/httpd.conf" ]]; then mv "${HTTPD_CONF_DIR}/httpd.conf" "${HTTPD_CONF_DIR}/httpd.conf.example" @@ -48,7 +47,7 @@ render_j2_config "/etc/httpd/conf/httpd.conf.j2" \ if [[ "$IRONIC_TLS_SETUP" == "true" ]]; then if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "true" ]]; then - render_j2_config "/tmp/httpd-ironic-api.conf.j2" \ + render_j2_config "/templates/httpd-ironic-api.conf.j2" \ "${HTTPD_CONF_DIR_D}/ironic.conf" fi else @@ -59,7 +58,7 @@ write_htpasswd_files # Render httpd TLS configuration for /shared/html/ if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]]; then - render_j2_config "/tmp/httpd-vmedia.conf.j2" \ + render_j2_config "/templates/httpd-vmedia.conf.j2" \ "${HTTPD_CONF_DIR_D}/vmedia.conf" fi @@ -67,7 +66,7 @@ fi if [[ "$IPXE_TLS_SETUP" == "true" ]]; then mkdir -p /shared/html/custom-ipxe chmod 0777 /shared/html/custom-ipxe - render_j2_config "/tmp/httpd-ipxe.conf.j2" "${HTTPD_CONF_DIR_D}/ipxe.conf" + render_j2_config "/templates/httpd-ipxe.conf.j2" "${HTTPD_CONF_DIR_D}/ipxe.conf" cp "${IPXE_CUSTOM_FIRMWARE_DIR}/undionly.kpxe" \ "${IPXE_CUSTOM_FIRMWARE_DIR}/snponly.efi" \ "/shared/html/custom-ipxe" diff --git a/ironic-image/scripts/runironic b/ironic-image/scripts/runironic index 2d2b35e..887b6e7 100755 --- a/ironic-image/scripts/runironic +++ b/ironic-image/scripts/runironic @@ -15,4 +15,13 @@ configure_restart_on_certificate_update "${IRONIC_TLS_SETUP}" ironic "${IRONIC_C configure_ironic_auth +if [[ -d "${BMC_CACERTS_PATH}" ]]; then + # shellcheck disable=SC2034 + watchmedo shell-command \ + --patterns="*" \ + --ignore-directories \ + --command='cat "${BMC_CACERTS_PATH}"/* > "${BMC_CACERT_FILE}"' \ + "${BMC_CACERTS_PATH}" & +fi + exec /usr/bin/ironic --config-dir "${IRONIC_CONF_DIR}" diff --git a/ironic-image/scripts/runironic-exporter b/ironic-image/scripts/runironic-exporter new file mode 100755 index 0000000..3eb4b17 --- /dev/null +++ b/ironic-image/scripts/runironic-exporter @@ -0,0 +1,20 @@ +#!/usr/bin/bash + +# Set dummy provisioning IP to avoid interface detection issues (not needed to run IPE to service `/metrics`) +export PROVISIONING_IP="127.0.0.1" +# Set to true since running this script implies sensor data metrics are needed +# ironic-prometheus-exporter (IPE) needs to read from oslo_messaging_notifications.location (i.e content under /shared) where Ironic writes to +export SEND_SENSOR_DATA=true + +# shellcheck disable=SC1091 +. /bin/configure-ironic.sh +# shellcheck disable=SC1091 +. /bin/ironic-common.sh + +FLASK_RUN_HOST=${FLASK_RUN_HOST:-0.0.0.0} +FLASK_RUN_PORT=${FLASK_RUN_PORT:-9608} + +export IRONIC_CONFIG="${IRONIC_CONF_DIR}/ironic.conf" + +exec gunicorn -b "${FLASK_RUN_HOST}:${FLASK_RUN_PORT}" -w 4 \ + ironic_prometheus_exporter.app.wsgi:application diff --git a/ironic-image/scripts/tls-common.sh b/ironic-image/scripts/tls-common.sh index 4d25c70..5df4231 100644 --- a/ironic-image/scripts/tls-common.sh +++ b/ironic-image/scripts/tls-common.sh @@ -1,13 +1,14 @@ #!/bin/bash -export IRONIC_CERT_FILE=/certs/ironic/tls.crt -export IRONIC_KEY_FILE=/certs/ironic/tls.key -export IRONIC_CACERT_FILE=/certs/ca/ironic/tls.crt export IRONIC_INSECURE=${IRONIC_INSECURE:-false} export IRONIC_SSL_PROTOCOL=${IRONIC_SSL_PROTOCOL:-"-ALL +TLSv1.2 +TLSv1.3"} export IPXE_SSL_PROTOCOL=${IPXE_SSL_PROTOCOL:-"-ALL +TLSv1.2 +TLSv1.3"} export IRONIC_VMEDIA_SSL_PROTOCOL=${IRONIC_VMEDIA_SSL_PROTOCOL:-"ALL"} +# Node image storage is using the same cert and port as the API +export IRONIC_CERT_FILE=/certs/ironic/tls.crt +export IRONIC_KEY_FILE=/certs/ironic/tls.key + export IRONIC_VMEDIA_CERT_FILE=/certs/vmedia/tls.crt export IRONIC_VMEDIA_KEY_FILE=/certs/vmedia/tls.key @@ -16,15 +17,15 @@ export IPXE_KEY_FILE=/certs/ipxe/tls.key export RESTART_CONTAINER_CERTIFICATE_UPDATED=${RESTART_CONTAINER_CERTIFICATE_UPDATED:-"false"} +# By default every cert has to be signed with Ironic's +# CA otherwise node image and IPA verification would fail export MARIADB_CACERT_FILE=/certs/ca/mariadb/tls.crt +export BMC_CACERTS_PATH=/certs/ca/bmc +export BMC_CACERT_FILE=/conf/bmc-tls.pem +export IRONIC_CACERT_FILE=/certs/ca/ironic/tls.crt export IPXE_TLS_PORT="${IPXE_TLS_PORT:-8084}" -mkdir -p /certs/ironic -mkdir -p /certs/ca/ironic -mkdir -p /certs/ipxe -mkdir -p /certs/vmedia - if [[ -f "$IRONIC_CERT_FILE" ]] && [[ ! -f "$IRONIC_KEY_FILE" ]]; then echo "Missing TLS Certificate key file $IRONIC_KEY_FILE" exit 1 @@ -69,6 +70,7 @@ if [[ -f "$IRONIC_CERT_FILE" ]] || [[ -f "$IRONIC_CACERT_FILE" ]]; then export IRONIC_TLS_SETUP="true" export IRONIC_SCHEME="https" if [[ ! -f "$IRONIC_CACERT_FILE" ]]; then + mkdir -p "$(dirname "${IRONIC_CACERT_FILE}")" copy_atomic "$IRONIC_CERT_FILE" "$IRONIC_CACERT_FILE" fi else @@ -119,3 +121,9 @@ configure_restart_on_certificate_update() fi } +if [ -d "${BMC_CACERTS_PATH}" ]; then + export BMC_TLS_ENABLED="true" + cat "${BMC_CACERTS_PATH}"/* > "${BMC_CACERT_FILE}" +else + export BMC_TLS_ENABLED="false" +fi diff --git a/metal3-chart/Chart.yaml b/metal3-chart/Chart.yaml index 4e44b0a..743aebf 100644 --- a/metal3-chart/Chart.yaml +++ b/metal3-chart/Chart.yaml @@ -1,21 +1,21 @@ -#!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.19_up0.12.9 -#!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.19_up0.12.9-%RELEASE% +#!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.20_up0.13.0 +#!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.20_up0.13.0-%RELEASE% apiVersion: v2 -appVersion: 0.12.9 +appVersion: 0.13.0 dependencies: - alias: metal3-baremetal-operator name: baremetal-operator repository: file://./charts/baremetal-operator - version: 0.10.4 + version: 0.11.2 - alias: metal3-ironic name: ironic repository: file://./charts/ironic - version: 0.11.6 + version: 0.12.0 - alias: metal3-mariadb condition: global.enable_mariadb name: mariadb repository: file://./charts/mariadb - version: 0.6.1 + version: 0.6.2 - alias: metal3-media condition: global.enable_metal3_media_server name: media @@ -25,4 +25,4 @@ description: A Helm chart that installs all of the dependencies needed for Metal icon: https://github.com/cncf/artwork/raw/master/projects/metal3/icon/color/metal3-icon-color.svg name: metal3 type: application -version: "%%CHART_MAJOR%%.0.19+up0.12.9" +version: "%%CHART_MAJOR%%.0.20+up0.13.0" diff --git a/metal3-chart/charts/baremetal-operator/Chart.yaml b/metal3-chart/charts/baremetal-operator/Chart.yaml index edf9219..bf92e36 100644 --- a/metal3-chart/charts/baremetal-operator/Chart.yaml +++ b/metal3-chart/charts/baremetal-operator/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 -appVersion: 0.10.2 +appVersion: 0.11.2 description: A Helm chart for baremetal-operator, used by Metal3 name: baremetal-operator type: application -version: 0.10.4 +version: 0.11.2 diff --git a/metal3-chart/charts/baremetal-operator/crds/customresource-baremetalhosts.yaml b/metal3-chart/charts/baremetal-operator/crds/customresource-baremetalhosts.yaml index 07953c9..0dc05bd 100644 --- a/metal3-chart/charts/baremetal-operator/crds/customresource-baremetalhosts.yaml +++ b/metal3-chart/charts/baremetal-operator/crds/customresource-baremetalhosts.yaml @@ -291,6 +291,15 @@ spec: required: - url type: object + inspectionMode: + description: |- + Specifies the mode for host inspection. + "disabled" - no inspection will be performed + "agent" - normal agent-based inspection will run + enum: + - disabled + - agent + type: string metaData: description: |- MetaData holds the reference to the Secret containing host metadata @@ -578,9 +587,8 @@ spec: description: Required. The taint key to be applied to a node. type: string timeAdded: - description: |- - TimeAdded represents the time at which the taint was added. - It is only written for NoExecute taints. + description: TimeAdded represents the time at which the taint + was added. format: date-time type: string value: @@ -710,6 +718,19 @@ spec: if one is present. If both IPv4 and IPv6 addresses are present in a dual-stack environment, two nics will be output, one with each IP. type: string + lldp: + description: LLDP data for this interface + properties: + portID: + description: The switch port ID from LLDP + type: string + switchID: + description: The switch chassis ID from LLDP + type: string + switchSystemName: + description: The switch system name from LLDP + type: string + type: object mac: description: The device MAC address pattern: '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}' diff --git a/metal3-chart/charts/baremetal-operator/crds/customresource-hardwaredata.yaml b/metal3-chart/charts/baremetal-operator/crds/customresource-hardwaredata.yaml index 0693bf3..1a86077 100644 --- a/metal3-chart/charts/baremetal-operator/crds/customresource-hardwaredata.yaml +++ b/metal3-chart/charts/baremetal-operator/crds/customresource-hardwaredata.yaml @@ -99,6 +99,19 @@ spec: if one is present. If both IPv4 and IPv6 addresses are present in a dual-stack environment, two nics will be output, one with each IP. type: string + lldp: + description: LLDP data for this interface + properties: + portID: + description: The switch port ID from LLDP + type: string + switchID: + description: The switch chassis ID from LLDP + type: string + switchSystemName: + description: The switch system name from LLDP + type: string + type: object mac: description: The device MAC address pattern: '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}' diff --git a/metal3-chart/charts/baremetal-operator/values.yaml b/metal3-chart/charts/baremetal-operator/values.yaml index 870fb73..b9c089c 100644 --- a/metal3-chart/charts/baremetal-operator/values.yaml +++ b/metal3-chart/charts/baremetal-operator/values.yaml @@ -28,7 +28,7 @@ images: baremetalOperator: repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/baremetal-operator pullPolicy: IfNotPresent - tag: "0.10.2.1" + tag: "0.11.2.0" imagePullSecrets: [] nameOverride: "manger" diff --git a/metal3-chart/charts/ironic/Chart.yaml b/metal3-chart/charts/ironic/Chart.yaml index 5b8d3a8..aad87ad 100644 --- a/metal3-chart/charts/ironic/Chart.yaml +++ b/metal3-chart/charts/ironic/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 -appVersion: 29.0.4 +appVersion: 32.0.0 description: A Helm chart for Ironic, used by Metal3 name: ironic type: application -version: 0.11.6 +version: 0.12.0 diff --git a/metal3-chart/charts/ironic/templates/deployment.yaml b/metal3-chart/charts/ironic/templates/deployment.yaml index 5204253..d679d0b 100644 --- a/metal3-chart/charts/ironic/templates/deployment.yaml +++ b/metal3-chart/charts/ironic/templates/deployment.yaml @@ -160,12 +160,7 @@ spec: image: {{ .Values.images.ironic.repository }}:{{ .Values.images.ironic.tag }} imagePullPolicy: {{ .Values.images.ironic.pullPolicy }} securityContext: - {{- toYaml .Values.securityContext | nindent 10 }} - securityContext: - capabilities: - add: - - NET_ADMIN - - NET_RAW + {{- merge .Values.securityContext .Values.dnsmasqSecurityContext | toYaml | nindent 10 }} command: - /bin/rundnsmasq envFrom: diff --git a/metal3-chart/charts/ironic/values.yaml b/metal3-chart/charts/ironic/values.yaml index f5390c7..8b1b430 100644 --- a/metal3-chart/charts/ironic/values.yaml +++ b/metal3-chart/charts/ironic/values.yaml @@ -64,7 +64,7 @@ images: ironic: repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic pullPolicy: IfNotPresent - tag: 29.0.4.4 + tag: 32.0.0.0 ironicIPADownloader: repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic-ipa-downloader pullPolicy: IfNotPresent @@ -97,6 +97,12 @@ securityContext: type: RuntimeDefault runAsNonRoot: true +dnsmasqSecurityContext: + capabilities: + add: + - NET_ADMIN + - NET_RAW + service: type: LoadBalancer annotations: {} diff --git a/metal3-chart/charts/mariadb/Chart.yaml b/metal3-chart/charts/mariadb/Chart.yaml index 4cb4c8c..ce3ff86 100644 --- a/metal3-chart/charts/mariadb/Chart.yaml +++ b/metal3-chart/charts/mariadb/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v2 -appVersion: "10.11" +appVersion: "11.8" description: A Helm chart for MariaDB, used by Metal3 name: mariadb type: application -version: 0.6.1 +version: 0.6.2 diff --git a/metal3-chart/charts/mariadb/values.yaml b/metal3-chart/charts/mariadb/values.yaml index 3d6639c..0e5f0a8 100644 --- a/metal3-chart/charts/mariadb/values.yaml +++ b/metal3-chart/charts/mariadb/values.yaml @@ -14,7 +14,7 @@ service: image: repository: registry.suse.com/suse/mariadb pullPolicy: IfNotPresent - tag: 10.11 + tag: 11.8 nameOverride: "" fullnameOverride: "" diff --git a/release-manifest-image/release_manifest.yaml b/release-manifest-image/release_manifest.yaml index 38f9d8d..bf79cc7 100644 --- a/release-manifest-image/release_manifest.yaml +++ b/release-manifest-image/release_manifest.yaml @@ -171,7 +171,7 @@ spec: - prettyName: Metal3 releaseName: metal3 chart: '%%CHART_REPO%%/%%CHART_PREFIX%%metal3' - version: '%%CHART_MAJOR%%.0.19+up0.12.9' + version: '%%CHART_MAJOR%%.0.20+up0.13.0' - prettyName: RancherTurtles releaseName: rancher-turtles chart: '%%CHART_REPO%%/%%CHART_PREFIX%%rancher-turtles'