12 Commits

Author SHA256 Message Date
e5f765ec69 Let Apache use separate IPv4 and IPv6 sockets for listening to any
All checks were successful
Check Release Manifest Local Charts Versions / Check Release Manifest Local Charts Versions (pull_request) Successful in -6s
Build PR in OBS / Build PR in OBS (pull_request_target) Successful in 3m25s
Enable the use of two separate sockets for IPv4 and IPv6 when
LISTEN_ALL_INTERFACES is set to true. While desirable, on Linux Apache uses
IPv4-mapped IPv6 addresses by default, thus leveraging a single IPv6 socket
for IPv4 connections as well.

This behaviour is far from being desirable and can be disabled at compile
time via the "--disable-v4-mapped" flag, so make sure both an ANY address
Listen directive is present for both IPv4 and IPv6. When Apache is compiled
with "--enable-v4-mapped", the IPv4 socket will be simply ignored.

Please see https://httpd.apache.org/docs/2.4/bind.html for more
information.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 19:15:25 +00:00
2d83191e53 Update httpd.conf to bind to IPv4 and/or IPv6 sockets
Enable the use of individual IPv4 and IPv6 sockets when the respective
IP is detected and LISTEN_ALL_INTERFACES is not set to true. This allows
to correctly bind to both the IPv4 and IPv6 addresses found and not just
one of them.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 19:15:25 +00:00
11cd6f8ebe Let Ironic API use IPv4 and IPv6 sockets when possible
When LISTEN_ALL_INTERFACES is not set, Apache should make Ironic API
avaiable on either or both IPv4 and IPv6 sockets, depending on the
addresses requested or found on the system.

Make sure to set the "Listen" directive according to ENABLE_IPV4 and
ENABLE_IPV4, and the VirtualHost when IRONIC_URL_HOSTNAME is present.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 19:15:25 +00:00
ad68f891f5 Set host_ip to an IPv6 address when found
Prioritize IPv6 over IPv4 when available to set host_ip in ironic.conf
when LISTEN_ALL_INTERFACES is not set to true.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 19:15:25 +00:00
e155a809b8 Use my_ipv6 when IRONIC_IPV6 is defined in ironic.conf
As per the Ironic documentation:

"This field [my_ip] does accept an IPv6 address as an override for templates
and URLs, however it is recommended that [DEFAULT]my_ipv6 is used along with
DNS names for service URLs for dual-stack environments."

Fill my_ipv6 when an IPv6 address has been found for binding.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 19:15:25 +00:00
8b6d7e409c Allow binding on the provisioning network via a hostname
In a dual-stack scenario, especially when deploying in direct mode via
virtual media, it might be useful to 1) use a hostname to enable "dual IP"
URLs 2) have ironic bind to those two addresses, if found on the system.

To make this possible, this commit introduces:
- a new user environment variable named IRONIC_URL_HOSTNAME, to be used
  as immutable external only input, to derive IRONIC_URL_HOST and the
  IP addresses to bind on
- a new utility function named "get_ip_of_hostname" to help look up the
  A and AAAA records
- additional logic to look for the returned address on the system, for
  binding the processes; this new logic has lower priority than
  PROVISIONING_IP (which can then be used to enforce one specific IP
  version) and PROVISIONING_INTERFACE

Note, while IRONIC_URL_HOSTNAME and PROVISIONING_IP are considered to be
mutually exclusive, IRONIC_URL_HOSTNAME and PROVISIONING_INTERFACE are
not.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 19:15:25 +00:00
e6700bd732 Introduce IRONIC_IPV6 to bind on IPv6 sockets
The ironic scripts either use PROVISIONING_IP as an input or try to
determine an IP address to bind the sockets to. This results in
IRONIC_IP being defined once the process is complete, and it can carry
either an IPv4 or an IPv6 address.

Likely, the assumption is that on Linux, by default, IPv4-mapped IPv6
addresses can be leveraged to serve both IPv4 and IPv6 through a single
socket. However this is not a good practice and two separate sockets
should be used instead, whenever possible.

This change modifies such logic by
- introducing the variable IRONIC_IPV6 alongside the existing
- matching IRONIC_IP and attempting to populate both variables

Please note that hostname based URLs, with both A and AAAA records, are
also required for a fully working dual-stack configuration.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 19:15:25 +00:00
a1ee32b951 Revert 2742439 being now redundant
Commit 2742439 added logic to tentatively identify the interface name
in get_provisioning_interface if the PROVISIONING_IP is provided.
However the same process in then repeated in wait_for_interface_or_ip.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 19:15:25 +00:00
250635e51c Leverage get_interface_of_ip to look PROVISIONING_IP up
Use the previously introduced get_interface_of_ip, to determine if the
PROVISIONING_IP address is actually present on a network interface.

This improves the code readability and enables additional debugging
output.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 19:15:25 +00:00
f5676b293c Add two new utility functions for later refactoring
The way the ironic-image processes are bound to internet sockets is mainly
by PROVISIONING_IP or PROVISIONING_INTERFACE, that is, by looking up a
specific address on an interface, or a specific interface for a workable
address.

Introduce two new utility functions in ironic-common.sh for these two
purposes:
get_interface_of_ip: returns the name of the interface where the IP address
                     provided as argument is found
get_ip_of_interface: returns the first IP associated to the interface
                     provided as argument

These two functions will be put into use in subsequent commits.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 19:15:23 +00:00
1f98a15d26 Remove PROVISIONING_INTERFACE default for better validation
Whenever PROVISIONING_INTERFACE is not set by the user, function
get_provisioning_interface attempts to determine one, or provide
"provisionign" as default value. However this can cause confusing errors
down the line.

Remove this default value and fail gracefully, with proper logging,
if the PROVISIONING_INTERFACE value is not detected.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 17:38:30 +00:00
783a3fd5c2 Simplify the setting of host_ip in ironic.conf
The value of host_ip is determined twice within the ironic.conf.j2 template
file, by means of a relatively hard to read set of conditions.

Avoid this duplication and improve readability by exporting the correct
value once in scripts/configure-ironic.sh. This also leave more room for
more complex evaluations should these be needed in the future.

Signed-off-by: Marco Chiappero <marco.chiappero@suse.com>
2025-07-29 17:38:30 +00:00
153 changed files with 31274 additions and 3735 deletions

24
.gitmodules vendored
View File

@@ -13,27 +13,3 @@
[submodule "autoconf"]
path = autoconf
url = https://src.opensuse.org/SLFO-pool/autoconf.git
[submodule "python-pydantic"]
path = python-pydantic
url = https://src.opensuse.org/SLFO-pool/python-pydantic
[submodule "python-pydantic-core"]
path = python-pydantic-core
url = https://src.opensuse.org/SLFO-pool/python-pydantic-core
[submodule "python-inline-snapshot"]
path = python-inline-snapshot
url = https://src.opensuse.org/SLFO-pool/python-inline-snapshot
[submodule "python-executing"]
path = python-executing
url = https://src.opensuse.org/SLFO-pool/python-executing
[submodule "python-typing-inspection"]
path = python-typing-inspection
url = https://src.opensuse.org/SLFO-pool/python-typing-inspection
[submodule "python-annotated-types"]
path = python-annotated-types
url = https://src.opensuse.org/SLFO-pool/python-annotated-types
[submodule "python-typing_extensions"]
path = python-typing_extensions
url = https://src.opensuse.org/SLFO-pool/python-typing_extensions
[submodule "python-flit-core"]
path = python-flit-core
url = https://src.opensuse.org/SLFO-pool/python-flit-core

View File

@@ -1,3 +1,3 @@
PROJECT = "isv:SUSE:Edge:3.4"
PROJECT = "isv:SUSE:Edge:Factory"
REPOSITORY = "https://src.opensuse.org/suse-edge/Factory"
BRANCH = "3.4"
BRANCH = "main"

View File

@@ -12,8 +12,6 @@ def get_buildstatus(project: str) -> ET.Element:
output = subprocess.check_output(["osc", "pr", "--xml", project])
return ET.fromstring(output)
except subprocess.CalledProcessError:
# Don't retry immediatly just in case is a network error
time.sleep(5)
continue
print("Failed to get buildstatus from OBS")
@@ -22,12 +20,6 @@ def do_wait(project:str, commit:str) -> ET.Element:
while True:
time.sleep(5)
status = get_buildstatus(project)
# Just in case the buildstatus fails
if status is None:
print("Could not retrieve status, retrying...")
continue
if last_state == status.get("state"):
continue
else:
@@ -88,4 +80,4 @@ def main():
sys.exit(print_results(status))
if __name__ == "__main__":
main()
main()

View File

@@ -3,7 +3,7 @@ repos:
hooks:
- id: check-manifest
name: "Check release-manifest"
entry: python3 .obs/manifest-check.py
entry: .obs/manifest-check.py
language: python
additional_dependencies: ['ruamel.yaml']
pass_filenames: false

29
_config
View File

@@ -1,5 +1,5 @@
Prefer: -libqpid-proton10 -python311-urllib3_1
Prefer: -cargo1.58 -cargo1.57 cargo1.89
Prefer: -cargo1.58 -cargo1.57 cargo1.88
Macros:
%__python3 /usr/bin/python3.11
@@ -50,15 +50,6 @@ Macros:
BuildFlags: excludebuild:autoconf:el
BuildFlags: excludebuild:autoconf:testsuite
# Missing deps for python packages related to suse-edge-components-versions
BuildFlags: excludebuild:python-pydantic:test
BuildFlags: excludebuild:python-pydantic-core:test
BuildFlags: excludebuild:python-inline-snapshot:test
BuildFlags: excludebuild:python-executing:test
BuildFlags: excludebuild:python-annotated-types:test
BuildFlags: excludebuild:python-typing-inspection:test
BuildFlags: excludebuild:python-typing_extensions:test
# Only build manifest embedding images here
%if "%_repository" == "test_manifest_images"
BuildFlags: onlybuild:edge-image-builder-image
@@ -75,8 +66,6 @@ BuildFlags: onlybuild:release-manifest-image
BuildFlags: excludebuild:kube-rbac-proxy-image
BuildFlags: excludebuild:metallb-controller-image
BuildFlags: excludebuild:metallb-speaker-image
BuildFlags: excludebuild:nessie-image
BuildFlags: excludebuild:suse-edge-components-versions-image
%endif
%else
# Only a subset of stack is arm64 ready
@@ -105,22 +94,8 @@ BuildFlags: onlybuild:release-manifest-image
BuildFlags: onlybuild:metallb
BuildFlags: onlybuild:metallb-controller-image
BuildFlags: onlybuild:metallb-speaker-image
BuildFlags: onlybuild:nessie
BuildFlags: onlybuild:nessie-image
BuildFlags: onlybuild:nm-configurator
BuildFlags: onlybuild:python-annotated-types
BuildFlags: onlybuild:python-executing
BuildFlags: onlybuild:python-flit-core
BuildFlags: onlybuild:python-inline-snapshot
BuildFlags: onlybuild:python-pydantic
BuildFlags: onlybuild:python-pydantic-core
BuildFlags: onlybuild:python-pyhelm3
BuildFlags: onlybuild:python-rich
BuildFlags: onlybuild:python-suse-edge-components-versions
BuildFlags: onlybuild:python-typing-inspection
BuildFlags: onlybuild:python-typing_extensions
BuildFlags: onlybuild:shim-noarch
BuildFlags: onlybuild:suse-edge-components-versions-image
%endif
%endif
@@ -171,8 +146,6 @@ BuildFlags: onlybuild:release-manifest-image
BuildFlags: excludebuild:kube-rbac-proxy-image
BuildFlags: excludebuild:metallb-controller-image
BuildFlags: excludebuild:metallb-speaker-image
BuildFlags: excludebuild:nessie-image
BuildFlags: excludebuild:suse-edge-components-versions-image
%endif
%else

2
_meta
View File

@@ -43,7 +43,7 @@
{%- if repository == "images_16.0" %}
<path project="SUSE:CA" repository="16.0"/>
<path project="SUSE:SLFO:Products:SLES:16.0" repository="standard"/>
<path project="SUSE:SLFO:1.2" repository="standard"/>
<path project="SUSE:SLFO:Main:Build" repository="standard"/>
{%- else %}
<path project="SUSE:CA" repository="SLE_15_SP7"/>
<path project="{{ project }}" repository="standard"/>

View File

@@ -1,5 +1,5 @@
#!BuildTag: %%CHART_PREFIX%%akri-dashboard-extension:%%CHART_MAJOR%%.0.3_up1.3.1
#!BuildTag: %%CHART_PREFIX%%akri-dashboard-extension:%%CHART_MAJOR%%.0.3_up1.3.1-%RELEASE%
#!BuildTag: %%CHART_PREFIX%%akri-dashboard-extension:%%CHART_MAJOR%%.0.2_up1.3.1
#!BuildTag: %%CHART_PREFIX%%akri-dashboard-extension:%%CHART_MAJOR%%.0.2_up1.3.1-%RELEASE%
annotations:
catalog.cattle.io/certified: rancher
catalog.cattle.io/namespace: cattle-ui-plugin-system
@@ -12,10 +12,10 @@ annotations:
catalog.cattle.io/ui-extensions-version: '>= 3.0.2 < 4.0.0'
catalog.cattle.io/kube-version: '>= v1.26.0-0'
apiVersion: v2
appVersion: 304.0.3+up1.3.1
appVersion: 303.0.2+up1.3.1
description: 'SUSE Edge: Akri extension for Rancher Dashboard'
name: akri-dashboard-extension
type: application
version: "%%CHART_MAJOR%%.0.3+up1.3.1"
version: "%%CHART_MAJOR%%.0.2+up1.3.1"
icon: >-
https://raw.githubusercontent.com/cncf/artwork/main/projects/akri/icon/color/akri-icon-color.svg

