forked from suse-edge/Factory
		
	Compare commits
	
		
			202 Commits
		
	
	
		
			dprodanov-
			...
			3.4
		
	
	| Author | SHA256 | Date | |
|---|---|---|---|
| fdab9b0bde | |||
| ef31131144 | |||
| 0a0264cc2b | |||
| 8b156f3a42 | |||
| fffb09efe0 | |||
| a6fde4c761 | |||
| e8ee070133 | |||
|  | 1e5f60b17e | ||
|  | 386550eb41 | ||
| 05061793f1 | |||
| 853872d9ba | |||
| 696440c3c7 | |||
| aad7827d67 | |||
| 40869007bd | |||
| 4326b883e5 | |||
|  | 0b3f99e64c | ||
| d77cc8744f | |||
| d3e972e242 | |||
| 6fd87db1ad | |||
| 24685d27be | |||
| 9d93dd001a | |||
| da8736177f | |||
| 5408eb4de5 | |||
| 1fac881ebc | |||
| 5e533c35b9 | |||
| 8eeb3b2a26 | |||
| 042175ff4c | |||
| f54cc0c0a3 | |||
| 265467d53f | |||
| b4a7eadd88 | |||
| be12376b9c | |||
| 4b7ad790c8 | |||
| 59f7f6c4d2 | |||
| 6c719f307c | |||
| e30c1fef4b | |||
| 3fea007d77 | |||
| 1bce8490f6 | |||
| 47bdcb200c | |||
|  | bf869dec4e | ||
| 92f49dbbfc | |||
| 96320cc7f2 | |||
| 7be5f59e4f | |||
| bb4ab90787 | |||
| 6c05726947 | |||
| 9a87f37674 | |||
| 6d50385ec3 | |||
|  | b94d722028 | ||
| 35054ff64b | |||
| e5f6b76d8b | |||
| 4e32759250 | |||
| 59fd3c1a8b | |||
|  | 5b167e10ab | ||
| 9cbf868ba7 | |||
| 7e04a91e72 | |||
| e9554a4399 | |||
| 45cd7fbc36 | |||
| 05f49fec7b | |||
| d1cb632801 | |||
| a1ba635f5d | |||
| 0295819a86 | |||
| 6875eea67f | |||
| 3652c43179 | |||
| 8403958d39 | |||
| b77a565a57 | |||
| a0180aa25a | |||
| 2a852b4266 | |||
| 1b112a8727 | |||
| 411e9ab220 | |||
| 9227c1bbeb | |||
| 994273a2a3 | |||
| ec829ba559 | |||
| 9821dab715 | |||
| 0eec81256f | |||
| 0fd2e6472a | |||
| d648a17268 | |||
| d056b82800 | |||
| e935c18527 | |||
| d1dcfadea6 | |||
| 594a388a50 | |||
| a8a7b3a542 | |||
| 6059a859a1 | |||
| 8da51ba73f | |||
| 5bf3812659 | |||
| a11bb47c19 | |||
| d18aef225e | |||
| 8d1f677931 | |||
| d0bbc1d844 | |||
| 47df258e97 | |||
| 5ece6cd64e | |||
| 0da5de1c06 | |||
| 27af056dce | |||
| e233adfec2 | |||
| 8617c36789 | |||
| aa56c231d4 | |||
| 29dd8dda17 | |||
| 6012f480b0 | |||
| 110a7b1f7c | |||
| 343fcd24b7 | |||
| 03d7a39ead | |||
| e2d38a867c | |||
| eecd30e90d | |||
| fc0cfda2c0 | |||
| 582aaaa424 | |||
| a94cde2a35 | |||
| ad01fecc4f | |||
| d59126b517 | |||
| 19394a8b03 | |||
| ca7da400d0 | |||
| c69044ff2b | |||
| 60f0bdd5f0 | |||
| 4e4f9e591a | |||
|  | 51b082a3f1 | ||
| d45c9764a4 | |||
| efd8bf1075 | |||
| 892400cea7 | |||
| ff1b390d09 | |||
| c3f1be5640 | |||
| e021cfa92f | |||
| 5f0d0b019e | |||
| dc254aa461 | |||
| 62f9faf144 | |||
| 8164b5f125 | |||
| 5f6e0185f5 | |||
| 57dca6f0a4 | |||
| 54bf2edf7b | |||
| 9c60855914 | |||
| bc1d924cc6 | |||
| 2f4f94238f | |||
| dae0b33326 | |||
| 4e4231b39e | |||
| c9f13a514a | |||
| f8f730087f | |||
| 7c0423ee04 | |||
| 0358093370 | |||
| a69e54a6df | |||
| 65201fd575 | |||
| 2adc97e581 | |||
| ed4448d7a6 | |||
| 6251d8b670 | |||
| 3a98fe8f00 | |||
| f9df52a457 | |||
| 9bcffd112d | |||
| 83b660285a | |||
| f23003c01f | |||
| 4b9928ccdf | |||
| df55d2abd4 | |||
| 214a65f2db | |||
| d00b6ece5f | |||
| 67f63aadc7 | |||
| f88e75a724 | |||
| ef6989b0d8 | |||
| b2ca623d14 | |||
| 53c16ce7c9 | |||
| e55bf1ab63 | |||
| 4f71473b0a | |||
| e20624cf98 | |||
| afba5dedef | |||
| 5cbf832b02 | |||
| 7cf1b8ea26 | |||
| 83b44c9bc7 | |||
| a7cb23a9c1 | |||
| 07505665e4 | |||
| 13b18090d0 | |||
| 22947d9847 | |||
| 3d087070a7 | |||
| 9bc3066279 | |||
| ec4c51d003 | |||
| 70ff1fdd31 | |||
| ce6519f470 | |||
| 0ccade5817 | |||
| 87f163939c | |||
| f0d7ede6e0 | |||
| aa677745a8 | |||
| 08797b0030 | |||
| 8b37096c3a | |||
| 6ca1cc0ded | |||
| fc24747ee5 | |||
| 9c2d445b06 | |||
| e5de658ae9 | |||
| 8cc06f4ccb | |||
| 9dc5ba4c52 | |||
| f92f3600e6 | |||
| e379d5df4e | |||
| 346d6137fe | |||
| 1f36228510 | |||
| ec7da715f4 | |||
| 1ad6c99257 | |||
| 12e91c2102 | |||
| 6fb80441cd | |||
| 93a5f6813d | |||
| bdaa422813 | |||
| c25bf622bc | |||
| fa57d15ff9 | |||
| 1a29da28ca | |||
| f2d39a7025 | |||
| 629e96dded | |||
| c190a1c800 | |||
| be87fb0fc6 | |||
| 01dfdc5fd9 | |||
| 90ce8e165c | |||
| ad68a91755 | |||
| c37782e077 | 
| @@ -17,7 +17,7 @@ jobs: | ||||
|           object-format: 'sha256' | ||||
|       - name: Setup dependencies | ||||
|         run: | | ||||
|           zypper in -y python3-PyYAML | ||||
|           zypper in -y python3-ruamel.yaml | ||||
|       - name: Check release manifest | ||||
|         run: | | ||||
|           python3 .obs/manifest-check.py | ||||
|           python3 .obs/manifest-check.py --check | ||||
|   | ||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,4 @@ | ||||
| */.osc | ||||
| */__pycache__ | ||||
| .venv/ | ||||
| .idea/ | ||||
							
								
								
									
										24
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -13,3 +13,27 @@ | ||||
| [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 | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| PROJECT = "isv:SUSE:Edge:Factory" | ||||
| PROJECT = "isv:SUSE:Edge:3.4" | ||||
| REPOSITORY = "https://src.opensuse.org/suse-edge/Factory" | ||||
| BRANCH = "main" | ||||
| BRANCH = "3.4" | ||||
|   | ||||
							
								
								
									
										51
									
								
								.obs/manifest-check.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										51
									
								
								.obs/manifest-check.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -1,11 +1,15 @@ | ||||
| #!/usr/bin/python3 | ||||
|  | ||||
| import yaml | ||||
| import ruamel.yaml | ||||
| import pathlib | ||||
| import argparse | ||||
| import sys | ||||
|  | ||||
| yaml = ruamel.yaml.YAML() | ||||
|  | ||||
| def get_chart_version(chart_name: str) -> str: | ||||
|     with open(f"./{chart_name}-chart/Chart.yaml") as f: | ||||
|         chart = yaml.safe_load(f) | ||||
|         chart = yaml.load(f) | ||||
|         return chart["version"] | ||||
|  | ||||
| def get_charts(chart): | ||||
| @@ -21,22 +25,57 @@ def get_charts(chart): | ||||
|  | ||||
| def get_charts_list(): | ||||
|     with open("./release-manifest-image/release_manifest.yaml") as f: | ||||
|         manifest = yaml.safe_load(f) | ||||
|         manifest = yaml.load(f) | ||||
|     charts = {} | ||||
|     for chart in manifest["spec"]["components"]["workloads"]["helm"]: | ||||
|         charts.update(get_charts(chart)) | ||||
|     return charts | ||||
|  | ||||
| def main(): | ||||
|     print("Checking charts versions in release manifest") | ||||
| def check_charts(fix: bool) -> bool: | ||||
|     success = True | ||||
|     charts = get_charts_list() | ||||
|     to_fix = {} | ||||
|     for chart in charts: | ||||
|         expected_version = get_chart_version(chart) | ||||
|         if expected_version != charts[chart]: | ||||
|             success = False | ||||
|             to_fix[f'%%CHART_REPO%%/%%CHART_PREFIX%%{chart}'] = expected_version | ||||
|             print(f"{chart}: Expected: {expected_version}, Got: {charts[chart]}") | ||||
|     if not success: | ||||
|     if fix and not success: | ||||
|         fix_charts(to_fix) | ||||
|         return True | ||||
|     return success | ||||
|  | ||||
| def fix_charts(to_fix): | ||||
|     manifest_path = pathlib.Path("./release-manifest-image/release_manifest.yaml") | ||||
|     manifest = yaml.load(manifest_path) | ||||
|     yaml.indent(mapping=2, sequence=4, offset=2) | ||||
|     yaml.width = 4096 | ||||
|     for chart_index, chart in enumerate(manifest["spec"]["components"]["workloads"]["helm"]): | ||||
|         changed = False | ||||
|         if chart["chart"] in to_fix.keys(): | ||||
|             changed = True | ||||
|             chart["version"] = to_fix[chart["chart"]] | ||||
|         for subchart_index, subchart in enumerate(chart.get("addonCharts", [])): | ||||
|             if subchart["chart"] in to_fix.keys(): | ||||
|                 changed = True | ||||
|                 subchart["version"] = to_fix[subchart["chart"]] | ||||
|                 chart["addonCharts"][subchart_index] = subchart | ||||
|         for subchart_index, subchart in enumerate(chart.get("dependencyCharts", [])): | ||||
|             if subchart["chart"] in to_fix.keys(): | ||||
|                 changed = True | ||||
|                 subchart["version"] = to_fix[subchart["chart"]] | ||||
|                 chart["dependencyCharts"][subchart_index] = subchart | ||||
|         if changed: | ||||
|             manifest["spec"]["components"]["workloads"]["helm"][chart_index] = chart | ||||
|     yaml.dump(manifest, manifest_path) | ||||
|  | ||||
| def main(): | ||||
|     print("Checking charts versions in release manifest") | ||||
|     parser = argparse.ArgumentParser() | ||||
|     parser.add_argument('-c', '--check', action='store_true') | ||||
|     args = parser.parse_args() | ||||
|     if not check_charts(not args.check): | ||||
|         sys.exit(1) | ||||
|     else: | ||||
|         print("All local charts in release manifest are using the right version") | ||||
|   | ||||
							
								
								
									
										10
									
								
								.pre-commit-config.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								.pre-commit-config.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| repos: | ||||
|   - repo: local | ||||
|     hooks: | ||||
|       - id: check-manifest | ||||
|         name: "Check release-manifest" | ||||
|         entry: python3 .obs/manifest-check.py | ||||
|         language: python | ||||
|         additional_dependencies: ['ruamel.yaml'] | ||||
|         pass_filenames: false | ||||
|         always_run: true | ||||
							
								
								
									
										46
									
								
								_config
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								_config
									
									
									
									
									
								
							| @@ -1,4 +1,5 @@ | ||||
| Prefer: -libqpid-proton10 -python311-urllib3_1 | ||||
| Prefer: -cargo1.58 -cargo1.57 cargo1.89 | ||||
|  | ||||
| Macros: | ||||
| %__python3 /usr/bin/python3.11 | ||||
| @@ -49,6 +50,15 @@ 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 | ||||
| @@ -60,10 +70,13 @@ BuildFlags: onlybuild:release-manifest-image | ||||
|     BuildFlags: excludebuild:endpoint-copier-operator-image | ||||
|     BuildFlags: excludebuild:ironic-image | ||||
|     BuildFlags: excludebuild:ironic-ipa-downloader-image | ||||
|     BuildFlags: excludebuild:kiwi-builder-image | ||||
|     BuildFlags: excludebuild:kubectl-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 | ||||
| @@ -92,8 +105,22 @@ 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 | ||||
|  | ||||
| @@ -104,11 +131,16 @@ BuildFlags: onlybuild:release-manifest-image | ||||
|     Patterntype: none | ||||
|     BuildEngine: podman | ||||
|     Prefer: sles-release | ||||
|     BuildFlags: dockerarg:SLE_VERSION=15.6 | ||||
|     BuildFlags: dockerarg:SLE_VERSION=15.7 | ||||
|  | ||||
|     # Publish multi-arch container images only once all archs have been built | ||||
|     PublishFlags: archsync | ||||
|      | ||||
|     # skopeo and umoci are used by build scripts to list packages | ||||
|     Substitute: system-packages:podman podman buildah createrepo_c release-compare skopeo umoci | ||||
| %endif | ||||
|  | ||||
| %if "%_repository" == "images" | ||||
|     # skopeo and umoci are used by build scripts to list packages | ||||
|     Substitute: system-packages:podman podman buildah createrepo_c release-compare edge-build-checks skopeo umoci | ||||
|  | ||||
| @@ -123,6 +155,8 @@ BuildFlags: onlybuild:release-manifest-image | ||||
|     BuildFlags: dockerarg:SLE_VERSION=16.0 | ||||
|     BuildFlags: onlybuild:kiwi-builder-image | ||||
|      | ||||
|     Substitute: system-packages:podman podman buildah createrepo_c release-compare skopeo umoci | ||||
|  | ||||
|     # Publish multi-arch container images only once all archs have been built | ||||
|     PublishFlags: archsync | ||||
|  | ||||
| @@ -137,10 +171,18 @@ 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 | ||||
|     BuildFlags: excludebuild:kiwi-builder-image | ||||
|     %if "%{sub %{reverse %_project} 1 7}" != "%{reverse :ToTest}" && "%{sub %{reverse %_project} 1 9}" != "%{reverse :Snapshot}" | ||||
|       BuildFlags: excludebuild:kiwi-builder-image | ||||
|     %else | ||||
|       %ifarch aarch64 | ||||
|         BuildFlags: onlybuild:kiwi-builder-image | ||||
|       %endif | ||||
|     %endif | ||||
| %endif | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										9
									
								
								_meta
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								_meta
									
									
									
									
									
								
							| @@ -23,6 +23,9 @@ | ||||
|     <disable/> | ||||
|     <enable repository="charts"/> | ||||
|     <enable repository="test_manifest_images"/> | ||||
|     {%- if for_release %} | ||||
|     <enable repository="releasecharts"/> | ||||
|     {%- endif %} | ||||
|   </build> | ||||
|   <publish> | ||||
|     <disable repository="phantomcharts"/> | ||||
| @@ -42,7 +45,7 @@ | ||||
|       <path project="SUSE:SLFO:Products:SLES:16.0" repository="standard"/> | ||||
|       <path project="SUSE:SLFO:Main:Build" repository="standard"/> | ||||
|     {%- else %} | ||||
|       <path project="SUSE:CA" repository="SLE_15_SP6"/> | ||||
|       <path project="SUSE:CA" repository="SLE_15_SP7"/> | ||||
|       <path project="{{ project }}" repository="standard"/> | ||||
|     {%- endif %} | ||||
|     <arch>x86_64</arch> | ||||
| @@ -53,8 +56,8 @@ | ||||
|     {%- if release_project is defined and not for_release %} | ||||
|     <releasetarget project="{{ release_project }}" repository="standard" trigger="manual"/> | ||||
|     {%- endif %} | ||||
|     <path project="{{ ironic_base }}:2024.2" repository="15.6"/> | ||||
|     <path project="SUSE:SLE-15-SP6:Update" repository="standard"/> | ||||
|     <path project="{{ ironic_base }}:2025.1" repository="15.7"/> | ||||
|     <path project="SUSE:SLE-15-SP7:Update" repository="standard"/> | ||||
|     <arch>x86_64</arch> | ||||
|     <arch>aarch64</arch> | ||||
|   </repository> | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| #!BuildTag: %%CHART_PREFIX%%akri-dashboard-extension:%%CHART_MAJOR%%.0.2 | ||||
| #!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% | ||||
| #!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% | ||||
| annotations: | ||||
|   catalog.cattle.io/certified: rancher | ||||
|   catalog.cattle.io/namespace: cattle-ui-plugin-system | ||||
| @@ -13,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: 303.0.2+up1.3.1 | ||||
| appVersion: 304.0.3+up1.3.1 | ||||
| description: 'SUSE Edge: Akri extension for Rancher Dashboard' | ||||
| name: akri-dashboard-extension | ||||
| type: application | ||||
| version: "%%CHART_MAJOR%%.0.2+up1.3.1" | ||||
| version: "%%CHART_MAJOR%%.0.3+up1.3.1" | ||||
| icon: >- | ||||
|   https://raw.githubusercontent.com/cncf/artwork/main/projects/akri/icon/color/akri-icon-color.svg | ||||
|   | ||||
| @@ -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/303.0.2+up1.3.1 | ||||
|     endpoint: https://raw.githubusercontent.com/suse-edge/dashboard-extensions/gh-pages/extensions/akri-dashboard-extension/304.0.3+up1.3.1 | ||||
|     noCache: {{ .Values.plugin.noCache }} | ||||
|     noAuth: {{ .Values.plugin.noAuth }} | ||||
|     metadata: {{ include "extension-server.pluginMetadata" . | indent 6 }} | ||||
|   | ||||
| @@ -1,13 +1,12 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%baremetal-operator:%%baremetal-operator_version%% | ||||
| #!BuildTag: %%IMG_PREFIX%%baremetal-operator:%%baremetal-operator_version%%-%RELEASE% | ||||
| #!BuildVersion: 15.6 | ||||
| #!BuildTag: %%IMG_PREFIX%%baremetal-operator:%%baremetal-operator_version%%.1 | ||||
| #!BuildTag: %%IMG_PREFIX%%baremetal-operator:%%baremetal-operator_version%%.1-%RELEASE% | ||||
| ARG SLE_VERSION | ||||
| FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro | ||||
|  | ||||
| FROM registry.suse.com/bci/bci-base:$SLE_VERSION AS base | ||||
| COPY --from=micro / /installroot/ | ||||
| RUN zypper --installroot /installroot --non-interactive install --no-recommends baremetal-operator iproute2 bind-utils vim shadow; zypper -n clean; rm -rf /var/log/* | ||||
| RUN zypper --installroot /installroot --non-interactive install --no-recommends baremetal-operator inotify-tools procps iproute2 bind-utils vim shadow; zypper -n clean; rm -rf /var/log/* | ||||
|  | ||||
| FROM micro AS final | ||||
| # Define labels according to https://en.opensuse.org/Building_derived_containers | ||||
| @@ -19,7 +18,7 @@ LABEL org.opencontainers.image.version="%%baremetal-operator_version%%" | ||||
| 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%%baremetal-operator:%%baremetal-operator_version%%-%RELEASE%" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%baremetal-operator:%%baremetal-operator_version%%.1-%RELEASE%" | ||||
| LABEL org.openbuildservice.disturl="%DISTURL%" | ||||
| LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" | ||||
| LABEL com.suse.eula="SUSE Combined EULA February 2024" | ||||
| @@ -29,6 +28,8 @@ LABEL com.suse.release-stage="released" | ||||
| # endlabelprefix | ||||
|  | ||||
| COPY --from=base /installroot / | ||||
| COPY bmo-run /usr/bin/bmo-run | ||||
| RUN chmod +x /usr/bin/bmo-run | ||||
| RUN groupadd -r -g 11000 bmo | ||||
| RUN useradd -u 11000 -g 11000 bmo | ||||
| ENTRYPOINT [ "/usr/bin/baremetal-operator" ] | ||||
| ENTRYPOINT [ "/usr/bin/bmo-run" ] | ||||
|   | ||||
							
								
								
									
										12
									
								
								baremetal-operator-image/bmo-run
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								baremetal-operator-image/bmo-run
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| #!/bin/bash | ||||
| export RESTART_CONTAINER_CERTIFICATE_UPDATED=${RESTART_CONTAINER_CERTIFICATE_UPDATED:-"false"} | ||||
| export IRONIC_CACERT_FILE=${IRONIC_CACERT_FILE:-"/opt/metal3/certs/ca/tls.crt"} | ||||
|  | ||||
| if [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then | ||||
|     # shellcheck disable=SC2034 | ||||
|     inotifywait -m -e delete_self "${IRONIC_CACERT_FILE}" | while read -r file event; do | ||||
|         kill $(pgrep baremetal-opera) | ||||
|     done & | ||||
| fi | ||||
|  | ||||
| exec /usr/bin/baremetal-operator $@ | ||||
							
								
								
									
										163
									
								
								baremetal-operator/0001-Enable-exhaustive-linter.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								baremetal-operator/0001-Enable-exhaustive-linter.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,163 @@ | ||||
| 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 | ||||
|  | ||||
| @@ -0,0 +1,91 @@ | ||||
| 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 | ||||
|  | ||||
| @@ -0,0 +1,49 @@ | ||||
| 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 | ||||
|  | ||||
| @@ -0,0 +1,422 @@ | ||||
| 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 | ||||
|  | ||||
| @@ -0,0 +1,46 @@ | ||||
| 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 | ||||
|  | ||||
| @@ -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.9.1</param> | ||||
|     <param name="revision">v0.10.2</param> | ||||
|     <param name="version">_auto_</param> | ||||
|     <param name="versionformat">@PARENT_TAG@</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
|   | ||||
| @@ -17,14 +17,21 @@ | ||||
|  | ||||
|  | ||||
| Name:           baremetal-operator | ||||
| Version:        0.9.1 | ||||
| Version:        0.10.2 | ||||
| Release:        0 | ||||
| Summary:        Implements a Kubernetes API for managing bare metal hosts | ||||
| License:        Apache-2.0 | ||||
| URL:            https://github.com/metal3-io/baremetal-operator | ||||
| Source:         baremetal-operator-%{version}.tar | ||||
| Source1:        vendor.tar.gz | ||||
| BuildRequires:  golang(API) = 1.23 | ||||
| # Patches related to multi-architecture support, upstream PRs #2506 #2559 #2537 | ||||
| Patch0:		0001-Enable-exhaustive-linter.patch | ||||
| Patch1:		0002-Stop-requiring-DEPLOY_KERNEL-RAMDISK.patch | ||||
| Patch2:		0003-Remove-DEPLOY_KERNEL_URL-from-deployment-scripts-for.patch | ||||
| Patch3:		0004-Refactor-setting-various-Ironic-properties.patch | ||||
| Patch4:		0005-Provide-inline-docs-for-node-configuration-calls.patch | ||||
|  | ||||
| BuildRequires:  golang(API) = 1.24 | ||||
| ExcludeArch:    s390 | ||||
| ExcludeArch:    %{ix86} | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| #!BuildTag: %%CHART_PREFIX%%cdi:%%CHART_MAJOR%%.0.0_up0.5.0 | ||||
| #!BuildTag: %%CHART_PREFIX%%cdi:%%CHART_MAJOR%%.0.0_up0.5.0-%RELEASE% | ||||
| #!BuildTag: %%CHART_PREFIX%%cdi:%%CHART_MAJOR%%.0.1_up0.6.0 | ||||
| #!BuildTag: %%CHART_PREFIX%%cdi:%%CHART_MAJOR%%.0.1_up0.6.0-%RELEASE% | ||||
| apiVersion: v2 | ||||
| appVersion: 1.61.0 | ||||
| appVersion: 1.62.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.0+up0.5.0" | ||||
| version: "%%CHART_MAJOR%%.0.1+up0.6.0" | ||||
|   | ||||
| @@ -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. | ||||
|                       description: |- | ||||
|                         DataVolumeTTLSeconds is the time in seconds after DataVolume completion it can be garbage collected. Disabled by default. | ||||
|                         Deprecated: Removed in v1.62. | ||||
|                       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. | ||||
|                       description: |- | ||||
|                         DataVolumeTTLSeconds is the time in seconds after DataVolume completion it can be garbage collected. Disabled by default. | ||||
|                         Deprecated: Removed in v1.62. | ||||
|                       format: int32 | ||||
|                       type: integer | ||||
|                     featureGates: | ||||
|   | ||||
| @@ -599,6 +599,8 @@ spec: | ||||
|   strategy: {} | ||||
|   template: | ||||
|     metadata: | ||||
|       annotations: | ||||
|         openshift.io/required-scc: restricted-v2 | ||||
|       labels: | ||||
|         cdi.kubevirt.io: cdi-operator | ||||
|         name: cdi-operator | ||||
|   | ||||
| @@ -19,3 +19,7 @@ spec: | ||||
|   workload: | ||||
|   {{- toYaml . | nindent 4 }} | ||||
|   {{- end }} | ||||
|   {{- with .Values.cdi.customizeComponents }} | ||||
|   customizeComponents: | ||||
|   {{- toYaml . | nindent 4 }} | ||||
|   {{- end }} | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| deployment: | ||||
|   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 | ||||
|   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 | ||||
|   pullPolicy: IfNotPresent | ||||
|   affinity: | ||||
|     podAffinity: | ||||
| @@ -30,6 +30,7 @@ cdi: | ||||
|     featureGates: | ||||
|       - HonorWaitForFirstConsumer | ||||
|   imagePullPolicy: "IfNotPresent" | ||||
|   customizeComponents: {} | ||||
|   infra: | ||||
|     nodeSelector: | ||||
|       kubernetes.io/os: linux | ||||
| @@ -41,7 +42,7 @@ cdi: | ||||
|     nodeSelector: | ||||
|       kubernetes.io/os: linux | ||||
|  | ||||
| hookImage: registry.rancher.com/rancher/kubectl:v1.30.10 | ||||
| hookImage: registry.rancher.com/rancher/kubectl:v1.33.1 | ||||
| hookRestartPolicy: OnFailure | ||||
| hookSecurityContext: | ||||
|   seccompProfile: | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| #!BuildTag: %%IMG_PREFIX%%edge-image-builder:1.2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%edge-image-builder:1.2.0-%RELEASE% | ||||
| #!BuildVersion: 15.6 | ||||
| #!BuildTag: %%IMG_PREFIX%%edge-image-builder:1.3.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%edge-image-builder:1.3.0-%RELEASE% | ||||
| ARG SLE_VERSION | ||||
| FROM registry.suse.com/bci/bci-base:$SLE_VERSION | ||||
| MAINTAINER SUSE LLC (https://www.suse.com/) | ||||
| @@ -15,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.2.0" | ||||
| LABEL org.opencontainers.image.version="1.3.0" | ||||
| 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.2.0-%RELEASE%" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%edge-image-builder:1.3.0-%RELEASE%" | ||||
| LABEL org.openbuildservice.disturl="%DISTURL%" | ||||
| LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" | ||||
| LABEL com.suse.eula="SUSE Combined EULA February 2024" | ||||
|   | ||||
| @@ -5,11 +5,15 @@ metallb: | ||||
| endpoint-copier-operator: | ||||
|   chart: endpoint-copier-operator | ||||
|   repository: "%%CHART_REPO%%/%%CHART_PREFIX%%" | ||||
|   version: "%%CHART_MAJOR%%.0.0+up0.2.1" | ||||
|   version: "%%CHART_MAJOR%%.0.1+up0.3.0" | ||||
| 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/ | ||||
|   | ||||
| @@ -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.2.0</param> | ||||
|     <param name="revision">v1.3.0</param> | ||||
|     <!-- Uncomment and set this For Pre-Release Version --> | ||||
|     <!-- <param name="version">1.2.0~rc1</param> --> | ||||
|     <!-- <param name="version">1.3.0</param> --> | ||||
|     <!-- Uncomment and this for regular version --> | ||||
|     <param name="versionformat">@PARENT_TAG@</param> | ||||
|     <param name="versionrewrite-pattern">v(\d+).(\d+).(\d+)</param> | ||||
|   | ||||
| @@ -17,7 +17,7 @@ | ||||
|  | ||||
|  | ||||
| Name:           edge-image-builder | ||||
| Version:        1.2.0 | ||||
| Version:        1.3.0 | ||||
| Release:        0 | ||||
| Summary:        Edge Image Builder | ||||
| License:        Apache-2.0 | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| #!BuildTag: %%CHART_PREFIX%%endpoint-copier-operator:%%CHART_MAJOR%%.0.0_up0.2.1 | ||||
| #!BuildTag: %%CHART_PREFIX%%endpoint-copier-operator:%%CHART_MAJOR%%.0.0_up0.2.1-%RELEASE% | ||||
| #!BuildTag: %%CHART_PREFIX%%endpoint-copier-operator:%%CHART_MAJOR%%.0.1_up0.3.0 | ||||
| #!BuildTag: %%CHART_PREFIX%%endpoint-copier-operator:%%CHART_MAJOR%%.0.1_up0.3.0-%RELEASE% | ||||
| apiVersion: v2 | ||||
| appVersion: v0.2.0 | ||||
| appVersion: v0.3.0 | ||||
| description: A Helm chart for Kubernetes | ||||
| name: endpoint-copier-operator | ||||
| type: application | ||||
| version: "%%CHART_MAJOR%%.0.0+up0.2.1" | ||||
| version: "%%CHART_MAJOR%%.0.1+up0.3.0" | ||||
|   | ||||
| @@ -20,8 +20,23 @@ spec: | ||||
|       labels: | ||||
|         {{- include "endpoint-copier-operator.selectorLabels" . | nindent 8 }} | ||||
|     spec: | ||||
|       {{- if .Values.priorityClassName }} | ||||
|       priorityClassName: {{ .Values.priorityClassName }} | ||||
|       {{- end }} | ||||
|       securityContext: | ||||
|         {{- toYaml .Values.podSecurityContext | nindent 8 }} | ||||
|       {{- with .Values.nodeSelector }} | ||||
|       nodeSelector: | ||||
|         {{- toYaml . | nindent 8 }} | ||||
|       {{- end }} | ||||
|       {{- with .Values.affinity }} | ||||
|       affinity: | ||||
|         {{- toYaml . | nindent 8 }} | ||||
|       {{- end }} | ||||
|       {{- with .Values.tolerations }} | ||||
|       tolerations: | ||||
|         {{- toYaml . | nindent 8 }} | ||||
|       {{- end }} | ||||
|       containers: | ||||
|       - command: | ||||
|         - /manager | ||||
|   | ||||
| @@ -7,9 +7,9 @@ metadata: | ||||
|   name: {{ include "endpoint-copier-operator.fullname" . }} | ||||
| rules: | ||||
| - apiGroups: | ||||
|   - "" | ||||
|   - "discovery.k8s.io" | ||||
|   resources: | ||||
|   - endpoints | ||||
|   - endpointslices | ||||
|   verbs: | ||||
|   - create | ||||
|   - delete | ||||
|   | ||||
| @@ -8,7 +8,7 @@ image: | ||||
|   repository: %%IMG_REPO%%/%%IMG_PREFIX%%endpoint-copier-operator | ||||
|   pullPolicy: IfNotPresent | ||||
|   # Overrides the image tag whose default is the chart appVersion. | ||||
|   tag: "0.2.0" | ||||
|   tag: "0.3.0" | ||||
|  | ||||
| nameOverride: "endpoint-copier-operator" | ||||
| fullnameOverride: "endpoint-copier-operator" | ||||
| @@ -29,6 +29,8 @@ podSecurityContext: | ||||
|   seccompProfile: | ||||
|     type: RuntimeDefault | ||||
|  | ||||
| priorityClassName: "system-cluster-critical" | ||||
|  | ||||
| securityContext: | ||||
|   allowPrivilegeEscalation: false | ||||
|   capabilities: | ||||
| @@ -37,11 +39,11 @@ securityContext: | ||||
|  | ||||
| resources: | ||||
|   limits: | ||||
|     cpu: 500m | ||||
|     memory: 128Mi | ||||
|   requests: | ||||
|     cpu: 10m | ||||
|     cpu: 100m | ||||
|     memory: 64Mi | ||||
|   requests: | ||||
|     cpu: 5m | ||||
|     memory: 32Mi | ||||
|  | ||||
| autoscaling: | ||||
|   enabled: false | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%endpoint-copier-operator:%%endpoint-copier-operator_version%% | ||||
| #!BuildTag: %%IMG_PREFIX%%endpoint-copier-operator:%%endpoint-copier-operator_version%%-%RELEASE% | ||||
| #!BuildVersion: 15.6 | ||||
| ARG SLE_VERSION | ||||
| FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  <service name="obs_scm"> | ||||
|     <param name="url">https://github.com/suse-edge/endpoint-copier-operator</param> | ||||
|     <param name="scm">git</param> | ||||
|     <param name="revision">v0.2.0</param> | ||||
|     <param name="revision">v0.3.0</param> | ||||
|     <param name="version">_auto_</param> | ||||
|     <param name="versionformat">@PARENT_TAG@</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
|   | ||||
| @@ -17,14 +17,14 @@ | ||||
|  | ||||
|  | ||||
| Name:           endpoint-copier-operator | ||||
| Version:        0.2.0 | ||||
| Release:        0.2.0 | ||||
| Version:        0.3.0 | ||||
| Release:        0.3.0 | ||||
| Summary:        Implements a Kubernetes API for copying endpoint resources | ||||
| License:        Apache-2.0 | ||||
| URL:            https://github.com/suse-edge/endpoint-copier-operator | ||||
| Source:         endpoint-copier-operator-%{version}.tar | ||||
| Source1:        vendor.tar.gz | ||||
| BuildRequires:  golang(API) = 1.20 | ||||
| BuildRequires:  golang(API) = 1.24 | ||||
| ExcludeArch:    s390 | ||||
| ExcludeArch:    %{ix86} | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| # SPDX-License-Identifier: MIT | ||||
| #!BuildTag: %%IMG_PREFIX%%frr:8.5.6 | ||||
| #!BuildTag: %%IMG_PREFIX%%frr:8.5.6-%RELEASE% | ||||
| #!BuildVersion: 15.6 | ||||
| ARG SLE_VERSION | ||||
| FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%frr-k8s:v%%frr-k8s_version%% | ||||
| #!BuildTag: %%IMG_PREFIX%%frr-k8s:v%%frr-k8s_version%%-%RELEASE% | ||||
| #!BuildVersion: 15.6 | ||||
| ARG SLE_VERSION | ||||
| FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro | ||||
|  | ||||
|   | ||||
| @@ -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.1</param> | ||||
|     <param name="revision">v1.2.5</param> | ||||
|     <param name="versionrewrite-pattern">v(.*)</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
|   </service> | ||||
|   | ||||
| @@ -18,7 +18,7 @@ | ||||
| %define project github.com/hauler-dev/hauler | ||||
|  | ||||
| Name:           hauler | ||||
| Version:        1.2.1 | ||||
| Version:        1.2.5 | ||||
| Release:        0 | ||||
| Summary:        Airgap Swiss Army Knife | ||||
| License:        Apache-2.0 | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic:26.1.2.4 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic:26.1.2.4-%RELEASE% | ||||
| #!BuildVersion: 15.6 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic:29.0.4.4 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic:29.0.4.4-%RELEASE% | ||||
|  | ||||
| ARG SLE_VERSION | ||||
| FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro | ||||
| @@ -20,11 +19,11 @@ RUN sed -i -e 's%^# rpm.install.excludedocs = no.*%rpm.install.excludedocs = yes | ||||
|  | ||||
| #!ArchExclusiveLine: x86_64 | ||||
| RUN if [ "$(uname -m)" = "x86_64" ];then \ | ||||
|       zypper --installroot /installroot --non-interactive install --no-recommends syslinux python311-devel python311 python311-pip python-dracclient python311-sushy-oem-idrac python311-proliantutils python311-sushy python3-ironicclient git curl sles-release tar gzip vim gawk dnsmasq dosfstools apache2 apache2-mod_wsgi inotify-tools ipcalc ipmitool iproute2 procps qemu-tools sqlite3 util-linux xorriso tftp ipxe-bootimgs python311-sushy-tools crudini openstack-ironic openstack-ironic-inspector-api; \ | ||||
|       zypper --installroot /installroot --non-interactive install --no-recommends syslinux python311-devel python311 python311-pip python311-sushy-oem-idrac python311-proliantutils python311-sushy python311-pyinotify python3-ironicclient git curl sles-release tar gzip vim gawk dnsmasq dosfstools apache2 apache2-mod_wsgi ipcalc ipmitool iproute2 bind-utils procps qemu-tools sqlite3 util-linux xorriso tftp ipxe-bootimgs python311-sushy-tools crudini openstack-ironic; \ | ||||
|     fi | ||||
| #!ArchExclusiveLine: aarch64 | ||||
| RUN if [ "$(uname -m)" = "aarch64" ];then \ | ||||
|       zypper --installroot /installroot --non-interactive install --no-recommends python311-devel python311 python311-pip python-dracclient python311-sushy-oem-idrac python311-proliantutils python311-sushy python3-ironicclient git curl sles-release tar gzip vim gawk dnsmasq dosfstools apache2 apache2-mod_wsgi inotify-tools ipcalc ipmitool iproute2 procps qemu-tools sqlite3 util-linux xorriso tftp ipxe-bootimgs python311-sushy-tools crudini openstack-ironic openstack-ironic-inspector-api; \ | ||||
|       zypper --installroot /installroot --non-interactive install --no-recommends python311-devel python311 python311-pip python311-sushy-oem-idrac python311-proliantutils python311-sushy python311-pyinotify python3-ironicclient git curl sles-release tar gzip vim gawk dnsmasq dosfstools apache2 apache2-mod_wsgi ipcalc ipmitool iproute2 bind-utils procps qemu-tools sqlite3 util-linux xorriso tftp ipxe-bootimgs python311-sushy-tools crudini openstack-ironic; \ | ||||
|     fi | ||||
|      | ||||
| # DATABASE | ||||
| @@ -32,7 +31,9 @@ RUN mkdir -p /installroot/var/lib/ironic && \ | ||||
|   /installroot/usr/bin/sqlite3 /installroot/var/lib/ironic/ironic.sqlite "pragma journal_mode=wal" && \ | ||||
|   zypper --installroot /installroot --non-interactive remove sqlite3 | ||||
|  | ||||
| # build actual image | ||||
| FROM micro AS final | ||||
|  | ||||
| MAINTAINER SUSE LLC (https://www.suse.com/) | ||||
| # Define labels according to https://en.opensuse.org/Building_derived_containers | ||||
| LABEL org.opencontainers.image.title="SLE Openstack Ironic Container Image" | ||||
| @@ -40,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="26.1.2.4" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic:26.1.2.4-%RELEASE%" | ||||
| 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.openbuildservice.disturl="%DISTURL%" | ||||
| LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" | ||||
| LABEL com.suse.eula="SUSE Combined EULA February 2024" | ||||
| @@ -62,14 +63,19 @@ RUN echo 'alias mkisofs="xorriso -as mkisofs"' >> ~/.bashrc | ||||
| COPY mkisofs_wrapper /usr/bin/mkisofs | ||||
| RUN set -euo pipefail; chmod +x /usr/bin/mkisofs | ||||
|  | ||||
| COPY auth-common.sh configure-ironic.sh ironic-common.sh rundnsmasq runhttpd runironic runlogwatch.sh tls-common.sh configure-nonroot.sh ironic-probe.j2 /bin/ | ||||
| RUN set -euo pipefail; chmod +x /bin/auth-common.sh; chmod +x /bin/configure-ironic.sh; chmod +x /bin/ironic-common.sh; chmod +x /bin/rundnsmasq; chmod +x /bin/runhttpd; chmod +x /bin/runironic; chmod +x /bin/runlogwatch.sh; chmod +x /bin/tls-common.sh; chmod +x /bin/configure-nonroot.sh; | ||||
| RUN mkdir -p /tftpboot | ||||
| RUN mkdir -p $GRUB_DIR | ||||
|  | ||||
| # No need to support the Legacy BIOS boot | ||||
| #RUN cp /usr/share/syslinux/pxelinux.0 /tftpboot | ||||
| #RUN cp /usr/share/syslinux/chain.c32 /tftpboot/ | ||||
| COPY scripts/ /bin/ | ||||
| COPY configure-nonroot.sh /bin/ | ||||
| RUN set -euo pipefail; chmod +x /bin/configure-ironic.sh /bin/ironic-probe.sh /bin/rundatabase-upgrade /bin/rundnsmasq /bin/runhttpd /bin/runironic /bin/runlogwatch.sh /bin/runonline-data-migrations /bin/configure-nonroot.sh | ||||
|  | ||||
| RUN mv /bin/ironic-probe.sh /bin/ironic-readiness | ||||
| RUN cp /bin/ironic-readiness /bin/ironic-liveness | ||||
|  | ||||
| COPY ironic-config/inspector.ipxe.j2 ironic-config/httpd-ironic-api.conf.j2 \ | ||||
|      ironic-config/ipxe_config.template ironic-config/dnsmasq.conf.j2 \ | ||||
|      /tmp/ | ||||
|  | ||||
| # IRONIC # | ||||
| RUN cp /usr/share/ipxe/undionly.kpxe /tftpboot/undionly.kpxe | ||||
| @@ -77,31 +83,24 @@ RUN cp /usr/share/ipxe/undionly.kpxe /tftpboot/undionly.kpxe | ||||
| RUN if [ "$(uname -m)" = "x86_64" ];then \ | ||||
|       cp /usr/share/ipxe/ipxe-x86_64.efi /tftpboot/ipxe.efi ;\ | ||||
|     fi | ||||
| #!ArchExclusiveLine: x86_64 | ||||
| #!ArchExclusiveLine: aarch64  | ||||
| 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 ;\ | ||||
|       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/esp-x86_64.img /tmp/uefi_esp-x86_64.img | ||||
| COPY --from=base /tmp/esp-aarch64.img /tmp/uefi_esp-arm64.img | ||||
| COPY --from=base /tmp/uefi_esp_*.img /templates/ | ||||
|  | ||||
| COPY ironic.conf.j2 /etc/ironic/ | ||||
| COPY inspector.ipxe.j2 httpd-ironic-api.conf.j2 ipxe_config.template /tmp/ | ||||
| COPY network-data-schema-empty.json /etc/ironic/ | ||||
|  | ||||
| # DNSMASQ | ||||
| COPY dnsmasq.conf.j2 /etc/ | ||||
|  | ||||
| # Custom httpd config, removes all but the bare minimum needed modules | ||||
| COPY httpd.conf.j2 /etc/httpd/conf/ | ||||
| COPY httpd-modules.conf /etc/httpd/conf.modules.d/ | ||||
| COPY apache2-vmedia.conf.j2 /etc/httpd-vmedia.conf.j2 | ||||
| COPY apache2-ipxe.conf.j2 /etc/httpd-ipxe.conf.j2 | ||||
| COPY ironic-config/ironic.conf.j2 ironic-config/network-data-schema-empty.json /etc/ironic/ | ||||
|  | ||||
| # Workaround | ||||
| # Removing the 010-ironic.conf file that comes with the package  | ||||
| RUN rm /etc/ironic/ironic.conf.d/010-ironic.conf | ||||
|  | ||||
| # Custom httpd config, removes all but the bare minimum needed modules | ||||
| COPY ironic-config/httpd.conf.j2 /etc/httpd/conf/ | ||||
| COPY ironic-config/httpd-modules.conf /etc/httpd/conf.modules.d/ | ||||
| COPY ironic-config/apache2-vmedia.conf.j2 /tmp/httpd-vmedia.conf.j2 | ||||
| COPY ironic-config/apache2-ipxe.conf.j2 /tmp/httpd-ipxe.conf.j2 | ||||
|  | ||||
| # configure non-root user and set relevant permissions | ||||
| RUN configure-nonroot.sh && \ | ||||
|   rm -f /bin/configure-nonroot.sh | ||||
| RUN configure-nonroot.sh && rm -f /bin/configure-nonroot.sh | ||||
|   | ||||
| @@ -1,27 +0,0 @@ | ||||
| Listen {{ env.VMEDIA_TLS_PORT }} | ||||
|  | ||||
| <VirtualHost *:{{ env.VMEDIA_TLS_PORT }}> | ||||
|     ErrorLog /dev/stderr | ||||
|     LogLevel debug | ||||
|     CustomLog /dev/stdout combined | ||||
|  | ||||
|     SSLEngine on | ||||
|     SSLProtocol {{ env.IRONIC_VMEDIA_SSL_PROTOCOL }} | ||||
|     SSLCertificateFile {{ env.IRONIC_VMEDIA_CERT_FILE }} | ||||
|     SSLCertificateKeyFile {{ env.IRONIC_VMEDIA_KEY_FILE }} | ||||
|  | ||||
|     <Directory "/shared"> | ||||
|         AllowOverride None | ||||
|         Require all granted | ||||
|     </Directory> | ||||
|  | ||||
|     <Directory "/shared/html"> | ||||
|         Options Indexes FollowSymLinks | ||||
|         AllowOverride None | ||||
|         Require all granted | ||||
|     </Directory> | ||||
| </VirtualHost> | ||||
|  | ||||
| <Location ~ "^/(redfish|ilo)/"> | ||||
|     SSLRequireSSL | ||||
| </Location> | ||||
| @@ -1,59 +0,0 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| set -euxo pipefail | ||||
|  | ||||
| export IRONIC_REVERSE_PROXY_SETUP=${IRONIC_REVERSE_PROXY_SETUP:-false} | ||||
|  | ||||
| # Backward compatibility | ||||
| if [[ "${IRONIC_DEPLOYMENT:-}" == "Conductor" ]]; then | ||||
|     export IRONIC_EXPOSE_JSON_RPC=true | ||||
| else | ||||
|     export IRONIC_EXPOSE_JSON_RPC="${IRONIC_EXPOSE_JSON_RPC:-false}" | ||||
| fi | ||||
|  | ||||
| IRONIC_HTPASSWD_FILE=/etc/ironic/htpasswd | ||||
| if [[ -f "/auth/ironic/htpasswd" ]]; then | ||||
|     IRONIC_HTPASSWD=$(</auth/ironic/htpasswd) | ||||
| fi | ||||
| export IRONIC_HTPASSWD=${IRONIC_HTPASSWD:-${HTTP_BASIC_HTPASSWD:-}} | ||||
|  | ||||
| configure_client_basic_auth() | ||||
| { | ||||
|     local auth_config_file="/auth/$1/auth-config" | ||||
|     local dest="${2:-/etc/ironic/ironic.conf}" | ||||
|     if [[ -f "${auth_config_file}" ]]; then | ||||
|         # Merge configurations in the "auth" directory into the default ironic configuration file | ||||
|         crudini --merge "${dest}" < "${auth_config_file}" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| configure_json_rpc_auth() | ||||
| { | ||||
|     if [[ "${IRONIC_EXPOSE_JSON_RPC}" == "true" ]]; then | ||||
|         if [[ -z "${IRONIC_HTPASSWD}" ]]; then | ||||
|             echo "FATAL: enabling JSON RPC requires authentication" | ||||
|             exit 1 | ||||
|         fi | ||||
|         printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}-rpc" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| configure_ironic_auth() | ||||
| { | ||||
|     local config=/etc/ironic/ironic.conf | ||||
|     # Configure HTTP basic auth for API server | ||||
|     if [[ -n "${IRONIC_HTPASSWD}" ]]; then | ||||
|         printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}" | ||||
|         if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "false" ]]; then | ||||
|             crudini --set "${config}" DEFAULT auth_strategy http_basic | ||||
|             crudini --set "${config}" DEFAULT http_basic_auth_user_file "${IRONIC_HTPASSWD_FILE}" | ||||
|         fi | ||||
|     fi | ||||
| } | ||||
|  | ||||
| write_htpasswd_files() | ||||
| { | ||||
|     if [[ -n "${IRONIC_HTPASSWD:-}" ]]; then | ||||
|         printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}" | ||||
|     fi | ||||
| } | ||||
| @@ -1,119 +0,0 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| set -euxo pipefail | ||||
|  | ||||
| IRONIC_EXTERNAL_IP="${IRONIC_EXTERNAL_IP:-}" | ||||
|  | ||||
| # Define the VLAN interfaces to be included in introspection report, e.g. | ||||
| #   all - all VLANs on all interfaces using LLDP information | ||||
| #   <interface> - all VLANs on a particular interface using LLDP information | ||||
| #   <interface.vlan> - a particular VLAN on an interface, not relying on LLDP | ||||
| export IRONIC_ENABLE_VLAN_INTERFACES=${IRONIC_ENABLE_VLAN_INTERFACES:-${IRONIC_INSPECTOR_VLAN_INTERFACES:-all}} | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/tls-common.sh | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/ironic-common.sh | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/auth-common.sh | ||||
|  | ||||
| export HTTP_PORT=${HTTP_PORT:-80} | ||||
|  | ||||
| export IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB:-true} | ||||
|  | ||||
| if [[ "$IRONIC_USE_MARIADB" == "true" ]]; then | ||||
|     MARIADB_PASSWORD=${MARIADB_PASSWORD} | ||||
|     MARIADB_DATABASE=${MARIADB_DATABASE:-ironic} | ||||
|     MARIADB_USER=${MARIADB_USER:-ironic} | ||||
|     MARIADB_HOST=${MARIADB_HOST:-127.0.0.1} | ||||
|     export MARIADB_CONNECTION="mysql+pymysql://${MARIADB_USER}:${MARIADB_PASSWORD}@${MARIADB_HOST}/${MARIADB_DATABASE}?charset=utf8" | ||||
|     if [[ "$MARIADB_TLS_ENABLED" == "true" ]]; then | ||||
|         export MARIADB_CONNECTION="${MARIADB_CONNECTION}&ssl=on&ssl_ca=${MARIADB_CACERT_FILE}" | ||||
|     fi | ||||
| fi | ||||
|  | ||||
| # TODO(dtantsur): remove the explicit default once we get | ||||
| # https://review.opendev.org/761185 in the repositories | ||||
| NUMPROC="$(grep -c "^processor" /proc/cpuinfo)" | ||||
| if [[ "$NUMPROC" -lt 4 ]]; then | ||||
|     NUMPROC=4 | ||||
| fi | ||||
| export NUMWORKERS=${NUMWORKERS:-$NUMPROC} | ||||
|  | ||||
| # Whether to enable fast_track provisioning or not | ||||
| export IRONIC_FAST_TRACK=${IRONIC_FAST_TRACK:-true} | ||||
|  | ||||
| # Whether cleaning disks before and after deployment | ||||
| export IRONIC_AUTOMATED_CLEAN=${IRONIC_AUTOMATED_CLEAN:-true} | ||||
|  | ||||
| # Wheter to enable the sensor data collection | ||||
| export SEND_SENSOR_DATA=${SEND_SENSOR_DATA:-false} | ||||
|  | ||||
| # Set of collectors that should be used with IPA inspection | ||||
| export IRONIC_IPA_COLLECTORS=${IRONIC_IPA_COLLECTORS:-default,logs} | ||||
|  | ||||
| wait_for_interface_or_ip | ||||
|  | ||||
| # Hostname to use for the current conductor instance. | ||||
| export IRONIC_CONDUCTOR_HOST=${IRONIC_CONDUCTOR_HOST:-${IRONIC_URL_HOST}} | ||||
|  | ||||
| export IRONIC_BASE_URL=${IRONIC_BASE_URL:-"${IRONIC_SCHEME}://${IRONIC_URL_HOST}:${IRONIC_ACCESS_PORT}"} | ||||
|  | ||||
| if [[ -n "$IRONIC_EXTERNAL_IP" ]]; then | ||||
|     export IRONIC_EXTERNAL_CALLBACK_URL=${IRONIC_EXTERNAL_CALLBACK_URL:-"${IRONIC_SCHEME}://${IRONIC_EXTERNAL_IP}:${IRONIC_ACCESS_PORT}"} | ||||
|     if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]]; then | ||||
|         export IRONIC_EXTERNAL_HTTP_URL=${IRONIC_EXTERNAL_HTTP_URL:-"https://${IRONIC_EXTERNAL_IP}:${VMEDIA_TLS_PORT}"} | ||||
|     else | ||||
|         export IRONIC_EXTERNAL_HTTP_URL=${IRONIC_EXTERNAL_HTTP_URL:-"http://${IRONIC_EXTERNAL_IP}:${HTTP_PORT}"} | ||||
|     fi | ||||
| fi | ||||
|  | ||||
| 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 /etc/ironic/ironic.conf ]]; then | ||||
|     # Make a copy of the original supposed empty configuration file | ||||
|     cp /etc/ironic/ironic.conf /etc/ironic/ironic.conf_orig | ||||
| fi | ||||
|  | ||||
| # oslo.config also supports Config Opts From Environment, log them to stdout | ||||
| echo 'Options set from Environment variables' | ||||
| env | grep "^OS_" || true | ||||
|  | ||||
| mkdir -p /shared/html | ||||
| mkdir -p /shared/ironic_prometheus_exporter | ||||
|  | ||||
| configure_json_rpc_auth | ||||
|  | ||||
| if [[ -f /proc/sys/crypto/fips_enabled ]]; then | ||||
|     ENABLE_FIPS_IPA=$(cat /proc/sys/crypto/fips_enabled) | ||||
|     export ENABLE_FIPS_IPA | ||||
| fi | ||||
|  | ||||
| # The original ironic.conf is empty, and can be found in ironic.conf_orig | ||||
| render_j2_config /etc/ironic/ironic.conf.j2 /etc/ironic/ironic.conf | ||||
|  | ||||
| configure_client_basic_auth ironic-rpc | ||||
|  | ||||
| # Make sure ironic traffic bypasses any proxies | ||||
| export NO_PROXY="${NO_PROXY:-},$IRONIC_IP" | ||||
|  | ||||
| PROBE_CURL_ARGS= | ||||
| if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "true" ]]; then | ||||
|     if [[ "${IRONIC_PRIVATE_PORT}" == "unix" ]]; then | ||||
|         PROBE_URL="http://127.0.0.1:6385" | ||||
|         PROBE_CURL_ARGS="--unix-socket /shared/ironic.sock" | ||||
|     else | ||||
|         PROBE_URL="http://127.0.0.1:${IRONIC_PRIVATE_PORT}" | ||||
|     fi | ||||
| else | ||||
|         PROBE_URL="${IRONIC_BASE_URL}" | ||||
| fi | ||||
| export PROBE_CURL_ARGS | ||||
| export PROBE_URL | ||||
|  | ||||
| PROBE_KIND=readiness render_j2_config /bin/ironic-probe.j2 /bin/ironic-readiness | ||||
| PROBE_KIND=liveness render_j2_config /bin/ironic-probe.j2 /bin/ironic-liveness | ||||
							
								
								
									
										57
									
								
								ironic-image/configure-nonroot.sh
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										57
									
								
								ironic-image/configure-nonroot.sh
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -1,53 +1,70 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| # This script changes permissions to allow Ironic container to run as non-root | ||||
| # user. As the same image is used to run ironic, ironic-httpd, ironic-dsnmasq, | ||||
| # and ironic-log-watch via BMO's ironic k8s manifest, it has | ||||
| # to be configured to work with multiple different users and groups, while they | ||||
| # share files via bind mounts (/shared, /certs/*), which can only get one | ||||
| # group id as "fsGroup". Additionally, dnsmasq needs three capabilities to run | ||||
| # which we provide via "setcap", and "allowPrivilegeEscalation: true" in | ||||
| # manifest. | ||||
|  | ||||
| set -eux | ||||
|  | ||||
| # user and group are from ironic rpms (uid 997, gid 994) | ||||
| NONROOT_UID=10475 | ||||
| NONROOT_GID=10475 | ||||
| USER="ironic-suse" | ||||
| IRONIC_USER="ironic-suse" | ||||
| IRONIC_GROUP="ironic-suse" | ||||
|  | ||||
| groupadd -r -g ${NONROOT_GID} ${USER} | ||||
| groupadd -r -g ${NONROOT_GID} ${IRONIC_GROUP} | ||||
| useradd -r -g ${NONROOT_GID} \ | ||||
|            -u ${NONROOT_UID} \ | ||||
|            -d /var/lib/ironic \ | ||||
|            -s /sbin/nologin \ | ||||
|            ${USER} | ||||
|            ${IRONIC_USER} | ||||
|  | ||||
| # create ironic's http_root directory | ||||
| mkdir -p /shared/html | ||||
| chown "${NONROOT_UID}":"${NONROOT_GID}" /shared/html | ||||
| # most containers mount /shared but dnsmasq can live without it | ||||
| mkdir -p /shared | ||||
| mkdir -p /data | ||||
| mkdir -p /conf | ||||
| chown "${IRONIC_USER}":"${IRONIC_GROUP}" /shared | ||||
| chown "${IRONIC_USER}":"${IRONIC_GROUP}" /data | ||||
| chown "${IRONIC_USER}":"${IRONIC_GROUP}" /conf | ||||
|  | ||||
| # we'll bind mount shared ca and ironic certificate dirs here | ||||
| # that need to have correct ownership as the entire ironic in BMO | ||||
| # deployment shares a single fsGroup in manifest's securityContext | ||||
| mkdir -p /certs/ca | ||||
| chown "${NONROOT_UID}":"${NONROOT_GID}" /certs{,/ca} | ||||
| chown "${IRONIC_USER}":"${IRONIC_GROUP}" /certs{,/ca} | ||||
| chmod 2775 /certs{,/ca} | ||||
|  | ||||
| # apache2 permission changes | ||||
| chown -R "${NONROOT_UID}":"${NONROOT_GID}" /etc/apache2 | ||||
| chown -R "${NONROOT_UID}":"${NONROOT_GID}" /run | ||||
| chown -R "${IRONIC_USER}":"${IRONIC_GROUP}" /etc/apache2 | ||||
| chown -R "${IRONIC_USER}":"${IRONIC_GROUP}" /run | ||||
|  | ||||
| # ironic and httpd related changes | ||||
| mkdir -p /etc/httpd/conf.d | ||||
| chown -R "${NONROOT_UID}":"${NONROOT_GID}" /etc/ironic /etc/httpd /etc/httpd | ||||
| chown -R "${NONROOT_UID}":"${NONROOT_GID}" /var/log | ||||
| chmod 2775 /etc/ironic /etc/httpd/conf /etc/httpd/conf.d | ||||
| chmod 664 /etc/ironic/* /etc/httpd/conf/* /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/ | ||||
| #chmod 664 /etc/ironic/* /etc/httpd/conf/* /etc/httpd/conf.d/* | ||||
| chmod 664 /etc/ironic/* /etc/httpd/conf/* /etc/httpd/conf.modules.d/* | ||||
|  | ||||
| chown -R "${NONROOT_UID}":"${NONROOT_GID}" /var/lib/ironic | ||||
| chown -R "${IRONIC_USER}":"${IRONIC_GROUP}" /var/lib/ironic | ||||
| chmod 2775 /var/lib/ironic | ||||
| chmod 664 /var/lib/ironic/ironic.sqlite | ||||
|  | ||||
| # dnsmasq, and the capabilities required to run it as non-root user | ||||
| chown -R "${NONROOT_UID}":"${NONROOT_GID}" /etc/dnsmasq.conf /var/lib/dnsmasq | ||||
| chmod 2775 /var/lib/dnsmasq | ||||
| touch /var/lib/dnsmasq/dnsmasq.leases | ||||
| chmod 664 /etc/dnsmasq.conf /var/lib/dnsmasq/dnsmasq.leases | ||||
| chown -R "${IRONIC_USER}":"${IRONIC_GROUP}" /etc/dnsmasq.conf | ||||
| #handled at chart level | ||||
| #setcap "cap_net_raw,cap_net_admin,cap_net_bind_service=+eip" /usr/sbin/dnsmasq | ||||
|  | ||||
| # ca-certificates permission changes | ||||
| touch /var/lib/ca-certificates/ca-bundle.pem.new | ||||
| chown -R "${NONROOT_UID}":"${NONROOT_GID}" /var/lib/ca-certificates/ | ||||
| chown -R "${IRONIC_USER}":"${IRONIC_GROUP}" /var/lib/ca-certificates/ | ||||
| chmod -R +w /var/lib/ca-certificates/ | ||||
|  | ||||
| # probes that are created before start | ||||
| touch /bin/ironic-{readi,live}ness | ||||
| chown root:"${NONROOT_GID}" /bin/ironic-{readi,live}ness | ||||
| chown root:"${IRONIC_GROUP}" /bin/ironic-{readi,live}ness | ||||
| chmod 775 /bin/ironic-{readi,live}ness | ||||
|   | ||||
| @@ -1,57 +0,0 @@ | ||||
| # Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||
| # not use this file except in compliance with the License. You may obtain | ||||
| # a copy of the License at | ||||
| # | ||||
| #      http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software | ||||
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
| # License for the specific language governing permissions and limitations | ||||
| # under the License. | ||||
|  | ||||
|  | ||||
| {% if env.LISTEN_ALL_INTERFACES | lower == "true" %} | ||||
| Listen {{ env.IRONIC_INSPECTOR_LISTEN_PORT }} | ||||
|  <VirtualHost *:{{ env.IRONIC_INSPECTOR_LISTEN_PORT }}> | ||||
| {% else %} | ||||
| Listen {{ env.IRONIC_URL_HOST }}:{{ env.IRONIC_INSPECTOR_LISTEN_PORT }} | ||||
|  <VirtualHost {{ env.IRONIC_URL_HOST }}:{{ env.IRONIC_INSPECTOR_LISTEN_PORT }}> | ||||
| {% endif %} | ||||
|     {% if env.IRONIC_INSPECTOR_PRIVATE_PORT == "unix" %} | ||||
|     ProxyPass "/"  "unix:/shared/inspector.sock|http://127.0.0.1/" | ||||
|     ProxyPassReverse "/"  "unix:/shared/inspector.sock|http://127.0.0.1/" | ||||
|     {% else %} | ||||
|     ProxyPass "/"  "http://127.0.0.1:{{ env.IRONIC_INSPECTOR_PRIVATE_PORT }}/" | ||||
|     ProxyPassReverse "/"  "http://127.0.0.1:{{ env.IRONIC_INSPECTOR_PRIVATE_PORT }}/" | ||||
|     {% endif %} | ||||
|  | ||||
|     SetEnv APACHE_RUN_USER ironic-suse | ||||
|     SetEnv APACHE_RUN_GROUP ironic-suse | ||||
|  | ||||
|     ErrorLog /dev/stdout | ||||
|     LogLevel debug | ||||
|     CustomLog /dev/stdout combined | ||||
|  | ||||
|     SSLEngine On | ||||
|     SSLProtocol {{ env.IRONIC_SSL_PROTOCOL }} | ||||
|     SSLCertificateFile {{ env.IRONIC_INSPECTOR_CERT_FILE }}  | ||||
|     SSLCertificateKeyFile {{ env.IRONIC_INSPECTOR_KEY_FILE }} | ||||
|  | ||||
|     {% if "INSPECTOR_HTPASSWD" in env and env.INSPECTOR_HTPASSWD | length %} | ||||
|     <Location / > | ||||
|         AuthType Basic | ||||
|         AuthName "Restricted area" | ||||
|         AuthUserFile "/etc/ironic-inspector/htpasswd" | ||||
|         Require valid-user | ||||
|     </Location> | ||||
|  | ||||
|     <Location ~ "^/(v1/?)?$" > | ||||
|         Require all granted | ||||
|     </Location> | ||||
|  | ||||
|     <Location /v1/continue > | ||||
|         Require all granted | ||||
|     </Location> | ||||
|     {% endif %} | ||||
| </VirtualHost> | ||||
| @@ -1,10 +0,0 @@ | ||||
| #!ipxe | ||||
|  | ||||
| :retry_boot | ||||
| echo In inspector.ipxe | ||||
| imgfree | ||||
| # NOTE(dtantsur): keep inspection kernel params in [mdns]params in | ||||
| # ironic-inspector-image and configuration in configure-ironic.sh | ||||
| kernel --timeout 60000 http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/images/ironic-python-agent-${buildarch}.kernel ipa-insecure=1 ipa-inspection-collectors={{ env.IRONIC_IPA_COLLECTORS }} systemd.journald.forward_to_console=yes BOOTIF=${mac} ipa-debug=1 ipa-enable-vlan-interfaces={{ env.IRONIC_ENABLE_VLAN_INTERFACES }} ipa-inspection-dhcp-all-interfaces=1 ipa-collect-lldp=1 {{ env.INSPECTOR_EXTRA_ARGS }} initrd=ironic-python-agent.initramfs {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} || goto retry_boot | ||||
| initrd --timeout 60000 http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/images/ironic-python-agent-${buildarch}.initramfs || goto retry_boot | ||||
| boot | ||||
| @@ -1,107 +0,0 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| set -euxo pipefail | ||||
|  | ||||
| IRONIC_IP="${IRONIC_IP:-}" | ||||
| PROVISIONING_INTERFACE="${PROVISIONING_INTERFACE:-}" | ||||
| PROVISIONING_IP="${PROVISIONING_IP:-}" | ||||
| PROVISIONING_MACS="${PROVISIONING_MACS:-}" | ||||
| IPXE_CUSTOM_FIRMWARE_DIR="${IPXE_CUSTOM_FIRMWARE_DIR:-/shared/custom_ipxe_firmware}" | ||||
|  | ||||
| get_provisioning_interface() | ||||
| { | ||||
|     if [[ -n "$PROVISIONING_INTERFACE" ]]; then | ||||
|         # don't override the PROVISIONING_INTERFACE if one is provided | ||||
|         echo "$PROVISIONING_INTERFACE" | ||||
|         return | ||||
|     fi | ||||
|  | ||||
|     local interface="provisioning" | ||||
|  | ||||
|     if [[ -n "${PROVISIONING_IP}" ]]; then | ||||
|         if ip -br addr show | grep -qi " ${PROVISIONING_IP}/"; then | ||||
|             interface="$(ip -br addr show | grep -i " ${PROVISIONING_IP}/" | cut -f 1 -d ' ' | cut -f 1 -d '@')" | ||||
|         fi | ||||
|     fi | ||||
|  | ||||
|     for mac in ${PROVISIONING_MACS//,/ }; do | ||||
|         if ip -br link show up | grep -qi "$mac"; then | ||||
|             interface="$(ip -br link show up | grep -i "$mac" | cut -f 1 -d ' ' | cut -f 1 -d '@')" | ||||
|             break | ||||
|         fi | ||||
|     done | ||||
|  | ||||
|     echo "$interface" | ||||
| } | ||||
|  | ||||
| PROVISIONING_INTERFACE="$(get_provisioning_interface)" | ||||
| export PROVISIONING_INTERFACE | ||||
|  | ||||
| export LISTEN_ALL_INTERFACES="${LISTEN_ALL_INTERFACES:-true}" | ||||
|  | ||||
| # Wait for the interface or IP to be up, sets $IRONIC_IP | ||||
| wait_for_interface_or_ip() | ||||
| { | ||||
|     # If $PROVISIONING_IP is specified, then we wait for that to become available on an interface, otherwise we look at $PROVISIONING_INTERFACE for an IP | ||||
|     if [[ -n "$PROVISIONING_IP" ]]; then | ||||
|         # Convert the address using ipcalc which strips out the subnet. For IPv6 addresses, this will give the short-form address | ||||
|         IRONIC_IP="$(ipcalc "${PROVISIONING_IP}" | grep "^Address:" | awk '{print $2}')" | ||||
|         export IRONIC_IP | ||||
|         until grep -F " ${IRONIC_IP}/" <(ip -br addr show); do | ||||
|             echo "Waiting for ${IRONIC_IP} to be configured on an interface" | ||||
|             sleep 1 | ||||
|         done | ||||
|     else | ||||
|         until [[ -n "$IRONIC_IP" ]]; do | ||||
|             echo "Waiting for ${PROVISIONING_INTERFACE} interface to be configured" | ||||
|             IRONIC_IP="$(ip -br add show scope global up dev "${PROVISIONING_INTERFACE}" | awk '{print $3}' | sed -e 's%/.*%%' | head -n 1)" | ||||
|             export IRONIC_IP | ||||
|             sleep 1 | ||||
|         done | ||||
|     fi | ||||
|  | ||||
|     # If the IP contains a colon, then it's an IPv6 address, and the HTTP | ||||
|     # host needs surrounding with brackets | ||||
|     if [[ "$IRONIC_IP" =~ .*:.* ]]; then | ||||
|         export IPV=6 | ||||
|         export IRONIC_URL_HOST="[$IRONIC_IP]" | ||||
|     else | ||||
|         export IPV=4 | ||||
|         export IRONIC_URL_HOST="$IRONIC_IP" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| render_j2_config() | ||||
| { | ||||
|     ls $1 # DEBUG | ||||
|     python3 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' < "$1" | ||||
|     python3 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' < "$1" > "$2" | ||||
|     ls $2 # DEBUG | ||||
| } | ||||
|  | ||||
| run_ironic_dbsync() | ||||
| { | ||||
|     if [[ "${IRONIC_USE_MARIADB:-true}" == "true" ]]; then | ||||
|         # It's possible for the dbsync to fail if mariadb is not up yet, so | ||||
|         # retry until success | ||||
|         until ironic-dbsync --config-file /etc/ironic/ironic.conf upgrade; do | ||||
|             echo "WARNING: ironic-dbsync failed, retrying" | ||||
|             sleep 1 | ||||
|         done | ||||
|     else | ||||
|         # SQLite does not support some statements. Fortunately, we can just create | ||||
|         # the schema in one go if not already created, instead of going through an upgrade | ||||
|         DB_VERSION="$(ironic-dbsync --config-file /etc/ironic/ironic.conf version)" | ||||
|         if [[ "${DB_VERSION}" == "None" ]]; then | ||||
|             ironic-dbsync --config-file /etc/ironic/ironic.conf create_schema | ||||
|         fi | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # Use the special value "unix" for unix sockets | ||||
| export IRONIC_PRIVATE_PORT=${IRONIC_PRIVATE_PORT:-unix} | ||||
|  | ||||
| export IRONIC_ACCESS_PORT=${IRONIC_ACCESS_PORT:-6385} | ||||
| export IRONIC_LISTEN_PORT=${IRONIC_LISTEN_PORT:-$IRONIC_ACCESS_PORT} | ||||
|  | ||||
| export IRONIC_ENABLE_DISCOVERY=${IRONIC_ENABLE_DISCOVERY:-${IRONIC_INSPECTOR_ENABLE_DISCOVERY:-false}} | ||||
| @@ -1,4 +1,5 @@ | ||||
| Listen {{ env.IPXE_TLS_PORT }} | ||||
| Listen 0.0.0.0:{{ env.IPXE_TLS_PORT }} | ||||
| Listen [::]:{{ env.IPXE_TLS_PORT }} | ||||
| 
 | ||||
| <VirtualHost *:{{ env.IPXE_TLS_PORT }}> | ||||
|     ErrorLog /dev/stderr | ||||
							
								
								
									
										41
									
								
								ironic-image/ironic-config/apache2-vmedia.conf.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								ironic-image/ironic-config/apache2-vmedia.conf.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| Listen 0.0.0.0:{{ env.VMEDIA_TLS_PORT }} | ||||
| Listen [::]:{{ env.VMEDIA_TLS_PORT }} | ||||
|  | ||||
| <VirtualHost *:{{ env.VMEDIA_TLS_PORT }}> | ||||
|     ErrorLog /dev/stderr | ||||
|     LogLevel debug | ||||
|     CustomLog /dev/stdout combined | ||||
|  | ||||
|     SSLEngine on | ||||
|     SSLProtocol {{ env.IRONIC_VMEDIA_SSL_PROTOCOL }} | ||||
|     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> | ||||
|     <Directory ~ "/shared/html/(redfish|ilo)/"> | ||||
|         Options Indexes FollowSymLinks | ||||
|         AllowOverride None | ||||
|         Require all granted | ||||
|     </Directory> | ||||
| </VirtualHost> | ||||
|  | ||||
| <Location ~ "^/(redfish|ilo)/"> | ||||
|     SSLRequireSSL | ||||
| </Location> | ||||
| @@ -3,6 +3,7 @@ bind-dynamic | ||||
| enable-tftp | ||||
| tftp-root=/shared/tftpboot | ||||
| log-queries | ||||
| dhcp-leasefile=/data/dnsmasq/dnsmasq.leases | ||||
| 
 | ||||
| # Configure listening for DNS (0 disables DNS) | ||||
| port={{ env.DNS_PORT }} | ||||
| @@ -31,11 +32,11 @@ dhcp-match=ipxe,175 | ||||
| # Client is already running iPXE; move to next stage of chainloading | ||||
| {%- if env.IPXE_TLS_SETUP == "true"  %} | ||||
| # iPXE with (U)EFI | ||||
| dhcp-boot=tag:efi,tag:ipxe,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/custom-ipxe/snponly.efi | ||||
| dhcp-boot=tag:efi,tag:ipxe,{{ env.IRONIC_HTTP_URL }}/custom-ipxe/snponly.efi | ||||
| # iPXE with BIOS | ||||
| dhcp-boot=tag:ipxe,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/custom-ipxe/undionly.kpxe | ||||
| dhcp-boot=tag:ipxe,{{ env.IRONIC_HTTP_URL }}/custom-ipxe/undionly.kpxe | ||||
| {% else %} | ||||
| dhcp-boot=tag:ipxe,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/boot.ipxe | ||||
| dhcp-boot=tag:ipxe,{{ env.IRONIC_HTTP_URL }}/boot.ipxe | ||||
| {% endif %} | ||||
| 
 | ||||
| # Note: Need to test EFI booting | ||||
| @@ -59,8 +60,8 @@ ra-param={{ env.PROVISIONING_INTERFACE }},0,0 | ||||
| 
 | ||||
| dhcp-vendorclass=set:pxe6,enterprise:343,PXEClient | ||||
| dhcp-userclass=set:ipxe6,iPXE | ||||
| dhcp-option=tag:pxe6,option6:bootfile-url,tftp://{{ env.IRONIC_URL_HOST }}/snponly.efi | ||||
| dhcp-option=tag:ipxe6,option6:bootfile-url,http://{{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }}/boot.ipxe | ||||
| dhcp-option=tag:pxe6,option6:bootfile-url,{{ env.IRONIC_TFTP_URL }}/snponly.efi | ||||
| dhcp-option=tag:ipxe6,option6:bootfile-url,{{ env.IRONIC_HTTP_URL }}/boot.ipxe | ||||
| 
 | ||||
| # It can be used when setting DNS or GW variables. | ||||
| {%- if env["GATEWAY_IP"] is undefined %} | ||||
| @@ -12,11 +12,21 @@ | ||||
| 
 | ||||
| 
 | ||||
| {% if env.LISTEN_ALL_INTERFACES | lower == "true" %} | ||||
| Listen {{ env.IRONIC_LISTEN_PORT }} | ||||
| Listen 0.0.0.0:{{ env.IRONIC_LISTEN_PORT }} | ||||
| Listen [::]:{{ env.IRONIC_LISTEN_PORT }} | ||||
|  <VirtualHost *:{{ env.IRONIC_LISTEN_PORT }}> | ||||
| {% else %} | ||||
| Listen {{ env.IRONIC_URL_HOST }}:{{ env.IRONIC_LISTEN_PORT }} | ||||
|  <VirtualHost {{ env.IRONIC_URL_HOST }}:{{ env.IRONIC_LISTEN_PORT }}> | ||||
| {% if env.ENABLE_IPV4 %} | ||||
| Listen {{ env.IRONIC_IP }}:{{ env.IRONIC_LISTEN_PORT }} | ||||
| {% endif %} | ||||
| {% if env.ENABLE_IPV6 %} | ||||
| Listen [{{ env.IRONIC_IPV6 }}]:{{ env.IRONIC_LISTEN_PORT }} | ||||
| {% endif %} | ||||
| {% if env.IRONIC_URL_HOSTNAME is defined and env.IRONIC_URL_HOSTNAME|length %} | ||||
| <VirtualHost {{ env.IRONIC_URL_HOSTNAME }}:{{ env.IRONIC_LISTEN_PORT }}> | ||||
| {% else %} | ||||
| <VirtualHost {% if env.ENABLE_IPV4 %}{{ env.IRONIC_IP }}:{{ env.IRONIC_LISTEN_PORT }}{% endif %} {% if env.ENABLE_IPV6 %}[{{ env.IRONIC_IPV6 }}]:{{ env.IRONIC_LISTEN_PORT }}{% endif %}> | ||||
| {% endif %} | ||||
| {% endif %} | ||||
| 
 | ||||
|     {% if env.IRONIC_PRIVATE_PORT == "unix" %} | ||||
| @@ -45,7 +55,7 @@ Listen {{ env.IRONIC_URL_HOST }}:{{ env.IRONIC_LISTEN_PORT }} | ||||
|          {% if "IRONIC_HTPASSWD" in env and env.IRONIC_HTPASSWD | length %} | ||||
|             AuthType Basic | ||||
|             AuthName "Restricted area" | ||||
|             AuthUserFile "/etc/ironic/htpasswd" | ||||
|             AuthUserFile {{ env.HTPASSWD_FILE }} | ||||
|             Require valid-user | ||||
|          {% endif %} | ||||
|     </Location> | ||||
| @@ -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 | ||||
| @@ -1,10 +1,16 @@ | ||||
| ServerRoot "/etc/httpd" | ||||
| ServerRoot {{ env.HTTPD_DIR }} | ||||
| {%- if env.LISTEN_ALL_INTERFACES | lower == "true" %} | ||||
| Listen {{ env.HTTP_PORT }} | ||||
| Listen 0.0.0.0:{{ env.HTTP_PORT }} | ||||
| Listen [::]:{{ env.HTTP_PORT }} | ||||
| {% else %} | ||||
| Listen {{ env.IRONIC_URL_HOST }}:{{ env.HTTP_PORT }} | ||||
| {% if env.ENABLE_IPV4 %} | ||||
| Listen {{ env.IRONIC_IP }}:{{ env.HTTP_PORT }} | ||||
| {% endif %} | ||||
| Include conf.modules.d/*.conf | ||||
| {% if env.ENABLE_IPV6 %} | ||||
| Listen [{{ env.IRONIC_IPV6 }}]:{{ env.HTTP_PORT }} | ||||
| {% endif %} | ||||
| {% endif %} | ||||
| Include /etc/httpd/conf.modules.d/*.conf | ||||
| User ironic-suse | ||||
| Group ironic-suse | ||||
| 
 | ||||
							
								
								
									
										10
									
								
								ironic-image/ironic-config/inspector.ipxe.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ironic-image/ironic-config/inspector.ipxe.j2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #!ipxe | ||||
|  | ||||
| :retry_boot | ||||
| echo In inspector.ipxe | ||||
| imgfree | ||||
| # NOTE(dtantsur): keep inspection kernel params in [mdns]params in | ||||
| # ironic-inspector-image and configuration in configure-ironic.sh | ||||
| kernel --timeout 60000 {{ env.IRONIC_HTTP_URL }}/images/ironic-python-agent-${buildarch}.kernel ipa-insecure={{ env.IPA_INSECURE }} ipa-inspection-collectors={{ env.IRONIC_IPA_COLLECTORS }} systemd.journald.forward_to_console=yes BOOTIF=${mac} ipa-debug=1 ipa-enable-vlan-interfaces={{ env.IRONIC_ENABLE_VLAN_INTERFACES }} ipa-inspection-dhcp-all-interfaces=1 ipa-collect-lldp=1 {{ env.INSPECTOR_EXTRA_ARGS }} initrd=ironic-python-agent-${buildarch}.initramfs {% if env.IRONIC_RAMDISK_SSH_KEY %}sshkey="{{ env.IRONIC_RAMDISK_SSH_KEY|trim }}"{% endif %} {{ env.IRONIC_KERNEL_PARAMS|trim }} || goto retry_boot | ||||
| initrd --timeout 60000 {{ env.IRONIC_HTTP_URL }}/images/ironic-python-agent-${buildarch}.initramfs || goto retry_boot | ||||
| boot | ||||
| @@ -25,8 +25,15 @@ rpc_transport = none | ||||
| use_stderr = true | ||||
| # NOTE(dtantsur): the default md5 is not compatible with FIPS mode | ||||
| hash_ring_algorithm = sha256 | ||||
| {% if env.ENABLE_IPV4 %} | ||||
| my_ip = {{ env.IRONIC_IP }} | ||||
| {% endif %} | ||||
| {% if env.ENABLE_IPV6 %} | ||||
| my_ipv6 = {{ env.IRONIC_IPV6 }} | ||||
| {% endif %} | ||||
| 
 | ||||
| host = {{ env.IRONIC_CONDUCTOR_HOST }} | ||||
| tempdir = {{ env.IRONIC_TMP_DATA_DIR }} | ||||
| 
 | ||||
| # If a path to a certificate is defined, use that first for webserver | ||||
| {% if env.WEBSERVER_CACERT_FILE %} | ||||
| @@ -49,6 +56,7 @@ deploy_logs_local_path = /shared/log/ironic/deploy | ||||
| # retries here works around such problems without affecting the normal path. | ||||
| # See https://bugzilla.redhat.com/show_bug.cgi?id=1822763 | ||||
| max_command_attempts = 30 | ||||
| certificates_path = {{ env.IRONIC_GEN_CERT_DIR }} | ||||
| 
 | ||||
| [api] | ||||
| {% if env.IRONIC_REVERSE_PROXY_SETUP == "true" %} | ||||
| @@ -63,7 +71,7 @@ port = {{ env.IRONIC_PRIVATE_PORT }} | ||||
| {% endif %} | ||||
| public_endpoint = {{ env.IRONIC_BASE_URL }} | ||||
| {% else %} | ||||
| host_ip = {% if env.LISTEN_ALL_INTERFACES | lower == "true" %}::{% else %}{{ env.IRONIC_IP }}{% endif %} | ||||
| host_ip = {{ env.IRONIC_HOST_IP }} | ||||
| port = {{ env.IRONIC_LISTEN_PORT }} | ||||
| {% if env.IRONIC_TLS_SETUP == "true" %} | ||||
| enable_ssl_api = true | ||||
| @@ -83,28 +91,37 @@ 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 = {{ env.IRONIC_BOOT_BASE_URL }}/uefi_esp-{{ env.DEPLOY_ARCHITECTURE }}.img | ||||
| bootloader_by_arch = {{ env.BOOTLOADER_BY_ARCH }} | ||||
| verify_step_priority_override = management.clear_job_queue:90 | ||||
| # We don't use this feature, and it creates an additional load on the database | ||||
| node_history = False | ||||
| # Provide for a timeout longer than 60 seconds for certain vendor's hardware | ||||
| power_state_change_timeout = 120 | ||||
| {% if env.IRONIC_DEFAULT_KERNEL is defined %} | ||||
| deploy_kernel = file://{{ env.IRONIC_DEFAULT_KERNEL }} | ||||
| {% if env.DEPLOY_KERNEL_URL is defined %} | ||||
| deploy_kernel = {{ env.DEPLOY_KERNEL_URL }} | ||||
| {% endif %} | ||||
| {% if env.IRONIC_DEFAULT_RAMDISK is defined %} | ||||
| deploy_ramdisk = file://{{ env.IRONIC_DEFAULT_RAMDISK }} | ||||
| {% 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 }} | ||||
| {% endif %} | ||||
| {% if env.DISABLE_DEEP_IMAGE_INSPECTION | lower == "true" %} | ||||
| disable_deep_image_inspection = True | ||||
| {% endif %} | ||||
| 
 | ||||
| [database] | ||||
| {% if env.IRONIC_USE_MARIADB | lower == "false" %} | ||||
| connection = sqlite:////var/lib/ironic/ironic.sqlite | ||||
| {% if env.IRONIC_USE_MARIADB | lower == "true" %} | ||||
| connection = {{ env.MARIADB_CONNECTION }} | ||||
| {% else %} | ||||
| connection = {{ env.LOCAL_DB_URI }} | ||||
| # Synchronous mode is required for data integrity in case of operating system | ||||
| # crash. In our case we restart the container from scratch, so we can save some | ||||
| # IO by not doing syncs all the time. | ||||
| sqlite_synchronous = False | ||||
| {% else %} | ||||
| connection = {{ env.MARIADB_CONNECTION }} | ||||
| {% endif %} | ||||
| 
 | ||||
| [deploy] | ||||
| @@ -112,15 +129,15 @@ default_boot_option = local | ||||
| erase_devices_metadata_priority = 10 | ||||
| erase_devices_priority = 0 | ||||
| http_root = /shared/html/ | ||||
| http_url = {{ env.IRONIC_BOOT_BASE_URL }} | ||||
| http_url = {% if env.VMEDIA_TLS_PORT %}{{ env.IRONIC_HTTPS_VMEDIA_URL }}{% else %}{{ env.IRONIC_HTTP_URL }}{% endif %} | ||||
| 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.IRONIC_VMEDIA_TLS_SETUP == "true" %} | ||||
| external_http_url = https://{{ env.IRONIC_URL_HOST }}:{{ env.VMEDIA_TLS_PORT }} | ||||
| {% elif env.VMEDIA_TLS_PORT %} | ||||
| external_http_url = {{ env.IRONIC_HTTPS_VMEDIA_URL }} | ||||
| {% endif %} | ||||
| {% if env.IRONIC_EXTERNAL_CALLBACK_URL %} | ||||
| external_callback_url = {{ env.IRONIC_EXTERNAL_CALLBACK_URL }} | ||||
| @@ -175,8 +192,8 @@ cipher_suite_versions = 3,17 | ||||
| # unauthenticated connections from other processes in the same host since the | ||||
| # containers are in host networking. | ||||
| auth_strategy = http_basic | ||||
| http_basic_auth_user_file = /etc/ironic/htpasswd-rpc | ||||
| host_ip = {% if env.LISTEN_ALL_INTERFACES | lower == "true" %}::{% else %}{{ env.IRONIC_IP }}{% endif %} | ||||
| http_basic_auth_user_file = {{ env.IRONIC_RPC_HTPASSWD_FILE }} | ||||
| host_ip = {{ env.IRONIC_HOST_IP }} | ||||
| {% if env.IRONIC_TLS_SETUP == "true" %} | ||||
| use_ssl = true | ||||
| cafile = {{ env.IRONIC_CACERT_FILE }} | ||||
| @@ -187,11 +204,6 @@ insecure = {{ env.IRONIC_INSECURE }} | ||||
| [nova] | ||||
| send_power_notifications = false | ||||
| 
 | ||||
| [oslo_messaging_notifications] | ||||
| driver = prometheus_exporter | ||||
| location = /shared/ironic_prometheus_exporter | ||||
| transport_url = fake:// | ||||
| 
 | ||||
| [pxe] | ||||
| # NOTE(dtantsur): keep this value at least 3x lower than | ||||
| # [conductor]deploy_callback_timeout so that at least some retries happen. | ||||
| @@ -1,68 +0,0 @@ | ||||
| [DEFAULT] | ||||
| auth_strategy = noauth | ||||
| debug = true | ||||
| transport_url = fake:// | ||||
| use_stderr = true | ||||
| {% if env.INSPECTOR_REVERSE_PROXY_SETUP == "true" %} | ||||
| {% if env.IRONIC_INSPECTOR_PRIVATE_PORT == "unix" %} | ||||
| listen_unix_socket = /shared/inspector.sock | ||||
| # NOTE(dtantsur): this is not ideal, but since the socket is accessed from | ||||
| # another container, we need to make it world-writeable. | ||||
| listen_unix_socket_mode = 0666 | ||||
| {% else %} | ||||
| listen_port = {{ env.IRONIC_INSPECTOR_PRIVATE_PORT }} | ||||
| listen_address = 127.0.0.1 | ||||
| {% endif %} | ||||
| {% elif env.LISTEN_ALL_INTERFACES | lower == "true" %} | ||||
| listen_port = {{ env.IRONIC_INSPECTOR_LISTEN_PORT }} | ||||
| listen_address = :: | ||||
| {% else %} | ||||
| listen_port = {{ env.IRONIC_INSPECTOR_LISTEN_PORT }} | ||||
| listen_address = {{ env.IRONIC_IP }} | ||||
| {% endif %} | ||||
| host = {{ env.IRONIC_IP }} | ||||
| {% if env.IRONIC_INSPECTOR_TLS_SETUP == "true" and env.INSPECTOR_REVERSE_PROXY_SETUP == "false" %} | ||||
| use_ssl = true | ||||
| {% endif %} | ||||
|  | ||||
| [database] | ||||
| connection = sqlite:////var/lib/ironic-inspector/ironic-inspector.db | ||||
|  | ||||
| {% if env.IRONIC_INSPECTOR_ENABLE_DISCOVERY == "true" %} | ||||
| [discovery] | ||||
| enroll_node_driver = ipmi | ||||
| {% endif %} | ||||
|  | ||||
| [ironic] | ||||
| auth_type = none | ||||
| endpoint_override = {{ env.IRONIC_BASE_URL }} | ||||
| {% if env.IRONIC_TLS_SETUP == "true" %} | ||||
| cafile = {{ env.IRONIC_CACERT_FILE }} | ||||
| insecure = {{ env.IRONIC_INSECURE }} | ||||
| {% endif %} | ||||
|  | ||||
| [processing] | ||||
| add_ports = all | ||||
| always_store_ramdisk_logs = true | ||||
| keep_ports = present | ||||
| {% if env.IRONIC_INSPECTOR_ENABLE_DISCOVERY == "true" %} | ||||
| node_not_found_hook = enroll | ||||
| {% endif %} | ||||
| permit_active_introspection = true | ||||
| power_off = false | ||||
| processing_hooks = $default_processing_hooks,lldp_basic | ||||
| ramdisk_logs_dir = /shared/log/ironic-inspector/ramdisk | ||||
| store_data = database | ||||
|  | ||||
| [pxe_filter] | ||||
| driver = noop | ||||
|  | ||||
| [service_catalog] | ||||
| auth_type = none | ||||
| endpoint_override = {{ env.IRONIC_INSPECTOR_BASE_URL }} | ||||
|  | ||||
| {% if env.IRONIC_INSPECTOR_TLS_SETUP == "true" and env.INSPECTOR_REVERSE_PROXY_SETUP == "false" %} | ||||
| [ssl] | ||||
| cert_file = {{ env.IRONIC_INSPECTOR_CERT_FILE }} | ||||
| key_file = {{ env.IRONIC_INSPECTOR_KEY_FILE }} | ||||
| {% endif %} | ||||
| @@ -1,9 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| set -eu -o pipefail | ||||
|  | ||||
| curl -sSf {{ env.PROBE_CURL_ARGS }} "{{ env.PROBE_URL }}" | ||||
|  | ||||
| # TODO(dtantsur): when PROBE_KIND==readiness, try the conductor and driver API | ||||
| # to make sure the conductor is ready. This requires having access to secrets | ||||
| # since these endpoints are authenticated. | ||||
| @@ -9,7 +9,7 @@ declare -A efi_arch=( | ||||
|  | ||||
| for arch in "${!efi_arch[@]}"; do | ||||
|    | ||||
|   DEST=/tmp/esp-${arch}.img | ||||
|   DEST=/tmp/uefi_esp_${arch}.img | ||||
|  | ||||
|   dd bs=1024 count=6400 if=/dev/zero of=$DEST | ||||
|   mkfs.msdos -F 12 -n 'ESP_IMAGE' $DEST | ||||
|   | ||||
| @@ -1,23 +0,0 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| # This setting must go before configure-ironic since it has different defaults. | ||||
| export IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB:-false} | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/configure-ironic.sh | ||||
|  | ||||
| # Ramdisk logs | ||||
| mkdir -p /shared/log/ironic/deploy | ||||
|  | ||||
| run_ironic_dbsync | ||||
|  | ||||
| if [[ "$IRONIC_TLS_SETUP" == "true" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then | ||||
|     # shellcheck disable=SC2034 | ||||
|     inotifywait -m -e delete_self "${IRONIC_CERT_FILE}" | while read -r file event; do | ||||
|         kill $(pgrep ironic) | ||||
|     done & | ||||
| fi | ||||
|  | ||||
| configure_ironic_auth | ||||
|  | ||||
| exec /usr/bin/ironic | ||||
| @@ -1,13 +0,0 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| export IRONIC_DEPLOYMENT="API" | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/configure-ironic.sh | ||||
|  | ||||
| export IRONIC_REVERSE_PROXY_SETUP=false | ||||
|  | ||||
| python3 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' < /tmp/httpd-ironic-api.conf.j2 > /etc/httpd/conf.d/ironic.conf | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/runhttpd | ||||
| @@ -1,20 +0,0 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| export IRONIC_DEPLOYMENT="Conductor" | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/configure-ironic.sh | ||||
|  | ||||
| # Ramdisk logs | ||||
| mkdir -p /shared/log/ironic/deploy | ||||
|  | ||||
| run_ironic_dbsync | ||||
|  | ||||
| if [[ "$IRONIC_TLS_SETUP" == "true" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then | ||||
|     # shellcheck disable=SC2034 | ||||
|     inotifywait -m -e delete_self "${IRONIC_CERT_FILE}" | while read -r file event; do | ||||
|         kill $(pgrep ironic) | ||||
|     done & | ||||
| fi | ||||
|  | ||||
| exec /usr/bin/ironic-conductor | ||||
| @@ -1,12 +0,0 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/configure-ironic.sh | ||||
|  | ||||
| FLASK_RUN_HOST=${FLASK_RUN_HOST:-0.0.0.0} | ||||
| FLASK_RUN_PORT=${FLASK_RUN_PORT:-9608} | ||||
|  | ||||
| export IRONIC_CONFIG="/etc/ironic/ironic.conf" | ||||
|  | ||||
| exec gunicorn -b "${FLASK_RUN_HOST}:${FLASK_RUN_PORT}" -w 4 \ | ||||
|     ironic_prometheus_exporter.app.wsgi:application | ||||
| @@ -1,62 +0,0 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| set -euxo pipefail | ||||
|  | ||||
| CONFIG=/etc/ironic-inspector/ironic-inspector.conf | ||||
|  | ||||
| export IRONIC_INSPECTOR_ENABLE_DISCOVERY=${IRONIC_INSPECTOR_ENABLE_DISCOVERY:-false} | ||||
| export INSPECTOR_REVERSE_PROXY_SETUP=${INSPECTOR_REVERSE_PROXY_SETUP:-false} | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/tls-common.sh | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/ironic-common.sh | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/auth-common.sh | ||||
|  | ||||
| if [[ "$USE_IRONIC_INSPECTOR" == "false" ]]; then | ||||
|     echo "FATAL: ironic-inspector is disabled via USE_IRONIC_INSPECTOR" | ||||
|     exit 1 | ||||
| fi | ||||
|  | ||||
| wait_for_interface_or_ip | ||||
|  | ||||
| IRONIC_INSPECTOR_PORT=${IRONIC_INSPECTOR_ACCESS_PORT} | ||||
| if [[ "$IRONIC_INSPECTOR_TLS_SETUP" == "true" ]]; then | ||||
|     if [[ "${INSPECTOR_REVERSE_PROXY_SETUP}" == "true" ]] && [[ "${IRONIC_INSPECTOR_PRIVATE_PORT}" != "unix" ]]; then | ||||
|         IRONIC_INSPECTOR_PORT=$IRONIC_INSPECTOR_PRIVATE_PORT | ||||
|     fi | ||||
| else | ||||
|     export INSPECTOR_REVERSE_PROXY_SETUP="false" # If TLS is not used, we have no reason to use the reverse proxy | ||||
| fi | ||||
|  | ||||
| export IRONIC_INSPECTOR_BASE_URL="${IRONIC_INSPECTOR_SCHEME}://${IRONIC_URL_HOST}:${IRONIC_INSPECTOR_PORT}" | ||||
| export IRONIC_BASE_URL="${IRONIC_SCHEME}://${IRONIC_URL_HOST}:${IRONIC_ACCESS_PORT}" | ||||
|  | ||||
| build_j2_config() | ||||
| { | ||||
|     local CONFIG_FILE="$1" | ||||
|     python3 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' < "$CONFIG_FILE.j2" | ||||
| } | ||||
|  | ||||
| # Merge with the original configuration file from the package. | ||||
| build_j2_config "$CONFIG" | crudini --merge "$CONFIG" | ||||
|  | ||||
| configure_inspector_auth | ||||
|  | ||||
| configure_client_basic_auth ironic "${CONFIG}" | ||||
|  | ||||
| ironic-inspector-dbsync --config-file "${CONFIG}" upgrade | ||||
|  | ||||
| if [[ "$INSPECTOR_REVERSE_PROXY_SETUP" == "false" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then | ||||
|     # shellcheck disable=SC2034 | ||||
|     inotifywait -m -e delete_self "${IRONIC_INSPECTOR_CERT_FILE}" | while read -r file event; do | ||||
|         kill $(pgrep ironic) | ||||
|     done & | ||||
| fi | ||||
|  | ||||
| # Make sure ironic traffic bypasses any proxies | ||||
| export NO_PROXY="${NO_PROXY:-},$IRONIC_IP" | ||||
|  | ||||
| # shellcheck disable=SC2086 | ||||
| exec /usr/bin/ironic-inspector | ||||
| @@ -1,19 +0,0 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| # Ramdisk logs path | ||||
| LOG_DIR="/shared/log/ironic/deploy" | ||||
|  | ||||
| # The ironic container creates the directory, wait for | ||||
| # it to exist before running inotifywait or it can fail causing | ||||
| # a spurious restart | ||||
| while [ ! -d "${LOG_DIR}" ]; do | ||||
|   echo "Waiting for ${LOG_DIR}" | ||||
|   sleep 5 | ||||
| done | ||||
|  | ||||
| inotifywait -m "${LOG_DIR}" -e close_write | | ||||
|     while read -r path _action file; do | ||||
|         echo "************ Contents of ${path}/${file} ramdisk log file bundle **************" | ||||
|         tar -xOzvvf "${path}/${file}" | sed -e "s/^/${file}: /" | ||||
|         rm -f "${path}/${file}" | ||||
|     done | ||||
							
								
								
									
										97
									
								
								ironic-image/scripts/auth-common.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								ironic-image/scripts/auth-common.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| set -euxo pipefail | ||||
|  | ||||
| export IRONIC_REVERSE_PROXY_SETUP=${IRONIC_REVERSE_PROXY_SETUP:-false} | ||||
|  | ||||
| # CUSTOM_CONFIG_DIR is also managed in the ironic-common.sh, in order to | ||||
| # keep auth-common and ironic-common separate (to stay consistent with the | ||||
| # architecture) part of the ironic-common logic had to be duplicated | ||||
| CUSTOM_CONFIG_DIR="${CUSTOM_CONFIG_DIR:-/conf}" | ||||
| IRONIC_CONF_DIR="${CUSTOM_CONFIG_DIR}/ironic" | ||||
|  | ||||
| # Backward compatibility | ||||
| if [[ "${IRONIC_DEPLOYMENT:-}" == "Conductor" ]]; then | ||||
|     export IRONIC_EXPOSE_JSON_RPC=true | ||||
| else | ||||
|     export IRONIC_EXPOSE_JSON_RPC="${IRONIC_EXPOSE_JSON_RPC:-false}" | ||||
| fi | ||||
|  | ||||
| IRONIC_HTPASSWD_FILE="${IRONIC_CONF_DIR}/htpasswd" | ||||
| export IRONIC_RPC_HTPASSWD_FILE="${IRONIC_HTPASSWD_FILE}-rpc" | ||||
| if [[ -f "/auth/ironic/htpasswd" ]]; then | ||||
|     IRONIC_HTPASSWD=$(</auth/ironic/htpasswd) | ||||
| fi | ||||
| if [[ -f "/auth/ironic-rpc/htpasswd" ]]; then | ||||
|     IRONIC_RPC_HTPASSWD=$(</auth/ironic-rpc/htpasswd) | ||||
| fi | ||||
| export IRONIC_HTPASSWD=${IRONIC_HTPASSWD:-${HTTP_BASIC_HTPASSWD:-}} | ||||
| export IRONIC_RPC_HTPASSWD=${IRONIC_RPC_HTPASSWD:-${IRONIC_HTPASSWD}} | ||||
|  | ||||
| if [[ -n "${MARIADB_PASSWORD:-}" ]]; then | ||||
|     echo "WARNING: passing MARIADB_PASSWORD is deprecated, mount a secret under /auth/mariadb instead" | ||||
| elif [[ -f /auth/mariadb/password ]]; then | ||||
|     MARIADB_PASSWORD=$(</auth/mariadb/password) | ||||
| fi | ||||
|  | ||||
| if [[ -z "${MARIADB_USER:-}" ]] && [[ -f /auth/mariadb/username ]]; then | ||||
|     MARIADB_USER=$(</auth/mariadb/username) | ||||
| fi | ||||
|  | ||||
| IRONIC_CONFIG="${IRONIC_CONF_DIR}/ironic.conf" | ||||
|  | ||||
| configure_json_rpc_auth() | ||||
| { | ||||
|     if [[ "${IRONIC_EXPOSE_JSON_RPC}" != "true" ]]; then | ||||
|         return | ||||
|     fi | ||||
|  | ||||
|     local auth_config_file="/auth/ironic-rpc/auth-config" | ||||
|     local username_file="/auth/ironic-rpc/username" | ||||
|     local password_file="/auth/ironic-rpc/password" | ||||
|     if [[ -f "${username_file}" ]] && [[ -f "${password_file}" ]]; then | ||||
|         crudini --set "${IRONIC_CONFIG}" json_rpc username "$(<${username_file})" | ||||
|         set +x | ||||
|         crudini --set "${IRONIC_CONFIG}" json_rpc password "$(<${password_file})" | ||||
|         set -x | ||||
|     elif [[ -f "${auth_config_file}" ]]; then | ||||
|         echo "WARNING: using auth-config is deprecated, mount a secret directly" | ||||
|         # Merge configurations in the "auth" directory into the default ironic configuration file | ||||
|         crudini --merge "${IRONIC_CONFIG}" < "${auth_config_file}" | ||||
|     else | ||||
|         echo "FATAL: no client-side credentials provided for JSON RPC" | ||||
|         echo "HINT: mount a secret with username and password fields under /auth/ironic-rpc" | ||||
|         exit 1 | ||||
|     fi | ||||
|  | ||||
|     if [[ -z "${IRONIC_RPC_HTPASSWD}" ]]; then | ||||
|         if [[ -f "${username_file}" ]] && [[ -f "${password_file}" ]]; then | ||||
|             htpasswd -c -i -B "${IRONIC_RPC_HTPASSWD_FILE}" "$(<${username_file})" <"${password_file}" | ||||
|         else | ||||
|             echo "FATAL: enabling JSON RPC requires authentication" | ||||
|             echo "HINT: mount a secret with either username and password or htpasswd under /auth/ironic-rpc" | ||||
|             exit 1 | ||||
|         fi | ||||
|     else | ||||
|         printf "%s\n" "${IRONIC_RPC_HTPASSWD}" > "${IRONIC_RPC_HTPASSWD_FILE}" | ||||
|     fi | ||||
| } | ||||
|  | ||||
| configure_ironic_auth() | ||||
| { | ||||
|     # Configure HTTP basic auth for API server | ||||
|     if [[ -n "${IRONIC_HTPASSWD}" ]]; then | ||||
|         printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}" | ||||
|         if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "false" ]]; then | ||||
|             crudini --set "${IRONIC_CONFIG}" DEFAULT auth_strategy http_basic | ||||
|             crudini --set "${IRONIC_CONFIG}" DEFAULT http_basic_auth_user_file "${IRONIC_HTPASSWD_FILE}" | ||||
|         fi | ||||
|     fi | ||||
| } | ||||
|  | ||||
| write_htpasswd_files() | ||||
| { | ||||
|     if [[ -n "${IRONIC_HTPASSWD:-}" ]]; then | ||||
|         printf "%s\n" "${IRONIC_HTPASSWD}" > "${IRONIC_HTPASSWD_FILE}" | ||||
|     fi | ||||
| } | ||||
							
								
								
									
										153
									
								
								ironic-image/scripts/configure-ironic.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										153
									
								
								ironic-image/scripts/configure-ironic.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,153 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| 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 | ||||
| #   <interface> - all VLANs on a particular interface using LLDP information | ||||
| #   <interface.vlan> - a particular VLAN on an interface, not relying on LLDP | ||||
| export IRONIC_ENABLE_VLAN_INTERFACES=${IRONIC_ENABLE_VLAN_INTERFACES:-${IRONIC_INSPECTOR_VLAN_INTERFACES:-all}} | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/tls-common.sh | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/ironic-common.sh | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/auth-common.sh | ||||
|  | ||||
| export HTTP_PORT=${HTTP_PORT:-80} | ||||
|  | ||||
| if [[ "${IRONIC_USE_MARIADB}" == true ]]; then | ||||
|     if [[ -z "${MARIADB_PASSWORD:-}" ]]; then | ||||
|         echo "FATAL: IRONIC_USE_MARIADB requires password, mount a secret under /auth/mariadb" | ||||
|         exit 1 | ||||
|     fi | ||||
|     MARIADB_DATABASE=${MARIADB_DATABASE:-ironic} | ||||
|     MARIADB_USER=${MARIADB_USER:-ironic} | ||||
|     MARIADB_HOST=${MARIADB_HOST:-127.0.0.1} | ||||
|     export MARIADB_CONNECTION="mysql+pymysql://${MARIADB_USER}:${MARIADB_PASSWORD}@${MARIADB_HOST}/${MARIADB_DATABASE}?charset=utf8" | ||||
|     if [[ "$MARIADB_TLS_ENABLED" == "true" ]]; then | ||||
|         export MARIADB_CONNECTION="${MARIADB_CONNECTION}&ssl=on&ssl_ca=${MARIADB_CACERT_FILE}" | ||||
|     fi | ||||
| fi | ||||
|  | ||||
| # zero makes it do cpu number detection on Ironic side | ||||
| export NUMWORKERS=${NUMWORKERS:-0} | ||||
|  | ||||
|  | ||||
| # Whether to enable fast_track provisioning or not | ||||
| export IRONIC_FAST_TRACK=${IRONIC_FAST_TRACK:-true} | ||||
|  | ||||
| # Whether cleaning disks before and after deployment | ||||
| export IRONIC_AUTOMATED_CLEAN=${IRONIC_AUTOMATED_CLEAN:-true} | ||||
|  | ||||
| # Wheter to enable the sensor data collection | ||||
| export SEND_SENSOR_DATA=${SEND_SENSOR_DATA:-false} | ||||
|  | ||||
| # Set of collectors that should be used with IPA inspection | ||||
| export IRONIC_IPA_COLLECTORS=${IRONIC_IPA_COLLECTORS:-default,logs} | ||||
|  | ||||
| wait_for_interface_or_ip | ||||
|  | ||||
| if [[ "$(echo "$LISTEN_ALL_INTERFACES" | tr '[:upper:]' '[:lower:]')" == "true" ]]; then | ||||
| export IRONIC_HOST_IP="::" | ||||
| elif [[ -n "${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}} | ||||
|  | ||||
| if [[ -n "$IRONIC_EXTERNAL_IP" ]]; then | ||||
|     export IRONIC_EXTERNAL_CALLBACK_URL=${IRONIC_EXTERNAL_CALLBACK_URL:-"${IRONIC_SCHEME}://${IRONIC_EXTERNAL_IP}:${IRONIC_ACCESS_PORT}"} | ||||
|     if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]]; then | ||||
|         export IRONIC_EXTERNAL_HTTP_URL=${IRONIC_EXTERNAL_HTTP_URL:-"https://${IRONIC_EXTERNAL_IP}:${VMEDIA_TLS_PORT}"} | ||||
|     else | ||||
|         export IRONIC_EXTERNAL_HTTP_URL=${IRONIC_EXTERNAL_HTTP_URL:-"http://${IRONIC_EXTERNAL_IP}:${HTTP_PORT}"} | ||||
|     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%?}" | ||||
| fi | ||||
|  | ||||
| if [[ -f "${IRONIC_CONF_DIR}/ironic.conf" ]]; then | ||||
|     # Make a copy of the original supposed empty configuration file | ||||
|     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 | ||||
|  | ||||
| mkdir -p /shared/html | ||||
|  | ||||
| if [[ -f /proc/sys/crypto/fips_enabled ]]; then | ||||
|     ENABLE_FIPS_IPA=$(cat /proc/sys/crypto/fips_enabled) | ||||
|     export ENABLE_FIPS_IPA | ||||
| fi | ||||
|  | ||||
| # The original ironic.conf is empty, and can be found in ironic.conf_orig | ||||
| render_j2_config "/etc/ironic/ironic.conf.j2" \ | ||||
|     "${IRONIC_CONF_DIR}/ironic.conf" | ||||
|  | ||||
| configure_json_rpc_auth | ||||
|  | ||||
| # Make sure ironic traffic bypasses any proxies | ||||
| export NO_PROXY="${NO_PROXY:-}" | ||||
|  | ||||
| if [[ -n "$IRONIC_IPV6" ]]; then | ||||
| export NO_PROXY="${NO_PROXY},${IRONIC_IPV6}" | ||||
| fi | ||||
| if [[ -n "$IRONIC_IP" ]]; then | ||||
| export NO_PROXY="${NO_PROXY},${IRONIC_IP}" | ||||
| fi | ||||
							
								
								
									
										295
									
								
								ironic-image/scripts/ironic-common.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										295
									
								
								ironic-image/scripts/ironic-common.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,295 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| 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:-}" | ||||
| PROVISIONING_INTERFACE="${PROVISIONING_INTERFACE:-}" | ||||
| PROVISIONING_IP="${PROVISIONING_IP:-}" | ||||
| PROVISIONING_MACS="${PROVISIONING_MACS:-}" | ||||
| IRONIC_URL_HOSTNAME="${IRONIC_URL_HOSTNAME:-}" | ||||
| IPXE_CUSTOM_FIRMWARE_DIR="${IPXE_CUSTOM_FIRMWARE_DIR:-/shared/custom_ipxe_firmware}" | ||||
| CUSTOM_CONFIG_DIR="${CUSTOM_CONFIG_DIR:-/conf}" | ||||
| CUSTOM_DATA_DIR="${CUSTOM_DATA_DIR:-/data}" | ||||
| export DNSMASQ_CONF_DIR="${CUSTOM_CONFIG_DIR}/dnsmasq" | ||||
| export DNSMASQ_DATA_DIR="${CUSTOM_DATA_DIR}/dnsmasq" | ||||
| export DNSMASQ_TEMP_DIR="${CUSTOM_CONFIG_DIR}/dnsmasq" | ||||
| export HTTPD_DIR="${CUSTOM_CONFIG_DIR}/httpd" | ||||
| export HTTPD_CONF_DIR="${HTTPD_DIR}/conf" | ||||
| export HTTPD_CONF_DIR_D="${HTTPD_DIR}/conf.d" | ||||
| export IRONIC_CONF_DIR="${CUSTOM_CONFIG_DIR}/ironic" | ||||
| export IRONIC_DB_DIR="${CUSTOM_DATA_DIR}/db" | ||||
| export IRONIC_GEN_CERT_DIR="${CUSTOM_DATA_DIR}/auto_gen_certs" | ||||
| export IRONIC_TMP_DATA_DIR="${CUSTOM_DATA_DIR}/tmp" | ||||
| export PROBE_CONF_DIR="${CUSTOM_CONFIG_DIR}/probes" | ||||
|  | ||||
| mkdir -p "${IRONIC_CONF_DIR}" "${PROBE_CONF_DIR}" "${HTTPD_CONF_DIR}" \ | ||||
|     "${HTTPD_CONF_DIR_D}" "${DNSMASQ_CONF_DIR}" "${DNSMASQ_TEMP_DIR}" \ | ||||
|     "${IRONIC_DB_DIR}" "${IRONIC_GEN_CERT_DIR}" "${DNSMASQ_DATA_DIR}" \ | ||||
|     "${IRONIC_TMP_DATA_DIR}" | ||||
|  | ||||
| export HTPASSWD_FILE="${IRONIC_CONF_DIR}/htpasswd" | ||||
| export LOCAL_DB_URI="sqlite:///${IRONIC_DB_DIR}/ironic.sqlite" | ||||
|  | ||||
| export IRONIC_USE_MARIADB=${IRONIC_USE_MARIADB:-false} | ||||
|  | ||||
|  | ||||
| get_ip_of_hostname() | ||||
| { | ||||
|     if [[ "$#" -ne 2 ]]; then | ||||
|         echo "${FUNCNAME}: two parameters required, $# provided" >&2 | ||||
|         return 1 | ||||
|     fi | ||||
|  | ||||
|     case $2 in | ||||
|         4) | ||||
|             QUERY="a";; | ||||
|         6) | ||||
|             QUERY="aaaa";; | ||||
|         *) | ||||
|             echo "${FUNCNAME}: the second parameter should be [a|aaaa] for A and AAAA records" | ||||
|             return 1;; | ||||
|     esac | ||||
|  | ||||
|     local HOSTNAME=$1 | ||||
|  | ||||
|     echo $(nslookup -type=${QUERY} "${HOSTNAME}" | tail -n2 | grep -w "Address:" | cut -d " " -f2) | ||||
| } | ||||
|  | ||||
| get_interface_of_ip() | ||||
| { | ||||
|     local IP_VERS="" | ||||
|  | ||||
|     if [[ "$#" -gt 2 ]]; then | ||||
|         echo "${FUNCNAME}: too many parameters" >&2 | ||||
|         return 1 | ||||
|     fi | ||||
|  | ||||
|     if [[ "$#" -eq 2 ]]; then | ||||
|         case $2 in | ||||
|         4|6) | ||||
|             local IP_VERS="-${2}" | ||||
|             ;; | ||||
|         *) | ||||
|             echo "${FUNCNAME}: the second parameter should be [4|6] (or missing for both)" >&2 | ||||
|             return 2 | ||||
|             ;; | ||||
|         esac | ||||
|     fi | ||||
|  | ||||
|     local IP_ADDR=$1 | ||||
|  | ||||
|     # Convert the address using ipcalc which strips out the subnet. | ||||
|     # 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 '@') | ||||
| } | ||||
|  | ||||
| get_ip_of_interface() | ||||
| { | ||||
|     local IP_VERS="" | ||||
|  | ||||
|     if [[ "$#" -gt 2 ]]; then | ||||
|         echo "${FUNCNAME}: too many parameters" >&2 | ||||
|         return 1 | ||||
|     fi | ||||
|  | ||||
|     if [[ "$#" -eq 2 ]]; then | ||||
|         case $2 in | ||||
|         4|6) | ||||
|             local IP_VERS="-${2}" | ||||
|             ;; | ||||
|         *) | ||||
|             echo "${FUNCNAME}: the second parameter should be [4|6] (or missing for both)" >&2 | ||||
|             return 2 | ||||
|             ;; | ||||
|         esac | ||||
|     fi | ||||
|  | ||||
|     local IFACE=$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() | ||||
| { | ||||
|     if [[ -n "$PROVISIONING_INTERFACE" ]]; then | ||||
|         # don't override the PROVISIONING_INTERFACE if one is provided | ||||
|         echo "$PROVISIONING_INTERFACE" | ||||
|         return | ||||
|     fi | ||||
|  | ||||
|     local interface="" | ||||
|  | ||||
|     for mac in ${PROVISIONING_MACS//,/ }; do | ||||
|         if ip -br link show up | grep -i "$mac" &>/dev/null; then | ||||
|             interface="$(ip -br link show up | grep -i "$mac" | cut -f 1 -d ' ' | cut -f 1 -d '@')" | ||||
|             break | ||||
|         fi | ||||
|     done | ||||
|  | ||||
|     echo "$interface" | ||||
| } | ||||
|  | ||||
| PROVISIONING_INTERFACE="$(get_provisioning_interface)" | ||||
| export PROVISIONING_INTERFACE | ||||
|  | ||||
| export LISTEN_ALL_INTERFACES="${LISTEN_ALL_INTERFACES:-true}" | ||||
|  | ||||
| # Wait for the interface or IP to be up, sets $IRONIC_IP | ||||
| wait_for_interface_or_ip() | ||||
| { | ||||
|     # If $PROVISIONING_IP is specified, then we wait for that to become | ||||
|     # available on an interface, otherwise we look at $PROVISIONING_INTERFACE | ||||
|     # for an IP | ||||
|     if [[ -n "${PROVISIONING_IP}" ]]; then | ||||
|         local IFACE_OF_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}")" | ||||
|             sleep 1 | ||||
|         done | ||||
|  | ||||
|         echo "Found $PROVISIONING_IP on interface \"${IFACE_OF_IP}\"!" | ||||
|  | ||||
|         export PROVISIONING_INTERFACE="$IFACE_OF_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)" | ||||
|             sleep 1 | ||||
|  | ||||
|             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="" | ||||
|         local IPV4_IFACE="" | ||||
|          | ||||
|         # we should get at least one IP address | ||||
|         until [[ -n "$IPV6_IFACE" ]] || [[ -n "$IPV4_IFACE" ]]; do | ||||
|             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)" | ||||
|  | ||||
|             # 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 | ||||
|                 return 1 | ||||
|             fi | ||||
|  | ||||
|             echo "Waiting for ${IPV6_RECORD} to be configured on an interface" | ||||
|             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)" | ||||
|             sleep 1 | ||||
|         done | ||||
|  | ||||
|         # Add some debugging output | ||||
|         if [[ -n "$IPV6_IFACE" ]]; then | ||||
|             echo "Found $IPV6_RECORD on interface \"${IPV6_IFACE}\"!" | ||||
|             export IRONIC_IPV6="$IPV6_RECORD" | ||||
|         fi | ||||
|         if [[ -n "$IPV4_IFACE" ]]; then | ||||
|             echo "Found $IPV4_RECORD on interface \"${IPV4_IFACE}\"!" | ||||
|             export IRONIC_IP="$IPV4_RECORD" | ||||
|         fi | ||||
|  | ||||
|         # Make sure both IPs are asigned to the same interface | ||||
|         if [[ -n "$IPV6_IFACE" ]] && [[ -n "$IPV4_IFACE" ]] && [[ "$IPV6_IFACE" != "$IPV4_IFACE" ]]; then | ||||
|             echo "Warning, the IPv4 and IPv6 addresses from \"${HOSTNAME}\" are assigned to different " \ | ||||
|             "interfaces (\"${IPV6_IFACE}\" and \"${IPV4_IFACE}\")" >&2 | ||||
|         fi | ||||
|  | ||||
|     else | ||||
|         echo "Cannot determine an interface or an IP for binding and creating URLs" | ||||
|         return 1 | ||||
|     fi | ||||
|  | ||||
|     # Define the URLs based on the what we have found, | ||||
|     # prioritize IPv6 for IRONIC_URL_HOST | ||||
|     if [[ -n "$IRONIC_IP" ]]; then | ||||
|         export ENABLE_IPV4=yes | ||||
|         export IRONIC_URL_HOST="$IRONIC_IP" | ||||
|     fi | ||||
|     if [[ -n "$IRONIC_IPV6" ]]; then | ||||
|         export ENABLE_IPV6=yes | ||||
|         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 | ||||
|     if [[ -n "$IRONIC_URL_HOSTNAME" ]]; then | ||||
|         IRONIC_URL_HOST=$IRONIC_URL_HOSTNAME | ||||
|     fi | ||||
|  | ||||
|     # Avoid having to construct full URL multiple times while allowing | ||||
|     # the override of IRONIC_HTTP_URL for environments in which IRONIC_IP | ||||
|     # is unreachable from hosts being provisioned. | ||||
|     export IRONIC_HTTP_URL="${IRONIC_HTTP_URL:-http://${IRONIC_URL_HOST}:${HTTP_PORT}}" | ||||
|     export IRONIC_TFTP_URL="${IRONIC_TFTP_URL:-tftp://${IRONIC_URL_HOST}}" | ||||
|     export IRONIC_BASE_URL=${IRONIC_BASE_URL:-"${IRONIC_SCHEME}://${IRONIC_URL_HOST}:${IRONIC_ACCESS_PORT}"} | ||||
| } | ||||
|  | ||||
| render_j2_config() | ||||
| { | ||||
|     python3.11 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' < "$1" > "$2" | ||||
| } | ||||
|  | ||||
| run_ironic_dbsync() | ||||
| { | ||||
|     if [[ "${IRONIC_USE_MARIADB}" == "true" ]]; then | ||||
|         # It's possible for the dbsync to fail if mariadb is not up yet, so | ||||
|         # retry until success | ||||
|         until ironic-dbsync --config-file "${IRONIC_CONF_DIR}/ironic.conf" upgrade; do | ||||
|             echo "WARNING: ironic-dbsync failed, retrying" | ||||
|             sleep 1 | ||||
|         done | ||||
|     else | ||||
|         # SQLite does not support some statements. Fortunately, we can just | ||||
|         # create the schema in one go if not already created, instead of going | ||||
|         # through an upgrade | ||||
|         cp "/var/lib/ironic/ironic.sqlite" "${IRONIC_DB_DIR}/ironic.sqlite" | ||||
|         DB_VERSION="$(ironic-dbsync --config-file "${IRONIC_CONF_DIR}/ironic.conf" version)" | ||||
|         if [[ "${DB_VERSION}" == "None" ]]; then | ||||
|             ironic-dbsync --config-file "${IRONIC_CONF_DIR}/ironic.conf" create_schema | ||||
|         fi | ||||
|     fi | ||||
| } | ||||
|  | ||||
| # Use the special value "unix" for unix sockets | ||||
| export IRONIC_PRIVATE_PORT=${IRONIC_PRIVATE_PORT:-unix} | ||||
|  | ||||
| export IRONIC_ACCESS_PORT=${IRONIC_ACCESS_PORT:-6385} | ||||
| export IRONIC_LISTEN_PORT=${IRONIC_LISTEN_PORT:-$IRONIC_ACCESS_PORT} | ||||
|  | ||||
| export IRONIC_ENABLE_DISCOVERY=${IRONIC_ENABLE_DISCOVERY:-${IRONIC_INSPECTOR_ENABLE_DISCOVERY:-false}} | ||||
							
								
								
									
										23
									
								
								ironic-image/scripts/ironic-probe.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								ironic-image/scripts/ironic-probe.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| set -eu -o pipefail | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/ironic-common.sh | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/auth-common.sh | ||||
|  | ||||
| PROBE_CURL_ARGS= | ||||
| if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "true" ]]; then | ||||
|     if [[ "${IRONIC_PRIVATE_PORT}" == "unix" ]]; then | ||||
|         PROBE_URL="http://127.0.0.1:6385" | ||||
|         PROBE_CURL_ARGS="--unix-socket /shared/ironic.sock" | ||||
|     else | ||||
|         PROBE_URL="http://127.0.0.1:${IRONIC_PRIVATE_PORT}" | ||||
|     fi | ||||
| else | ||||
|         PROBE_URL="${IRONIC_BASE_URL}" | ||||
| fi | ||||
|  | ||||
| # shellcheck disable=SC2086 | ||||
| curl -sSf ${PROBE_CURL_ARGS} "${PROBE_URL}" | ||||
							
								
								
									
										10
									
								
								ironic-image/scripts/rundatabase-upgrade
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								ironic-image/scripts/rundatabase-upgrade
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| set -euxo pipefail | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/configure-ironic.sh | ||||
|  | ||||
| # NOTE(dtantsur): no retries here: this script is supposed to be run as a Job | ||||
| # that is retried on failure. | ||||
| exec ironic-dbsync --config-file "${IRONIC_CONF_DIR}/ironic.conf" upgrade | ||||
							
								
								
									
										16
									
								
								ironic-image/rundnsmasq → ironic-image/scripts/rundnsmasq
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										16
									
								
								ironic-image/rundnsmasq → ironic-image/scripts/rundnsmasq
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -13,7 +13,11 @@ export DNS_PORT=${DNS_PORT:-0} | ||||
| 
 | ||||
| wait_for_interface_or_ip | ||||
| if [[ "${DNS_IP:-}" == "provisioning" ]]; then | ||||
|     export DNS_IP="$IRONIC_URL_HOST" | ||||
|     if [[ "${IPV}" == "4" ]]; then | ||||
|       export DNS_IP="${IRONIC_IP}" | ||||
|     else | ||||
|       export DNS_IP="[${IRONIC_IP}]" | ||||
|     fi | ||||
| fi | ||||
| 
 | ||||
| mkdir -p /shared/tftpboot | ||||
| @@ -32,12 +36,12 @@ fi | ||||
| # Template and write dnsmasq.conf | ||||
| # we template via /tmp as sed otherwise creates temp files in /etc directory | ||||
| # where we can't write | ||||
| python3 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' </etc/dnsmasq.conf.j2 >/tmp/dnsmasq.conf | ||||
| python3.11 -c 'import os; import sys; import jinja2; sys.stdout.write(jinja2.Template(sys.stdin.read()).render(env=os.environ))' <"/tmp/dnsmasq.conf.j2" >"${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf" | ||||
| 
 | ||||
| for iface in $(echo "$DNSMASQ_EXCEPT_INTERFACE" | tr ',' ' '); do | ||||
|     sed -i -e "/^interface=.*/ a\except-interface=${iface}" /tmp/dnsmasq.conf | ||||
|     sed -i -e "/^interface=.*/ a\except-interface=${iface}" "${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf" | ||||
| done | ||||
| cat /tmp/dnsmasq.conf > /etc/dnsmasq.conf | ||||
| rm /tmp/dnsmasq.conf | ||||
| cat "${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf" > "${DNSMASQ_CONF_DIR}/dnsmasq.conf" | ||||
| rm "${DNSMASQ_TEMP_DIR}/dnsmasq_temp.conf" | ||||
| 
 | ||||
| exec /usr/sbin/dnsmasq -d -q -C /etc/dnsmasq.conf | ||||
| exec /usr/sbin/dnsmasq -d -q -C "${DNSMASQ_CONF_DIR}/dnsmasq.conf" | ||||
							
								
								
									
										38
									
								
								ironic-image/runhttpd → ironic-image/scripts/runhttpd
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										38
									
								
								ironic-image/runhttpd → ironic-image/scripts/runhttpd
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -28,25 +28,28 @@ wait_for_interface_or_ip | ||||
| mkdir -p /shared/html | ||||
| chmod 0777 /shared/html | ||||
| 
 | ||||
| IRONIC_BASE_URL="${IRONIC_SCHEME}://${IRONIC_URL_HOST}" | ||||
| 
 | ||||
| INSPECTOR_EXTRA_ARGS=" ipa-inspection-callback-url=${IRONIC_BASE_URL}:${IRONIC_ACCESS_PORT}/v1/continue_inspection" | ||||
| INSPECTOR_EXTRA_ARGS=" ipa-inspection-callback-url=${IRONIC_BASE_URL}/v1/continue_inspection" | ||||
| 
 | ||||
| if [[ "$IRONIC_FAST_TRACK" == "true" ]]; then | ||||
|     INSPECTOR_EXTRA_ARGS+=" ipa-api-url=${IRONIC_BASE_URL}:${IRONIC_ACCESS_PORT}" | ||||
|     INSPECTOR_EXTRA_ARGS+=" ipa-api-url=${IRONIC_BASE_URL}" | ||||
| fi | ||||
| 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" | ||||
| fi | ||||
| 
 | ||||
| # Render the core httpd config | ||||
| render_j2_config /etc/httpd/conf/httpd.conf.j2 /etc/httpd/conf/httpd.conf | ||||
| render_j2_config "/etc/httpd/conf/httpd.conf.j2" \ | ||||
|     "${HTTPD_CONF_DIR}/httpd.conf" | ||||
| 
 | ||||
| if [[ "$IRONIC_TLS_SETUP" == "true" ]]; then | ||||
|     if [[ "${IRONIC_REVERSE_PROXY_SETUP}" == "true" ]]; then | ||||
|         render_j2_config /tmp/httpd-ironic-api.conf.j2 /etc/httpd/conf.d/ironic.conf | ||||
|         render_j2_config "/tmp/httpd-ironic-api.conf.j2" \ | ||||
|             "${HTTPD_CONF_DIR_D}/ironic.conf" | ||||
|     fi | ||||
| else | ||||
|     export IRONIC_REVERSE_PROXY_SETUP="false" # If TLS is not used, we have no reason to use the reverse proxy | ||||
| @@ -56,33 +59,24 @@ write_htpasswd_files | ||||
| 
 | ||||
| # Render httpd TLS configuration for /shared/html/<redifsh;ilo> | ||||
| if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]]; then | ||||
|     render_j2_config /etc/httpd-vmedia.conf.j2 /etc/httpd/conf.d/vmedia.conf | ||||
|     render_j2_config "/tmp/httpd-vmedia.conf.j2" \ | ||||
|         "${HTTPD_CONF_DIR_D}/vmedia.conf" | ||||
| fi | ||||
| 
 | ||||