View File

@@ -8,7 +8,7 @@ spec:
plugin:
name: {{ include "extension-server.fullname" . }}
version: {{ (semver (default .Chart.AppVersion .Values.plugin.versionOverride)).Original }}
endpoint: https://raw.githubusercontent.com/suse-edge/dashboard-extensions/gh-pages/extensions/akri-dashboard-extension/304.0.3+up1.3.1
endpoint: https://raw.githubusercontent.com/suse-edge/dashboard-extensions/gh-pages/extensions/akri-dashboard-extension/303.0.2+up1.3.1
noCache: {{ .Values.plugin.noCache }}
noAuth: {{ .Values.plugin.noAuth }}
metadata: {{ include "extension-server.pluginMetadata" . | indent 6 }}

View File

@@ -1,163 +0,0 @@
From f8c1ba1696fd8555e8e94246ec5afa38536fa8bd Mon Sep 17 00:00:00 2001
From: erjavaskivuori <erja.vaskivuori@est.tech>
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 <erja.vaskivuori@est.tech>
(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

View File

@@ -1,91 +0,0 @@
From 509ba92a8ed7303a418c5277f7544db2765c3802 Mon Sep 17 00:00:00 2001
From: Dmitry Tantsur <dtantsur@protonmail.com>
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 <dtantsur@protonmail.com>
(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

View File

@@ -1,49 +0,0 @@
From ea10df866f0fc491cac15ba5005f3b820e1ccecb Mon Sep 17 00:00:00 2001
From: Dmitry Tantsur <dtantsur@protonmail.com>
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 <dtantsur@protonmail.com>
(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

View File

@@ -1,422 +0,0 @@
From b2e8a1a42c95a3338c9c83a4781ba4744da5ff6a Mon Sep 17 00:00:00 2001
From: Dmitry Tantsur <dtantsur@protonmail.com>
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 <dtantsur@protonmail.com>
(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

View File

@@ -1,46 +0,0 @@
From 5419f8d95306efed8667936156d8081c21e068ed Mon Sep 17 00:00:00 2001
From: Dmitry Tantsur <dtantsur@protonmail.com>
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 <dtantsur@protonmail.com>
(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

View File

@@ -2,7 +2,7 @@
<service name="obs_scm">
<param name="url">https://github.com/metal3-io/baremetal-operator</param>
<param name="scm">git</param>
<param name="revision">v0.10.2</param>
<param name="revision">v0.9.1</param>
<param name="version">_auto_</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="changesgenerate">enable</param>

View File

@@ -17,21 +17,14 @@
Name: baremetal-operator
Version: 0.10.2
Version: 0.9.1
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
BuildRequires: golang(API) = 1.23
ExcludeArch: s390
ExcludeArch: %{ix86}

View File

@@ -1,9 +1,9 @@
#!BuildTag: %%CHART_PREFIX%%cdi:%%CHART_MAJOR%%.0.1_up0.6.0
#!BuildTag: %%CHART_PREFIX%%cdi:%%CHART_MAJOR%%.0.1_up0.6.0-%RELEASE%
#!BuildTag: %%CHART_PREFIX%%cdi:%%CHART_MAJOR%%.0.0_up0.5.0
#!BuildTag: %%CHART_PREFIX%%cdi:%%CHART_MAJOR%%.0.0_up0.5.0-%RELEASE%
apiVersion: v2
appVersion: 1.62.0
appVersion: 1.61.0
description: A Helm chart for Containerized Data Importer (CDI)
icon: https://raw.githubusercontent.com/cncf/artwork/main/projects/kubevirt/icon/color/kubevirt-icon-color.svg
name: cdi
type: application
version: "%%CHART_MAJOR%%.0.1+up0.6.0"
version: "%%CHART_MAJOR%%.0.0+up0.5.0"

View File

@@ -109,9 +109,9 @@ spec:
description: CDIConfig at CDI level
properties:
dataVolumeTTLSeconds:
description: |-
DataVolumeTTLSeconds is the time in seconds after DataVolume completion it can be garbage collected. Disabled by default.
Deprecated: Removed in v1.62.
description: DataVolumeTTLSeconds is the time in seconds after
DataVolume completion it can be garbage collected. Disabled
by default.
format: int32
type: integer
featureGates:
@@ -2641,9 +2641,9 @@ spec:
description: CDIConfig at CDI level
properties:
dataVolumeTTLSeconds:
description: |-
DataVolumeTTLSeconds is the time in seconds after DataVolume completion it can be garbage collected. Disabled by default.
Deprecated: Removed in v1.62.
description: DataVolumeTTLSeconds is the time in seconds after
DataVolume completion it can be garbage collected. Disabled
by default.
format: int32
type: integer
featureGates:

View File

@@ -599,8 +599,6 @@ spec:
strategy: {}
template:
metadata:
annotations:
openshift.io/required-scc: restricted-v2
labels:
cdi.kubevirt.io: cdi-operator
name: cdi-operator

View File

@@ -18,8 +18,4 @@ spec:
{{- with .Values.cdi.workload }}
workload:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.cdi.customizeComponents }}
customizeComponents:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@@ -1,12 +1,12 @@
deployment:
version: 1.62.0-150700.9.3.1
operatorImage: registry.suse.com/suse/sles/15.7/cdi-operator
controllerImage: registry.suse.com/suse/sles/15.7/cdi-controller
importerImage: registry.suse.com/suse/sles/15.7/cdi-importer
clonerImage: registry.suse.com/suse/sles/15.7/cdi-cloner
apiserverImage: registry.suse.com/suse/sles/15.7/cdi-apiserver
uploadserverImage: registry.suse.com/suse/sles/15.7/cdi-uploadserver
uploadproxyImage: registry.suse.com/suse/sles/15.7/cdi-uploadproxy
version: 1.61.0-150600.3.12.1
operatorImage: registry.suse.com/suse/sles/15.6/cdi-operator
controllerImage: registry.suse.com/suse/sles/15.6/cdi-controller
importerImage: registry.suse.com/suse/sles/15.6/cdi-importer
clonerImage: registry.suse.com/suse/sles/15.6/cdi-cloner
apiserverImage: registry.suse.com/suse/sles/15.6/cdi-apiserver
uploadserverImage: registry.suse.com/suse/sles/15.6/cdi-uploadserver
uploadproxyImage: registry.suse.com/suse/sles/15.6/cdi-uploadproxy
pullPolicy: IfNotPresent
affinity:
podAffinity:
@@ -30,7 +30,6 @@ cdi:
featureGates:
- HonorWaitForFirstConsumer
imagePullPolicy: "IfNotPresent"
customizeComponents: {}
infra:
nodeSelector:
kubernetes.io/os: linux
@@ -42,7 +41,7 @@ cdi:
nodeSelector:
kubernetes.io/os: linux
hookImage: registry.rancher.com/rancher/kubectl:v1.33.1
hookImage: registry.rancher.com/rancher/kubectl:v1.30.10
hookRestartPolicy: OnFailure
hookSecurityContext:
seccompProfile:

View File

@@ -1,5 +1,5 @@
#!BuildTag: %%IMG_PREFIX%%edge-image-builder:1.3.1
#!BuildTag: %%IMG_PREFIX%%edge-image-builder:1.3.1-%RELEASE%
#!BuildTag: %%IMG_PREFIX%%edge-image-builder:1.2.1
#!BuildTag: %%IMG_PREFIX%%edge-image-builder:1.2.1-%RELEASE%
ARG SLE_VERSION
FROM registry.suse.com/bci/bci-base:$SLE_VERSION
MAINTAINER SUSE LLC (https://www.suse.com/)
@@ -14,11 +14,11 @@ RUN zypper --non-interactive install --no-recommends edge-image-builder qemu-x86
LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)"
LABEL org.opencontainers.image.title="SLE edge-image-builder Container Image"
LABEL org.opencontainers.image.description="edge-image-builder based on the SLE Base Container Image."
LABEL org.opencontainers.image.version="1.3.1"
LABEL org.opencontainers.image.version="1.2.1"
LABEL org.opencontainers.image.url="https://www.suse.com/products/server/"
LABEL org.opencontainers.image.created="%BUILDTIME%"
LABEL org.opencontainers.image.vendor="SUSE LLC"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%edge-image-builder:1.3.1-%RELEASE%"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%edge-image-builder:1.2.1-%RELEASE%"
LABEL org.openbuildservice.disturl="%DISTURL%"
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
LABEL com.suse.eula="SUSE Combined EULA February 2024"

View File

@@ -10,10 +10,6 @@ kubernetes:
k3s:
selinuxPackage: k3s-selinux-1.6-1.slemicro.noarch
selinuxRepository: https://rpm.rancher.io/k3s/stable/common/slemicro/noarch
selinuxRepositoryPriority: 1
releaseURL: https://github.com/k3s-io/k3s/releases/download/
rke2:
selinuxPackage: rke2-selinux
selinuxRepository: https://rpm.rancher.io/rke2/stable/common/slemicro/noarch
selinuxRepositoryPriority: 1
releaseURL: https://github.com/rancher/rke2/releases/download/

View File

@@ -3,9 +3,9 @@
<param name="url">https://github.com/suse-edge/edge-image-builder.git</param>
<param name="scm">git</param>
<param name="exclude">.git</param>
<param name="revision">v1.3.1</param>
<param name="revision">v1.2.1</param>
<!-- Uncomment and set this For Pre-Release Version -->
<!-- <param name="version">1.3.1</param> -->
<!-- <param name="version">1.2.0~rc1</param> -->
<!-- Uncomment and this for regular version -->
<param name="versionformat">@PARENT_TAG@</param>
<param name="versionrewrite-pattern">v(\d+).(\d+).(\d+)</param>

View File

@@ -17,7 +17,7 @@
Name: edge-image-builder
Version: 1.3.1
Version: 1.2.1
Release: 0
Summary: Edge Image Builder
License: Apache-2.0
@@ -52,7 +52,7 @@ Requires: ca-certificates-suse
Tool for creating and configuring a set of images to automate the deployment of Edge environments
%prep
%autosetup -a1 -n edge-image-builder-%{version} -p1
%autosetup -a1 -n edge-image-builder-%{version}
%build
tar -xf %{SOURCE1}

View File

@@ -4,7 +4,7 @@
<param name="versionformat">@PARENT_TAG@</param>
<param name="scm">git</param>
<param name="exclude">.get</param>
<param name="revision">v1.2.5</param>
<param name="revision">v1.2.1</param>
<param name="versionrewrite-pattern">v(.*)</param>
<param name="changesgenerate">enable</param>
</service>

View File

@@ -18,7 +18,7 @@
%define project github.com/hauler-dev/hauler
Name: hauler
Version: 1.2.5
Version: 1.2.1
Release: 0
Summary: Airgap Swiss Army Knife
License: Apache-2.0

View File

@@ -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:29.0.4.0
#!BuildTag: %%IMG_PREFIX%%ironic:29.0.4.0-%RELEASE%
ARG SLE_VERSION
FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro
@@ -41,8 +41,8 @@ LABEL org.opencontainers.image.description="Openstack Ironic based on the SLE Ba
LABEL org.opencontainers.image.url="https://www.suse.com/products/server/"
LABEL org.opencontainers.image.created="%BUILDTIME%"
LABEL org.opencontainers.image.vendor="SUSE LLC"
LABEL org.opencontainers.image.version="29.0.4.4"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic:29.0.4.4-%RELEASE%"
LABEL org.opencontainers.image.version="29.0.4.0"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic:29.0.4.0-%RELEASE%"
LABEL org.openbuildservice.disturl="%DISTURL%"
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
LABEL com.suse.eula="SUSE Combined EULA February 2024"
@@ -88,7 +88,8 @@ RUN if [ "$(uname -m)" = "aarch64" ]; then\
cp /usr/share/ipxe/snp-arm64.efi /tftpboot/ipxe.efi; cp /usr/share/ipxe/snp-arm64.efi /tftpboot/snp-arm64.efi; cp /usr/share/ipxe/snp-arm64.efi /tftpboot/snp.efi ;\
fi
COPY --from=base /tmp/uefi_esp_*.img /templates/
COPY --from=base /tmp/esp-x86_64.img /tmp/uefi_esp-x86_64.img
COPY --from=base /tmp/esp-aarch64.img /tmp/uefi_esp-arm64.img
COPY ironic-config/ironic.conf.j2 ironic-config/network-data-schema-empty.json /etc/ironic/

View File

@@ -45,10 +45,10 @@ chown -R "${IRONIC_USER}":"${IRONIC_GROUP}" /run
# ironic and httpd related changes
mkdir -p /etc/httpd/conf.d
chown -R "${IRONIC_USER}":"${IRONIC_GROUP}" /etc/ironic /etc/httpd/conf /etc/httpd/conf.d /etc/httpd/conf.modules.d/
chmod 2775 /etc/ironic /etc/httpd/conf /etc/httpd/conf.d /etc/httpd/conf.modules.d/
chown -R "${IRONIC_USER}":"${IRONIC_GROUP}" /etc/ironic /etc/httpd/conf /etc/httpd/conf.d
chmod 2775 /etc/ironic /etc/httpd/conf /etc/httpd/conf.d
#chmod 664 /etc/ironic/* /etc/httpd/conf/* /etc/httpd/conf.d/*
chmod 664 /etc/ironic/* /etc/httpd/conf/* /etc/httpd/conf.modules.d/*
chmod 664 /etc/ironic/* /etc/httpd/conf/*
chown -R "${IRONIC_USER}":"${IRONIC_GROUP}" /var/lib/ironic
chmod 2775 /var/lib/ironic

View File

@@ -11,28 +11,13 @@ Listen [::]:{{ env.VMEDIA_TLS_PORT }}
SSLCertificateFile {{ env.IRONIC_VMEDIA_CERT_FILE }}
SSLCertificateKeyFile {{ env.IRONIC_VMEDIA_KEY_FILE }}
{% if "IRONIC_VMEDIA_TLS_12_CIPHERS" in env and env.IRONIC_VMEDIA_TLS_12_CIPHERS %}
SSLCipherSuite {{ env.IRONIC_VMEDIA_TLS_12_CIPHERS }}
{% endif %}
{% if "IRONIC_VMEDIA_TLS_13_CIPHERS" in env and env.IRONIC_VMEDIA_TLS_13_CIPHERS %}
SSLCipherSuite TLSv1.3 {{ env.IRONIC_VMEDIA_TLS_13_CIPHERS }}
{% endif %}
{% if "IRONIC_VMEDIA_CURVES" in env and env.IRONIC_VMEDIA_CURVES %}
SSLOpenSSLConfCmd Curves {{ env.IRONIC_VMEDIA_CURVES }}
{% endif %}
{% if env.IRONIC_VMEDIA_TLS_ENFORCE_SERVER_CIPHER_ORDER | lower == "true" %}
SSLHonorCipherOrder on
{% endif %}
<Directory "/shared/html/">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
<Directory ~ "/shared/html">
Order deny,allow
deny from all
</Directory>
<Directory ~ "/shared/html/(redfish|ilo)/">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
Order allow,deny
allow from all
</Directory>
</VirtualHost>

View File

@@ -17,4 +17,4 @@ LoadModule authn_core_module /usr/lib64/apache2/mod_authn_core.so
LoadModule auth_basic_module /usr/lib64/apache2/mod_auth_basic.so
LoadModule authn_file_module /usr/lib64/apache2/mod_authn_file.so
LoadModule authz_user_module /usr/lib64/apache2/mod_authz_user.so
#LoadModule access_compat_module /usr/lib64/apache2/mod_access_compat.so
LoadModule access_compat_module /usr/lib64/apache2/mod_access_compat.so

View File

@@ -91,23 +91,17 @@ send_sensor_data = {{ env.SEND_SENSOR_DATA }}
# 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 }}
bootloader = {{ env.IRONIC_HTTP_URL }}/uefi_esp-{{ env.DEPLOY_ARCHITECTURE }}.img
verify_step_priority_override = management.clear_job_queue:90
# We don't use this feature, and it creates an additional load on the database
node_history = False
# Provide for a timeout longer than 60 seconds for certain vendor's hardware
power_state_change_timeout = 120
{% if env.DEPLOY_KERNEL_URL is defined %}
deploy_kernel = {{ env.DEPLOY_KERNEL_URL }}
{% if env.IRONIC_DEFAULT_KERNEL is defined %}
deploy_kernel = file://{{ env.IRONIC_DEFAULT_KERNEL }}
{% endif %}
{% if env.DEPLOY_KERNEL_BY_ARCH is defined %}
deploy_kernel_by_arch = {{ env.DEPLOY_KERNEL_BY_ARCH }}
{% endif %}
{% if env.DEPLOY_RAMDISK_URL is defined %}
deploy_ramdisk = {{ env.DEPLOY_RAMDISK_URL }}
{% endif %}
{% if env.DEPLOY_RAMDISK_BY_ARCH is defined %}
deploy_ramdisk_by_arch = {{ env.DEPLOY_RAMDISK_BY_ARCH }}
{% if env.IRONIC_DEFAULT_RAMDISK is defined %}
deploy_ramdisk = file://{{ env.IRONIC_DEFAULT_RAMDISK }}
{% endif %}
{% if env.DISABLE_DEEP_IMAGE_INSPECTION | lower == "true" %}
disable_deep_image_inspection = True
@@ -129,15 +123,15 @@ default_boot_option = local
erase_devices_metadata_priority = 10
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 %}
http_url = {{ env.IRONIC_HTTP_URL }}
fast_track = {{ env.IRONIC_FAST_TRACK }}
{% if env.IRONIC_BOOT_ISO_SOURCE %}
ramdisk_image_download_source = {{ env.IRONIC_BOOT_ISO_SOURCE }}
{% endif %}
{% if env.IRONIC_EXTERNAL_HTTP_URL %}
external_http_url = {{ env.IRONIC_EXTERNAL_HTTP_URL }}
{% elif env.VMEDIA_TLS_PORT %}
external_http_url = {{ env.IRONIC_HTTPS_VMEDIA_URL }}
{% elif env.IRONIC_VMEDIA_TLS_SETUP == "true" %}
external_http_url = https://{{ env.IRONIC_URL_HOST }}:{{ env.VMEDIA_TLS_PORT }}
{% endif %}
{% if env.IRONIC_EXTERNAL_CALLBACK_URL %}
external_callback_url = {{ env.IRONIC_EXTERNAL_CALLBACK_URL }}
@@ -213,7 +207,7 @@ images_path = /shared/html/tmp
instance_master_path = /shared/html/master_images
tftp_master_path = /shared/tftpboot/master_images
tftp_root = /shared/tftpboot
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' }}
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
# This makes networking boot templates generated even for nodes using local
# boot (the default), ensuring that they boot correctly even if they start
# netbooting for some reason (e.g. with the noop management interface).
@@ -226,14 +220,14 @@ ipxe_config_template = /tmp/ipxe_config.template
[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' }}
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
[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' }}
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
use_web_server_for_images = true
[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' }}
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
[service_catalog]
endpoint_override = {{ env.IRONIC_BASE_URL }}

View File

@@ -9,7 +9,7 @@ declare -A efi_arch=(
for arch in "${!efi_arch[@]}"; do
DEST=/tmp/uefi_esp_${arch}.img
DEST=/tmp/esp-${arch}.img
dd bs=1024 count=6400 if=/dev/zero of=$DEST
mkfs.msdos -F 12 -n 'ESP_IMAGE' $DEST

View File

@@ -3,7 +3,6 @@
set -euxo pipefail
IRONIC_EXTERNAL_IP="${IRONIC_EXTERNAL_IP:-}"
export VMEDIA_TLS_PORT="${VMEDIA_TLS_PORT:-}"
# Define the VLAN interfaces to be included in introspection report, e.g.
# all - all VLANs on all interfaces using LLDP information
@@ -54,16 +53,12 @@ wait_for_interface_or_ip
if [[ "$(echo "$LISTEN_ALL_INTERFACES" | tr '[:upper:]' '[:lower:]')" == "true" ]]; then
export IRONIC_HOST_IP="::"
elif [[ -n "${ENABLE_IPV6}" ]]; then
elif [[ -n env.ENABLE_IPV6 ]]; then
export IRONIC_HOST_IP="$IRONIC_IPV6"
else
export IRONIC_HOST_IP="$IRONIC_IP"
fi
if [[ "${VMEDIA_TLS_PORT}" ]]; then
export IRONIC_HTTPS_VMEDIA_URL="https://${IRONIC_URL_HOST}:${VMEDIA_TLS_PORT}"
fi
# Hostname to use for the current conductor instance.
export IRONIC_CONDUCTOR_HOST=${IRONIC_CONDUCTOR_HOST:-${IRONIC_URL_HOST}}
@@ -76,41 +71,10 @@ if [[ -n "$IRONIC_EXTERNAL_IP" ]]; then
fi
fi
IMAGE_CACHE_PREFIX="/shared/html/images/ironic-python-agent"
if [[ -z "${DEPLOY_KERNEL_URL:-}" ]] && [[ -z "${DEPLOY_RAMDISK_URL:-}" ]] && \
[[ -f "${IMAGE_CACHE_PREFIX}.kernel" ]] && [[ -f "${IMAGE_CACHE_PREFIX}.initramfs" ]]; then
export DEPLOY_KERNEL_URL="file://${IMAGE_CACHE_PREFIX}.kernel"
export DEPLOY_RAMDISK_URL="file://${IMAGE_CACHE_PREFIX}.initramfs"
fi
declare -A detected_arch
for var_arch in "${!DEPLOY_KERNEL_URL_@}"; do
IPA_ARCH="${var_arch#DEPLOY_KERNEL_URL}"
detected_arch["${IPA_ARCH,,}"]=1
done
for file_arch in "${IMAGE_CACHE_PREFIX}"_*.kernel; do
if [[ -f "${file_arch}" ]]; then
IPA_ARCH="$(basename "${file_arch#"${IMAGE_CACHE_PREFIX}"_}" .kernel)"
detected_arch["${IPA_ARCH}"]=1
fi
done
DEPLOY_KERNEL_BY_ARCH=""
DEPLOY_RAMDISK_BY_ARCH=""
for IPA_ARCH in "${!detected_arch[@]}"; do
kernel_var="DEPLOY_KERNEL_URL_${IPA_ARCH^^}"
ramdisk_var="DEPLOY_RAMDISK_URL_${IPA_ARCH^^}"
if [[ -z "${!kernel_var:-}" ]] && [[ -z "${!ramdisk_var:-}" ]] && \
[[ -f "${IMAGE_CACHE_PREFIX}_${IPA_ARCH}.kernel" ]] && [[ -f "${IMAGE_CACHE_PREFIX}_${IPA_ARCH}.initramfs" ]]; then
export "${kernel_var}"="file://${IMAGE_CACHE_PREFIX}_${IPA_ARCH}.kernel"
export "${ramdisk_var}"="file://${IMAGE_CACHE_PREFIX}_${IPA_ARCH}.initramfs"
fi
DEPLOY_KERNEL_BY_ARCH+="${!kernel_var:+${IPA_ARCH}:${!kernel_var},}"
DEPLOY_RAMDISK_BY_ARCH+="${!ramdisk_var:+${IPA_ARCH}:${!ramdisk_var},}"
done
if [[ -n "${DEPLOY_KERNEL_BY_ARCH}" ]] && [[ -n "${DEPLOY_RAMDISK_BY_ARCH}" ]]; then
export DEPLOY_KERNEL_BY_ARCH="${DEPLOY_KERNEL_BY_ARCH%?}"
export DEPLOY_RAMDISK_BY_ARCH="${DEPLOY_RAMDISK_BY_ARCH%?}"
IMAGE_CACHE_PREFIX="/shared/html/images/ironic-python-agent-${DEPLOY_ARCHITECTURE}"
if [[ -f "${IMAGE_CACHE_PREFIX}.kernel" ]] && [[ -f "${IMAGE_CACHE_PREFIX}.initramfs" ]]; then
export IRONIC_DEFAULT_KERNEL="${IMAGE_CACHE_PREFIX}.kernel"
export IRONIC_DEFAULT_RAMDISK="${IMAGE_CACHE_PREFIX}.initramfs"
fi
if [[ -f "${IRONIC_CONF_DIR}/ironic.conf" ]]; then
@@ -118,13 +82,6 @@ if [[ -f "${IRONIC_CONF_DIR}/ironic.conf" ]]; then
cp "${IRONIC_CONF_DIR}/ironic.conf" "${IRONIC_CONF_DIR}/ironic.conf.orig"
fi
BOOTLOADER_BY_ARCH=""
for bootloader in /templates/uefi_esp_*.img; do
BOOTLOADER_ARCH="$(basename "${bootloader#/templates/uefi_esp_}" .img)"
BOOTLOADER_BY_ARCH+="${BOOTLOADER_ARCH}:file://${bootloader},"
done
export BOOTLOADER_BY_ARCH="${BOOTLOADER_BY_ARCH%?}"
# oslo.config also supports Config Opts From Environment, log them to stdout
echo 'Options set from Environment variables'
env | grep "^OS_" || true

View File

@@ -5,7 +5,7 @@ set -euxo pipefail
# Export IRONIC_IP to avoid needing to lean on IRONIC_URL_HOST for consumption in
# e.g. dnsmasq configuration
export IRONIC_IP="${IRONIC_IP:-}"
IRONIC_IPV6="${IRONIC_IPV6:-}"
export IRONIC_IPV6="${IRONIC_IPV6:-}"
PROVISIONING_INTERFACE="${PROVISIONING_INTERFACE:-}"
PROVISIONING_IP="${PROVISIONING_IP:-}"
PROVISIONING_MACS="${PROVISIONING_MACS:-}"
@@ -55,7 +55,7 @@ get_ip_of_hostname()
local HOSTNAME=$1
echo $(nslookup -type=${QUERY} "${HOSTNAME}" | tail -n2 | grep -w "Address:" | cut -d " " -f2)
echo "$(nslookup -type=${QUERY} $HOSTNAME | tail -n2 | grep -w "Address:" | cut -d " " -f2)"
}
get_interface_of_ip()
@@ -85,7 +85,7 @@ get_interface_of_ip()
# For IPv6 addresses, this will give the short-form address
IP_ADDR="$(ipcalc "${IP_ADDR}" | grep "^Address:" | awk '{print $2}')"
echo $(ip ${IP_VERS} -br addr show scope global | grep -i " ${IP_ADDR}/" | cut -f 1 -d ' ' | cut -f 1 -d '@')
echo "$(ip $IP_VERS -br addr show scope global | grep -i " ${IP_ADDR}/" | cut -f 1 -d ' ' | cut -f 1 -d '@')"
}
get_ip_of_interface()
@@ -111,7 +111,7 @@ get_ip_of_interface()
local IFACE=$1
echo $(ip ${IP_VERS} -br addr show scope global up dev ${IFACE} | awk '{print $3}' | sed -e 's%/.*%%' | head -n 1)
echo "$(ip $IP_VERS -br addr show scope global up dev $IFACE | awk '{print $3}' | sed -e 's%/.*%%' | head -n 1)"
}
get_provisioning_interface()
@@ -150,7 +150,7 @@ wait_for_interface_or_ip()
until [[ -n "$IFACE_OF_IP" ]]; do
echo "Waiting for ${PROVISIONING_IP} to be configured on an interface..."
IFACE_OF_IP="$(get_interface_of_ip "${PROVISIONING_IP}")"
IFACE_OF_IP="$(get_interface_of_ip $PROVISIONING_IP)"
sleep 1
done
@@ -160,33 +160,25 @@ wait_for_interface_or_ip()
# If the IP contains a colon, then it's an IPv6 address
if [[ "$PROVISIONING_IP" =~ .*:.* ]]; then
export IRONIC_IPV6="$PROVISIONING_IP"
export IRONIC_IP=""
else
export IRONIC_IP="$PROVISIONING_IP"
fi
elif [[ -n "${IRONIC_IP}" ]]; then
if [[ "$IRONIC_IP" =~ .*:.* ]]; then
export IRONIC_IPV6="$IRONIC_IP"
export IRONIC_IP=""
fi
elif [[ -n "${PROVISIONING_INTERFACE}" ]]; then
until [[ -n "$IRONIC_IPV6" ]] || [[ -n "$IRONIC_IP" ]]; do
echo "Waiting for ${PROVISIONING_INTERFACE} interface to be configured..."
IRONIC_IPV6="$(get_ip_of_interface "${PROVISIONING_INTERFACE}" 6)"
export IRONIC_IPV6="$(get_ip_of_interface $PROVISIONING_INTERFACE 6)"
sleep 1
IRONIC_IP="$(get_ip_of_interface "${PROVISIONING_INTERFACE}" 4)"
export IRONIC_IP="$(get_ip_of_interface $PROVISIONING_INTERFACE 4)"
sleep 1
done
if [[ -n "$IRONIC_IPV6" ]]; then
echo "Found $IRONIC_IPV6 on interface \"${PROVISIONING_INTERFACE}\"!"
export IRONIC_IPV6
fi
if [[ -n "$IRONIC_IP" ]]; then
echo "Found $IRONIC_IP on interface \"${PROVISIONING_INTERFACE}\"!"
export IRONIC_IP
fi
elif [[ -n "$IRONIC_URL_HOSTNAME" ]]; then
local IPV6_IFACE=""
@@ -197,21 +189,21 @@ wait_for_interface_or_ip()
local IPV6_RECORD=""
local IPV4_RECORD=""
IPV6_RECORD="$(get_ip_of_hostname "${IRONIC_URL_HOSTNAME}" 6)"
IPV4_RECORD="$(get_ip_of_hostname "${IRONIC_URL_HOSTNAME}" 4)"
IPV6_RECORD="$(get_ip_of_hostname $IRONIC_URL_HOSTNAME 6)"
IPV4_RECORD="$(get_ip_of_hostname $IRONIC_URL_HOSTNAME 4)"
# We couldn't get any IP
if [[ -z "$IPV4_RECORD" ]] && [[ -z "$IPV6_RECORD" ]]; then
echo "${FUNCNAME}: no valid IP found for hostname ${IRONIC_URL_HOSTNAME}" >&2
echo "${FUNCNAME}: no valid IP found for hostname $IRONIC_URL_HOSTNAME" >&2
return 1
fi
echo "Waiting for ${IPV6_RECORD} to be configured on an interface"
IPV6_IFACE="$(get_interface_of_ip "${IPV6_RECORD}" 6)"
IPV6_IFACE="$(get_interface_of_ip $IPV6_RECORD 6)"
sleep 1
echo "Waiting for ${IPV4_RECORD} to be configured on an interface"
IPV4_IFACE="$(get_interface_of_ip "${IPV4_RECORD}" 4)"
IPV4_IFACE="$(get_interface_of_ip $IPV4_RECORD 4)"
sleep 1
done
@@ -244,7 +236,7 @@ wait_for_interface_or_ip()
fi
if [[ -n "$IRONIC_IPV6" ]]; then
export ENABLE_IPV6=yes
export IRONIC_URL_HOST="[${IRONIC_IPV6}]" # The HTTP host needs surrounding with brackets
export IRONIC_URL_HOST="[$IRONIC_IPV6]" # The HTTP host needs surrounding with brackets
fi
# Once determined if we have IPv4 and/or IPv6, override the hostname if provided

View File

@@ -37,6 +37,7 @@ export INSPECTOR_EXTRA_ARGS
# Copy files to shared mount
render_j2_config /tmp/inspector.ipxe.j2 /shared/html/inspector.ipxe
cp /tmp/uefi_esp*.img /shared/html/
# 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"

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.10
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.10-%RELEASE%
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.8
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.8-%RELEASE%
ARG SLE_VERSION
FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro
@@ -18,11 +18,11 @@ FROM micro AS final
LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)"
LABEL org.opencontainers.image.title="SLE Based Ironic IPA Downloader Container Image"
LABEL org.opencontainers.image.description="ironic-ipa-downloader based on the SLE Base Container Image."
LABEL org.opencontainers.image.version="3.0.10"
LABEL org.opencontainers.image.version="3.0.8"
LABEL org.opencontainers.image.url="https://www.suse.com/solutions/edge-computing/"
LABEL org.opencontainers.image.created="%BUILDTIME%"
LABEL org.opencontainers.image.vendor="SUSE LLC"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.10-%RELEASE%"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.8-%RELEASE%"
LABEL org.openbuildservice.disturl="%DISTURL%"
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
LABEL com.suse.eula="SUSE Combined EULA February 2024"

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-aarch64:3.0.10
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-aarch64:3.0.10-%RELEASE%
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-aarch64:3.0.8
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-aarch64:3.0.8-%RELEASE%
ARG SLE_VERSION
FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro
@@ -18,11 +18,11 @@ FROM micro AS final
LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)"
LABEL org.opencontainers.image.title="SLE Based Ironic IPA Downloader Container Image"
LABEL org.opencontainers.image.description="ironic-ipa-downloader based on the SLE Base Container Image."
LABEL org.opencontainers.image.version="3.0.10"
LABEL org.opencontainers.image.version="3.0.8"
LABEL org.opencontainers.image.url="https://www.suse.com/solutions/edge-computing/"
LABEL org.opencontainers.image.created="%BUILDTIME%"
LABEL org.opencontainers.image.vendor="SUSE LLC"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.10-%RELEASE%"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.8-%RELEASE%"
LABEL org.openbuildservice.disturl="%DISTURL%"
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
LABEL com.suse.eula="SUSE Combined EULA February 2024"

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-x86_64:3.0.10
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-x86_64:3.0.10-%RELEASE%
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-x86_64:3.0.8
#!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-x86_64:3.0.8-%RELEASE%
ARG SLE_VERSION
FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro
@@ -18,11 +18,11 @@ FROM micro AS final
LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)"
LABEL org.opencontainers.image.title="SLE Based Ironic IPA Downloader Container Image"
LABEL org.opencontainers.image.description="ironic-ipa-downloader based on the SLE Base Container Image."
LABEL org.opencontainers.image.version="3.0.10"
LABEL org.opencontainers.image.version="3.0.8"
LABEL org.opencontainers.image.url="https://www.suse.com/solutions/edge-computing/"
LABEL org.opencontainers.image.created="%BUILDTIME%"
LABEL org.opencontainers.image.vendor="SUSE LLC"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.10-%RELEASE%"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.8-%RELEASE%"
LABEL org.openbuildservice.disturl="%DISTURL%"
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
LABEL com.suse.eula="SUSE Combined EULA February 2024"

View File

@@ -29,12 +29,13 @@ if [ -z "${IPA_BASEURI}" ]; then
# SLES BASED IPA - ironic-ipa-ramdisk-x86_64 and ironic-ipa-ramdisk-aarch64 packages
mkdir -p /shared/html/images
if [ -f ${IMAGES_BASE_PATH}/initrd-x86_64.zst ]; then
cp ${IMAGES_BASE_PATH}/initrd-x86_64.zst /shared/html/images/ironic-python-agent_x86_64.initramfs
cp ${IMAGES_BASE_PATH}/openstack-ironic-image.x86_64*.kernel /shared/html/images/ironic-python-agent_x86_64.kernel
cp ${IMAGES_BASE_PATH}/initrd-x86_64.zst /shared/html/images/ironic-python-agent-x86_64.initramfs
cp ${IMAGES_BASE_PATH}/openstack-ironic-image.x86_64*.kernel /shared/html/images/ironic-python-agent-x86_64.kernel
fi
# Use arm64 as destination for iPXE compatibility
if [ -f ${IMAGES_BASE_PATH}/initrd-aarch64.zst ]; then
cp ${IMAGES_BASE_PATH}/initrd-aarch64.zst /shared/html/images/ironic-python-agent_aarch64.initramfs
cp ${IMAGES_BASE_PATH}/openstack-ironic-image.aarch64*.kernel /shared/html/images/ironic-python-agent_aarch64.kernel
cp ${IMAGES_BASE_PATH}/initrd-aarch64.zst /shared/html/images/ironic-python-agent-arm64.initramfs
cp ${IMAGES_BASE_PATH}/openstack-ironic-image.aarch64*.kernel /shared/html/images/ironic-python-agent-arm64.kernel
fi
cp /tmp/images.sha256 /shared/images.sha256
@@ -86,8 +87,8 @@ else
chmod 755 "$TMPDIR"
mv "$TMPDIR" "$FILENAME-$ETAG"
ln -sf "$FILENAME-$ETAG/$FFILENAME.headers" "$FFILENAME.headers"
ln -sf "$FILENAME-$ETAG/$FILENAME.initramfs" "${FILENAME}_${ARCH,,}.initramfs"
ln -sf "$FILENAME-$ETAG/$FILENAME.kernel" "${FILENAME}_${ARCH,,}.kernel"
ln -sf "$FILENAME-$ETAG/$FILENAME.initramfs" "$FILENAME-${ARCH,,}.initramfs"
ln -sf "$FILENAME-$ETAG/$FILENAME.kernel" "$FILENAME-${ARCH,,}.kernel"
IMAGE_CHANGED=1
else
@@ -99,7 +100,7 @@ if [ "${CERTS_CHANGED:-0}" = "1" ] || [ "${IMAGE_CHANGED:-0}" = "1" ]; then
mkdir -p /tmp/ca/tmp-initrd && cd /tmp/ca/tmp-initrd
mkdir -p etc/ironic-python-agent.d/ca-certs
cp /tmp/ironic-certificates/* etc/ironic-python-agent.d/ca-certs/
for initramfs in /shared/html/images/ironic-python-agent_*.initramfs; do
for initramfs in /shared/html/images/ironic-python-agent-*.initramfs; do
find . | cpio -o -H newc --reproducible | zstd -c >> "${initramfs}"
done
cp /tmp/certificates.sha256 /shared/certificates.sha256

View File

@@ -16,7 +16,7 @@ baseSetupBuildDay
#==========================================
# remove unneded kernel files
#------------------------------------------
#suseStripKernel
suseStripKernel
baseStripLocales en_US.utf-8 C.utf8
#======================================

View File

@@ -28,6 +28,68 @@
<source path="dir:///.build.binaries"/>
</repository>
<drivers>
<file name="crypto/*"/>
<file name="drivers/acpi/*"/>
<file name="drivers/acpi/dock.ko"/>
<file name="drivers/ata/*"/>
<file name="drivers/block/brd.ko"/>
<file name="drivers/block/cciss.ko"/>
<file name="drivers/block/loop.ko"/>
<file name="drivers/block/virtio_blk.ko"/>
<file name="drivers/cdrom/*"/>
<file name="drivers/char/hw_random/virtio-rng.ko"/>
<file name="drivers/char/lp.ko"/>
<file name="drivers/char/ipmi/*"/>
<file name="drivers/firmware/iscsi_ibft.ko"/>
<file name="drivers/firmware/edd.ko"/>
<file name="drivers/gpu/drm/*"/>
<file name="drivers/hid/*"/>
<file name="drivers/hv/*"/>
<file name="drivers/hwmon/*"/>
<file name="drivers/ide/*"/>
<file name="drivers/input/keyboard/*"/>
<file name="drivers/input/mouse/*"/>
<file name="drivers/md/*"/>
<file name="drivers/message/fusion/*"/>
<file name="drivers/misc/hpilo.ko"/>
<file name="drivers/net/*"/>
<file name="drivers/parport/*"/>
<file name="drivers/scsi/*"/>
<file name="drivers/staging/hv/*"/>
<file name="drivers/target/*"/>
<file name="drivers/thermal/*"/>
<file name="drivers/usb/*"/>
<file name="drivers/virtio/*"/>
<file name="fs/binfmt_aout.ko"/>
<file name="fs/binfmt_misc.ko"/>
<file name="fs/overlayfs/*"/>
<file name="fs/btrfs/*"/>
<file name="fs/exportfs/*"/>
<file name="fs/ext4/*"/>
<file name="fs/fat/*"/>
<file name="fs/fuse/*"/>
<file name="fs/hfs/*"/>
<file name="fs/jbd2/*"/>
<file name="fs/nfs/*"/>
<file name="fs/mbcache.ko"/>
<file name="fs/nls/nls_cp437.ko"/>
<file name="fs/nls/nls_iso8859-1.ko"/>
<file name="fs/nls/nls_utf8.ko"/>
<file name="fs/quota_v1.ko"/>
<file name="fs/quota_v2.ko"/>
<file name="fs/squashfs/*"/>
<file name="fs/udf/*"/>
<file name="fs/vfat/*"/>
<file name="fs/xfs/*"/>
<file name="fs/isofs/*"/>
<file name="lib/crc-t10dif.ko"/>
<file name="lib/crc16.ko"/>
<file name="lib/libcrc32c.ko"/>
<file name="lib/zlib_deflate/zlib_deflate.ko"/>
<file name="net/packet/*"/>
</drivers>
<packages type="delete">
<package name="gpg2"/>
<package name="libcairo2"/>

View File

@@ -19,7 +19,7 @@
Name: ironic-ipa-ramdisk
Version: 3.0.8
Version: 3.0.7
Release: 0
Summary: Kernel and ramdisk image for OpenStack Ironic
License: SUSE-EULA

View File

@@ -1,5 +1,5 @@
#!BuildTag: %%IMG_PREFIX%%kiwi-builder:10.2.12.1-%RELEASE%
#!BuildTag: %%IMG_PREFIX%%kiwi-builder:10.2.12.1
#!BuildTag: %%IMG_PREFIX%%kiwi-builder:10.2.12.0-%RELEASE%
#!BuildTag: %%IMG_PREFIX%%kiwi-builder:10.2.12.0
# Base image version, should match the tag above
ARG KIWIVERSION="10.2.12"
@@ -15,7 +15,7 @@ LABEL org.opencontainers.image.version="${KIWIVERSION}"
LABEL org.opencontainers.image.url="https://www.suse.com/solutions/edge-computing/"
LABEL org.opencontainers.image.created="%BUILDTIME%"
LABEL org.opencontainers.image.vendor="SUSE LLC"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%kiwi-builder:${KIWIVERSION}.1-%RELEASE%"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%kiwi-builder:${KIWIVERSION}.0-%RELEASE%"
LABEL org.openbuildservice.disturl="%DISTURL%"
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
LABEL com.suse.eula="SUSE Combined EULA February 2024"

View File

@@ -1033,7 +1033,6 @@
<!-- FIXME does not build without control file which is obsolete
<package name="live-add-yast-repos"/> -->
<package name="parted"/> <!-- seems missing to deploy the image -->
<package name="iptables"/> <!-- needed by RKE2 -->
</packages>
<packages type="image" profiles="bootloader">

View File

@@ -1041,7 +1041,6 @@
<!-- FIXME does not build without control file which is obsolete
<package name="live-add-yast-repos"/> -->
<package name="parted"/> <!-- seems missing to deploy the image -->
<package name="iptables"/> <!-- needed by RKE2 -->
</packages>
<packages type="image" profiles="bootloader">

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#!BuildTag: %%IMG_PREFIX%%kubectl:1.33.4
#!BuildTag: %%IMG_PREFIX%%kubectl:1.33.4-%RELEASE%
#!BuildTag: %%IMG_PREFIX%%kubectl:1.32.4
#!BuildTag: %%IMG_PREFIX%%kubectl:1.32.4-%RELEASE%
ARG SLE_VERSION
FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro
@@ -15,11 +15,11 @@ FROM micro AS final
LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)"
LABEL org.opencontainers.image.title="SLE kubectl image"
LABEL org.opencontainers.image.description="kubectl on the SLE Base Container Image."
LABEL org.opencontainers.image.version="1.33.4"
LABEL org.opencontainers.image.version="1.32.4"
LABEL org.opencontainers.image.url="https://www.suse.com/solutions/edge-computing/"
LABEL org.opencontainers.image.created="%BUILDTIME%"
LABEL org.opencontainers.image.vendor="SUSE LLC"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%kubectl:1.33.4-%RELEASE%"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%kubectl:1.32.4-%RELEASE%"
LABEL org.openbuildservice.disturl="%DISTURL%"
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
LABEL com.suse.eula="SUSE Combined EULA February 2024"

View File

@@ -1,7 +1,7 @@
%global debug_package %{nil}
Name: kubectl
Version: 1.33.4
Version: 1.32.4
Release: 0
Summary: Command-line utility for interacting with a Kubernetes cluster

Binary file not shown.

Binary file not shown.

View File

@@ -1,9 +1,9 @@
#!BuildTag: %%CHART_PREFIX%%kubevirt:%%CHART_MAJOR%%.0.1_up0.6.0-%RELEASE%
#!BuildTag: %%CHART_PREFIX%%kubevirt:%%CHART_MAJOR%%.0.1_up0.6.0
#!BuildTag: %%CHART_PREFIX%%kubevirt:%%CHART_MAJOR%%.0.0_up0.5.0-%RELEASE%
#!BuildTag: %%CHART_PREFIX%%kubevirt:%%CHART_MAJOR%%.0.0_up0.5.0
apiVersion: v2
appVersion: 1.5.2
appVersion: 1.4.0
description: A Helm chart for KubeVirt
icon: https://raw.githubusercontent.com/cncf/artwork/main/projects/kubevirt/icon/color/kubevirt-icon-color.svg
name: kubevirt
type: application
version: "%%CHART_MAJOR%%.0.1+up0.6.0"
version: "%%CHART_MAJOR%%.0.0+up0.5.0"

View File

@@ -593,13 +593,6 @@ spec:
If set to true, migrations will still start in pre-copy, but switch to post-copy when
CompletionTimeoutPerGiB triggers. Defaults to false
type: boolean
allowWorkloadDisruption:
description: |-
AllowWorkloadDisruption indicates that the migration shouldn't be
canceled after acceptableCompletionTime is exceeded. Instead, if
permitted, migration will be switched to post-copy or the VMI will be
paused to allow the migration to complete
type: boolean
bandwidthPerMigration:
anyOf:
- type: integer
@@ -612,8 +605,8 @@ spec:
completionTimeoutPerGiB:
description: |-
CompletionTimeoutPerGiB is the maximum number of seconds per GiB a migration is allowed to take.
If the timeout is reached, the migration will be either paused, switched
to post-copy or cancelled depending on other settings. Defaults to 150
If a live-migration takes longer to migrate than this value multiplied by the size of the VMI,
the migration will be cancelled, unless AllowPostCopy is true. Defaults to 150
format: int64
type: integer
disableTLS:
@@ -971,17 +964,17 @@ spec:
type: object
type: object
vmRolloutStrategy:
description: |-
VMRolloutStrategy defines how live-updatable fields, like CPU sockets, memory,
tolerations, and affinity, are propagated from a VM to its VMI.
description: VMRolloutStrategy defines how changes to a VM object
propagate to its VMI
enum:
- Stage
- LiveUpdate
nullable: true
type: string
vmStateStorageClass:
description: VMStateStorageClass is the name of the storage class
to use for the PVCs created to preserve VM state, like TPM.
description: |-
VMStateStorageClass is the name of the storage class to use for the PVCs created to preserve VM state, like TPM.
The storage class must support RWX in filesystem mode.
type: string
webhookConfiguration:
description: |-
@@ -3857,13 +3850,6 @@ spec:
If set to true, migrations will still start in pre-copy, but switch to post-copy when
CompletionTimeoutPerGiB triggers. Defaults to false
type: boolean
allowWorkloadDisruption:
description: |-
AllowWorkloadDisruption indicates that the migration shouldn't be
canceled after acceptableCompletionTime is exceeded. Instead, if
permitted, migration will be switched to post-copy or the VMI will be
paused to allow the migration to complete
type: boolean
bandwidthPerMigration:
anyOf:
- type: integer
@@ -3876,8 +3862,8 @@ spec:
completionTimeoutPerGiB:
description: |-
CompletionTimeoutPerGiB is the maximum number of seconds per GiB a migration is allowed to take.
If the timeout is reached, the migration will be either paused, switched
to post-copy or cancelled depending on other settings. Defaults to 150
If a live-migration takes longer to migrate than this value multiplied by the size of the VMI,
the migration will be cancelled, unless AllowPostCopy is true. Defaults to 150
format: int64
type: integer
disableTLS:
@@ -4235,17 +4221,17 @@ spec:
type: object
type: object
vmRolloutStrategy:
description: |-
VMRolloutStrategy defines how live-updatable fields, like CPU sockets, memory,
tolerations, and affinity, are propagated from a VM to its VMI.
description: VMRolloutStrategy defines how changes to a VM object
propagate to its VMI
enum:
- Stage
- LiveUpdate
nullable: true
type: string
vmStateStorageClass:
description: VMStateStorageClass is the name of the storage class
to use for the PVCs created to preserve VM state, like TPM.
description: |-
VMStateStorageClass is the name of the storage class to use for the PVCs created to preserve VM state, like TPM.
The storage class must support RWX in filesystem mode.
type: string
webhookConfiguration:
description: |-

View File

@@ -608,7 +608,6 @@ rules:
resources:
- virtualmachinesnapshots
- virtualmachinesnapshots/status
- virtualmachinesnapshots/finalizers
- virtualmachinesnapshotcontents
- virtualmachinesnapshotcontents/status
- virtualmachinesnapshotcontents/finalizers
@@ -661,18 +660,15 @@ rules:
- kubevirt.io
resources:
- virtualmachines/finalizers
- virtualmachineinstances/finalizers
verbs:
- update
- apiGroups:
- subresources.kubevirt.io
resources:
- virtualmachines/stop
- virtualmachineinstances/addvolume
- virtualmachineinstances/removevolume
- virtualmachineinstances/freeze
- virtualmachineinstances/unfreeze
- virtualmachineinstances/reset
- virtualmachineinstances/softreboot
- virtualmachineinstances/sev/setupsession
- virtualmachineinstances/sev/injectlaunchsecret
@@ -776,14 +772,6 @@ rules:
verbs:
- list
- watch
- apiGroups:
- batch
resources:
- jobs
verbs:
- create
- get
- delete
- apiGroups:
- kubevirt.io
resources:
@@ -895,7 +883,6 @@ rules:
- virtualmachineinstances/freeze
- virtualmachineinstances/unfreeze
- virtualmachineinstances/softreboot
- virtualmachineinstances/reset
- virtualmachineinstances/sev/setupsession
- virtualmachineinstances/sev/injectlaunchsecret
verbs:
@@ -915,6 +902,7 @@ rules:
- virtualmachines/restart
- virtualmachines/addvolume
- virtualmachines/removevolume
- virtualmachines/migrate
- virtualmachines/memorydump
verbs:
- update
@@ -931,6 +919,7 @@ rules:
- virtualmachineinstances
- virtualmachineinstancepresets
- virtualmachineinstancereplicasets
- virtualmachineinstancemigrations
verbs:
- get
- delete
@@ -940,14 +929,6 @@ rules:
- list
- watch
- deletecollection
- apiGroups:
- kubevirt.io
resources:
- virtualmachineinstancemigrations
verbs:
- get
- list
- watch
- apiGroups:
- snapshot.kubevirt.io
resources:
@@ -1051,7 +1032,6 @@ rules:
- virtualmachineinstances/freeze
- virtualmachineinstances/unfreeze
- virtualmachineinstances/softreboot
- virtualmachineinstances/reset
- virtualmachineinstances/sev/setupsession
- virtualmachineinstances/sev/injectlaunchsecret
verbs:
@@ -1071,6 +1051,7 @@ rules:
- virtualmachines/restart
- virtualmachines/addvolume
- virtualmachines/removevolume
- virtualmachines/migrate
- virtualmachines/memorydump
verbs:
- update
@@ -1087,6 +1068,7 @@ rules:
- virtualmachineinstances
- virtualmachineinstancepresets
- virtualmachineinstancereplicasets
- virtualmachineinstancemigrations
verbs:
- get
- delete
@@ -1095,14 +1077,6 @@ rules:
- patch
- list
- watch
- apiGroups:
- kubevirt.io
resources:
- virtualmachineinstancemigrations
verbs:
- get
- list
- watch
- apiGroups:
- snapshot.kubevirt.io
resources:
@@ -1281,25 +1255,6 @@ rules:
- get
- list
- watch
- apiGroups:
- subresources.kubevirt.io
resources:
- virtualmachines/migrate
verbs:
- update
- apiGroups:
- kubevirt.io
resources:
- virtualmachineinstancemigrations
verbs:
- get
- delete
- create
- update
- patch
- list
- watch
- deletecollection
- apiGroups:
- authentication.k8s.io
resources:
@@ -1345,8 +1300,6 @@ spec:
type: RollingUpdate
template:
metadata:
annotations:
openshift.io/required-scc: restricted-v2
labels:
kubevirt.io: virt-operator
name: virt-operator

View File

@@ -1,6 +1,6 @@
operator:
image: registry.suse.com/suse/sles/15.7/virt-operator
version: 1.5.2-150700.3.5.2
image: registry.suse.com/suse/sles/15.6/virt-operator
version: 1.4.0-150600.5.15.1
replicas: 2
pullPolicy: IfNotPresent
affinity:
@@ -40,7 +40,7 @@ kubevirt:
monitorAccount: ""
monitorNamespace: ""
hookImage: registry.rancher.com/rancher/kubectl:v1.33.1
hookImage: registry.rancher.com/rancher/kubectl:v1.30.10
hookRestartPolicy: OnFailure
hookSecurityContext:
seccompProfile:

View File

@@ -1,5 +1,5 @@
#!BuildTag: %%CHART_PREFIX%%kubevirt-dashboard-extension:%%CHART_MAJOR%%.0.3_up1.3.2
#!BuildTag: %%CHART_PREFIX%%kubevirt-dashboard-extension:%%CHART_MAJOR%%.0.3_up1.3.2-%RELEASE%
#!BuildTag: %%CHART_PREFIX%%kubevirt-dashboard-extension:%%CHART_MAJOR%%.0.2_up1.3.2
#!BuildTag: %%CHART_PREFIX%%kubevirt-dashboard-extension:%%CHART_MAJOR%%.0.2_up1.3.2-%RELEASE%
annotations:
catalog.cattle.io/certified: rancher
catalog.cattle.io/namespace: cattle-ui-plugin-system
@@ -12,10 +12,10 @@ annotations:
catalog.cattle.io/ui-extensions-version: '>= 3.0.2 < 4.0.0'
catalog.cattle.io/kube-version: '>= v1.26.0-0'
apiVersion: v2
appVersion: 304.0.3+up1.3.2
appVersion: 303.0.2+up1.3.2
description: 'SUSE Edge: KubeVirt extension for Rancher Dashboard'
name: kubevirt-dashboard-extension
type: application
version: "%%CHART_MAJOR%%.0.3+up1.3.2"
version: "%%CHART_MAJOR%%.0.2+up1.3.2"
icon: >-
https://raw.githubusercontent.com/cncf/artwork/master/projects/kubevirt/icon/color/kubevirt-icon-color.svg

View File

@@ -8,7 +8,7 @@ spec:
plugin:
name: {{ include "extension-server.fullname" . }}
version: {{ (semver (default .Chart.AppVersion .Values.plugin.versionOverride)).Original }}
endpoint: https://raw.githubusercontent.com/suse-edge/dashboard-extensions/gh-pages/extensions/kubevirt-dashboard-extension/304.0.3+up1.3.2
endpoint: https://raw.githubusercontent.com/suse-edge/dashboard-extensions/gh-pages/extensions/kubevirt-dashboard-extension/303.0.2+up1.3.2
noCache: {{ .Values.plugin.noCache }}
noAuth: {{ .Values.plugin.noAuth }}
metadata: {{ include "extension-server.pluginMetadata" . | indent 6 }}

View File

@@ -1,28 +1,28 @@
#!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.10_up0.12.0
#!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.10_up0.12.0-%RELEASE%
apiVersion: v2
appVersion: 0.12.9
appVersion: 0.12.0
dependencies:
- alias: metal3-baremetal-operator
name: baremetal-operator
repository: file://./charts/baremetal-operator
version: 0.10.4
version: 0.9.2
- alias: metal3-ironic
name: ironic
repository: file://./charts/ironic
version: 0.11.6
version: 0.11.0
- alias: metal3-mariadb
condition: global.enable_mariadb
name: mariadb
repository: file://./charts/mariadb
version: 0.6.1
version: 0.6.0
- alias: metal3-media
condition: global.enable_metal3_media_server
name: media
repository: file://./charts/media
version: 0.7.1
version: 0.6.4
description: A Helm chart that installs all of the dependencies needed for Metal3
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.10+up0.12.0"

View File

@@ -1,6 +1,6 @@
apiVersion: v2
appVersion: 0.10.2
appVersion: 0.9.1
description: A Helm chart for baremetal-operator, used by Metal3
name: baremetal-operator
type: application
version: 0.10.4
version: 0.9.2

View File

@@ -202,11 +202,6 @@ spec:
description: Description is a human-entered text used to help identify
the host.
type: string
disablePowerOff:
description: |-
When set to true, power off of the node will be disabled,
instead, a reboot will be used in place of power on/off
type: boolean
externallyProvisioned:
description: |-
ExternallyProvisioned means something else has provisioned the

View File

@@ -61,19 +61,3 @@ Create the name of the service account to use
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create the URL to use for connecting to the Ironic servers (e.g. API, cache)
*/}}
{{- define "baremetal-operator.ironicHttpHost" -}}
{{- $hostIP := include "metal3.hostIP" . -}}
{{- with .Values.global }}
{{- if .provisioningHostname }}
{{- .provisioningHostname }}
{{- else if regexMatch ".*:.*" $hostIP}}
{{- print "[" $hostIP "]" }}
{{- else }}
{{- $hostIP }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -1,18 +1,19 @@
{{- $enableTLS := .Values.global.enable_tls }}
{{- $enableVMediaTLS := .Values.global.enable_vmedia_tls }}
{{- $protocol := ternary "https" "http" $enableTLS }}
{{- $ironicHost := include "baremetal-operator.ironicHttpHost" . | required "Missing host information for BMO to connect to Ironic" }}
{{- $ironicApiHost := print $ironicHost ":6385" }}
{{- $ironicBootHost := print $ironicHost ":6180" }}
{{- $ironicCacheHost := print $ironicHost ":6180" }}
{{- $ironicIP := .Values.global.ironicIP | default "" }}
{{- $ironicApiHost := print $ironicIP ":6385" }}
{{- $ironicBootHost := print $ironicIP ":6180" }}
{{- $ironicCacheHost := print $ironicIP ":6180" }}
{{- $deployArch := .Values.global.deployArchitecture }}
apiVersion: v1
data:
IRONIC_ENDPOINT: "{{ $protocol }}://{{ $ironicApiHost }}/v1/"
# Switch VMedia to HTTP if enable_vmedia_tls is false
{{- if and $enableTLS $enableVMediaTLS }}
{{- $ironicBootHost = print $ironicHost ":" .Values.global.vmediaTLSPort }}
{{- $ironicCacheHost = print $ironicHost ":" .Values.global.vmediaTLSPort }}
{{- $ironicBootHost = print $ironicIP ":" .Values.global.vmediaTLSPort }}
{{- $ironicCacheHost = print $ironicIP ":" .Values.global.vmediaTLSPort }}
{{- $protocol = "https" }}
RESTART_CONTAINER_CERTIFICATE_UPDATED: "true"
{{- else }}
@@ -20,10 +21,9 @@ data:
RESTART_CONTAINER_CERTIFICATE_UPDATED: "false"
{{- end }}
CACHEURL: "{{ $protocol }}://{{ $ironicCacheHost }}/images"
{{- if .Values.baremetaloperator.externalHttpIPv6 }}
{{- $port := ternary .Values.global.vmediaTLSPort .Values.baremetaloperator.httpPort $enableVMediaTLS }}
IRONIC_EXTERNAL_URL_V6: "{{ $protocol }}://[{{ .Values.baremetaloperator.externalHttpIPv6 }}]:{{ $port }}"
{{- end }}
DEPLOY_KERNEL_URL: "{{ $protocol }}://{{ $ironicBootHost }}/images/ironic-python-agent-{{ $deployArch }}.kernel"
DEPLOY_RAMDISK_URL: "{{ $protocol }}://{{ $ironicBootHost }}/images/ironic-python-agent-{{ $deployArch }}.initramfs"
DEPLOY_ARCHITECTURE: "{{ $deployArch }}"
kind: ConfigMap
metadata:
name: baremetal-operator-ironic

View File

@@ -6,7 +6,6 @@ metadata:
control-plane: controller-manager
name: {{ include "baremetal-operator.fullname" . }}-controller-manager-metrics-service
spec:
ipFamilyPolicy: PreferDualStack
ports:
- name: https
port: 8443

View File

@@ -5,7 +5,6 @@ metadata:
{{- include "baremetal-operator.labels" . | nindent 4 }}
name: {{ include "baremetal-operator.fullname" . }}-webhook-service
spec:
ipFamilyPolicy: PreferDualStack
ports:
- port: 443
targetPort: 9443

View File

@@ -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.9.1.1"
imagePullSecrets: []
nameOverride: "manger"
@@ -84,8 +84,3 @@ affinity: {}
baremetaloperator:
httpPort: "6180"
# IPv6 used for accessing the Ironic HTTP server for BMCs with an IPv6 only address.
# It should not be used in conjunction with 'provisioningHostname' unless BMCs do not
# support hostnames.
externalHttpIPv6: ""

View File

@@ -3,4 +3,4 @@ appVersion: 29.0.4
description: A Helm chart for Ironic, used by Metal3
name: ironic
type: application
version: 0.11.6
version: 0.11.0

View File

@@ -83,50 +83,3 @@ Get ironic CA volumeMounts
readOnly: true
{{- end }}
{{- end }}
{{/*
Get the formatted "External" hostname or IP based URL
*/}}
{{- define "ironic.externalHttpUrl" }}
{{- $host := ternary (include "metal3.hostIP" .) .Values.global.externalHttpHost (empty .Values.global.externalHttpHost) }}
{{- if regexMatch ".*:.*" $host }}
{{- $host = print "[" $host "]" }}
{{- end }}
{{- $protocol := "http" }}
{{- $port := "6180" }}
{{- if .Values.global.enable_vmedia_tls }}
{{- $protocol = "https" }}
{{- $port = .Values.global.vmediaTLSPort | default "6185" }}
{{- end }}
{{- print $protocol "://" $host ":" $port }}
{{- end }}
{{/*
Get the command to use for Liveness and Readiness probes
*/}}
{{- define "ironic.probeCommand" }}
{{- $host := "127.0.0.1" }}
{{- if eq .Values.listenOnAll false }}
{{- $host = coalesce .Values.global.provisioningIP .Values.global.ironicIP .Values.global.provisioningHostname }}
{{- if regexMatch ".*:.*" $host }}
{{- $host = print "[" $host "]" }}
{{- end }}
{{- end }}
{{- print "curl -sSfk https://" $host ":6385" }}
{{- end }}
{{/*
Create the subjectAltNames section to be set on the Certificate
*/}}
{{- define "ironic.subjectAltNames" -}}
{{- with .Values.global }}
{{- if .provisioningHostname }}
dnsNames:
- {{ .provisioningHostname }}
{{- end -}}
{{- if or .ironicIP .provisioningIP }}
ipAddresses:
- {{ coalesce .provisioningIP .ironicIP }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -6,7 +6,8 @@ metadata:
spec:
commonName: ironic-ca
isCA: true
{{- include "ironic.subjectAltNames" . | indent 2 }}
ipAddresses:
- {{ .Values.global.ironicIP }}
issuerRef:
kind: Issuer
name: selfsigned-issuer
@@ -18,7 +19,8 @@ metadata:
name: ironic-cert
spec:
commonName: ironic-cert
{{- include "ironic.subjectAltNames" . | indent 2 }}
ipAddresses:
- {{ .Values.global.ironicIP }}
issuerRef:
kind: Issuer
name: ca-issuer
@@ -31,7 +33,8 @@ metadata:
name: ironic-vmedia-cert
spec:
commonName: ironic-vmedia-cert
{{- include "ironic.subjectAltNames" . | indent 2 }}
ipAddresses:
- {{ .Values.global.ironicIP }}
issuerRef:
kind: Issuer
name: ca-issuer

View File

@@ -5,7 +5,16 @@ metadata:
labels:
{{- include "ironic.labels" . | nindent 4 }}
data:
{{- $enableTLS := .Values.global.enable_tls }}
{{- $enableVMediaTLS := .Values.global.enable_vmedia_tls }}
{{- $protocol := ternary "https" "http" $enableTLS }}
{{- $ironicIP := .Values.global.ironicIP | default "" }}
{{- $ironicBootHost := print $ironicIP ":6180" }}
{{- $ironicCacheHost := print $ironicIP ":6180" }}
{{- $deployArch := .Values.global.deployArchitecture }}
{{- if ( .Values.global.enable_dnsmasq ) }}
DNSMASQ_BOOT_SERVER_ADDRESS: {{ $ironicBootHost }}
DNSMASQ_DNS_SERVER_ADDRESS: {{ .Values.global.dnsmasqDNSServer }}
DNSMASQ_DEFAULT_ROUTER: {{ .Values.global.dnsmasqDefaultRouter }}
DHCP_RANGE: {{ .Values.global.dhcpRange }}
@@ -15,20 +24,29 @@ data:
{{- end }}
HTTP_PORT: "6180"
PREDICTABLE_NIC_NAMES: "{{ .Values.global.predictableNicNames }}"
IRONIC_EXTERNAL_HTTP_URL: {{ include "ironic.externalHttpUrl" . }}
# Switch VMedia to HTTP if enable_vmedia_tls is false
{{- if and $enableTLS $enableVMediaTLS }}
{{- $ironicBootHost = print $ironicIP ":" .Values.global.vmediaTLSPort }}
{{- $ironicCacheHost = print $ironicIP ":" .Values.global.vmediaTLSPort }}
{{- $protocol = "https" }}
{{- else }}
{{- $protocol = "http" }}
{{- end }}
IRONIC_EXTERNAL_HTTP_URL: {{ $protocol }}://{{ $ironicCacheHost }}
DEPLOY_ARCHITECTURE: {{ $deployArch }}
IRONIC_BOOT_BASE_URL: {{ $protocol }}://{{ $ironicBootHost }}
ENABLE_PXE_BOOT: "{{ .Values.global.enable_pxe_boot }}"
{{- if .Values.global.provisioningInterface }}
PROVISIONING_INTERFACE: {{ .Values.global.provisioningInterface }}
{{- end }}
{{- if .Values.global.provisioningIP }}
PROVISIONING_IP: {{ include "metal3.hostIP" . }}
{{- else if .Values.global.ironicIP }}
IRONIC_IP: {{ include "metal3.hostIP" . }}
{{- else if .Values.global.provisioningHostname }}
IRONIC_URL_HOSTNAME: {{ .Values.global.provisioningHostname }}
PROVISIONING_IP: {{ .Values.global.provisioningIP }}
{{- end }}
IRONIC_FAST_TRACK: "true"
LISTEN_ALL_INTERFACES: "{{ .Values.listenOnAll }}"
LISTEN_ALL_INTERFACES: "true"
{{- if .Values.global.ironicIP }}
IRONIC_IP: {{ .Values.global.ironicIP }}
{{- end }}
{{- if ( .Values.global.enable_tls ) }}
RESTART_CONTAINER_CERTIFICATE_UPDATED: "true"
IRONIC_KERNEL_PARAMS: {{ .Values.global.ironicKernelParams }} tls.enabled=true
@@ -52,6 +70,3 @@ data:
{{- else }}
IRONIC_USE_MARIADB: "false"
{{- end }}
{{- with .Values.ironicExtraEnv -}}
{{ toYaml . | nindent 2 }}
{{- end -}}

View File

@@ -42,7 +42,7 @@ spec:
name: ironic
livenessProbe:
exec:
command: ["sh", "-c", "{{ include "ironic.probeCommand" . }}"]
command: ["sh", "-c", "curl -sSfk https://127.0.0.1:6385"]
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
@@ -60,7 +60,7 @@ spec:
{{- end }}
readinessProbe:
exec:
command: ["sh", "-c", "{{ include "ironic.probeCommand" . }}"]
command: ["sh", "-c", "curl -sSfk https://127.0.0.1:6385"]
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30

View File

@@ -10,7 +10,6 @@ metadata:
{{- end }}
spec:
type: {{ .Values.service.type }}
ipFamilyPolicy: PreferDualStack
ports:
{{- $enableTLS := .Values.global.enable_tls }}
{{- $enableVMediaTLS := .Values.global.enable_vmedia_tls }}

View File

@@ -32,12 +32,6 @@ global:
# IP Address assigned to network interface on provisioning network
provisioningIP: ""
# Fully Qualified Domain Name used by Ironic for both binding (to the
# associated IPv4 and/or IPv6 addresses) and exposing the API, dnsmask and
# media, also used by BMO. Note, this is the only way to enable a fully
# working dual-stack configuration.
provisioningHostname: ""
# Whether the NIC names should be predictable or not
predictableNicNames: "true"
@@ -58,17 +52,15 @@ global:
replicaCount: 1
listenOnAll: true
images:
ironic:
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic
pullPolicy: IfNotPresent
tag: 29.0.4.4
tag: 29.0.4.0
ironicIPADownloader:
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic-ipa-downloader
pullPolicy: IfNotPresent
tag: 3.0.10
tag: 3.0.8
nameOverride: ""
fullnameOverride: ""
@@ -138,8 +130,6 @@ baremetaloperator:
debug:
ironicRamdiskSshKey: ""
ironicExtraEnv: {}
tlscerts:
cacert: ""
key: ""

View File

@@ -3,4 +3,4 @@ appVersion: "10.11"
description: A Helm chart for MariaDB, used by Metal3
name: mariadb
type: application
version: 0.6.1
version: 0.6.0

View File

@@ -5,11 +5,10 @@ metadata:
labels:
{{- include "mariadb.labels" . | nindent 4 }}
spec:
ipFamilyPolicy: PreferDualStack
type: {{ .Values.service.type }}
selector:
{{- include "mariadb.selectorLabels" . | nindent 4 }}
ports:
{{- with .Values.service.ports }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end }}

View File

@@ -1,6 +1,6 @@
apiVersion: v2
appVersion: 1.21.0
appVersion: 1.16.0
description: A Helm chart for Media, used by Metal3
name: media
type: application
version: 0.7.1
version: 0.6.4

View File

@@ -34,9 +34,13 @@ spec:
{{- end }}
containers:
- name: {{ .Chart.Name }}
command:
- /usr/sbin/httpd
args:
- -DFOREGROUND
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http

View File

@@ -5,7 +5,6 @@ metadata:
labels:
{{- include "media.labels" . | nindent 4 }}
spec:
ipFamilyPolicy: PreferDualStack
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}

View File

@@ -22,9 +22,9 @@ global:
replicaCount: 1
image:
repository: registry.suse.com/suse/nginx
repository: registry.opensuse.org/isv/suse/edge/metal3/containers/images/ironic
pullPolicy: IfNotPresent
tag: 1.21
tag: 29.0.4.0
imagePullSecrets: []
nameOverride: ""
@@ -42,8 +42,8 @@ serviceAccount:
podAnnotations: {}
podSecurityContext:
runAsUser: 499
fsGroup: 486
runAsUser: 10475
fsGroup: 10475
securityContext:
allowPrivilegeEscalation: false
@@ -102,16 +102,11 @@ volumes:
- name: assets
persistentVolumeClaim:
claimName: media
- name: run
emptyDir:
sizeLimit: 10Mi
# volume mounts
volumeMounts:
- mountPath: /srv/www/htdocs
name: assets
- mountPath: /run
name: run
# media volume settings
mediaVolume:

View File

@@ -60,18 +60,3 @@ Create the name of the service account to use
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Produce the correct IP or hostname for Ironic provisioning
*/}}
{{- define "metal3.hostIP" -}}
{{- with .Values.global }}
{{- if and .provisioningHostname (or .provisioningIP .ironicIP) }}
{{ fail "Please provide either provisioningHostname or provisioningIP or ironicIP" }}
{{- end }}
{{- if and .provisioningIP .ironicIP }}
{{ fail "Please provide either ironicIP or provisioningIP" }}
{{- end }}
{{- coalesce .provisioningIP .ironicIP }}
{{- end }}
{{- end }}

View File

@@ -60,18 +60,12 @@ global:
# IP Address assigned to network interface on provisioning network
provisioningIP: ""
# Fully Qualified Domain Name used by Ironic for both binding (to the
# associated IPv4 and/or IPv6 addresses) and exposing the API, dnsmask and
# media, also used by BMO. Note, this is the only way to enable a fully
# working dual-stack configuration.
provisioningHostname: ""
# Hostname or IP for accessing the Ironic API server from a non-provisioning network
externalHttpHost: ""
# Name for the MariaDB service
databaseServiceName: metal3-mariadb
# Architecture for deployed nodes (either x86_64 or arm64)
deployArchitecture: x86_64
# In a multi-node cluster use the node selector to ensure the pods
# all run on the same host where the dnsmasqDNSServer and provisioningIP
# and /opt/media exist. Uncomment the nodeSelector and update the

View File

@@ -1,31 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
#!BuildTag: %%IMG_PREFIX%%nessie:%%nessie_version%%
#!BuildTag: %%IMG_PREFIX%%nessie:%%nessie_version%%-%RELEASE%
ARG SLE_VERSION
FROM registry.suse.com/bci/bci-base:$SLE_VERSION
# labelprefix=com.suse.application.nessie
LABEL org.opencontainers.image.title="nessie"
LABEL org.opencontainers.image.description="Nessie diagnostic tool for SUSE Kubernetes environments"
LABEL org.opencontainers.image.version="%%nessie_version%%"
LABEL org.opencontainers.image.authors="George Agriogiannis <george.agriogiannis2@suse.com>"
LABEL org.opencontainers.image.url="https://github.com/suse-edge/support-tools/tree/main/nessie"
LABEL org.opencontainers.image.vendor="SUSE LLC"
LABEL org.opencontainers.image.created="%BUILDTIME%"
LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%nessie:%%nessie_version%%-%RELEASE%"
LABEL org.openbuildservice.disturl="%DISTURL%"
LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
LABEL com.suse.eula="SUSE Combined EULA February 2024"
LABEL com.suse.lifecycle-url="https://www.suse.com/lifecycle"
LABEL com.suse.image-type="application"
LABEL com.suse.release-stage="released"
# endlabelprefix
RUN zypper --non-interactive refresh && \
zypper --non-interactive install --no-recommends nessie && \
zypper clean
WORKDIR /tmp
ENTRYPOINT ["/usr/bin/nessie"]