| # Render httpd TLS configuration for /shared/html | ||||
| if [[ "$IPXE_TLS_SETUP" == "true" ]]; then | ||||
|     mkdir -p /shared/html/custom-ipxe | ||||
|     chmod 0777 /shared/html/custom-ipxe | ||||
|     render_j2_config "/etc/httpd-ipxe.conf.j2" "/etc/httpd/conf.d/ipxe.conf" | ||||
|     render_j2_config "/tmp/httpd-ipxe.conf.j2" "${HTTPD_CONF_DIR_D}/ipxe.conf" | ||||
|     cp "${IPXE_CUSTOM_FIRMWARE_DIR}/undionly.kpxe" \ | ||||
|        "${IPXE_CUSTOM_FIRMWARE_DIR}/snponly.efi" \ | ||||
|        "/shared/html/custom-ipxe" | ||||
| fi | ||||
| 
 | ||||
| # Set up inotify to kill the container (restart) whenever cert files for ironic api change | ||||
| if [[ "$IRONIC_TLS_SETUP" == "true" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then | ||||
|     # shellcheck disable=SC2034 | ||||
|     inotifywait -m -e delete_self "${IRONIC_CERT_FILE}" | while read -r file event; do | ||||
|         kill -WINCH $(pgrep httpd) | ||||
|     done & | ||||
| fi | ||||
| configure_restart_on_certificate_update "${IRONIC_TLS_SETUP}" httpd "${IRONIC_CERT_FILE}" | ||||
| 
 | ||||
| # Set up inotify to kill the container (restart) whenever cert of httpd for /shared/html/<redifsh;ilo> path change | ||||
| if [[ "$IRONIC_VMEDIA_TLS_SETUP" == "true" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then | ||||
|     # shellcheck disable=SC2034 | ||||
|     inotifywait -m -e delete_self "${IRONIC_VMEDIA_CERT_FILE}" | while read -r file event; do | ||||
|         kill -WINCH $(pgrep httpd) | ||||
|     done & | ||||
| fi | ||||
| configure_restart_on_certificate_update "${IRONIC_VMEDIA_TLS_SETUP}" httpd "${IRONIC_VMEDIA_CERT_FILE}" | ||||
| 
 | ||||
| exec /usr/sbin/httpd -DFOREGROUND -f /etc/httpd/conf/httpd.conf | ||||
| exec /usr/sbin/httpd -DFOREGROUND -f "${HTTPD_CONF_DIR}/httpd.conf" | ||||
							
								
								
									
										18
									
								
								ironic-image/scripts/runironic
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								ironic-image/scripts/runironic
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/configure-ironic.sh | ||||
|  | ||||
| # Ramdisk logs | ||||
| mkdir -p /shared/log/ironic/deploy | ||||
|  | ||||
| # Allows skipping dbsync if it's done by an external job | ||||
| if [[ "${IRONIC_SKIP_DBSYNC:-false}" != true ]]; then | ||||
|     run_ironic_dbsync | ||||
| fi | ||||
|  | ||||
| configure_restart_on_certificate_update "${IRONIC_TLS_SETUP}" ironic "${IRONIC_CERT_FILE}" | ||||
|  | ||||
| configure_ironic_auth | ||||
|  | ||||
| exec /usr/bin/ironic --config-dir "${IRONIC_CONF_DIR}" | ||||
							
								
								
									
										17
									
								
								ironic-image/scripts/runlogwatch.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								ironic-image/scripts/runlogwatch.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| # Ramdisk logs path | ||||
| LOG_DIR="/shared/log/ironic/deploy" | ||||
|  | ||||
| mkdir -p "${LOG_DIR}" | ||||
|  | ||||
| # shellcheck disable=SC2034 | ||||
| python3.11 -m pyinotify --raw-format -e IN_CLOSE_WRITE -v "${LOG_DIR}" | | ||||
|     while read -r event dir mask maskname filename filepath pathname wd; do | ||||
|         #NOTE(elfosardo): a pyinotify event looks like this: | ||||
|         # <Event dir=False mask=0x8 maskname=IN_CLOSE_WRITE name=mylogs.gzip path=/shared/log/ironic/deploy pathname=/shared/log/ironic/deploy/mylogs.gzip wd=1 > | ||||
|         FILENAME=$(echo "${filename}" | cut -d'=' -f2-) | ||||
|         echo "************ Contents of ${LOG_DIR}/${FILENAME} ramdisk log file bundle **************" | ||||
|         tar -xOzvvf "${LOG_DIR}/${FILENAME}" | sed -e "s/^/${FILENAME}: /" | ||||
|         rm -f "${LOG_DIR}/${FILENAME}" | ||||
|     done | ||||
							
								
								
									
										10
									
								
								ironic-image/scripts/runonline-data-migrations
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								ironic-image/scripts/runonline-data-migrations
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #!/usr/bin/bash | ||||
|  | ||||
| set -euxo pipefail | ||||
|  | ||||
| # shellcheck disable=SC1091 | ||||
| . /bin/configure-ironic.sh | ||||
|  | ||||
| # NOTE(dtantsur): no retries here: this script is supposed to be run as a Job | ||||
| # that is retried on failure. | ||||
| exec ironic-dbsync --config-file "${IRONIC_CONF_DIR}/ironic.conf" online_data_migrations | ||||
| @@ -95,3 +95,21 @@ if [[ -f "$MARIADB_CACERT_FILE" ]]; then | ||||
| else | ||||
|     export MARIADB_TLS_ENABLED="false" | ||||
| fi | ||||
| 
 | ||||
| configure_restart_on_certificate_update() | ||||
| { | ||||
|     local enabled="$1" | ||||
|     local service="$2" | ||||
|     local cert_file="$3" | ||||
|     local signal="TERM" | ||||
| 
 | ||||
|     if [[ "${enabled}" == "true" ]] && [[ "${RESTART_CONTAINER_CERTIFICATE_UPDATED}" == "true" ]]; then | ||||
|         if [[ "${service}" == httpd ]]; then | ||||
|             signal="WINCH" | ||||
|         fi | ||||
|         python3 -m pyinotify --raw-format -e IN_DELETE_SELF -v "${cert_file}" | | ||||
|             while read -r; do | ||||
|                 pkill "-${signal}" "${service}" | ||||
|             done & | ||||
|     fi | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.6 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.6-%RELEASE% | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.10 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader:3.0.10-%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.6" | ||||
| LABEL org.opencontainers.image.version="3.0.10" | ||||
| 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.6-%RELEASE%" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.10-%RELEASE%" | ||||
| LABEL org.openbuildservice.disturl="%DISTURL%" | ||||
| LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" | ||||
| LABEL com.suse.eula="SUSE Combined EULA February 2024" | ||||
| @@ -33,8 +33,6 @@ LABEL com.suse.release-stage="released" | ||||
|  | ||||
| COPY --from=base /installroot / | ||||
| RUN cp /getopt /usr/bin/ | ||||
| RUN cp /srv/tftpboot/openstack-ironic-image/initrd*.zst /tmp | ||||
| RUN cp /srv/tftpboot/openstack-ironic-image/openstack-ironic-image*.kernel /tmp | ||||
| RUN sha256sum /srv/tftpboot/openstack-ironic-image/initrd*.zst /srv/tftpboot/openstack-ironic-image/openstack-ironic-image*.kernel > /tmp/images.sha256 | ||||
| # configure non-root user | ||||
| COPY configure-nonroot.sh /bin/ | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-aarch64:3.0.6 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-aarch64:3.0.6-%RELEASE% | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-aarch64:3.0.10 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-aarch64:3.0.10-%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.6" | ||||
| LABEL org.opencontainers.image.version="3.0.10" | ||||
| 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.6-%RELEASE%" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.10-%RELEASE%" | ||||
| LABEL org.openbuildservice.disturl="%DISTURL%" | ||||
| LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" | ||||
| LABEL com.suse.eula="SUSE Combined EULA February 2024" | ||||
| @@ -33,8 +33,6 @@ LABEL com.suse.release-stage="released" | ||||
|  | ||||
| COPY --from=base /installroot / | ||||
| RUN cp /getopt /usr/bin/ | ||||
| RUN cp /srv/tftpboot/openstack-ironic-image/initrd*.zst /tmp | ||||
| RUN cp /srv/tftpboot/openstack-ironic-image/openstack-ironic-image*.kernel /tmp | ||||
| RUN sha256sum /srv/tftpboot/openstack-ironic-image/initrd*.zst /srv/tftpboot/openstack-ironic-image/openstack-ironic-image*.kernel > /tmp/images.sha256 | ||||
| # configure non-root user | ||||
| COPY configure-nonroot.sh /bin/ | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-x86_64:3.0.6 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-x86_64:3.0.6-%RELEASE% | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-x86_64:3.0.10 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic-ipa-downloader-x86_64:3.0.10-%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.6" | ||||
| LABEL org.opencontainers.image.version="3.0.10" | ||||
| 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.6-%RELEASE%" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic-ipa-downloader:3.0.10-%RELEASE%" | ||||
| LABEL org.openbuildservice.disturl="%DISTURL%" | ||||
| LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" | ||||
| LABEL com.suse.eula="SUSE Combined EULA February 2024" | ||||
| @@ -33,8 +33,6 @@ LABEL com.suse.release-stage="released" | ||||
|  | ||||
| COPY --from=base /installroot / | ||||
| RUN cp /getopt /usr/bin/ | ||||
| RUN cp /srv/tftpboot/openstack-ironic-image/initrd*.zst /tmp | ||||
| RUN cp /srv/tftpboot/openstack-ironic-image/openstack-ironic-image*.kernel /tmp | ||||
| RUN sha256sum /srv/tftpboot/openstack-ironic-image/initrd*.zst /srv/tftpboot/openstack-ironic-image/openstack-ironic-image*.kernel > /tmp/images.sha256 | ||||
| # configure non-root user | ||||
| COPY configure-nonroot.sh /bin/ | ||||
|   | ||||
| @@ -6,6 +6,8 @@ export http_proxy=${http_proxy:-$HTTP_PROXY} | ||||
| export https_proxy=${https_proxy:-$HTTPS_PROXY} | ||||
| export no_proxy=${no_proxy:-$NO_PROXY} | ||||
|  | ||||
| IMAGES_BASE_PATH="/srv/tftpboot/openstack-ironic-image" | ||||
|  | ||||
| if [ -d "/tmp/ironic-certificates" ]; then | ||||
|   sha256sum /tmp/ironic-certificates/* > /tmp/certificates.sha256 | ||||
|   if cmp "/shared/certificates.sha256" "/tmp/certificates.sha256"; then | ||||
| @@ -26,14 +28,13 @@ if [ -z "${IPA_BASEURI}" ]; then | ||||
|   IMAGE_CHANGED=1 | ||||
|   # SLES BASED IPA - ironic-ipa-ramdisk-x86_64 and ironic-ipa-ramdisk-aarch64 packages | ||||
|   mkdir -p /shared/html/images | ||||
|   if [ -f /tmp/initrd-x86_64.zst ]; then | ||||
|     cp /tmp/initrd-x86_64.zst /shared/html/images/ironic-python-agent-x86_64.initramfs | ||||
|     cp /tmp/openstack-ironic-image.x86_64*.kernel /shared/html/images/ironic-python-agent-x86_64.kernel | ||||
|   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 | ||||
|   fi | ||||
|   # Use arm64 as destination for iPXE compatibility | ||||
|   if [ -f /tmp/initrd-aarch64.zst ]; then | ||||
|     cp /tmp/initrd-aarch64.zst /shared/html/images/ironic-python-agent-arm64.initramfs | ||||
|     cp /tmp/openstack-ironic-image.aarch64*.kernel /shared/html/images/ironic-python-agent-arm64.kernel | ||||
|   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 | ||||
|   fi | ||||
|  | ||||
|   cp /tmp/images.sha256 /shared/images.sha256 | ||||
| @@ -85,8 +86,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 | ||||
| @@ -98,7 +99,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 | ||||
|   | ||||
| @@ -16,7 +16,7 @@ baseSetupBuildDay | ||||
| #========================================== | ||||
| # remove unneded kernel files | ||||
| #------------------------------------------ | ||||
| suseStripKernel | ||||
| #suseStripKernel | ||||
| baseStripLocales en_US.utf-8 C.utf8 | ||||
|  | ||||
| #====================================== | ||||
|   | ||||
| @@ -28,68 +28,6 @@ | ||||
|       <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"/> | ||||
|   | ||||
| @@ -19,7 +19,7 @@ | ||||
|  | ||||
|  | ||||
| Name:           ironic-ipa-ramdisk | ||||
| Version:        3.0.6 | ||||
| Version:        3.0.8 | ||||
| Release:        0 | ||||
| Summary:        Kernel and ramdisk image for OpenStack Ironic | ||||
| License:        SUSE-EULA | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| #!BuildTag: %%IMG_PREFIX%%kiwi-builder:%%kiwi_version%%.0-%RELEASE% | ||||
| #!BuildTag: %%IMG_PREFIX%%kiwi-builder:%%kiwi_version%%.0 | ||||
| #!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" | ||||
| FROM registry.suse.com/bci/kiwi:${KIWIVERSION} | ||||
| ARG KIWIVERSION | ||||
| @@ -10,11 +11,11 @@ ARG KIWIVERSION | ||||
| LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)" | ||||
| LABEL org.opencontainers.image.title="SLE Kiwi Builder Container Image" | ||||
| LABEL org.opencontainers.image.description="kiwi-builder based on the SLE Base Container Image." | ||||
| LABEL org.opencontainers.image.version="%%kiwi_version%%" | ||||
| 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:%%kiwi_version%%.0-%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" | ||||
| @@ -23,9 +24,6 @@ LABEL com.suse.image-type="application" | ||||
| LABEL com.suse.release-stage="released" | ||||
| # endlabelprefix | ||||
|  | ||||
| # help the build service understand the need for python3-kiwi | ||||
| RUN zypper -n install -d -D python3-kiwi; [ "%%kiwi_version%%" = "${KIWIVERSION}" ] || { echo "expected kiwi version ${KIWIVERSION}: version mismatch"; exit 1; } | ||||
|  | ||||
| # Copy build script into image and make it executable | ||||
| ADD build-image.sh /usr/bin/build-image | ||||
| RUN chmod a+x /usr/bin/build-image | ||||
|   | ||||
| @@ -1,15 +1,9 @@ | ||||
| <services> | ||||
|   <service mode="buildtime" name="kiwi_metainfo_helper"/> | ||||
|   <service name="docker_label_helper" mode="buildtime"/> | ||||
|   <service name="replace_using_env" mode="buildtime"> | ||||
|     <param name="file">README</param> | ||||
|     <param name="eval">IMG_REPO=$(rpm --macros=/root/.rpmmacros -E %img_repo)</param> | ||||
|     <param name="var">IMG_REPO</param> | ||||
|     <param name="eval">IMG_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?img_prefix})</param> | ||||
|     <param name="var">IMG_PREFIX</param> | ||||
|   </service> | ||||
|   <service name="replace_using_env" mode="buildtime"> | ||||
|     <param name="file">Dockerfile</param> | ||||
|     <param name="file">README</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> | ||||
| @@ -17,14 +11,4 @@ | ||||
|     <param name="eval">SUPPORT_LEVEL=$(rpm --macros=/root/.rpmmacros -E %support_level)</param> | ||||
|     <param name="var">SUPPORT_LEVEL</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="replace_using_package_version"> | ||||
|     <param name="file">Dockerfile</param> | ||||
|     <param name="regex">%%kiwi_version%%</param> | ||||
|     <param name="package">python3-kiwi</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="replace_using_package_version"> | ||||
|     <param name="file">README</param> | ||||
|     <param name="regex">%%kiwi_version%%</param> | ||||
|     <param name="package">python3-kiwi</param> | ||||
|   </service> | ||||
| </services> | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%kube-rbac-proxy:%%kube-rbac-proxy_version%% | ||||
| #!BuildTag: %%IMG_PREFIX%%kube-rbac-proxy:%%kube-rbac-proxy_version%%-%RELEASE% | ||||
| #!BuildVersion: 15.6 | ||||
| ARG SLE_VERSION | ||||
| FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%kubectl:1.30.3 | ||||
| #!BuildTag: %%IMG_PREFIX%%kubectl:1.30.3-%RELEASE% | ||||
| #!BuildVersion: 15.6 | ||||
| #!BuildTag: %%IMG_PREFIX%%kubectl:1.33.4 | ||||
| #!BuildTag: %%IMG_PREFIX%%kubectl:1.33.4-%RELEASE% | ||||
| ARG SLE_VERSION | ||||
| FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro | ||||
|  | ||||
| @@ -16,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.30.3" | ||||
| LABEL org.opencontainers.image.version="1.33.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.30.3-%RELEASE%" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%kubectl:1.33.4-%RELEASE%" | ||||
| LABEL org.openbuildservice.disturl="%DISTURL%" | ||||
| LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" | ||||
| LABEL com.suse.eula="SUSE Combined EULA February 2024" | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| %global debug_package %{nil} | ||||
|  | ||||
| Name: kubectl | ||||
| Version: 1.30.3 | ||||
| Version: 1.33.4 | ||||
| Release: 0 | ||||
| Summary: Command-line utility for interacting with a Kubernetes cluster | ||||
|  | ||||
| @@ -12,7 +12,7 @@ Group: admin | ||||
| Packager: Kubernetes Authors <dev@kubernetes.io> | ||||
| License: Apache-2.0 | ||||
| URL: https://kubernetes.io | ||||
| Source0: kubectl_%{version}.orig.tar.gz | ||||
| Source0: %{name}_%{version}.orig.tar.gz | ||||
|  | ||||
| %description | ||||
| %{summary}. | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								kubectl/kubectl_1.30.3.orig.tar.gz
									 (Stored with Git LFS)
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								kubectl/kubectl_1.30.3.orig.tar.gz
									 (Stored with Git LFS)
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								kubectl/kubectl_1.33.4.orig.tar.gz
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								kubectl/kubectl_1.33.4.orig.tar.gz
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,9 +1,9 @@ | ||||
| #!BuildTag: %%CHART_PREFIX%%kubevirt:%%CHART_MAJOR%%.0.0_up0.5.0-%RELEASE% | ||||
| #!BuildTag: %%CHART_PREFIX%%kubevirt:%%CHART_MAJOR%%.0.0_up0.5.0 | ||||
| #!BuildTag: %%CHART_PREFIX%%kubevirt:%%CHART_MAJOR%%.0.1_up0.6.0-%RELEASE% | ||||
| #!BuildTag: %%CHART_PREFIX%%kubevirt:%%CHART_MAJOR%%.0.1_up0.6.0 | ||||
| apiVersion: v2 | ||||
| appVersion: 1.4.0 | ||||
| appVersion: 1.5.2 | ||||
| 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.0+up0.5.0" | ||||
| version: "%%CHART_MAJOR%%.0.1+up0.6.0" | ||||
|   | ||||
| @@ -593,6 +593,13 @@ 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 | ||||
| @@ -605,8 +612,8 @@ spec: | ||||
|                         completionTimeoutPerGiB: | ||||
|                           description: |- | ||||
|                             CompletionTimeoutPerGiB is the maximum number of seconds per GiB a migration is allowed to take. | ||||
|                             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 | ||||
|                             If the timeout is reached, the migration will be either paused, switched | ||||
|                             to post-copy or cancelled depending on other settings. Defaults to 150 | ||||
|                           format: int64 | ||||
|                           type: integer | ||||
|                         disableTLS: | ||||
| @@ -964,17 +971,17 @@ spec: | ||||
|                           type: object | ||||
|                       type: object | ||||
|                     vmRolloutStrategy: | ||||
|                       description: VMRolloutStrategy defines how changes to a VM object | ||||
|                         propagate to its VMI | ||||
|                       description: |- | ||||
|                         VMRolloutStrategy defines how live-updatable fields, like CPU sockets, memory, | ||||
|                         tolerations, and affinity, are propagated from a VM 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. | ||||
|                         The storage class must support RWX in filesystem mode. | ||||
|                       description: VMStateStorageClass is the name of the storage class | ||||
|                         to use for the PVCs created to preserve VM state, like TPM. | ||||
|                       type: string | ||||
|                     webhookConfiguration: | ||||
|                       description: |- | ||||
| @@ -3850,6 +3857,13 @@ 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 | ||||
| @@ -3862,8 +3876,8 @@ spec: | ||||
|                         completionTimeoutPerGiB: | ||||
|                           description: |- | ||||
|                             CompletionTimeoutPerGiB is the maximum number of seconds per GiB a migration is allowed to take. | ||||
|                             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 | ||||
|                             If the timeout is reached, the migration will be either paused, switched | ||||
|                             to post-copy or cancelled depending on other settings. Defaults to 150 | ||||
|                           format: int64 | ||||
|                           type: integer | ||||
|                         disableTLS: | ||||
| @@ -4221,17 +4235,17 @@ spec: | ||||
|                           type: object | ||||
|                       type: object | ||||
|                     vmRolloutStrategy: | ||||
|                       description: VMRolloutStrategy defines how changes to a VM object | ||||
|                         propagate to its VMI | ||||
|                       description: |- | ||||
|                         VMRolloutStrategy defines how live-updatable fields, like CPU sockets, memory, | ||||
|                         tolerations, and affinity, are propagated from a VM 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. | ||||
|                         The storage class must support RWX in filesystem mode. | ||||
|                       description: VMStateStorageClass is the name of the storage class | ||||
|                         to use for the PVCs created to preserve VM state, like TPM. | ||||
|                       type: string | ||||
|                     webhookConfiguration: | ||||
|                       description: |- | ||||
|   | ||||
| @@ -608,6 +608,7 @@ rules: | ||||
|     resources: | ||||
|       - virtualmachinesnapshots | ||||
|       - virtualmachinesnapshots/status | ||||
|       - virtualmachinesnapshots/finalizers | ||||
|       - virtualmachinesnapshotcontents | ||||
|       - virtualmachinesnapshotcontents/status | ||||
|       - virtualmachinesnapshotcontents/finalizers | ||||
| @@ -660,15 +661,18 @@ 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 | ||||
| @@ -772,6 +776,14 @@ rules: | ||||
|     verbs: | ||||
|       - list | ||||
|       - watch | ||||
|   - apiGroups: | ||||
|       - batch | ||||
|     resources: | ||||
|       - jobs | ||||
|     verbs: | ||||
|       - create | ||||
|       - get | ||||
|       - delete | ||||
|   - apiGroups: | ||||
|       - kubevirt.io | ||||
|     resources: | ||||
| @@ -883,6 +895,7 @@ rules: | ||||
|       - virtualmachineinstances/freeze | ||||
|       - virtualmachineinstances/unfreeze | ||||
|       - virtualmachineinstances/softreboot | ||||
|       - virtualmachineinstances/reset | ||||
|       - virtualmachineinstances/sev/setupsession | ||||
|       - virtualmachineinstances/sev/injectlaunchsecret | ||||
|     verbs: | ||||
| @@ -902,7 +915,6 @@ rules: | ||||
|       - virtualmachines/restart | ||||
|       - virtualmachines/addvolume | ||||
|       - virtualmachines/removevolume | ||||
|       - virtualmachines/migrate | ||||
|       - virtualmachines/memorydump | ||||
|     verbs: | ||||
|       - update | ||||
| @@ -919,7 +931,6 @@ rules: | ||||
|       - virtualmachineinstances | ||||
|       - virtualmachineinstancepresets | ||||
|       - virtualmachineinstancereplicasets | ||||
|       - virtualmachineinstancemigrations | ||||
|     verbs: | ||||
|       - get | ||||
|       - delete | ||||
| @@ -929,6 +940,14 @@ rules: | ||||
|       - list | ||||
|       - watch | ||||
|       - deletecollection | ||||
|   - apiGroups: | ||||
|       - kubevirt.io | ||||
|     resources: | ||||
|       - virtualmachineinstancemigrations | ||||
|     verbs: | ||||
|       - get | ||||
|       - list | ||||
|       - watch | ||||
|   - apiGroups: | ||||
|       - snapshot.kubevirt.io | ||||
|     resources: | ||||
| @@ -1032,6 +1051,7 @@ rules: | ||||
|       - virtualmachineinstances/freeze | ||||
|       - virtualmachineinstances/unfreeze | ||||
|       - virtualmachineinstances/softreboot | ||||
|       - virtualmachineinstances/reset | ||||
|       - virtualmachineinstances/sev/setupsession | ||||
|       - virtualmachineinstances/sev/injectlaunchsecret | ||||
|     verbs: | ||||
| @@ -1051,7 +1071,6 @@ rules: | ||||
|       - virtualmachines/restart | ||||
|       - virtualmachines/addvolume | ||||
|       - virtualmachines/removevolume | ||||
|       - virtualmachines/migrate | ||||
|       - virtualmachines/memorydump | ||||
|     verbs: | ||||
|       - update | ||||
| @@ -1068,7 +1087,6 @@ rules: | ||||
|       - virtualmachineinstances | ||||
|       - virtualmachineinstancepresets | ||||
|       - virtualmachineinstancereplicasets | ||||
|       - virtualmachineinstancemigrations | ||||
|     verbs: | ||||
|       - get | ||||
|       - delete | ||||
| @@ -1077,6 +1095,14 @@ rules: | ||||
|       - patch | ||||
|       - list | ||||
|       - watch | ||||
|   - apiGroups: | ||||
|       - kubevirt.io | ||||
|     resources: | ||||
|       - virtualmachineinstancemigrations | ||||
|     verbs: | ||||
|       - get | ||||
|       - list | ||||
|       - watch | ||||
|   - apiGroups: | ||||
|       - snapshot.kubevirt.io | ||||
|     resources: | ||||
| @@ -1255,6 +1281,25 @@ 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: | ||||
| @@ -1300,6 +1345,8 @@ spec: | ||||
|     type: RollingUpdate | ||||
|   template: | ||||
|     metadata: | ||||
|       annotations: | ||||
|         openshift.io/required-scc: restricted-v2 | ||||
|       labels: | ||||
|         kubevirt.io: virt-operator | ||||
|         name: virt-operator | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| operator: | ||||
|   image: registry.suse.com/suse/sles/15.6/virt-operator | ||||
|   version: 1.4.0-150600.5.15.1 | ||||
|   image: registry.suse.com/suse/sles/15.7/virt-operator | ||||
|   version: 1.5.2-150700.3.5.2 | ||||
|   replicas: 2 | ||||
|   pullPolicy: IfNotPresent | ||||
|   affinity: | ||||
| @@ -40,7 +40,7 @@ kubevirt: | ||||
|   monitorAccount: "" | ||||
|   monitorNamespace: "" | ||||
|  | ||||
| hookImage: registry.rancher.com/rancher/kubectl:v1.30.10 | ||||
| hookImage: registry.rancher.com/rancher/kubectl:v1.33.1 | ||||
| hookRestartPolicy: OnFailure | ||||
| hookSecurityContext: | ||||
|   seccompProfile: | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| #!BuildTag: %%CHART_PREFIX%%kubevirt-dashboard-extension:%%CHART_MAJOR%%.0.2 | ||||
| #!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% | ||||
| #!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% | ||||
| annotations: | ||||
|   catalog.cattle.io/certified: rancher | ||||
|   catalog.cattle.io/namespace: cattle-ui-plugin-system | ||||
| @@ -13,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: 303.0.2+up1.3.2 | ||||
| appVersion: 304.0.3+up1.3.2 | ||||
| description: 'SUSE Edge: KubeVirt extension for Rancher Dashboard' | ||||
| name: kubevirt-dashboard-extension | ||||
| type: application | ||||
| version: "%%CHART_MAJOR%%.0.2+up1.3.2" | ||||
| version: "%%CHART_MAJOR%%.0.3+up1.3.2" | ||||
| icon: >- | ||||
|   https://raw.githubusercontent.com/cncf/artwork/master/projects/kubevirt/icon/color/kubevirt-icon-color.svg | ||||
|   | ||||
| @@ -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/303.0.2+up1.3.2 | ||||
|     endpoint: https://raw.githubusercontent.com/suse-edge/dashboard-extensions/gh-pages/extensions/kubevirt-dashboard-extension/304.0.3+up1.3.2 | ||||
|     noCache: {{ .Values.plugin.noCache }} | ||||
|     noAuth: {{ .Values.plugin.noAuth }} | ||||
|     metadata: {{ include "extension-server.pluginMetadata" . | indent 6 }} | ||||
|   | ||||
| @@ -1,28 +1,28 @@ | ||||
| #!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.5_up0.11.3 | ||||
| #!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.5_up0.11.3-%RELEASE% | ||||
| #!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.19_up0.12.9 | ||||
| #!BuildTag: %%CHART_PREFIX%%metal3:%%CHART_MAJOR%%.0.19_up0.12.9-%RELEASE% | ||||
| apiVersion: v2 | ||||
| appVersion: 0.11.3 | ||||
| appVersion: 0.12.9 | ||||
| dependencies: | ||||
| - alias: metal3-baremetal-operator | ||||
|   name: baremetal-operator | ||||
|   repository: file://./charts/baremetal-operator | ||||
|   version: 0.9.1 | ||||
|   version: 0.10.4 | ||||
| - alias: metal3-ironic | ||||
|   name: ironic | ||||
|   repository: file://./charts/ironic | ||||
|   version: 0.10.3 | ||||
|   version: 0.11.6 | ||||
| - alias: metal3-mariadb | ||||
|   condition: global.enable_mariadb | ||||
|   name: mariadb | ||||
|   repository: file://./charts/mariadb | ||||
|   version: 0.5.4 | ||||
|   version: 0.6.1 | ||||
| - alias: metal3-media | ||||
|   condition: global.enable_metal3_media_server | ||||
|   name: media | ||||
|   repository: file://./charts/media | ||||
|   version: 0.6.1 | ||||
|   version: 0.7.1 | ||||
| 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.5+up0.11.3" | ||||
| version: "%%CHART_MAJOR%%.0.19+up0.12.9" | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| apiVersion: v2 | ||||
| appVersion: 0.9.1 | ||||
| appVersion: 0.10.2 | ||||
| description: A Helm chart for baremetal-operator, used by Metal3 | ||||
| name: baremetal-operator | ||||
| type: application | ||||
| version: 0.9.1 | ||||
| version: 0.10.4 | ||||
|   | ||||
| @@ -202,6 +202,11 @@ 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 | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user