View File

@@ -1,19 +0,0 @@
<services>
<service mode="buildtime" name="kiwi_metainfo_helper"/>
<service mode="buildtime" name="docker_label_helper"/>
<service name="replace_using_package_version" mode="buildtime">
<param name="file">Dockerfile</param>
<param name="regex">%%nessie_version%%</param>
<param name="package">nessie</param>
<param name="parse-version">patch</param>
</service>
<service name="replace_using_env" mode="buildtime">
<param name="file">Dockerfile</param>
<param name="eval">IMG_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?img_prefix})</param>
<param name="var">IMG_PREFIX</param>
<param name="eval">IMG_REPO=$(rpm --macros=/root/.rpmmacros -E %img_repo)</param>
<param name="var">IMG_REPO</param>
<param name="eval">SUPPORT_LEVEL=$(rpm --macros=/root/.rpmmacros -E %support_level)</param>
<param name="var">SUPPORT_LEVEL</param>
</service>
</services>

View File

@@ -1,26 +0,0 @@
<services>
<service name="obs_scm">
<param name="url">https://github.com/suse-edge/support-tools</param>
<param name="scm">git</param>
<param name="revision">nessie-v1.0.0</param>
<param name="version">_auto_</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="changesgenerate">enable</param>
<param name="changesauthor">george.agriogiannis2@suse.com</param>
<param name="match-tag">nessie-v*</param>
<param name="versionrewrite-pattern">nessie-v(\d+\.\d+\.\d+)</param>
<param name="versionrewrite-replacement">\1</param>
<param name="subdir">nessie</param>
<param name="exclude">.git</param>
<param name="without-version">yes</param>
<param name="filename">nessie</param>
</service>
<service mode="buildtime" name="tar">
<param name="obsinfo">nessie.obsinfo</param>
</service>
<service mode="buildtime" name="recompress">
<param name="file">*.tar</param>
<param name="compression">gz</param>
</service>
<service mode="buildtime" name="set_version" />
</services>

View File

@@ -1,80 +0,0 @@
#
# spec file for package nessie
#
# Copyright (c) 2024 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
Name: nessie
# Version will be set automatically by factory's set_version service
Version: 1.0.0
Release: 0
Summary: Node Environment Support Script for Inspection and Export
License: Apache-2.0
Group: System/Management
URL: https://github.com/suse-edge/support-tools/tree/main/nessie
Source0: %{name}-%{version}.tar.gz
BuildArch: noarch
# Build dependencies
BuildRequires: python3-devel
# Runtime dependencies
Requires: python3
Requires: python3-kubernetes
Requires: python3-PyYAML
Requires: helm
Requires: systemd
# Optional dependencies for enhanced functionality
Recommends: util-linux
%description
Nessie (Node Environment Support Script for Inspection and Export) is a
comprehensive diagnostic tool for SUSE Kubernetes environments. It collects
logs, configurations, and system information from Kubernetes clusters for
troubleshooting and support purposes.
Key features:
- Collects system service logs and Kubernetes pod logs
- Gathers cluster configurations and Helm releases
- Retrieves node metrics and component versions
- Supports RKE2 and K3s environments
- Fault-tolerant with configurable options
- Can be run directly or as a container
The tool is designed specifically for SUSE Edge environments and integrates
well with SUSE Linux Micro, RKE2, and K3s distributions.
%prep
%autosetup
%build
# Validate Python syntax
python3 -m py_compile nessie.py
%install
# Install the main script
install -D -m 0755 nessie.py %{buildroot}%{_bindir}/nessie
# Install documentation files
install -D -m 0644 README.md %{buildroot}%{_docdir}/%{name}/README.md
install -D -m 0644 LICENSE %{buildroot}%{_docdir}/%{name}/LICENSE
%files
%{_bindir}/nessie
%dir %{_docdir}/%{name}
%doc %{_docdir}/%{name}/README.md
%license %{_docdir}/%{name}/LICENSE
%changelog

View File

@@ -3,7 +3,7 @@
<param name="url">https://github.com/suse-edge/nm-configurator.git</param>
<param name="versionformat">@PARENT_TAG@</param>
<param name="scm">git</param>
<param name="revision">v0.3.5</param>
<param name="revision">v0.3.3</param>
<param name="match-tag">*</param>
<param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param>
<param name="versionrewrite-replacement">\1</param>

View File

@@ -1,4 +1,4 @@
<servicedata>
<service name="tar_scm">
<param name="url">https://github.com/suse-edge/nm-configurator.git</param>
<param name="changesrevision">0beb66b463e99dd2bf2379cd2e7c0ba9fafd9f9b</param></service></servicedata>
<param name="changesrevision">4563857d761c6d83e4013721f68ec4ac5828a1a7</param></service></servicedata>

Binary file not shown.

View File

@@ -1,4 +1,4 @@
name: nm-configurator
version: 0.3.5
mtime: 1764154195
commit: 0beb66b463e99dd2bf2379cd2e7c0ba9fafd9f9b
version: 0.3.3
mtime: 1748341626
commit: 4563857d761c6d83e4013721f68ec4ac5828a1a7

Binary file not shown.

Submodule python-executing deleted from ac466db0b5

Submodule python-flit-core deleted from 4362b05ea3

Submodule python-pydantic deleted from f19a5a780f

View File

@@ -1,39 +0,0 @@
From 2e89940b44d4be1d115aed987b4c610ed7173d66 Mon Sep 17 00:00:00 2001
From: e-minguez <e.minguez@gmail.com>
Date: Tue, 2 Sep 2025 18:03:50 +0200
Subject: [PATCH] fix: Allow icon metadata to be file
Fix #34
---
pyhelm3/models.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/pyhelm3/models.py b/pyhelm3/models.py
index d03fdc6..adb2c88 100644
--- a/pyhelm3/models.py
+++ b/pyhelm3/models.py
@@ -14,6 +14,7 @@
FilePath,
AnyUrl as PydanticAnyUrl,
HttpUrl as PydanticHttpUrl,
+ FileUrl as PydanticFileUrl,
constr,
field_validator
)
@@ -65,6 +66,7 @@ def validate_str_as(validate_type):
#: Annotated string types for URLs
AnyUrl = t.Annotated[str, AfterValidator(validate_str_as(PydanticAnyUrl))]
HttpUrl = t.Annotated[str, AfterValidator(validate_str_as(PydanticHttpUrl))]
+FileUrl = t.Annotated[str, AfterValidator(validate_str_as(PydanticFileUrl))]
class ChartDependency(BaseModel):
@@ -173,7 +175,7 @@ class ChartMetadata(BaseModel):
default_factory = list,
description = "List of maintainers for the chart."
)
- icon: t.Optional[HttpUrl] = Field(
+ icon: t.Optional[HttpUrl | FileUrl] = Field(
None,
description = "URL to an SVG or PNG image to be used as an icon."
)

View File

@@ -1,3 +0,0 @@
<services>
<service name="download_assets"></service>
</services>

View File

@@ -1,58 +0,0 @@
#
# spec file for package python-pyhelm3
#
# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
Name: python-pyhelm3
Version: 0.4.0
Release: 1
Summary: Python library for managing Helm releases using Helm 3
License: Apache-2.0
URL: https://github.com/azimuth-cloud/pyhelm3
#!RemoteAsset
Source: https://files.pythonhosted.org/packages/source/p/pyhelm3/pyhelm3-%{version}.tar.gz
# Allow icon metadata to be file:// as well as http/https://
# https://github.com/azimuth-cloud/pyhelm3/pull/35
Patch: 0001-icon-metadata-allow-fileurl.patch
BuildRequires: python-rpm-macros
BuildRequires: %{python_module pip}
BuildRequires: %{python_module setuptools >= 42}
BuildRequires: %{python_module setuptools_scm >= 3.4}
BuildRequires: %{python_module wheel}
BuildRequires: fdupes
Requires: %{python_module pydantic}
Requires: %{python_module PyYAML}
BuildArch: noarch
%python_subpackages
%description
Python library for managing Helm releases using Helm 3.
%prep
%autosetup -p1 -n pyhelm3-%{version}
%build
%pyproject_wheel
%install
%pyproject_install
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%files %{python_files}
%doc README.md
%license LICENSE
%{python_sitelib}/pyhelm3
%{python_sitelib}/pyhelm3-%{version}.dist-info
%changelog

View File

@@ -1,3 +0,0 @@
<services>
<service name="download_assets"></service>
</services>

View File

@@ -1,45 +0,0 @@
From 08be21dadfd2ce9e96e41e366ab38bd8d7cd0e39 Mon Sep 17 00:00:00 2001
From: Dan Lazin <dlazin@users.noreply.github.com>
Date: Tue, 7 Jan 2025 16:04:56 -0500
Subject: [PATCH] Fix test that changed with Pygments 2.19.
---
tests/test_markdown.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: rich-13.9.4/tests/test_markdown.py
===================================================================
--- rich-13.9.4.orig/tests/test_markdown.py
+++ rich-13.9.4/tests/test_markdown.py
@@ -110,7 +110,7 @@ def test_inline_code():
inline_code_theme="emacs",
)
result = render(markdown)
- expected = "inline \x1b[1;38;2;170;34;255;48;2;248;248;248mimport\x1b[0m\x1b[38;2;0;0;0;48;2;248;248;248m \x1b[0m\x1b[1;38;2;0;0;255;48;2;248;248;248mthis\x1b[0m code \n"
+ expected = "inline \x1b[1;38;2;170;34;255;48;2;248;248;248mimport\x1b[0m\x1b[38;2;187;187;187;48;2;248;248;248m \x1b[0m\x1b[1;38;2;0;0;255;48;2;248;248;248mthis\x1b[0m code \n"
print(result)
print(repr(result))
assert result == expected
Index: rich-13.9.4/tests/test_syntax.py
===================================================================
--- rich-13.9.4.orig/tests/test_syntax.py
+++ rich-13.9.4/tests/test_syntax.py
@@ -53,7 +53,7 @@ def test_blank_lines():
print(repr(result))
assert (
result
- == "\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m1 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m2 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m3 \x1b[0m\x1b[1;38;2;0;128;0;48;2;248;248;248mimport\x1b[0m\x1b[38;2;0;0;0;48;2;248;248;248m \x1b[0m\x1b[1;38;2;0;0;255;48;2;248;248;248mthis\x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m4 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m5 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n"
+ == "\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m1 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m2 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m3 \x1b[0m\x1b[1;38;2;0;128;0;48;2;248;248;248mimport\x1b[0m\x1b[38;2;187;187;187;48;2;248;248;248m \x1b[0m\x1b[1;38;2;0;0;255;48;2;248;248;248mthis\x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m4 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m5 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n"
)
@@ -119,7 +119,7 @@ def test_python_render_simple_indent_gui
)
rendered_syntax = render(syntax)
print(repr(rendered_syntax))
- expected = '\x1b[34mdef\x1b[0m \x1b[32mloop_first_last\x1b[0m(values: Iterable[T]) -> Iterable[Tuple[\x1b[36mb\x1b[0m\n\x1b[2;37m│ \x1b[0m\x1b[33m"""Iterate and generate a tuple with a flag for first an\x1b[0m\n\x1b[2m│ \x1b[0miter_values = \x1b[36miter\x1b[0m(values)\n\x1b[2m│ \x1b[0m\x1b[34mtry\x1b[0m:\n\x1b[2m│ │ \x1b[0mprevious_value = \x1b[36mnext\x1b[0m(iter_values)\n\x1b[2m│ \x1b[0m\x1b[34mexcept\x1b[0m \x1b[36mStopIteration\x1b[0m:\n\x1b[2m│ │ \x1b[0m\x1b[34mreturn\x1b[0m\n\x1b[2m│ \x1b[0mfirst = \x1b[34mTrue\x1b[0m\n\x1b[2m│ \x1b[0m\x1b[34mfor\x1b[0m value \x1b[35min\x1b[0m iter_values:\n\x1b[2m│ │ \x1b[0m\x1b[34myield\x1b[0m first, \x1b[34mFalse\x1b[0m, previous_value\n\x1b[2m│ │ \x1b[0mfirst = \x1b[34mFalse\x1b[0m\n\x1b[2m│ │ \x1b[0mprevious_value = value\n\x1b[2m│ \x1b[0m\x1b[34myield\x1b[0m first, \x1b[34mTrue\x1b[0m, previous_value\n'
+ expected = '\x1b[34mdef\x1b[0m\x1b[37m \x1b[0m\x1b[32mloop_first_last\x1b[0m(values: Iterable[T]) -> Iterable[Tuple[\x1b[36mb\x1b[0m\n\x1b[2;37m│ \x1b[0m\x1b[33m"""Iterate and generate a tuple with a flag for first an\x1b[0m\n\x1b[2m│ \x1b[0miter_values = \x1b[36miter\x1b[0m(values)\n\x1b[2m│ \x1b[0m\x1b[34mtry\x1b[0m:\n\x1b[2m│ │ \x1b[0mprevious_value = \x1b[36mnext\x1b[0m(iter_values)\n\x1b[2m│ \x1b[0m\x1b[34mexcept\x1b[0m \x1b[36mStopIteration\x1b[0m:\n\x1b[2m│ │ \x1b[0m\x1b[34mreturn\x1b[0m\n\x1b[2m│ \x1b[0mfirst = \x1b[34mTrue\x1b[0m\n\x1b[2m│ \x1b[0m\x1b[34mfor\x1b[0m value \x1b[35min\x1b[0m iter_values:\n\x1b[2m│ │ \x1b[0m\x1b[34myield\x1b[0m first, \x1b[34mFalse\x1b[0m, previous_value\n\x1b[2m│ │ \x1b[0mfirst = \x1b[34mFalse\x1b[0m\n\x1b[2m│ │ \x1b[0mprevious_value = value\n\x1b[2m│ \x1b[0m\x1b[34myield\x1b[0m first, \x1b[34mTrue\x1b[0m, previous_value\n'
assert rendered_syntax == expected

View File

@@ -1,66 +0,0 @@
#
# spec file for package python-rich
#
# Copyright (c) 2025 SUSE LLC
# Copyright (c) 2020-2021, Martin Hauke <mardnh@gmx.de>
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
%{?sle15_python_module_pythons}
Name: python-rich
Version: 14.0.0
Release: 0
Summary: A Python library for rich text and beautiful formatting in the terminal
License: MIT
URL: https://github.com/Textualize/rich
#!RemoteAsset: https://github.com/Textualize/rich/archive/refs/tags/v%{version}.tar.gz rich-%{version}.tar.gz
Source: rich-%{version}.tar.gz
# PATCH-FIX-UPSTREAM https://github.com/Textualize/rich/pull/3604 Fix test that changed with Pygments 2.19.
# and https://github.com/Textualize/rich/pull/3608 fix remaining tests with Pygments 2.19 #3604 did not fix
Patch: pygments.patch
BuildRequires: %{python_module base >= 3.8}
BuildRequires: %{python_module markdown-it-py >= 2.2.0}
BuildRequires: %{python_module pip}
BuildRequires: %{python_module poetry-core}
BuildRequires: %{python_module pygments >= 2.13.0}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-markdown-it-py >= 2.2.0
Requires: python-pygments >= 2.13.0
Suggests: python-ipywidgets >= 7.5.1
BuildArch: noarch
# TODO(edu): Disabled all tests
%python_subpackages
%description
Render rich text, tables, progress bars, syntax highlighting,
markdown and more to the terminal.
%prep
%autosetup -p1 -n rich-%{version}
%build
%pyproject_wheel
%install
%pyproject_install
%python_expand %fdupes %{buildroot}%{$python_sitelib}
%files %{python_files}
%license LICENSE
%doc README.md
%{python_sitelib}/rich
%{python_sitelib}/rich-%{version}.dist-info
%changelog

Some files were not shown because too many files have changed in this diff Show More