forked from suse-edge/Factory
		
	Compare commits
	
		
			382 Commits
		
	
	
		
	
	| Author | SHA256 | Date | |
|---|---|---|---|
| 609919d57e | |||
| c4dea6361d | |||
| 4a6119ca82 | |||
| b69a806fed | |||
| cd217a73f8 | |||
| 28f7c4b074 | |||
| a9079e0bfc | |||
|  | 84c1cd9964 | ||
| 69db0a0b16 | |||
| db47d9df65 | |||
| 1dc2e44dfd | |||
| 800c0464e2 | |||
| dcc86b217c | |||
| 54886117da | |||
| 8696dbedf8 | |||
|  | df4cde31b0 | ||
| 4664d645d4 | |||
| f60348562e | |||
| 8947818604 | |||
| 13964b8be1 | |||
| 1d374f13c9 | |||
| 03aeb3cef7 | |||
| 78898463aa | |||
| c67f9081a9 | |||
| d75736809d | |||
| de51bf9c83 | |||
| 948a0193d8 | |||
| 2ae659283a | |||
| 8a13f25dfa | |||
| 2d1c31e19a | |||
| 18844c5a25 | |||
| 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 | |||
| 71257047ed | |||
| 477a4e15eb | |||
| be0d25d8f7 | |||
| 70a42948aa | |||
| fb0f99ee20 | |||
| cc8d3fe431 | |||
| 4ee8e8c6f2 | |||
| 79268b8e71 | |||
| d5e487518a | |||
| a7d128b8c4 | |||
| d97b554f8c | |||
| 1ca6ea51ea | |||
| c9b9e2223b | |||
| 027df1b35c | |||
| e7448eeb1c | |||
| fb4d399f0f | |||
| f47b6df822 | |||
| 4e3f1b61fd | |||
| df60bb2ed3 | |||
| 3a654b9826 | |||
| 15e4de98a7 | |||
| fe8d0ba120 | |||
| 0b431c75e2 | |||
| a59e253ecd | |||
| b28f7a5817 | |||
| c6b78eb569 | |||
| 8f7747415c | |||
| e5ba38d02f | |||
| f221cf4b37 | |||
| f42ac11716 | |||
| 08ef2fe86f | |||
| ad221cd94e | |||
| 81a856e586 | |||
| 3c9ebbd7ef | |||
| 03018e5cd1 | |||
| e91096e13e | |||
| 93f3abfeb5 | |||
| 2c4991cb24 | |||
| e71339ae00 | |||
| f32718b5e4 | |||
| c81f5057ce | |||
| 6b8109c772 | |||
| 8b383c15fa | |||
| 2013caec19 | |||
| 4259b167fd | |||
| 652fc553b9 | |||
| 1048591769 | |||
| 8a9717c266 | |||
| 49405f41f9 | |||
| be29dbba41 | |||
| a2c817259f | |||
| dfe4892f4c | |||
| ef68dbfd92 | |||
| 6c1db68da8 | |||
| 376ec896fe | |||
| a473d935f9 | |||
| 27aa096244 | |||
| 3f968b0a06 | |||
| 481d7e90b4 | |||
|  | cb70d25886 | ||
|  | 04937b90b7 | ||
|  | ef256bc1d7 | ||
|  | 437b0fdc41 | ||
|  | 0dbc0f8b52 | ||
|  | 3adc816d98 | ||
| 5883bf7549 | |||
| ba5ed09bd8 | |||
| b91c34b6c3 | |||
| b2e4b5e259 | |||
| e3f36b74d9 | |||
| 2b020e9bd7 | |||
| 98fa8835f7 | |||
| 5f52392aa3 | |||
| 083c753a0d | |||
| 48472176f2 | |||
| 53f09dd00f | |||
| c610436551 | |||
| 3d1a70e87a | |||
| e439f489ca | |||
| 8e56e1edd3 | |||
| 2a3c37b31d | |||
| eacabe4d71 | |||
| d57078f9d9 | |||
| fef712e4e8 | |||
| 2b194211ee | |||
| a3fda4c5c0 | |||
| 3c08af8a28 | |||
| a1583230bd | |||
| c8c20ce47a | |||
| b30ece6b61 | |||
| 54c0850acf | |||
| ab92525cbe | |||
| 75ae14da78 | |||
| 20de7cd994 | |||
| ca510a470a | |||
| c68c882d35 | |||
| e83a9cea3c | |||
| ea8a9c590a | |||
| fb896ffe62 | |||
| dc19c71706 | |||
| 5db4c3bc79 | |||
| 389f19f7b9 | |||
| 78a681a3a3 | |||
| da3b39573b | |||
| 6531575f1b | |||
| d59f3540a2 | |||
| 43c764e69c | |||
| 0b306a3e7a | |||
| c744e56218 | |||
| ddabc54ac8 | |||
| 0cb039a9df | |||
| eff9a9b0c5 | |||
| 8d336f380b | |||
| 5947d531ab | |||
| 15362e9536 | |||
| 8f20b3433e | |||
| 704eec6875 | |||
| 98c4be017d | |||
| dccf206a98 | |||
| 9e41ee25d9 | |||
| d97e434fce | |||
| 3dea69443d | |||
| 331f08255c | |||
| 4a99805fde | |||
| 6b8a623372 | |||
| 34687fb5e9 | |||
| 5a73d61002 | |||
| 4c6d7dea17 | |||
| 531bb91d27 | |||
| 0d3c83fca1 | |||
| 4d824b71cc | |||
| 7f93226cd3 | |||
| d6d501ad99 | |||
| f61bb1e0e6 | |||
| a510134ed4 | |||
| 54e0941879 | |||
| c04b2af72b | |||
| c57aa3344d | |||
| c86d724e92 | |||
| 9d97e8a56d | |||
| b912f9d68a | |||
| 45443d5b5f | |||
| ac32110ac1 | |||
| 5d20bc38e3 | |||
| e085a97d98 | |||
| 58c8be887a | |||
| 0d59ad920e | |||
| 74133c22f6 | |||
| e85da96001 | |||
| dab7f36e0b | |||
| 5490ffcde2 | |||
| 04b9c07dd5 | |||
| 25de5df782 | |||
| 3f9b8c9e22 | |||
| 2a993e342e | |||
| cab6fe1bcb | |||
| fde506f9ef | |||
| f49e6be155 | |||
| e820e98a2f | |||
| 8c31073506 | |||
| 4bba5fd3f2 | |||
| 383705e9a3 | |||
| a752a25191 | |||
| 83fec09683 | |||
| 32519595dc | |||
| 87c7e1be88 | |||
| 568d5d1590 | |||
| fbd596290a | |||
| ec6c4745ea | |||
| 856ec2ac8e | |||
| 7721c66ab0 | |||
| cf6abb24fb | |||
| 602249c98d | |||
| 8a93aae7c5 | |||
| aba448b275 | |||
| 09954e5818 | |||
| 636493adba | 
							
								
								
									
										23
									
								
								.gitea/workflows/check_manifest.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								.gitea/workflows/check_manifest.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| name: Check Release Manifest Local Charts Versions | ||||
| on: | ||||
|   pull_request: | ||||
|       branches-ignore: | ||||
|       - "devel" | ||||
|  | ||||
|  | ||||
| jobs: | ||||
|   sync-pr-project: | ||||
|     name: "Check Release Manifest Local Charts Versions" | ||||
|     runs-on: tumbleweed | ||||
|     steps: | ||||
|         # Waiting on PR to get merged for support in upstream action/checkout action | ||||
|       - uses: 'https://github.com/yangskyboxlabs/action-checkout@sha256' | ||||
|         name: Checkout repository | ||||
|         with: | ||||
|           object-format: 'sha256' | ||||
|       - name: Setup dependencies | ||||
|         run: | | ||||
|           zypper in -y python3-ruamel.yaml | ||||
|       - name: Check release manifest | ||||
|         run: | | ||||
|           python3 .obs/manifest-check.py --check | ||||
							
								
								
									
										62
									
								
								.gitea/workflows/pr_project.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								.gitea/workflows/pr_project.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| name: Build PR in OBS | ||||
| on: | ||||
|   pull_request_target: | ||||
|     types: | ||||
|       - opened | ||||
|       - reopened | ||||
|       - synchronize | ||||
|       - closed | ||||
|     branches-ignore: | ||||
|       - "devel" | ||||
|  | ||||
| concurrency: | ||||
|   group: ${{ gitea.workflow }}-${{ gitea.ref }} | ||||
|   cancel-in-progress: true | ||||
|  | ||||
| jobs: | ||||
|   sync-pr-project: | ||||
|     name: "Build PR in OBS" | ||||
|     runs-on: tumbleweed | ||||
|     steps: | ||||
|       - name: Setup OSC | ||||
|         run: | | ||||
|           zypper in -y python3-jinja2 | ||||
|           mkdir -p ~/.config/osc | ||||
|           cat >~/.config/osc/oscrc <<'EOF' | ||||
|           [general] | ||||
|           apiurl = https://api.opensuse.org | ||||
|  | ||||
|           [https://api.opensuse.org] | ||||
|           user=${{ vars.OBS_USERNAME }} | ||||
|           pass=${{ secrets.OBS_PASSWORD }} | ||||
|           EOF | ||||
|     # Waiting on PR to get merged for support in upstream action/checkout action | ||||
|       - uses: 'https://github.com/yangskyboxlabs/action-checkout@sha256' | ||||
|         name: Checkout repository | ||||
|         with: | ||||
|           object-format: 'sha256' | ||||
|       - name: "[if PR is closed] Delete project in OBS" | ||||
|         run: | | ||||
|           if [ "${{ gitea.event.action }}" = "closed" ]; then | ||||
|           PROJECT="$(grep PROJECT .obs/common.py | sed 's/PROJECT = "\(.*\)"/\1/')" | ||||
|           osc rdelete -f -r -m "PR closed" "${PROJECT}:Staging:PR-${{ gitea.event.number }}" | ||||
|           fi | ||||
|       - name: "Setup PR project in OBS" | ||||
|         env: | ||||
|           SCM_URL: ${{ gitea.event.pull_request.head.repo.clone_url }}#${{ gitea.head_ref }} | ||||
|         run: | | ||||
|           if [ "${{ gitea.event.action }}" != "closed" ]; then | ||||
|           PROJECT="$(grep PROJECT .obs/common.py | sed 's/PROJECT = "\(.*\)"/\1/')" | ||||
|           python3 .obs/render_meta.py --pr ${{ gitea.event.number }} --scm-url "${SCM_URL}" | osc meta prj "${PROJECT}:Staging:PR-${{ gitea.event.number }}" -F - | ||||
|           echo "Project created ${PROJECT}:Staging:PR-${{ gitea.event.number }}" | ||||
|           echo "Follow build at: https://build.opensuse.org/project/monitor/${PROJECT}:Staging:PR-${{ gitea.event.number }}" | ||||
|           fi | ||||
|       - env: | ||||
|           GIT_SHA: ${{ gitea.event.pull_request.head.sha }} | ||||
|         name: "Wait for OBS to build the project" | ||||
|         run: | | ||||
|           if [ "${{ gitea.event.action }}" != "closed" ]; then | ||||
|           PROJECT="$(grep PROJECT .obs/common.py | sed 's/PROJECT = "\(.*\)"/\1/')" | ||||
|           export OBS_PROJECT="${PROJECT}:Staging:PR-${{ gitea.event.number }}" | ||||
|           python3 .obs/wait_obs.py | ||||
|           fi | ||||
							
								
								
									
										35
									
								
								.gitea/workflows/sync_config.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								.gitea/workflows/sync_config.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| name: Synchronize Project Config | ||||
| on: | ||||
|   push: | ||||
|     branches-ignore: | ||||
|       - "devel" | ||||
|     paths: | ||||
|       - "_config" | ||||
|       - ".gitea/workflows/sync_config.yaml" | ||||
|  | ||||
| jobs: | ||||
|   sync-prjconf: | ||||
|     name: "Update prjconf in OBS" | ||||
|     runs-on: tumbleweed | ||||
|     steps: | ||||
|       - name: Setup OSC | ||||
|         run: | | ||||
|           mkdir -p ~/.config/osc | ||||
|           cat >~/.config/osc/oscrc <<'EOF' | ||||
|           [general] | ||||
|           apiurl = https://api.opensuse.org | ||||
|  | ||||
|           [https://api.opensuse.org] | ||||
|           user=${{ vars.OBS_USERNAME }} | ||||
|           pass=${{ secrets.OBS_PASSWORD }} | ||||
|           EOF | ||||
|     # Waiting on PR to get merged for support in upstream action/checkout action | ||||
|       - uses: 'https://github.com/yangskyboxlabs/action-checkout@sha256' | ||||
|         name: Checkout repository | ||||
|         with: | ||||
|           object-format: 'sha256' | ||||
|       - run: | | ||||
|           PROJECT="$(grep PROJECT .obs/common.py | sed 's/PROJECT = "\(.*\)"/\1/')" | ||||
|           if [ "$(osc meta prjconf "${PROJECT}" | sha256sum)" != "$(cat _config | sha256sum)" ] ; then | ||||
|             osc meta prjconf "${PROJECT}" -F _config | ||||
|           fi | ||||
							
								
								
									
										45
									
								
								.gitea/workflows/sync_meta.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								.gitea/workflows/sync_meta.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| name: Synchronize Project Metadata | ||||
| on: | ||||
|   push: | ||||
|     branches-ignore: | ||||
|       - "devel" | ||||
|     paths: | ||||
|       - "*" # Will trigger on new directories and changes to files in root of repository | ||||
|       - ".gitea/workflows/sync_meta.yaml" | ||||
|       - ".obs/common.py" | ||||
|  | ||||
| jobs: | ||||
|   sync-prj-meta: | ||||
|     runs-on: tumbleweed | ||||
|     steps: | ||||
|       - name: Setup OSC | ||||
|         run: | | ||||
|           zypper in -y python3-jinja2 | ||||
|           mkdir -p ~/.config/osc | ||||
|           cat >~/.config/osc/oscrc <<'EOF' | ||||
|           [general] | ||||
|           apiurl = https://api.opensuse.org | ||||
|  | ||||
|           [https://api.opensuse.org] | ||||
|           user=${{ vars.OBS_USERNAME }} | ||||
|           pass=${{ secrets.OBS_PASSWORD }} | ||||
|           EOF | ||||
|     # Waiting on PR to get merged for support in upstream action/checkout action | ||||
|       - uses: 'https://github.com/yangskyboxlabs/action-checkout@sha256' | ||||
|         name: Checkout repository | ||||
|         with: | ||||
|           object-format: 'sha256' | ||||
|       - name: "Update or create OBS Project" | ||||
|         run: | | ||||
|           PROJECT="$(grep PROJECT .obs/common.py | sed 's/PROJECT = "\(.*\)"/\1/')" | ||||
|           set -o pipefail | ||||
|           if meta="$(osc meta prj "${PROJECT}" 2>/dev/null | sha256sum)"; then | ||||
|             new_meta="$(python3 .obs/render_meta.py)" | ||||
|             if [ "${meta}" != "$(echo "${new_meta}" | sha256sum)" ]; then | ||||
|               echo "${new_meta}" | osc meta prj "${PROJECT}" -F - | ||||
|             fi | ||||
|             python3 .obs/sync_packages.py | ||||
|           else | ||||
|             # Create the projects | ||||
|             bash .obs/create_projects.sh | ||||
|           fi | ||||
							
								
								
									
										31
									
								
								.gitea/workflows/trigger_devel.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								.gitea/workflows/trigger_devel.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| name: Trigger Devel Packages | ||||
| on: | ||||
|   # NOTE (fdegir): Cron is set to run midday every weekday | ||||
|   schedule: | ||||
|     - cron: "0 12 * * 1-5 | ||||
|  | ||||
| jobs: | ||||
|   sync-pr-project: | ||||
|     name: "Trigger source services for devel packages that changed" | ||||
|     runs-on: tumbleweed | ||||
|     steps: | ||||
|       - name: Setup OSC | ||||
|         run: | | ||||
|           mkdir -p ~/.config/osc | ||||
|           cat >~/.config/osc/oscrc <<'EOF' | ||||
|           [general] | ||||
|           apiurl = https://api.opensuse.org | ||||
|  | ||||
|           [https://api.opensuse.org] | ||||
|           user=${{ vars.OBS_USERNAME }} | ||||
|           pass=${{ secrets.OBS_PASSWORD }} | ||||
|           EOF | ||||
|     # Waiting on PR to get merged for support in upstream action/checkout action | ||||
|       - uses: 'https://github.com/yangskyboxlabs/action-checkout@sha256' | ||||
|         name: Checkout repository | ||||
|         with: | ||||
|           object-format: 'sha256' | ||||
|           ref: 'devel' | ||||
|       - name: "Trigger packages" | ||||
|         run: | | ||||
|           python3 .obs/trigger_package.py | ||||
							
								
								
									
										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,5 +1,4 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import yaml | ||||
| import subprocess | ||||
| import argparse | ||||
| import os | ||||
| @@ -7,30 +6,6 @@ import os.path | ||||
|  | ||||
| from common import PROJECT, REPOSITORY, BRANCH | ||||
|  | ||||
| def add_package_to_workflow(name: str): | ||||
|     modified = False | ||||
|     with open(".obs/workflows.yml", "r") as wf_file: | ||||
|         workflows = yaml.safe_load(wf_file) | ||||
|     if not any( | ||||
|         x | ||||
|         for x in workflows["staging_build"]["steps"] | ||||
|         if x["branch_package"]["source_package"] == name | ||||
|     ): | ||||
|         workflows["staging_build"]["steps"].append( | ||||
|             { | ||||
|                 "branch_package": { | ||||
|                     "source_project": PROJECT, | ||||
|                     "target_project": f"{PROJECT}:Staging", | ||||
|                     "source_package": name, | ||||
|                 } | ||||
|             } | ||||
|         ) | ||||
|         modified = True | ||||
|     if modified: | ||||
|         with open(".obs/workflows.yml", "w") as wf_file: | ||||
|             yaml.dump(workflows, wf_file) | ||||
|  | ||||
|  | ||||
| def add_package_to_project(name: str): | ||||
|     package_meta = f"""<package name="{name}" project="{PROJECT}"> | ||||
|   <title/> | ||||
| @@ -53,7 +28,6 @@ def add_package(package_name: str): | ||||
|         os.exit(1) | ||||
|  | ||||
|     add_package_to_project(package_name) | ||||
|     add_package_to_workflow(package_name) | ||||
|  | ||||
|  | ||||
| def main(): | ||||
| @@ -65,7 +39,7 @@ def main(): | ||||
|     add_package(args.package) | ||||
|      | ||||
|  | ||||
|     print("Package created in OBS, you can now push the modified workflow file") | ||||
|     print("Package created in OBS !") | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|   | ||||
							
								
								
									
										37
									
								
								.obs/create_projects.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								.obs/create_projects.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| show_help() { | ||||
|     echo "Usage: $(basename $0) [--internal]" | ||||
|     echo "options:" | ||||
|     echo "-h, --help       display this help and exit" | ||||
|     echo "-i, --internal   create project as internal" | ||||
|     exit 0 | ||||
| } | ||||
|  | ||||
| while [[ "$#" -gt 0 ]]; do | ||||
|     case $1 in | ||||
|         -h|--help) show_help;; | ||||
|         -i|--internal) internal="--internal" ;; | ||||
|         *) echo "Unknown parameter passed: $1";show_help ;; | ||||
|     esac | ||||
|     shift | ||||
| done | ||||
|  | ||||
| PROJECT="$(grep PROJECT .obs/common.py | sed 's/PROJECT = "\(.*\)"/\1/')" | ||||
| EXTRA_OSC_ARGS="" | ||||
| if [ -n "$internal" ]; then | ||||
|     PROJECT="ISV${PROJECT:3}" | ||||
|     EXTRA_OSC_ARGS="-A https://api.suse.de" | ||||
|  | ||||
|     python3 .obs/render_meta.py ${internal} Snapshot | osc ${EXTRA_OSC_ARGS} meta prj "${PROJECT}:Snapshot" -F - | ||||
|     osc ${EXTRA_OSC_ARGS} meta prjconf "${PROJECT}:Snapshot" -F _config | ||||
| fi | ||||
|  | ||||
| python3 .obs/render_meta.py ${internal} ToTest | osc ${EXTRA_OSC_ARGS} meta prj "${PROJECT}:ToTest" -F - | ||||
| python3 .obs/render_meta.py ${internal} | osc ${EXTRA_OSC_ARGS} meta prj "${PROJECT}" -F - | ||||
| osc ${EXTRA_OSC_ARGS} meta prjconf "${PROJECT}:ToTest" -F _config | ||||
| osc ${EXTRA_OSC_ARGS} meta prjconf "${PROJECT}" -F _config | ||||
|  | ||||
| if [ -z "$internal" ]; then | ||||
|     python3 .obs/sync_packages.py | ||||
| fi | ||||
| @@ -1,5 +1,4 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import yaml | ||||
| import subprocess | ||||
| import argparse | ||||
| import os | ||||
| @@ -8,18 +7,6 @@ import os.path | ||||
| from common import PROJECT | ||||
|  | ||||
|  | ||||
| def delete_package_from_workflow(name: str): | ||||
|     with open(".obs/workflows.yml", "r") as wf_file: | ||||
|         workflows = yaml.safe_load(wf_file) | ||||
|     workflows["staging_build"]["steps"] = [ | ||||
|         x | ||||
|         for x in workflows["staging_build"]["steps"] | ||||
|         if x["branch_package"]["source_package"] != name | ||||
|     ] | ||||
|     with open(".obs/workflows.yml", "w") as wf_file: | ||||
|         yaml.dump(workflows, wf_file) | ||||
|  | ||||
|  | ||||
| def delete_package_from_project(name: str): | ||||
|     p = subprocess.run(["osc", "rdelete", PROJECT, name, "-m \"Deleted via delete_package.py\"" ], stdout=subprocess.PIPE) | ||||
|     print(p.stdout) | ||||
| @@ -33,7 +20,6 @@ def delete_package(package_name: str): | ||||
|         os.exit(1) | ||||
|  | ||||
|     delete_package_from_project(package_name) | ||||
|     delete_package_from_workflow(package_name) | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|   | ||||
							
								
								
									
										84
									
								
								.obs/manifest-check.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										84
									
								
								.obs/manifest-check.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| #!/usr/bin/python3 | ||||
|  | ||||
| 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.load(f) | ||||
|         return chart["version"] | ||||
|  | ||||
| def get_charts(chart): | ||||
|     if not chart["chart"].startswith("%%CHART_REPO%%"): | ||||
|         # Not a locally managed chart | ||||
|         return {} | ||||
|  | ||||
|     chart_name = chart["chart"][len("%%CHART_REPO%%/%%CHART_PREFIX%%"):] | ||||
|     charts = { chart_name: chart["version"] } | ||||
|     for child_chart in chart.get("dependencyCharts", []) + chart.get("addonCharts", []): | ||||
|         charts.update(get_charts(child_chart)) | ||||
|     return charts | ||||
|  | ||||
| def get_charts_list(): | ||||
|     with open("./release-manifest-image/release_manifest.yaml") as f: | ||||
|         manifest = yaml.load(f) | ||||
|     charts = {} | ||||
|     for chart in manifest["spec"]["components"]["workloads"]["helm"]: | ||||
|         charts.update(get_charts(chart)) | ||||
|     return charts | ||||
|  | ||||
| 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 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") | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
							
								
								
									
										63
									
								
								.obs/render_meta.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								.obs/render_meta.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| import argparse | ||||
|  | ||||
| from jinja2 import Template | ||||
| from common import PROJECT | ||||
|  | ||||
| def render(base_project, subproject, internal, scm_url=None): | ||||
|     version = base_project.rsplit(':', 1)[-1] | ||||
|     context = { | ||||
|         "base_project": subproject == "", | ||||
|         "title": f"SUSE Edge {version} {subproject}".rstrip(), | ||||
|         "ironic_base": "ISV:SUSE:Edge:Ironic" if internal else "Cloud:OpenStack", | ||||
|     } | ||||
|     if subproject == "ToTest": | ||||
|         context["project"] = f"{base_project}:ToTest" | ||||
|         context["description"] = ( | ||||
|             f"This project doesn't build, it stores a snapshot of SUSE Edge {version} " | ||||
|             "project currently going through the automated test layer" | ||||
|         ) | ||||
|         if "Factory" in base_project or internal: | ||||
|             context["release_project"] = f"{base_project}:Snapshot" | ||||
|     elif subproject == "Snapshot": | ||||
|         context["project"] = f"{base_project}:Snapshot" | ||||
|         context["release_project"] = f"{base_project.rsplit(':', 1)[0]}:Containers" | ||||
|         context["for_release"] = True | ||||
|         context["description"] = ( | ||||
|             f"This project doesn't build, it stores a snapshot of SUSE Edge {version} " | ||||
|             "project that passed automated test layer" | ||||
|         ) | ||||
|     elif subproject == "": | ||||
|         context["project"] = base_project | ||||
|         context["release_project"] = f"{base_project}:ToTest" | ||||
|     else: # PR case direct python call | ||||
|         context["base_project"] = True | ||||
|         context["project"] = f"{base_project}:{subproject}" | ||||
|         if scm_url is not None: | ||||
|             context["scm_url"] = scm_url | ||||
|  | ||||
|     with open("_meta") as meta: | ||||
|         template = Template(meta.read()) | ||||
|     return template.render(context) | ||||
|  | ||||
| def main(): | ||||
|     parser = argparse.ArgumentParser( | ||||
|                     prog='ProgramName', | ||||
|                     description='What the program does', | ||||
|                     epilog='Text at the bottom of help') | ||||
|     parser.add_argument("subproject", default="", choices=["", "ToTest", "Snapshot"], nargs="?") | ||||
|     parser.add_argument("--internal", action="store_true") | ||||
|     parser.add_argument("--pr") | ||||
|     parser.add_argument("--scm-url") | ||||
|     args = parser.parse_args() | ||||
|     base_project = PROJECT.replace("isv", "ISV", 1) if args.internal else PROJECT | ||||
|  | ||||
|     print(render( | ||||
|         base_project=base_project, | ||||
|         subproject=args.subproject if args.pr is None else f"Staging:PR-{args.pr}", | ||||
|         internal=args.internal, | ||||
|         scm_url=args.scm_url, | ||||
|     )) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
| @@ -9,7 +9,7 @@ from common import PROJECT | ||||
|  | ||||
| def get_obs_packages() -> Set[str]: | ||||
|     packages = subprocess.run(["osc", "ls", PROJECT], encoding='utf-8' , capture_output=True) | ||||
|     return set(packages.stdout.splitlines()) | ||||
|     return { p for p in packages.stdout.splitlines() if ":" not in p } | ||||
|  | ||||
| def get_local_packages() -> Set[str]: | ||||
|     p = pathlib.Path('.') | ||||
|   | ||||
							
								
								
									
										83
									
								
								.obs/wait_obs.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								.obs/wait_obs.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| import xml.etree.ElementTree as ET | ||||
| import subprocess | ||||
| import time | ||||
| import os | ||||
| import sys | ||||
|  | ||||
| from collections import Counter | ||||
|  | ||||
| def get_buildstatus(project: str) -> ET.Element: | ||||
|     for _ in range(5): | ||||
|         try: | ||||
|             output = subprocess.check_output(["osc", "pr", "--xml", project]) | ||||
|             return ET.fromstring(output) | ||||
|         except subprocess.CalledProcessError: | ||||
|             continue | ||||
|     print("Failed to get buildstatus from OBS") | ||||
|  | ||||
| def do_wait(project:str, commit:str) -> ET.Element: | ||||
|     last_state = None | ||||
|     while True: | ||||
|         time.sleep(5) | ||||
|         status = get_buildstatus(project) | ||||
|         if last_state == status.get("state"): | ||||
|             continue | ||||
|         else: | ||||
|             last_state = status.get("state") | ||||
|  | ||||
|         scminfo = { e.text for e in status.findall(".//scminfo") } | ||||
|         if len(scminfo) != 1 or scminfo.pop() != commit: | ||||
|             print("Waiting for OBS to sync with SCM") | ||||
|             continue | ||||
|  | ||||
|         if not all([ e.get('state') == "published" and e.get('dirty') is None for e in status.findall("./result")]): | ||||
|             print("Waiting for OBS to finish building") | ||||
|             continue | ||||
|  | ||||
|         return status | ||||
|          | ||||
| def print_results(status: ET.Element) -> bool: | ||||
|     results = {} | ||||
|     failed = [] | ||||
|     for e in status.findall("./result"): | ||||
|         repo = results.get(e.get("repository"), {}) | ||||
|         repo[e.get("arch")] = e | ||||
|         results[e.get("repository")] = repo | ||||
|      | ||||
|     for repo in results.keys(): | ||||
|         print(f"{repo}:") | ||||
|         depth=1 | ||||
|         for arch in results[repo].keys(): | ||||
|             counts = Counter() | ||||
|             if repo != "charts": | ||||
|                 print(f"\t{arch}:") | ||||
|                 depth=2 | ||||
|             for package in results[repo][arch].findall("./status"): | ||||
|                 if package.get("code") in ["excluded", "disabled"]: | ||||
|                     continue | ||||
|                 if package.get("code") in ["failed", "unresolvable", "broken"]: | ||||
|                     details = package.findtext("details") | ||||
|                     if details: | ||||
|                         failed.append(f"{package.get('package')} ({arch}): {details}") | ||||
|                     else: | ||||
|                         failed.append(f"{package.get('package')} ({arch})") | ||||
|                 counts[package.get("code")] += 1 | ||||
|             for (code, count) in counts.items(): | ||||
|                 print("\t"*depth, f"{code}: {count}") | ||||
|      | ||||
|     failed.sort() | ||||
|     if failed: | ||||
|         print("\nPackages failing: ") | ||||
|     for fail in failed: | ||||
|         print("\t", fail) | ||||
|     return len(failed) | ||||
|  | ||||
| def main(): | ||||
|     project = os.environ.get("OBS_PROJECT") | ||||
|     sha = os.environ.get("GIT_SHA") | ||||
|     print(f"Waiting for OBS to build {project} for commit {sha}") | ||||
|     status = do_wait(project, sha) | ||||
|     sys.exit(print_results(status)) | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
| @@ -1,228 +0,0 @@ | ||||
| staging_build: | ||||
|   filters: | ||||
|     event: pull_request | ||||
|   steps: | ||||
|   - branch_package: | ||||
|       source_package: endpoint-copier-operator | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: endpoint-copier-operator-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: endpoint-copier-operator-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: akri | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: akri-agent-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: akri-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: akri-controller-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: akri-dashboard-extension-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: akri-debug-echo-discovery-handler-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: akri-onvif-discovery-handler-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: akri-opcua-discovery-handler-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: akri-udev-discovery-handler-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: akri-webhook-configuration-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: obs-service-set_version | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: cosign | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: frr-k8s | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: kubectl | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: upgrade-controller | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: nm-configurator | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: kube-rbac-proxy | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: edge-image-builder | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: metallb | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: hauler | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: ip-address-manager | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: baremetal-operator | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: cluster-api-provider-metal3 | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: cdi-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: cluster-api-provider-metal3-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: metallb-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: sriov-crd-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: upgrade-controller-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: edge-image-builder-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: ironic-ipa-downloader-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: upgrade-controller-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: metal3-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: baremetal-operator-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: sriov-network-operator-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: metallb-controller-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: ip-address-manager-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: metallb-speaker-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: ironic-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: cri-tools | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: crudini | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: fakeroot | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: ipcalc | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: autoconf | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: rancher-turtles-airgap-resources-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: rancher-turtles-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: kube-rbac-proxy-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: ironic-ipa-ramdisk | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: kubevirt-dashboard-extension-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: kiwi-builder-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: kubevirt-chart | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: release-manifest-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: frr-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
|   - branch_package: | ||||
|       source_package: kubectl-image | ||||
|       source_project: isv:SUSE:Edge:Factory | ||||
|       target_project: isv:SUSE:Edge:Factory:Staging | ||||
							
								
								
									
										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 | ||||
							
								
								
									
										15
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								README.md
									
									
									
									
									
								
							| @@ -5,15 +5,6 @@ Contains the definition of the packages built on OBS for the SUSE Edge Solution | ||||
| This repository is linked to an OBS project: <https://build.opensuse.org/project/show/isv:SUSE:Edge:Factory> | ||||
| Every directory in this repository represents a package in that OBS project, those should be synced automatically from this repository. | ||||
|  | ||||
| ## Adding a package | ||||
|  | ||||
| To add a package, first create a directory with your package as you intend it in OBS. | ||||
|  | ||||
| Then run the `.obs/add_package.py` script to create the package in the OBS project and add the required elements to the synchronization workflow. | ||||
| This script is using the `osc` command behind the scenes, so ensure you have it installed and correctly configured, as well as you have the correct permissions to create a new package in the project. | ||||
|  | ||||
| You will then get asked to push your changes. | ||||
|  | ||||
| ## Testing a fork or a development branch | ||||
|  | ||||
| You can create a project in your home space in OBS, use the same prjconf as the one of "isv:SUSE:Edge:Factory", and copy the repositories part of the metadata (adjust self references). | ||||
| @@ -23,16 +14,14 @@ Then add a scmsync stanza to your metadata like this (adjust repository path and | ||||
| <scmsync>https://src.opensuse.org/suse-edge/Factory#main</scmsync> | ||||
| ``` | ||||
|  | ||||
| This is done automatically for any PR filed against this repository. | ||||
|  | ||||
| ## Cutting a release version branch | ||||
|  | ||||
| 1. Do the appropriate git branch command | ||||
| 2. Change the project path in `.obs/common.py` file (e.g. from `isv:SUSE:Edge:Factory` to `isv:SUSE:Edge:3.2`) | ||||
| 3. Change the branch reference in `.obs/common.py` file (e.g. from `main` to `3.2`) | ||||
| 4. Edit the `.obs/workflows.yml` file to change the references to the correct projects | ||||
| 5. Commit those changes to the new branch and push the new branch | ||||
| 6. Create the base and to-test projects (e.g. `isv:SUSE:Edge:3.2` and `isv:SUSE:Edge:3.2:ToTest`), use the `isv:SUSE:Edge:Factory` projects as example for metadata part | ||||
| 7. Use the prjconf of Factory in all those projects | ||||
| 8. Run the `.obs/sync_packages.py` script to create all the packages in the base project | ||||
| 9. Go take a few cups of coffee/tea/mate/... while waiting for OBS to build everything | ||||
| 10. Once built do an `osc release` of the project for it to be copied over in the `ToTest` section | ||||
| 11. Hand over to QA to test whatever is in `ToTest`. (You can continue to work on the base branch if needed meanwhile) | ||||
|   | ||||
							
								
								
									
										215
									
								
								_config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								_config
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,215 @@ | ||||
| Prefer: -libqpid-proton10 -python311-urllib3_1 | ||||
| Prefer: -cargo1.58 -cargo1.57 cargo1.89 | ||||
|  | ||||
| Macros: | ||||
| %__python3 /usr/bin/python3.11 | ||||
| %registry_url %(echo %{vendor} | cut -d '/' -f 3 | sed 's/build/registry/') | ||||
| :Macros | ||||
|  | ||||
| %if "%{sub %{lower %_project} 1 14}" != "isv:suse:edge:" || "%{sub %_project 15 21}" == "Factory" | ||||
|     # Here we are in Factory like project so set chart major version to 999 | ||||
| Macros: | ||||
| %chart_major 999 | ||||
| :Macros | ||||
| %else | ||||
|     # Here we are in version branch, so set the image prefix and chart major accordingly | ||||
| Macros: | ||||
| %project_branch %(echo %{_project} | cut -d ':' -f 4) | ||||
| %img_prefix %{project_branch}/ | ||||
| %chart_major %(echo %{project_branch} | awk '{split($1,a,"."); print a[1]*100 + a[2]}') | ||||
| :Macros | ||||
| %endif | ||||
|  | ||||
| %if %{sub %_project 1 3} == ISV | ||||
| Macros: | ||||
| %img_repo registry.suse.com/edge | ||||
| %chart_repo oci://registry.suse.com/edge | ||||
| %chart_prefix charts/ | ||||
| %manifest_repo registry.suse.com/edge | ||||
| %support_level l3 | ||||
| :Macros | ||||
| %else | ||||
| Macros: | ||||
| %img_repo registry.opensuse.org/isv/suse/edge/containers/images | ||||
| %manifest_repo registry.opensuse.org/isv/suse/edge/containers/images | ||||
| %chart_repo oci://registry.opensuse.org/isv/suse/edge/containers/charts | ||||
| %support_level techpreview | ||||
| :Macros | ||||
| %endif | ||||
|  | ||||
| %if "%_repository" == "charts" || "%_repository" == "test_manifest_images" | ||||
| Macros: | ||||
| %img_repo %(echo %{registry_url}:%{_project}:images | tr ":" "/" | tr '[:upper:]' '[:lower:]') | ||||
| %manifest_repo %(echo %{registry_url}:%{_project}:test_manifest_images | tr ":" "/" | tr '[:upper:]' '[:lower:]') | ||||
| %chart_repo oci://%(echo %{registry_url}:%{_project}:charts | tr ":" "/" | tr '[:upper:]' '[:lower:]') | ||||
| %chart_prefix %(echo "") | ||||
| :Macros | ||||
| %endif | ||||
|  | ||||
| # Missing deps for testsuite | ||||
| 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 | ||||
| BuildFlags: onlybuild:release-manifest-image | ||||
|   # Exclude the images selected by the following section | ||||
|   # as the standard repository is a dependency | ||||
|   %ifarch aarch64 | ||||
|     BuildFlags: excludebuild:baremetal-operator-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 | ||||
|   %ifarch aarch64 | ||||
|     BuildFlags: onlybuild:autoconf | ||||
|     BuildFlags: onlybuild:baremetal-operator | ||||
|     BuildFlags: onlybuild:baremetal-operator-image | ||||
|     BuildFlags: onlybuild:ca-certificates-suse | ||||
|     BuildFlags: onlybuild:container-build-checks | ||||
|     BuildFlags: onlybuild:crudini | ||||
|     BuildFlags: onlybuild:edge-build-checks | ||||
|     BuildFlags: onlybuild:edge-image-builder | ||||
|     BuildFlags: onlybuild:edge-image-builder-image | ||||
|     BuildFlags: onlybuild:endpoint-copier-operator | ||||
|     BuildFlags: onlybuild:endpoint-copier-operator-image | ||||
|     BuildFlags: onlybuild:fakeroot | ||||
|     BuildFlags: onlybuild:hauler | ||||
|     BuildFlags: onlybuild:ipcalc | ||||
|     BuildFlags: onlybuild:ironic-image | ||||
|     BuildFlags: onlybuild:ironic-ipa-downloader-image | ||||
|     BuildFlags: onlybuild:ironic-ipa-ramdisk | ||||
|     BuildFlags: onlybuild:kubectl | ||||
|     BuildFlags: onlybuild:kubectl-image | ||||
|     BuildFlags: onlybuild:kube-rbac-proxy | ||||
|     BuildFlags: onlybuild:kube-rbac-proxy-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 | ||||
|  | ||||
| %if "%_repository" == "images" || "%_repository" == "test_manifest_images" | ||||
|     Prefer: container:sles15-image | ||||
|     Type: docker | ||||
|     Repotype: none | ||||
|     Patterntype: none | ||||
|     BuildEngine: podman | ||||
|     Prefer: sles-release | ||||
|     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 | ||||
|  | ||||
| %endif | ||||
|  | ||||
| %if "%_repository" == "images_16.0" | ||||
|     Prefer: container:sles15-image | ||||
|     Type: docker | ||||
|     BuildEngine: podman | ||||
|     Repotype: none | ||||
|     Patterntype: none | ||||
|     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 | ||||
|  | ||||
|     # Exclude the images selected by the aarch64 section | ||||
|     %ifarch aarch64 | ||||
|       BuildFlags: excludebuild:baremetal-operator-image | ||||
|       BuildFlags: excludebuild:edge-image-builder-image | ||||
|       BuildFlags: excludebuild:endpoint-copier-operator-image | ||||
|       BuildFlags: excludebuild:ironic-image | ||||
|       BuildFlags: excludebuild:ironic-ipa-downloader-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 | ||||
|     %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 | ||||
|  | ||||
|  | ||||
|  | ||||
| %if "%_repository" == "charts" || "%_repository" == "phantomcharts" || "%_repository" == "releasecharts" | ||||
|     Type: helm | ||||
|     Repotype: helm | ||||
|     Patterntype: none | ||||
|     Required: perl-YAML-LibYAML | ||||
|  | ||||
|     # include edge-build-checks here | ||||
|     Support: edge-build-checks | ||||
| %endif | ||||
|  | ||||
| %if "%_repository" == "standard" | ||||
|     # for build openstack-ironic-image | ||||
|     BuildFlags: allowrootforbuild | ||||
|  | ||||
|     # ironic-ipa-ramdisk are noarch packages that need to be availble to both archs | ||||
|     ExportFilter: ^ironic-ipa-ramdisk-.*\.noarch\.rpm$ aarch64 x86_64 | ||||
| %endif | ||||
|  | ||||
| # Enable reproducible builds | ||||
| # https://en.opensuse.org/openSUSE:Reproducible_Builds\#With_OBS | ||||
| Macros: | ||||
| %source_date_epoch_from_changelog Y | ||||
| %clamp_mtime_to_source_date_epoch Y | ||||
| %use_source_date_epoch_as_buildtime Y | ||||
| %_buildhost reproducible | ||||
| :Macros | ||||
							
								
								
									
										78
									
								
								_meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								_meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | ||||
| {#-  | ||||
|   This template is rendered by the render_meta.py script | ||||
|   it is not automatically enforced by OBS | ||||
| -#} | ||||
| {%- set maintainers = [ | ||||
|     "edge-engineering", | ||||
| ] -%} | ||||
| <project name="{{ project }}"> | ||||
|   <title>{{ title }}</title> | ||||
|   {%- if description is defined %} | ||||
|   <description>{{ description }}</description> | ||||
|   {%- else %} | ||||
|   <description/> | ||||
|   {%- endif %} | ||||
|   {%- if scm_url is defined %} | ||||
|   <scmsync>{{ scm_url }}</scmsync> | ||||
|   {%- endif %} | ||||
| {%- for maintainer in maintainers %} | ||||
|   <person userid="{{ maintainer }}" role="maintainer"/> | ||||
| {%- endfor %} | ||||
| {%- if not base_project %} | ||||
|   <build> | ||||
|     <disable/> | ||||
|     <enable repository="charts"/> | ||||
|     <enable repository="test_manifest_images"/> | ||||
|     {%- if for_release %} | ||||
|     <enable repository="releasecharts"/> | ||||
|     {%- endif %} | ||||
|   </build> | ||||
|   <publish> | ||||
|     <disable repository="phantomcharts"/> | ||||
|   </publish> | ||||
|   <repository name="phantomcharts"> | ||||
|     <arch>x86_64</arch> | ||||
|   </repository> | ||||
| {%- endif %} | ||||
| {%- for repository in ["images", "images_16.0", "test_manifest_images"] %} | ||||
|   <repository name="{{ repository }}"> | ||||
|     {%- if release_project is defined and repository != "test_manifest_images" %} | ||||
|     <releasetarget project="{{ release_project }}" repository="images" trigger="manual"/> | ||||
|     {%- endif %} | ||||
|     <path project="SUSE:Registry" repository="standard"/> | ||||
|     {%- if repository == "images_16.0" %} | ||||
|       <path project="SUSE:CA" repository="16.0"/> | ||||
|       <path project="SUSE:SLFO:Products:SLES:16.0" repository="standard"/> | ||||
|       <path project="SUSE:SLFO:Main:Build" repository="standard"/> | ||||
|     {%- else %} | ||||
|       <path project="SUSE:CA" repository="SLE_15_SP7"/> | ||||
|       <path project="{{ project }}" repository="standard"/> | ||||
|     {%- endif %} | ||||
|     <arch>x86_64</arch> | ||||
|     <arch>aarch64</arch> | ||||
|   </repository> | ||||
| {%- endfor %} | ||||
|   <repository name="standard" block="local"> | ||||
|     {%- if release_project is defined and not for_release %} | ||||
|     <releasetarget project="{{ release_project }}" repository="standard" trigger="manual"/> | ||||
|     {%- endif %} | ||||
|     <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> | ||||
|   <repository name="charts"{{ ' rebuild="local"' if not base_project }}> | ||||
|     {%- if release_project is defined and not for_release %} | ||||
|     <releasetarget project="{{ release_project }}" repository="phantomcharts" trigger="manual"/> | ||||
|     {%- endif %} | ||||
|     <path project="{{ project }}" repository="standard"/> | ||||
|     <arch>x86_64</arch> | ||||
|   </repository> | ||||
|   {%- if for_release %} | ||||
|   <repository name="releasecharts" rebuild="local"> | ||||
|     <releasetarget project="{{ release_project }}" repository="charts" trigger="manual"/> | ||||
|     <path project="{{ project }}" repository="standard"/> | ||||
|     <arch>x86_64</arch> | ||||
|   </repository> | ||||
|   {%- endif %} | ||||
| </project> | ||||
| @@ -1,5 +1,5 @@ | ||||
| #!BuildTag: %%IMG_PREFIX%%akri-chart:%%CHART_MAJOR%%.0.0_up0.12.20 | ||||
| #!BuildTag: %%IMG_PREFIX%%akri-chart:%%CHART_MAJOR%%.0.0_up0.12.20-%RELEASE% | ||||
| #!BuildTag: %%CHART_PREFIX%%akri:%%CHART_MAJOR%%.0.0_up0.12.20 | ||||
| #!BuildTag: %%CHART_PREFIX%%akri:%%CHART_MAJOR%%.0.0_up0.12.20-%RELEASE% | ||||
| annotations: | ||||
|   catalog.cattle.io/display-name: Akri | ||||
| apiVersion: v2 | ||||
|   | ||||
| @@ -9,8 +9,8 @@ | ||||
|   </service> | ||||
|   <service name="replace_using_env" mode="buildtime"> | ||||
|     <param name="file">Chart.yaml</param> | ||||
|     <param name="eval">IMG_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?img_prefix})</param> | ||||
|     <param name="var">IMG_PREFIX</param> | ||||
|     <param name="eval">CHART_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?chart_prefix})</param> | ||||
|     <param name="var">CHART_PREFIX</param> | ||||
|     <param name="eval">CHART_MAJOR=$(rpm --macros=/root/.rpmmacros -E %{?chart_major})</param> | ||||
|     <param name="var">CHART_MAJOR</param> | ||||
|   </service> | ||||
|   | ||||
| @@ -853,7 +853,7 @@ webhookConfiguration: | ||||
|     pullPolicy: Always | ||||
|   certImage: | ||||
|     # reference is the webhook-certgen image reference | ||||
|     reference: registry.k8s.io/ingress-nginx/kube-webhook-certgen | ||||
|     reference: registry.rancher.com/rancher/mirrored-ingress-nginx-kube-webhook-certgen | ||||
|     # tag is the webhook-certgen image tag | ||||
|     tag: v1.1.1 | ||||
|     # pullPolicy is the webhook-certgen pull policy | ||||
|   | ||||
| @@ -1,20 +1,21 @@ | ||||
| #!BuildTag: %%IMG_PREFIX%%akri-dashboard-extension-chart:%%CHART_MAJOR%%.0.0_up1.2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%akri-dashboard-extension-chart:%%CHART_MAJOR%%.0.0_up1.2.0-%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/display-name: Akri | ||||
|   catalog.cattle.io/kube-version: ">= v1.26.0-0" | ||||
|   catalog.cattle.io/namespace: cattle-ui-plugin-system | ||||
|   catalog.cattle.io/os: linux | ||||
|   catalog.cattle.io/permits-os: linux, windows | ||||
|   catalog.cattle.io/rancher-version: ">= 2.10.0-0" | ||||
|   catalog.cattle.io/scope: management | ||||
|   catalog.cattle.io/ui-component: plugins | ||||
|   catalog.cattle.io/ui-extensions-version: ">= 3.0.0" | ||||
|   catalog.cattle.io/display-name: Akri | ||||
|   catalog.cattle.io/rancher-version: '>= 2.11.0-0' | ||||
|   catalog.cattle.io/ui-extensions-version: '>= 3.0.2 < 4.0.0' | ||||
|   catalog.cattle.io/kube-version: '>= v1.26.0-0' | ||||
| apiVersion: v2 | ||||
| appVersion: 1.2.0 | ||||
| description: "SUSE Edge: Akri extension for Rancher Dashboard" | ||||
| icon: https://raw.githubusercontent.com/cncf/artwork/main/projects/akri/icon/color/akri-icon-color.svg | ||||
| 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.0+up1.2.0" | ||||
| version: "%%CHART_MAJOR%%.0.3+up1.3.1" | ||||
| icon: >- | ||||
|   https://raw.githubusercontent.com/cncf/artwork/main/projects/akri/icon/color/akri-icon-color.svg | ||||
|   | ||||
| @@ -9,8 +9,8 @@ | ||||
|   </service> | ||||
|   <service name="replace_using_env" mode="buildtime"> | ||||
|     <param name="file">Chart.yaml</param> | ||||
|     <param name="eval">IMG_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?img_prefix})</param> | ||||
|     <param name="var">IMG_PREFIX</param> | ||||
|     <param name="eval">CHART_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?chart_prefix})</param> | ||||
|     <param name="var">CHART_PREFIX</param> | ||||
|     <param name="eval">CHART_MAJOR=$(rpm --macros=/root/.rpmmacros -E %{?chart_major})</param> | ||||
|     <param name="var">CHART_MAJOR</param> | ||||
|   </service> | ||||
|   | ||||
| @@ -38,7 +38,7 @@ Common labels | ||||
| helm.sh/chart: {{ include "extension-server.chart" . }} | ||||
| {{ include "extension-server.selectorLabels" . }} | ||||
| {{- if .Chart.AppVersion }} | ||||
| app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} | ||||
| app.kubernetes.io/version: {{ .Chart.AppVersion | replace "+" "_" | quote }} | ||||
| {{- end }} | ||||
| app.kubernetes.io/managed-by: {{ .Release.Service }} | ||||
| {{- end }} | ||||
|   | ||||
| @@ -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/1.2.0 | ||||
|     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 }} | ||||
| @@ -7,6 +7,6 @@ plugin: | ||||
|   noAuth: false | ||||
|   metadata: | ||||
|     catalog.cattle.io/display-name: Akri | ||||
|     catalog.cattle.io/rancher-version: ">= 2.10.0-0" | ||||
|     catalog.cattle.io/ui-extensions-version: ">= 3.0.0" | ||||
|     catalog.cattle.io/rancher-version: ">= 2.11.0-0" | ||||
|     catalog.cattle.io/ui-extensions-version: ">= 3.0.2 < 4.0.0" | ||||
|     catalog.cattle.io/kube-version: ">= v1.26.0-0" | ||||
|   | ||||
| @@ -10,7 +10,9 @@ | ||||
| 	<service name="cargo_vendor" mode="manual"> | ||||
| 		<param name="srcdir">akri</param> | ||||
| 	</service> | ||||
| 	<service name="tar" mode="buildtime" /> | ||||
| 	<service name="tar" mode="buildtime"> | ||||
| 		<param name="obsinfo">akri.obsinfo</param> | ||||
| 	</service> | ||||
| 	<service name="set_version" mode="buildtime" > | ||||
| 		<param name="fromfile">version.txt</param> | ||||
| 		<param name="regex">^(.*)$</param> | ||||
|   | ||||
| @@ -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.8.0</param> | ||||
|     <param name="revision">v0.10.2</param> | ||||
|     <param name="version">_auto_</param> | ||||
|     <param name="versionformat">@PARENT_TAG@</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
| @@ -12,10 +12,8 @@ | ||||
|     <param name="without-version">yes</param> | ||||
|     <param name="versionrewrite-replacement">\1</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="tar" /> | ||||
|   <service mode="buildtime" name="recompress"> | ||||
|     <param name="file">*.tar</param> | ||||
|     <param name="compression">gz</param> | ||||
|   <service mode="buildtime" name="tar"> | ||||
|     <param name="obsinfo">baremetal-operator.obsinfo</param> | ||||
|   </service> | ||||
|    <service name="go_modules"> | ||||
|   </service> | ||||
| @@ -23,7 +21,7 @@ | ||||
|     <param name="file">baremetal-operator.spec</param> | ||||
|     <param name="var">SOURCE_COMMIT</param> | ||||
|     <param name="eval"> | ||||
|       SOURCE_COMMIT=$(grep commit *.obsinfo | cut -d" " -f2) | ||||
|       SOURCE_COMMIT=$(grep commit baremetal-operator.obsinfo | cut -d" " -f2) | ||||
|     </param> | ||||
|     <param name="verbose">1</param> | ||||
|   </service> | ||||
|   | ||||
| @@ -17,14 +17,21 @@ | ||||
|  | ||||
|  | ||||
| Name:           baremetal-operator | ||||
| Version:        0.8.0 | ||||
| Release:        0.8.0 | ||||
| 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.gz | ||||
| Source:         baremetal-operator-%{version}.tar | ||||
| Source1:        vendor.tar.gz | ||||
| BuildRequires:  golang(API) = 1.22 | ||||
| # 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: %%IMG_PREFIX%%cdi-chart:%%CHART_MAJOR%%.0.0_up0.4.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%cdi-chart:%%CHART_MAJOR%%.0.0_up0.4.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.60.1 | ||||
| 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.4.0" | ||||
| version: "%%CHART_MAJOR%%.0.1+up0.6.0" | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
|   <service mode="buildtime" name="kiwi_metainfo_helper"/> | ||||
|   <service name="replace_using_env" mode="buildtime"> | ||||
|     <param name="file">Chart.yaml</param> | ||||
|     <param name="eval">IMG_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?img_prefix})</param> | ||||
|     <param name="var">IMG_PREFIX</param> | ||||
|     <param name="eval">CHART_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?chart_prefix})</param> | ||||
|     <param name="var">CHART_PREFIX</param> | ||||
|     <param name="eval">CHART_MAJOR=$(rpm --macros=/root/.rpmmacros -E %{?chart_major})</param> | ||||
|     <param name="var">CHART_MAJOR</param> | ||||
|   </service> | ||||
|   | ||||
| @@ -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 | ||||
| @@ -606,17 +608,7 @@ spec: | ||||
|         prometheus.cdi.kubevirt.io: "true" | ||||
|     spec: | ||||
|       affinity: | ||||
|         podAffinity: | ||||
|           preferredDuringSchedulingIgnoredDuringExecution: | ||||
|             - podAffinityTerm: | ||||
|                 labelSelector: | ||||
|                   matchExpressions: | ||||
|                     - key: cdi.kubevirt.io | ||||
|                       operator: In | ||||
|                       values: | ||||
|                         - cdi-operator | ||||
|                 topologyKey: kubernetes.io/hostname | ||||
|               weight: 1 | ||||
| {{- .Values.deployment.affinity | toYaml | nindent 8 }} | ||||
|       containers: | ||||
|         - env: | ||||
|             - name: DEPLOY_CLUSTER_RESOURCES | ||||
| @@ -650,9 +642,7 @@ spec: | ||||
|               name: metrics | ||||
|               protocol: TCP | ||||
|           resources: | ||||
|             requests: | ||||
|               cpu: 100m | ||||
|               memory: 150Mi | ||||
| {{- .Values.deployment.resources | toYaml | nindent 12 }} | ||||
|           securityContext: | ||||
|             allowPrivilegeEscalation: false | ||||
|             capabilities: | ||||
| @@ -661,6 +651,8 @@ spec: | ||||
|             runAsNonRoot: true | ||||
|             seccompProfile: | ||||
|               type: RuntimeDefault | ||||
|           terminationMessagePath: /dev/termination-log | ||||
|           terminationMessagePolicy: File | ||||
|       nodeSelector: | ||||
|         kubernetes.io/os: linux | ||||
|       securityContext: | ||||
|   | ||||
| @@ -19,3 +19,7 @@ spec: | ||||
|   workload: | ||||
|   {{- toYaml . | nindent 4 }} | ||||
|   {{- end }} | ||||
|   {{- with .Values.cdi.customizeComponents }} | ||||
|   customizeComponents: | ||||
|   {{- toYaml . | nindent 4 }} | ||||
|   {{- end }} | ||||
|   | ||||
| @@ -1,19 +1,36 @@ | ||||
| deployment: | ||||
|   version: 1.60.1-150600.3.9.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: | ||||
|       preferredDuringSchedulingIgnoredDuringExecution: | ||||
|         - podAffinityTerm: | ||||
|             labelSelector: | ||||
|               matchExpressions: | ||||
|                 - key: cdi.kubevirt.io | ||||
|                   operator: In | ||||
|                   values: | ||||
|                     - cdi-operator | ||||
|             topologyKey: kubernetes.io/hostname | ||||
|           weight: 1 | ||||
|   resources: | ||||
|     requests: | ||||
|       cpu: 100m | ||||
|       memory: 150Mi | ||||
|  | ||||
| cdi: | ||||
|   config: | ||||
|     featureGates: | ||||
|       - HonorWaitForFirstConsumer | ||||
|   imagePullPolicy: "IfNotPresent" | ||||
|   customizeComponents: {} | ||||
|   infra: | ||||
|     nodeSelector: | ||||
|       kubernetes.io/os: linux | ||||
| @@ -25,7 +42,7 @@ cdi: | ||||
|     nodeSelector: | ||||
|       kubernetes.io/os: linux | ||||
|  | ||||
| hookImage: rancher/kubectl:v1.30.2 | ||||
| hookImage: registry.rancher.com/rancher/kubectl:v1.33.1 | ||||
| hookRestartPolicy: OnFailure | ||||
| hookSecurityContext: | ||||
|   seccompProfile: | ||||
|   | ||||
| @@ -1,36 +0,0 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%cluster-api-provider-metal3:v%%cluster-api-provider-metal3_version%% | ||||
| #!BuildTag: %%IMG_PREFIX%%cluster-api-provider-metal3:%%cluster-api-provider-metal3_version%% | ||||
| #!BuildTag: %%IMG_PREFIX%%cluster-api-provider-metal3:%%cluster-api-provider-metal3_version%%-%RELEASE% | ||||
| #!BuildVersion: 15.6 | ||||
| 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 cluster-api-provider-metal3 shadow; zypper -n clean; rm -rf /var/log/* | ||||
|  | ||||
| FROM micro AS final | ||||
| # Define labels according to https://en.opensuse.org/Building_derived_containers | ||||
| # labelprefix=com.suse.application.cluster-api-provider-metal3 | ||||
| LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)" | ||||
| LABEL org.opencontainers.image.title="SLE cluster-api-provider-metal3 Container Image" | ||||
| LABEL org.opencontainers.image.description="cluster-api-provider-metal3 based on the SLE Base Container Image." | ||||
| LABEL org.opencontainers.image.version="%%cluster-api-provider-metal3_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%%cluster-api-provider-metal3:%%cluster-api-provider-metal3_version%%-%RELEASE%" | ||||
| LABEL org.openbuildservice.disturl="%DISTURL%" | ||||
| LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" | ||||
| LABEL com.suse.eula="SUSE Combined EULA February 2024" | ||||
| LABEL com.suse.lifecycle-url="https://www.suse.com/lifecycle" | ||||
| LABEL com.suse.image-type="application" | ||||
| LABEL com.suse.release-stage="released" | ||||
| # endlabelprefix | ||||
|  | ||||
| COPY --from=base /installroot / | ||||
| RUN mv /usr/bin/cluster-api-provider-metal3 /manager | ||||
| # Use uid of nonroot user (65532) because kubernetes expects numeric user when applying pod security policies | ||||
| USER 65532 | ||||
| ENTRYPOINT [ "/manager" ] | ||||
| @@ -1,23 +0,0 @@ | ||||
| <services> | ||||
|  <service name="obs_scm"> | ||||
|     <param name="url">https://github.com/metal3-io/cluster-api-provider-metal3</param> | ||||
|     <param name="scm">git</param> | ||||
|     <param name="revision">v1.7.2</param> | ||||
|     <param name="version">_auto_</param> | ||||
|     <param name="versionformat">@PARENT_TAG@</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
|     <param name="changesauthor">steven.hardy@suse.com</param> | ||||
|     <param name="match-tag">v*</param> | ||||
|     <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param> | ||||
|     <param name="without-version">yes</param> | ||||
|     <param name="versionrewrite-replacement">\1</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="tar" /> | ||||
|   <service mode="buildtime" name="recompress"> | ||||
|     <param name="file">*.tar</param> | ||||
|     <param name="compression">gz</param> | ||||
|   </service> | ||||
|    <service name="go_modules"> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="set_version" /> | ||||
| </services> | ||||
| @@ -1,54 +0,0 @@ | ||||
| # | ||||
| # spec file for package cluster-api-provider-metal3 | ||||
| # | ||||
| # Copyright (c) 2023 SUSE LLC | ||||
| # | ||||
| # All modifications and additions to the file contributed by third parties | ||||
| # remain the property of their copyright owners, unless otherwise agreed | ||||
| # upon. The license for this file, and modifications and additions to the | ||||
| # file, is the same license as for the pristine package itself (unless the | ||||
| # license for the pristine package is not an Open Source License, in which | ||||
| # case the license is the MIT License). An "Open Source License" is a | ||||
| # license that conforms to the Open Source Definition (Version 1.9) | ||||
| # published by the Open Source Initiative. | ||||
|  | ||||
| # Please submit bugfixes or comments via https://bugs.opensuse.org/ | ||||
| # | ||||
|  | ||||
|  | ||||
| Name:           cluster-api-provider-metal3 | ||||
| Version:        1.7.2 | ||||
| Release:        0 | ||||
| Summary:        Cluster API Infrastructure Provider for Metal3 | ||||
| License:        Apache-2.0 | ||||
| URL:            https://github.com/metal3-io/cluster-api-provider-metal3 | ||||
| Source:         cluster-api-provider-metal3-%{version}.tar.gz | ||||
| Source1:        vendor.tar.gz | ||||
| BuildRequires:  golang(API) = 1.22 | ||||
| ExcludeArch:    s390 | ||||
| ExcludeArch:    %{ix86} | ||||
|  | ||||
| %description | ||||
|  | ||||
| Cluster API Provider Metal3 is one of the providers for Cluster API and enables | ||||
| users to deploy a Cluster API based cluster on top of bare metal infrastructure | ||||
| using Metal3. | ||||
|  | ||||
| %prep | ||||
| %autosetup -a1 -n cluster-api-provider-metal3-%{version} | ||||
|  | ||||
| %build | ||||
| go build \ | ||||
|    -mod=vendor \ | ||||
|    -buildmode=pie \ | ||||
|    -a -ldflags '-extldflags "-static"' | ||||
|  | ||||
| %install | ||||
| install -D -m0755 cluster-api-provider-metal3 %{buildroot}%{_bindir}/cluster-api-provider-metal3 | ||||
|  | ||||
| %files | ||||
| %license LICENSE | ||||
| %doc README.md | ||||
| %{_bindir}/cluster-api-provider-metal3 | ||||
|  | ||||
| %changelog | ||||
							
								
								
									
										23
									
								
								container-build-checks/.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								container-build-checks/.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| ## Default LFS | ||||
| *.7z filter=lfs diff=lfs merge=lfs -text | ||||
| *.bsp filter=lfs diff=lfs merge=lfs -text | ||||
| *.bz2 filter=lfs diff=lfs merge=lfs -text | ||||
| *.gem filter=lfs diff=lfs merge=lfs -text | ||||
| *.gz filter=lfs diff=lfs merge=lfs -text | ||||
| *.jar filter=lfs diff=lfs merge=lfs -text | ||||
| *.lz filter=lfs diff=lfs merge=lfs -text | ||||
| *.lzma filter=lfs diff=lfs merge=lfs -text | ||||
| *.obscpio filter=lfs diff=lfs merge=lfs -text | ||||
| *.oxt filter=lfs diff=lfs merge=lfs -text | ||||
| *.pdf filter=lfs diff=lfs merge=lfs -text | ||||
| *.png filter=lfs diff=lfs merge=lfs -text | ||||
| *.rpm filter=lfs diff=lfs merge=lfs -text | ||||
| *.tbz filter=lfs diff=lfs merge=lfs -text | ||||
| *.tbz2 filter=lfs diff=lfs merge=lfs -text | ||||
| *.tgz filter=lfs diff=lfs merge=lfs -text | ||||
| *.ttf filter=lfs diff=lfs merge=lfs -text | ||||
| *.txz filter=lfs diff=lfs merge=lfs -text | ||||
| *.whl filter=lfs diff=lfs merge=lfs -text | ||||
| *.xz filter=lfs diff=lfs merge=lfs -text | ||||
| *.zip filter=lfs diff=lfs merge=lfs -text | ||||
| *.zst filter=lfs diff=lfs merge=lfs -text | ||||
| @@ -0,0 +1,39 @@ | ||||
| From 982cfa8500250c9704448880a779ade06cc8f976 Mon Sep 17 00:00:00 2001 | ||||
| From: Nicolas Belouin <nicolas.belouin@suse.com> | ||||
| Date: Thu, 3 Apr 2025 16:53:49 +0200 | ||||
| Subject: [PATCH] Allow slash prefixes in registry | ||||
|  | ||||
| Signed-off-by: Nicolas Belouin <nicolas.belouin@suse.com> | ||||
| --- | ||||
|  container-build-checks.py | 12 ++++++++---- | ||||
|  1 file changed, 8 insertions(+), 4 deletions(-) | ||||
|  | ||||
| diff --git a/container-build-checks.py b/container-build-checks.py | ||||
| index b8c873c..d862f33 100755 | ||||
| --- a/container-build-checks.py | ||||
| +++ b/container-build-checks.py | ||||
| @@ -82,13 +82,17 @@ def verify_reference(image, result, value): | ||||
|          return | ||||
|   | ||||
|      (registry, repo, tag) = reference_match.groups() | ||||
| -    allowed_registries: list[str] = config["General"].getlist("Registry") | ||||
| -    if len(allowed_registries) and registry not in allowed_registries: | ||||
| +    raw_allowed_registries: list[str] = config["General"].getlist("Registry") | ||||
| +    allowed_registries: dict[str, str] = {v[0]: v[2] for v in map(lambda a: a.partition("/"), raw_allowed_registries)} | ||||
| + | ||||
| +    if len(allowed_registries) and (registry not in allowed_registries.keys() or not repo.startswith(allowed_registries[registry])): | ||||
|          result.warn( | ||||
|              f"The org.opensuse.reference label ({value}) does not use an " | ||||
| -            f"allowed registry: {','.join(allowed_registries)}") | ||||
| +            f"allowed registry: {','.join(raw_allowed_registries)}") | ||||
| + | ||||
| +    prefix = allowed_registries[registry] | ||||
|   | ||||
| -    if f"{repo}:{tag}" not in image.containerinfo["tags"]: | ||||
| +    if f"{repo[len(prefix)+1:]}:{tag}" not in image.containerinfo["tags"]: | ||||
|          tags = ", ".join(image.containerinfo["tags"]) | ||||
|          result.warn(f"The org.opensuse.reference label ({value}) does not refer to an existing tag ({tags})") | ||||
|      elif "release" in image.containerinfo and image.containerinfo["release"] not in tag: | ||||
| --  | ||||
| 2.49.0 | ||||
|  | ||||
							
								
								
									
										4
									
								
								container-build-checks/SUSE.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								container-build-checks/SUSE.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| [General] | ||||
| Vendor=com.suse | ||||
| Registry=registry.suse.com | ||||
| Registry+=dp.apps.rancher.io | ||||
							
								
								
									
										15
									
								
								container-build-checks/_service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								container-build-checks/_service
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| <services> | ||||
|   <service mode="manual" name="obs_scm"> | ||||
|     <param name="url">https://github.com/openSUSE/container-build-checks.git</param> | ||||
|     <param name="scm">git</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
|   </service> | ||||
|   <service mode="manual" name="set_version" /> | ||||
|   <service mode="buildtime" name="tar"> | ||||
|     <param name="obsinfo">container-build-checks.obsinfo</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="recompress"> | ||||
|     <param name="file">*.tar</param> | ||||
|     <param name="compression">xz</param> | ||||
|   </service> | ||||
| </services> | ||||
							
								
								
									
										4
									
								
								container-build-checks/_servicedata
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								container-build-checks/_servicedata
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| <servicedata> | ||||
| <service name="tar_scm"> | ||||
|                 <param name="url">https://github.com/openSUSE/container-build-checks.git</param> | ||||
|               <param name="changesrevision">412e7f60c08221a549b0f00dfcc4bee7694193ab</param></service></servicedata> | ||||
							
								
								
									
										
											BIN
										
									
								
								container-build-checks/container-build-checks-1723452932.412e7f6.obscpio
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								container-build-checks/container-build-checks-1723452932.412e7f6.obscpio
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										101
									
								
								container-build-checks/container-build-checks.changes
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								container-build-checks/container-build-checks.changes
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| ------------------------------------------------------------------- | ||||
| Mon Aug 12 11:33:57 UTC 2024 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - Update to version 1723452932.412e7f6: | ||||
|   * add test for missing substitutions | ||||
|   * Reject labels that are missing a substitution | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Mon Jul 22 13:43:57 UTC 2024 - Dirk Müller <dmueller@suse.com> | ||||
|  | ||||
| - update SUSE.conf: allow dp.rancher.apps.io | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Mon Jul 22 13:08:23 UTC 2024 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - Switch _service to mode="manual" | ||||
| - Update to version 1721653643.19092fe: | ||||
|   * Use generic name for the python setup step | ||||
|   * Allow specifying more than one registry | ||||
|   * Use Pathlib for resolving containerinfo | ||||
|   * Switch to test Python 3.11 | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Fri Apr 28 09:23:53 UTC 2023 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - Update to version 1682595397.5ce6d2f: | ||||
|   * Handle OCI style images as well | ||||
|   * Makefile: Add missing dependency of broken-derived on proper-base | ||||
|   * GitHub workflow: Update action versions | ||||
|   * GitHub workflow: Test python 3.6 and 3.10 | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Mon Aug  8 11:37:19 UTC 2022 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - Make the URL point to GitHub | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Thu Jul  7 13:42:05 UTC 2022 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - openSUSE.conf: Allow bci/* as prefix | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Wed Apr 20 14:26:26 UTC 2022 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - Update to version 1650464301.a198cf9: | ||||
|   * Detect and treat local builds specially | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Mon Mar  7 09:23:46 UTC 2022 - Silvio Moioli <moio@suse.com> | ||||
|  | ||||
| - Adding Uyuni prefix for https://www.uyuni-project.org/ | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Thu Feb 03 07:44:23 UTC 2022 - fvogt@suse.com | ||||
|  | ||||
| - Update to version 1643874076.3d0e13c: | ||||
|   * Avoid crash on local builds | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Tue Dec 14 13:49:12 UTC 2021 - fvogt@suse.com | ||||
|  | ||||
| - Update to version 1639489705.a4c5a3ab2a75: | ||||
|   * Don't error out when the release field is empty | ||||
|   * Add simple gitpod configuration | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Tue Jun  1 09:06:12 UTC 2021 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - Drop obsolete Requires: grep jq | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Fri May 28 13:57:34 UTC 2021 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - Update to version 1622209785.4616f4f: | ||||
|   * README.md: Point badge to new location | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Fri May 28 12:47:42 UTC 2021 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - Update to version 1622204213.c8ecb9f: | ||||
|   * Add options to allow and block specific tags | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Thu May 27 15:09:59 UTC 2021 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - Update to version 1622127842.b548dd8: | ||||
|   * Update README.md | ||||
|   * Add README.md | ||||
|   * Add broken-derived test | ||||
|   * Verify prefix of the image specific label prefix | ||||
|   * Add some comments in the Makefile | ||||
|   * Always check the tag used in org.opensuse.reference | ||||
|   * Add github workflow | ||||
|   * Use bash explicitly | ||||
|   * Make lint | ||||
|   * Less noise in Makefile | ||||
|  | ||||
| ------------------------------------------------------------------- | ||||
| Fri Apr 30 10:04:09 UTC 2021 - Fabian Vogt <fvogt@suse.com> | ||||
|  | ||||
| - Initial commit | ||||
							
								
								
									
										4
									
								
								container-build-checks/container-build-checks.obsinfo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								container-build-checks/container-build-checks.obsinfo
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| name: container-build-checks | ||||
| version: 1723452932.412e7f6 | ||||
| mtime: 1723452932 | ||||
| commit: 412e7f60c08221a549b0f00dfcc4bee7694193ab | ||||
							
								
								
									
										95
									
								
								container-build-checks/container-build-checks.spec
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								container-build-checks/container-build-checks.spec
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| # | ||||
| # spec file for package container-build-checks | ||||
| # | ||||
| # Copyright (c) 2024 SUSE LLC | ||||
| # | ||||
| # All modifications and additions to the file contributed by third parties | ||||
| # remain the property of their copyright owners, unless otherwise agreed | ||||
| # upon. The license for this file, and modifications and additions to the | ||||
| # file, is the same license as for the pristine package itself (unless the | ||||
| # license for the pristine package is not an Open Source License, in which | ||||
| # case the license is the MIT License). An "Open Source License" is a | ||||
| # license that conforms to the Open Source Definition (Version 1.9) | ||||
| # published by the Open Source Initiative. | ||||
|  | ||||
| # Please submit bugfixes or comments via https://bugs.opensuse.org/ | ||||
| # | ||||
|  | ||||
|  | ||||
| Name:           container-build-checks | ||||
| Version:        1723452932.412e7f6 | ||||
| Release:        0 | ||||
| Summary:        Scripts to validate built container images | ||||
| License:        GPL-2.0-or-later | ||||
| Group:          Development/Tools/Building | ||||
| URL:            https://github.com/openSUSE/container-build-checks | ||||
| Patch0:         0001-Allow-slash-prefixes-in-registry.patch | ||||
| Source0:        %{name}-%{version}.tar.xz | ||||
| Source1:        openSUSE.conf | ||||
| Source2:        SUSE.conf | ||||
| Requires:       %{name}-vendor | ||||
| BuildArch:      noarch | ||||
|  | ||||
| %package vendor-openSUSE | ||||
| Summary:        openSUSE configuration for %{name} | ||||
| Group:          Development/Tools/Building | ||||
| Requires:       %{name} = %{version} | ||||
| Provides:       %{name}-vendor | ||||
| Conflicts:      %{name}-vendor | ||||
|  | ||||
| %description vendor-openSUSE | ||||
| openSUSE configuration for %{name} | ||||
|  | ||||
| %package vendor-SUSE | ||||
| Summary:        SUSE configuration for %{name} | ||||
| Group:          Development/Tools/Building | ||||
| Requires:       %{name} = %{version} | ||||
| Provides:       %{name}-vendor | ||||
| Conflicts:      %{name}-vendor | ||||
|  | ||||
| %description vendor-SUSE | ||||
| SUSE configuration for %{name} | ||||
|  | ||||
| %package strict | ||||
| Summary:        Strict configuration for %{name} | ||||
| Group:          Development/Tools/Building | ||||
|  | ||||
| %description strict | ||||
| Strict configuration for %{name} | ||||
|  | ||||
| %description | ||||
| This tool checks that built container images conform to the openSUSE container | ||||
| image policies (https://en.opensuse.org/Building_derived_containers). | ||||
|  | ||||
| %prep | ||||
| %autosetup -p1 | ||||
|  | ||||
| %build | ||||
| %make_build | ||||
|  | ||||
| %install | ||||
| %make_install | ||||
|  | ||||
| mkdir -p %{buildroot}%{_datadir}/container-build-checks/ | ||||
| install -m0644 %{SOURCE1} %{buildroot}%{_datadir}/container-build-checks/openSUSE.conf | ||||
| install -m0644 %{SOURCE2} %{buildroot}%{_datadir}/container-build-checks/SUSE.conf | ||||
| echo -e "[General]\nFatalWarnings=true" > %{buildroot}%{_datadir}/container-build-checks/strict.conf | ||||
|  | ||||
| %files | ||||
| #%doc README | ||||
| %license LICENSE | ||||
| %dir %{_datadir}/container-build-checks | ||||
| %dir %{_prefix}/lib/build/ | ||||
| %dir %{_prefix}/lib/build/post-build-checks/ | ||||
| %{_prefix}/lib/build/post-build-checks/container-build-checks | ||||
|  | ||||
| %files vendor-openSUSE | ||||
| %{_datadir}/container-build-checks/openSUSE.conf | ||||
|  | ||||
| %files vendor-SUSE | ||||
| %{_datadir}/container-build-checks/SUSE.conf | ||||
|  | ||||
| %files strict | ||||
| %{_datadir}/container-build-checks/strict.conf | ||||
|  | ||||
| %changelog | ||||
							
								
								
									
										10
									
								
								container-build-checks/openSUSE.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								container-build-checks/openSUSE.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| [General] | ||||
| Vendor=org.opensuse | ||||
| Registry=registry.opensuse.org | ||||
|  | ||||
| [Tags] | ||||
| # To avoid conflicts with other stuff on the registry and | ||||
| # avoid ambiguities with images on other registries. | ||||
| Allowed+=opensuse/*,kubic/*,kubevirt/*,uyuni/*,bci/* | ||||
| # Those are images, not available as namespaces | ||||
| Blocked+=opensuse/tumbleweed/*,opensuse/leap/* | ||||
| @@ -1,20 +0,0 @@ | ||||
| <services> | ||||
|   <service name="obs_scm"> | ||||
|     <param name="url">https://github.com/rancher-government-carbide/cosign.git</param> | ||||
|     <param name="versionformat">@PARENT_TAG@</param> | ||||
|     <param name="scm">git</param> | ||||
|     <param name="exclude">.get</param> | ||||
|     <param name="revision">v2.2.3+carbide.2</param> | ||||
|     <param name="versionrewrite-pattern">v(.*)</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="tar" /> | ||||
|   <service mode="buildtime" name="recompress"> | ||||
|     <param name="file">*.tar</param> | ||||
|     <param name="compression">gz</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="set_version" /> | ||||
|   <service name="go_modules"> | ||||
|      <param name="compression">gz</param> | ||||
|   </service> | ||||
| </services> | ||||
| @@ -1,55 +0,0 @@ | ||||
| # | ||||
| # spec file for package cosign-rgs | ||||
| # | ||||
| # Copyright (c) 2024 SUSE LLC | ||||
| # | ||||
| # All modifications and additions to the file contributed by third parties | ||||
| # remain the property of their copyright owners, unless otherwise agreed | ||||
| # upon. The license for this file, and modifications and additions to the | ||||
| # file, is the same license as for the pristine package itself (unless the | ||||
| # license for the pristine package is not an Open Source License, in which | ||||
| # case the license is the MIT License). An "Open Source License" is a | ||||
| # license that conforms to the Open Source Definition (Version 1.9) | ||||
| # published by the Open Source Initiative. | ||||
|  | ||||
| # Please submit bugfixes or comments via https://bugs.opensuse.org/ | ||||
| # | ||||
|  | ||||
| %define project https://github.com/hauler-dev/cosign | ||||
| %define revision 49542360ffb5de63f9d2f5856b658651d5538e40  | ||||
|  | ||||
| Name:           cosign | ||||
| Version:        0 | ||||
| Release:        0 | ||||
| Summary:        Container Signing, Verification and Storage in an OCI registry | ||||
| License:        Apache-2.0 | ||||
| URL:            https://github.com/rancher-government-carbide/cosign | ||||
| Source:         cosign-%{version}.tar.gz | ||||
| Source1:        vendor.tar.gz          | ||||
| BuildRequires:  golang-packaging | ||||
|  | ||||
| %description | ||||
|  | ||||
| %prep | ||||
| %setup -q -a1 -n cosign-%{version} | ||||
|  | ||||
| %build | ||||
| %goprep %{project} | ||||
|  | ||||
| DATE_FMT="+%%Y-%%m-%%dT%%H:%%M:%%SZ" | ||||
| BUILD_DATE=$(date -u -d "@${SOURCE_DATE_EPOCH}" "${DATE_FMT}" 2>/dev/null || date -u -r "${SOURCE_DATE_EPOCH}" "${DATE_FMT}" 2>/dev/null || date -u "${DATE_FMT}") | ||||
|  | ||||
| CLI_PKG=sigs.k8s.io/release-utils/version | ||||
| CLI_LDFLAGS="-X ${CLI_PKG}.gitVersion=%{version} -X ${CLI_PKG}.gitCommit=%{revision} -X ${CLI_PKG}.gitTreeState=release -X ${CLI_PKG}.buildDate=${BUILD_DATE}" | ||||
|  | ||||
| CGO_ENABLED=0 go build -mod=vendor -buildmode=pie -trimpath -ldflags "${CLI_LDFLAGS}" -o cosign ./cmd/cosign | ||||
|  | ||||
| %install | ||||
| install -D -m 0755 cosign %{buildroot}%{_bindir}/cosign | ||||
|  | ||||
| %files | ||||
| %license LICENSE | ||||
| %doc *.md | ||||
| %{_bindir}/cosign | ||||
|  | ||||
| %changelog | ||||
							
								
								
									
										12
									
								
								edge-build-checks/10-helm-lint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								edge-build-checks/10-helm-lint
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| HELM="/usr/bin/helm" | ||||
| TOPDIR=/usr/src/packages/HELM | ||||
| failed=0 | ||||
|  | ||||
| if [ -x $HELM ]; then | ||||
|     $HELM lint "$TOPDIR"/*.tgz | ||||
|     failed=$? | ||||
| fi | ||||
|  | ||||
| exit $failed | ||||
							
								
								
									
										159
									
								
								edge-build-checks/20-helm-images
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								edge-build-checks/20-helm-images
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,159 @@ | ||||
| #!/usr/bin/python3 | ||||
| import os | ||||
| import glob | ||||
| import subprocess | ||||
| import yaml | ||||
| import sys | ||||
| import pprint | ||||
|  | ||||
| AUTHORIZED_REPOS = [ | ||||
|     "registry.suse.com/suse/sles/", | ||||
|     "registry.suse.com/rancher", | ||||
|     "registry.rancher.com", | ||||
| ] | ||||
|  | ||||
| EXTRA_CONFIG = None | ||||
|  | ||||
| class CheckResult: | ||||
|     """Class to track count of issues""" | ||||
|  | ||||
|     def __init__(self): | ||||
|         self.hints = 0 | ||||
|         self.warnings = 0 | ||||
|         self.errors = 0 | ||||
|  | ||||
|     def hint(self, msg): | ||||
|         print(f"Hint: {msg}") | ||||
|         self.hints += 1 | ||||
|  | ||||
|     def warn(self, msg): | ||||
|         print(f"Warning: {msg}") | ||||
|         self.warnings += 1 | ||||
|  | ||||
|     def error(self, msg): | ||||
|         print(f"Error: {msg}") | ||||
|         self.errors += 1 | ||||
|  | ||||
|  | ||||
| def tarballs(): | ||||
|     """Return a list of .helminfo files to check.""" | ||||
|     if "BUILD_ROOT" not in os.environ: | ||||
|         # Not running in an OBS build container | ||||
|         return glob.glob("*.tgz") | ||||
|  | ||||
|     # Running in an OBS build container | ||||
|     buildroot = os.environ["BUILD_ROOT"] | ||||
|     topdir = "/usr/src/packages" | ||||
|     if os.path.isdir(buildroot + "/.build.packages"): | ||||
|         topdir = "/.build.packages" | ||||
|     if os.path.islink(buildroot + "/.build.packages"): | ||||
|         topdir = "/" + os.readlink(buildroot + "/.build.packages") | ||||
|  | ||||
|     return glob.glob(f"{buildroot}{topdir}/HELM/*.tgz") | ||||
|  | ||||
| def get_extra_config(): | ||||
|     global EXTRA_CONFIG | ||||
|     if EXTRA_CONFIG is not None: | ||||
|         return EXTRA_CONFIG | ||||
|      | ||||
|     if "BUILD_ROOT" not in os.environ: | ||||
|         file_path = "./.checks_helm.yaml" | ||||
|     else: | ||||
|         buildroot = os.environ["BUILD_ROOT"] | ||||
|         topdir = "/usr/src/packages" | ||||
|         file_path = f"{buildroot}{topdir}/SOURCES/.checks_helm.yaml" | ||||
|     try: | ||||
|         with open(file_path) as config_file: | ||||
|             EXTRA_CONFIG = yaml.safe_load(config_file) | ||||
|             if EXTRA_CONFIG is None:  # No document in stream | ||||
|                 EXTRA_CONFIG = {} | ||||
|     except OSError: | ||||
|         EXTRA_CONFIG = {} | ||||
|     return EXTRA_CONFIG | ||||
|  | ||||
| def get_extra_params(): | ||||
|     config = get_extra_config() | ||||
|     args = [] | ||||
|     for api in config.get('extra_apis', []): | ||||
|         args.extend(['-a', api]) | ||||
|     return args | ||||
|  | ||||
| def is_exception(image): | ||||
|     config = get_extra_config() | ||||
|     exceptions = config.get('image_exceptions', []) | ||||
|     (namespace, _, _) = image.partition(':') | ||||
|     return namespace in exceptions | ||||
|  | ||||
| def get_template(tarball_path): | ||||
|     raw_templates = subprocess.check_output( | ||||
|         [ | ||||
|             "helm", | ||||
|             "template", | ||||
|             tarball_path, | ||||
|         ] + get_extra_params() | ||||
|     ).decode() | ||||
|     return yaml.safe_load_all(raw_templates) | ||||
|  | ||||
|  | ||||
| def extract_key(key, var): | ||||
|     if hasattr(var, "items"):  # hasattr(var,'items') for python 3 | ||||
|         for k, v in var.items():  # var.items() for python 3 | ||||
|             if k == key: | ||||
|                 yield v | ||||
|             if isinstance(v, dict): | ||||
|                 for result in extract_key(key, v): | ||||
|                     yield result | ||||
|             elif isinstance(v, list): | ||||
|                 for d in v: | ||||
|                     for result in extract_key(key, d): | ||||
|                         yield result | ||||
|  | ||||
|  | ||||
| def check_template(result, template): | ||||
|     if template["kind"] not in [ | ||||
|         "Pod", | ||||
|         "Deployment", | ||||
|         "StatefulSet", | ||||
|         "DaemonSet", | ||||
|         "ReplicaSet", | ||||
|         "Job", | ||||
|         "CronJob", | ||||
|     ]: | ||||
|         return | ||||
|     for image in extract_key("image", template): | ||||
|         if not image.startswith(tuple(AUTHORIZED_REPOS)) and not is_exception(image): | ||||
|             result.error(f"{image} is not from authorized source") | ||||
|     pass | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|     result = CheckResult() | ||||
|     img_repo = subprocess.check_output( | ||||
|         [ | ||||
|             "rpm", | ||||
|             "--macros=/root/.rpmmacros", | ||||
|             "-E", | ||||
|             "%{?img_repo}", | ||||
|         ] | ||||
|     ).strip() | ||||
|     if img_repo: | ||||
|         result.hint(f"Adding '{img_repo.decode()}' to authorized repo") | ||||
|         AUTHORIZED_REPOS.append(img_repo.decode()) | ||||
|     else: | ||||
|         result.warn("img_repo macro not defined, will not add extra authorized repo") | ||||
|     for tarball in tarballs(): | ||||
|         print(f"Looking at {tarball}") | ||||
|         for template in get_template(tarball): | ||||
|             if template:  # Exclude empty templates | ||||
|                 check_template(result, template) | ||||
|  | ||||
|     ret = 0 | ||||
|     if result.errors > 0: | ||||
|         print("Fatal errors found.") | ||||
|         ret = 1 | ||||
|  | ||||
|     sys.exit(ret) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
							
								
								
									
										92
									
								
								edge-build-checks/20-helm-tags
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								edge-build-checks/20-helm-tags
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| #!/usr/bin/python3 | ||||
| import json | ||||
| import os | ||||
| import glob | ||||
| import sys | ||||
| import re | ||||
|  | ||||
|  | ||||
| class CheckResult: | ||||
|     """Class to track count of issues""" | ||||
|  | ||||
|     def __init__(self): | ||||
|         self.hints = 0 | ||||
|         self.warnings = 0 | ||||
|         self.errors = 0 | ||||
|  | ||||
|     def hint(self, msg): | ||||
|         print(f"Hint: {msg}") | ||||
|         self.hints += 1 | ||||
|  | ||||
|     def warn(self, msg): | ||||
|         print(f"Warning: {msg}") | ||||
|         self.warnings += 1 | ||||
|  | ||||
|     def error(self, msg): | ||||
|         print(f"Error: {msg}") | ||||
|         self.errors += 1 | ||||
|  | ||||
|  | ||||
| TAG_RE = re.compile(r"(.*\/)?([^:]+):([^:]+)") | ||||
|  | ||||
|  | ||||
| def check_tags(helminfo, result): | ||||
|     release_tag_found = False | ||||
|     version_tag_found = False | ||||
|     for tag in helminfo["tags"]: | ||||
|         (tag_prefix, tag_name, tag_version) = TAG_RE.fullmatch(tag).groups() | ||||
|         if tag_name != helminfo.get("name"): | ||||
|             result.warn( | ||||
|                 f"Tag ({tag}) doesn't use the chart name ({helminfo.get('name')})" | ||||
|             ) | ||||
|         if "release" in helminfo and helminfo["release"] in tag_version: | ||||
|             release_tag_found = True | ||||
|         if tag_version.replace("_", "+") == helminfo["version"]: | ||||
|             version_tag_found = True | ||||
|     if not release_tag_found: | ||||
|         result.error( | ||||
|             "None of the tags are unique to a specific build of the image.\n" | ||||
|             + "Make sure that at least one tag contains the release." | ||||
|         ) | ||||
|     if not version_tag_found: | ||||
|         result.error( | ||||
|             "None of the tags is the equivalent of the chart's version.\n" | ||||
|             + "Make sure that one of the tag is the chart version." | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def helminfos(): | ||||
|     """Return a list of .helminfo files to check.""" | ||||
|     if "BUILD_ROOT" not in os.environ: | ||||
|         # Not running in an OBS build container | ||||
|         return glob.glob("*.helminfo") | ||||
|  | ||||
|     # Running in an OBS build container | ||||
|     buildroot = os.environ["BUILD_ROOT"] | ||||
|     topdir = "/usr/src/packages" | ||||
|     if os.path.isdir(buildroot + "/.build.packages"): | ||||
|         topdir = "/.build.packages" | ||||
|     if os.path.islink(buildroot + "/.build.packages"): | ||||
|         topdir = "/" + os.readlink(buildroot + "/.build.packages") | ||||
|  | ||||
|     return glob.glob(f"{buildroot}{topdir}/HELM/*.helminfo") | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|     result = CheckResult() | ||||
|     for helminfo in helminfos(): | ||||
|         print(f"Looking at {helminfo}") | ||||
|         with open(helminfo, "rb") as cifile: | ||||
|             ci_dict = json.load(cifile) | ||||
|             check_tags(ci_dict, result) | ||||
|  | ||||
|     ret = 0 | ||||
|     if result.errors > 0: | ||||
|         print("Fatal errors found.") | ||||
|         ret = 1 | ||||
|  | ||||
|     sys.exit(ret) | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
							
								
								
									
										340
									
								
								edge-build-checks/COPYING
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										340
									
								
								edge-build-checks/COPYING
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,340 @@ | ||||
| 		    GNU GENERAL PUBLIC LICENSE | ||||
| 		       Version 2, June 1991 | ||||
|  | ||||
|  Copyright (C) 1989, 1991 Free Software Foundation, Inc. | ||||
|                        59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  Everyone is permitted to copy and distribute verbatim copies | ||||
|  of this license document, but changing it is not allowed. | ||||
|  | ||||
| 			    Preamble | ||||
|  | ||||
|   The licenses for most software are designed to take away your | ||||
| freedom to share and change it.  By contrast, the GNU General Public | ||||
| License is intended to guarantee your freedom to share and change free | ||||
| software--to make sure the software is free for all its users.  This | ||||
| General Public License applies to most of the Free Software | ||||
| Foundation's software and to any other program whose authors commit to | ||||
| using it.  (Some other Free Software Foundation software is covered by | ||||
| the GNU Library General Public License instead.)  You can apply it to | ||||
| your programs, too. | ||||
|  | ||||
|   When we speak of free software, we are referring to freedom, not | ||||
| price.  Our General Public Licenses are designed to make sure that you | ||||
| have the freedom to distribute copies of free software (and charge for | ||||
| this service if you wish), that you receive source code or can get it | ||||
| if you want it, that you can change the software or use pieces of it | ||||
| in new free programs; and that you know you can do these things. | ||||
|  | ||||
|   To protect your rights, we need to make restrictions that forbid | ||||
| anyone to deny you these rights or to ask you to surrender the rights. | ||||
| These restrictions translate to certain responsibilities for you if you | ||||
| distribute copies of the software, or if you modify it. | ||||
|  | ||||
|   For example, if you distribute copies of such a program, whether | ||||
| gratis or for a fee, you must give the recipients all the rights that | ||||
| you have.  You must make sure that they, too, receive or can get the | ||||
| source code.  And you must show them these terms so they know their | ||||
| rights. | ||||
|  | ||||
|   We protect your rights with two steps: (1) copyright the software, and | ||||
| (2) offer you this license which gives you legal permission to copy, | ||||
| distribute and/or modify the software. | ||||
|  | ||||
|   Also, for each author's protection and ours, we want to make certain | ||||
| that everyone understands that there is no warranty for this free | ||||
| software.  If the software is modified by someone else and passed on, we | ||||
| want its recipients to know that what they have is not the original, so | ||||
| that any problems introduced by others will not reflect on the original | ||||
| authors' reputations. | ||||
|  | ||||
|   Finally, any free program is threatened constantly by software | ||||
| patents.  We wish to avoid the danger that redistributors of a free | ||||
| program will individually obtain patent licenses, in effect making the | ||||
| program proprietary.  To prevent this, we have made it clear that any | ||||
| patent must be licensed for everyone's free use or not licensed at all. | ||||
|  | ||||
|   The precise terms and conditions for copying, distribution and | ||||
| modification follow. | ||||
|  | ||||
| 		    GNU GENERAL PUBLIC LICENSE | ||||
|    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||||
|  | ||||
|   0. This License applies to any program or other work which contains | ||||
| a notice placed by the copyright holder saying it may be distributed | ||||
| under the terms of this General Public License.  The "Program", below, | ||||
| refers to any such program or work, and a "work based on the Program" | ||||
| means either the Program or any derivative work under copyright law: | ||||
| that is to say, a work containing the Program or a portion of it, | ||||
| either verbatim or with modifications and/or translated into another | ||||
| language.  (Hereinafter, translation is included without limitation in | ||||
| the term "modification".)  Each licensee is addressed as "you". | ||||
|  | ||||
| Activities other than copying, distribution and modification are not | ||||
| covered by this License; they are outside its scope.  The act of | ||||
| running the Program is not restricted, and the output from the Program | ||||
| is covered only if its contents constitute a work based on the | ||||
| Program (independent of having been made by running the Program). | ||||
| Whether that is true depends on what the Program does. | ||||
|  | ||||
|   1. You may copy and distribute verbatim copies of the Program's | ||||
| source code as you receive it, in any medium, provided that you | ||||
| conspicuously and appropriately publish on each copy an appropriate | ||||
| copyright notice and disclaimer of warranty; keep intact all the | ||||
| notices that refer to this License and to the absence of any warranty; | ||||
| and give any other recipients of the Program a copy of this License | ||||
| along with the Program. | ||||
|  | ||||
| You may charge a fee for the physical act of transferring a copy, and | ||||
| you may at your option offer warranty protection in exchange for a fee. | ||||
|  | ||||
|   2. You may modify your copy or copies of the Program or any portion | ||||
| of it, thus forming a work based on the Program, and copy and | ||||
| distribute such modifications or work under the terms of Section 1 | ||||
| above, provided that you also meet all of these conditions: | ||||
|  | ||||
|     a) You must cause the modified files to carry prominent notices | ||||
|     stating that you changed the files and the date of any change. | ||||
|  | ||||
|     b) You must cause any work that you distribute or publish, that in | ||||
|     whole or in part contains or is derived from the Program or any | ||||
|     part thereof, to be licensed as a whole at no charge to all third | ||||
|     parties under the terms of this License. | ||||
|  | ||||
|     c) If the modified program normally reads commands interactively | ||||
|     when run, you must cause it, when started running for such | ||||
|     interactive use in the most ordinary way, to print or display an | ||||
|     announcement including an appropriate copyright notice and a | ||||
|     notice that there is no warranty (or else, saying that you provide | ||||
|     a warranty) and that users may redistribute the program under | ||||
|     these conditions, and telling the user how to view a copy of this | ||||
|     License.  (Exception: if the Program itself is interactive but | ||||
|     does not normally print such an announcement, your work based on | ||||
|     the Program is not required to print an announcement.) | ||||
|  | ||||
| These requirements apply to the modified work as a whole.  If | ||||
| identifiable sections of that work are not derived from the Program, | ||||
| and can be reasonably considered independent and separate works in | ||||
| themselves, then this License, and its terms, do not apply to those | ||||
| sections when you distribute them as separate works.  But when you | ||||
| distribute the same sections as part of a whole which is a work based | ||||
| on the Program, the distribution of the whole must be on the terms of | ||||
| this License, whose permissions for other licensees extend to the | ||||
| entire whole, and thus to each and every part regardless of who wrote it. | ||||
|  | ||||
| Thus, it is not the intent of this section to claim rights or contest | ||||
| your rights to work written entirely by you; rather, the intent is to | ||||
| exercise the right to control the distribution of derivative or | ||||
| collective works based on the Program. | ||||
|  | ||||
| In addition, mere aggregation of another work not based on the Program | ||||
| with the Program (or with a work based on the Program) on a volume of | ||||
| a storage or distribution medium does not bring the other work under | ||||
| the scope of this License. | ||||
|  | ||||
|   3. You may copy and distribute the Program (or a work based on it, | ||||
| under Section 2) in object code or executable form under the terms of | ||||
| Sections 1 and 2 above provided that you also do one of the following: | ||||
|  | ||||
|     a) Accompany it with the complete corresponding machine-readable | ||||
|     source code, which must be distributed under the terms of Sections | ||||
|     1 and 2 above on a medium customarily used for software interchange; or, | ||||
|  | ||||
|     b) Accompany it with a written offer, valid for at least three | ||||
|     years, to give any third party, for a charge no more than your | ||||
|     cost of physically performing source distribution, a complete | ||||
|     machine-readable copy of the corresponding source code, to be | ||||
|     distributed under the terms of Sections 1 and 2 above on a medium | ||||
|     customarily used for software interchange; or, | ||||
|  | ||||
|     c) Accompany it with the information you received as to the offer | ||||
|     to distribute corresponding source code.  (This alternative is | ||||
|     allowed only for noncommercial distribution and only if you | ||||
|     received the program in object code or executable form with such | ||||
|     an offer, in accord with Subsection b above.) | ||||
|  | ||||
| The source code for a work means the preferred form of the work for | ||||
| making modifications to it.  For an executable work, complete source | ||||
| code means all the source code for all modules it contains, plus any | ||||
| associated interface definition files, plus the scripts used to | ||||
| control compilation and installation of the executable.  However, as a | ||||
| special exception, the source code distributed need not include | ||||
| anything that is normally distributed (in either source or binary | ||||
| form) with the major components (compiler, kernel, and so on) of the | ||||
| operating system on which the executable runs, unless that component | ||||
| itself accompanies the executable. | ||||
|  | ||||
| If distribution of executable or object code is made by offering | ||||
| access to copy from a designated place, then offering equivalent | ||||
| access to copy the source code from the same place counts as | ||||
| distribution of the source code, even though third parties are not | ||||
| compelled to copy the source along with the object code. | ||||
|  | ||||
|   4. You may not copy, modify, sublicense, or distribute the Program | ||||
| except as expressly provided under this License.  Any attempt | ||||
| otherwise to copy, modify, sublicense or distribute the Program is | ||||
| void, and will automatically terminate your rights under this License. | ||||
| However, parties who have received copies, or rights, from you under | ||||
| this License will not have their licenses terminated so long as such | ||||
| parties remain in full compliance. | ||||
|  | ||||
|   5. You are not required to accept this License, since you have not | ||||
| signed it.  However, nothing else grants you permission to modify or | ||||
| distribute the Program or its derivative works.  These actions are | ||||
| prohibited by law if you do not accept this License.  Therefore, by | ||||
| modifying or distributing the Program (or any work based on the | ||||
| Program), you indicate your acceptance of this License to do so, and | ||||
| all its terms and conditions for copying, distributing or modifying | ||||
| the Program or works based on it. | ||||
|  | ||||
|   6. Each time you redistribute the Program (or any work based on the | ||||
| Program), the recipient automatically receives a license from the | ||||
| original licensor to copy, distribute or modify the Program subject to | ||||
| these terms and conditions.  You may not impose any further | ||||
| restrictions on the recipients' exercise of the rights granted herein. | ||||
| You are not responsible for enforcing compliance by third parties to | ||||
| this License. | ||||
|  | ||||
|   7. If, as a consequence of a court judgment or allegation of patent | ||||
| infringement or for any other reason (not limited to patent issues), | ||||
| conditions are imposed on you (whether by court order, agreement or | ||||
| otherwise) that contradict the conditions of this License, they do not | ||||
| excuse you from the conditions of this License.  If you cannot | ||||
| distribute so as to satisfy simultaneously your obligations under this | ||||
| License and any other pertinent obligations, then as a consequence you | ||||
| may not distribute the Program at all.  For example, if a patent | ||||
| license would not permit royalty-free redistribution of the Program by | ||||
| all those who receive copies directly or indirectly through you, then | ||||
| the only way you could satisfy both it and this License would be to | ||||
| refrain entirely from distribution of the Program. | ||||
|  | ||||
| If any portion of this section is held invalid or unenforceable under | ||||
| any particular circumstance, the balance of the section is intended to | ||||
| apply and the section as a whole is intended to apply in other | ||||
| circumstances. | ||||
|  | ||||
| It is not the purpose of this section to induce you to infringe any | ||||
| patents or other property right claims or to contest validity of any | ||||
| such claims; this section has the sole purpose of protecting the | ||||
| integrity of the free software distribution system, which is | ||||
| implemented by public license practices.  Many people have made | ||||
| generous contributions to the wide range of software distributed | ||||
| through that system in reliance on consistent application of that | ||||
| system; it is up to the author/donor to decide if he or she is willing | ||||
| to distribute software through any other system and a licensee cannot | ||||
| impose that choice. | ||||
|  | ||||
| This section is intended to make thoroughly clear what is believed to | ||||
| be a consequence of the rest of this License. | ||||
|  | ||||
|   8. If the distribution and/or use of the Program is restricted in | ||||
| certain countries either by patents or by copyrighted interfaces, the | ||||
| original copyright holder who places the Program under this License | ||||
| may add an explicit geographical distribution limitation excluding | ||||
| those countries, so that distribution is permitted only in or among | ||||
| countries not thus excluded.  In such case, this License incorporates | ||||
| the limitation as if written in the body of this License. | ||||
|  | ||||
|   9. The Free Software Foundation may publish revised and/or new versions | ||||
| of the General Public License from time to time.  Such new versions will | ||||
| be similar in spirit to the present version, but may differ in detail to | ||||
| address new problems or concerns. | ||||
|  | ||||
| Each version is given a distinguishing version number.  If the Program | ||||
| specifies a version number of this License which applies to it and "any | ||||
| later version", you have the option of following the terms and conditions | ||||
| either of that version or of any later version published by the Free | ||||
| Software Foundation.  If the Program does not specify a version number of | ||||
| this License, you may choose any version ever published by the Free Software | ||||
| Foundation. | ||||
|  | ||||
|   10. If you wish to incorporate parts of the Program into other free | ||||
| programs whose distribution conditions are different, write to the author | ||||
| to ask for permission.  For software which is copyrighted by the Free | ||||
| Software Foundation, write to the Free Software Foundation; we sometimes | ||||
| make exceptions for this.  Our decision will be guided by the two goals | ||||
| of preserving the free status of all derivatives of our free software and | ||||
| of promoting the sharing and reuse of software generally. | ||||
|  | ||||
| 			    NO WARRANTY | ||||
|  | ||||
|   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | ||||
| FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN | ||||
| OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | ||||
| PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | ||||
| OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||||
| MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS | ||||
| TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE | ||||
| PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | ||||
| REPAIR OR CORRECTION. | ||||
|  | ||||
|   12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||||
| WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | ||||
| REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | ||||
| INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | ||||
| OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | ||||
| TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | ||||
| YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | ||||
| PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | ||||
| POSSIBILITY OF SUCH DAMAGES. | ||||
|  | ||||
| 		     END OF TERMS AND CONDITIONS | ||||
|  | ||||
| 	    How to Apply These Terms to Your New Programs | ||||
|  | ||||
|   If you develop a new program, and you want it to be of the greatest | ||||
| possible use to the public, the best way to achieve this is to make it | ||||
| free software which everyone can redistribute and change under these terms. | ||||
|  | ||||
|   To do so, attach the following notices to the program.  It is safest | ||||
| to attach them to the start of each source file to most effectively | ||||
| convey the exclusion of warranty; and each file should have at least | ||||
| the "copyright" line and a pointer to where the full notice is found. | ||||
|  | ||||
|     <one line to give the program's name and a brief idea of what it does.> | ||||
|     Copyright (C) <year>  <name of author> | ||||
|  | ||||
|     This program is free software; you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|     the Free Software Foundation; either version 2 of the License, or | ||||
|     (at your option) any later version. | ||||
|  | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
|  | ||||
|     You should have received a copy of the GNU General Public License | ||||
|     along with this program; if not, write to the Free Software | ||||
|     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  | ||||
|  | ||||
| Also add information on how to contact you by electronic and paper mail. | ||||
|  | ||||
| If the program is interactive, make it output a short notice like this | ||||
| when it starts in an interactive mode: | ||||
|  | ||||
|     Gnomovision version 69, Copyright (C) year name of author | ||||
|     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||||
|     This is free software, and you are welcome to redistribute it | ||||
|     under certain conditions; type `show c' for details. | ||||
|  | ||||
| The hypothetical commands `show w' and `show c' should show the appropriate | ||||
| parts of the General Public License.  Of course, the commands you use may | ||||
| be called something other than `show w' and `show c'; they could even be | ||||
| mouse-clicks or menu items--whatever suits your program. | ||||
|  | ||||
| You should also get your employer (if you work as a programmer) or your | ||||
| school, if any, to sign a "copyright disclaimer" for the program, if | ||||
| necessary.  Here is a sample; alter the names: | ||||
|  | ||||
|   Yoyodyne, Inc., hereby disclaims all copyright interest in the program | ||||
|   `Gnomovision' (which makes passes at compilers) written by James Hacker. | ||||
|  | ||||
|   <signature of Ty Coon>, 1 April 1989 | ||||
|   Ty Coon, President of Vice | ||||
|  | ||||
| This General Public License does not permit incorporating your program into | ||||
| proprietary programs.  If your program is a subroutine library, you may | ||||
| consider it more useful to permit linking proprietary applications with the | ||||
| library.  If this is what you want to do, use the GNU Library General | ||||
| Public License instead of this License. | ||||
							
								
								
									
										6
									
								
								edge-build-checks/SUSE-Edge.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								edge-build-checks/SUSE-Edge.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| [General] | ||||
| Vendor=com.suse | ||||
| Registry=%%IMG_REPO%% | ||||
|  | ||||
| [Tags] | ||||
| Allowed=%%IMG_PREFIX%%* | ||||
							
								
								
									
										9
									
								
								edge-build-checks/_service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								edge-build-checks/_service
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| <services> | ||||
|   <service name="replace_using_env" mode="buildtime"> | ||||
|     <param name="file">SUSE-Edge.conf</param> | ||||
|     <param name="eval">IMG_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?img_prefix})</param> | ||||
|     <param name="var">IMG_PREFIX</param> | ||||
|     <param name="eval">IMG_REPO=$(rpm --macros=/root/.rpmmacros -E %img_repo)</param> | ||||
|     <param name="var">IMG_REPO</param> | ||||
|   </service> | ||||
| </services> | ||||
							
								
								
									
										59
									
								
								edge-build-checks/edge-build-checks.spec
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								edge-build-checks/edge-build-checks.spec
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| # | ||||
| # spec file for package edge-build-checks | ||||
| # | ||||
| # Copyright (c) 2024 SUSE LLC | ||||
| # | ||||
| # All modifications and additions to the file contributed by third parties | ||||
| # remain the property of their copyright owners, unless otherwise agreed | ||||
| # upon. The license for this file, and modifications and additions to the | ||||
| # file, is the same license as for the pristine package itself (unless the | ||||
| # license for the pristine package is not an Open Source License, in which | ||||
| # case the license is the MIT License). An "Open Source License" is a | ||||
| # license that conforms to the Open Source Definition (Version 1.9) | ||||
| # published by the Open Source Initiative. | ||||
|  | ||||
| # Please submit bugfixes or comments via https://bugs.opensuse.org/ | ||||
| # | ||||
|  | ||||
|  | ||||
| Name:           edge-build-checks | ||||
| Summary:        post checks for build after charts and images are created | ||||
| License:        GPL-2.0-or-later | ||||
| Group:          Development/Tools/Building | ||||
| Version:        0.0.1 | ||||
| Release:        0 | ||||
| Source0:        COPYING | ||||
| Source1:        20-helm-images | ||||
| Source2:        10-helm-lint | ||||
| Source3:        SUSE-Edge.conf | ||||
| Source4:        20-helm-tags | ||||
| BuildArch:      noarch | ||||
| Requires:       container-build-checks | ||||
| Requires:       python3-PyYAML | ||||
| Provides:       container-build-checks-vendor | ||||
|  | ||||
| %description | ||||
| some scripts to check for problems in edge related helm charts and images after their creation | ||||
| in OBS. | ||||
|  | ||||
| %prep | ||||
| cp %{SOURCE0} . | ||||
|  | ||||
| %build | ||||
| %define _lto_cflags %{nil} | ||||
| # nothing to do | ||||
|  | ||||
| %install | ||||
| install -d $RPM_BUILD_ROOT/usr/lib/build/post-build-checks | ||||
| install -m 755 %{SOURCE1} $RPM_BUILD_ROOT/usr/lib/build/post-build-checks | ||||
| install -m 755 %{SOURCE2} $RPM_BUILD_ROOT/usr/lib/build/post-build-checks | ||||
| install -m 755 %{SOURCE4} $RPM_BUILD_ROOT/usr/lib/build/post-build-checks | ||||
| install -d %{buildroot}%{_datadir}/container-build-checks | ||||
| install -m 644 %{SOURCE3} %{buildroot}%{_datadir}/container-build-checks/SUSE-Edge.conf | ||||
|  | ||||
| %files | ||||
| %license COPYING | ||||
| %{_datadir}/container-build-checks | ||||
| /usr/lib/build | ||||
|  | ||||
| %changelog | ||||
| @@ -1,6 +1,5 @@ | ||||
| #!BuildTag: %%IMG_PREFIX%%edge-image-builder:1.1.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%edge-image-builder:1.1.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.1.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.1.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" | ||||
|   | ||||
| @@ -7,10 +7,13 @@ | ||||
|     <param name="eval">IMG_REPO=$(rpm --macros=/root/.rpmmacros -E %img_repo)</param> | ||||
|     <param name="var">IMG_REPO</param> | ||||
|     <param name="file">artifacts.yaml</param> | ||||
|     <param name="eval">CHART_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?chart_prefix})</param> | ||||
|     <param name="var">CHART_PREFIX</param> | ||||
|     <param name="eval">CHART_REPO=$(rpm --macros=/root/.rpmmacros -E %chart_repo)</param> | ||||
|     <param name="var">CHART_REPO</param> | ||||
|     <param name="eval">SUPPORT_LEVEL=$(rpm --macros=/root/.rpmmacros -E %support_level)</param> | ||||
|     <param name="var">SUPPORT_LEVEL</param> | ||||
|     <param name="eval">CHART_MAJOR=$(rpm --macros=/root/.rpmmacros -E %{?chart_major})</param> | ||||
|     <param name="var">CHART_MAJOR</param> | ||||
|   </service> | ||||
| </services> | ||||
|  | ||||
|   | ||||
| @@ -1,16 +1,19 @@ | ||||
| metallb: | ||||
|   chart: metallb-chart | ||||
|   repository: %%CHART_REPO%%/3.1 | ||||
|   version: 0.14.9 | ||||
|   chart: metallb | ||||
|   repository: "%%CHART_REPO%%/%%CHART_PREFIX%%" | ||||
|   version: "%%CHART_MAJOR%%.0.1+up0.15.2" | ||||
| endpoint-copier-operator: | ||||
|   chart: endpoint-copier-operator-chart | ||||
|   repository: %%CHART_REPO%%/3.1 | ||||
|   version: 0.2.1 | ||||
|   chart: endpoint-copier-operator | ||||
|   repository: "%%CHART_REPO%%/%%CHART_PREFIX%%" | ||||
|   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/ | ||||
|   | ||||
| @@ -1,18 +1,19 @@ | ||||
| <services> | ||||
|   <service name="obs_scm"> | ||||
|     <param name="url">https://github.com/suse-edge/edge-image-builder.git</param> | ||||
|     <param name="versionformat">@PARENT_TAG@</param> | ||||
|     <param name="scm">git</param> | ||||
|     <param name="exclude">.git</param> | ||||
|     <param name="revision">v1.1.0</param> | ||||
|     <param name="revision">v1.3.0</param> | ||||
|     <!-- Uncomment and set this For Pre-Release Version --> | ||||
|     <!-- <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> | ||||
|     <param name="versionrewrite-replacement">\1.\2.\3</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="tar" /> | ||||
|   <service mode="buildtime" name="recompress"> | ||||
|     <param name="file">*.tar</param> | ||||
|     <param name="compression">gz</param> | ||||
|   <service mode="buildtime" name="tar"> | ||||
|     <param name="obsinfo">edge-image-builder.obsinfo</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="set_version" /> | ||||
|   <service name="go_modules"> | ||||
|   | ||||
| @@ -17,14 +17,14 @@ | ||||
|  | ||||
|  | ||||
| Name:           edge-image-builder | ||||
| Version:        1.1.0 | ||||
| Version:        1.3.0 | ||||
| Release:        0 | ||||
| Summary:        Edge Image Builder | ||||
| License:        Apache-2.0 | ||||
| URL:            https://github.com/suse-edge/edge-image-builder | ||||
| Source:         edge-image-builder-%{version}.tar.gz | ||||
| Source:         edge-image-builder-%{version}.tar | ||||
| Source1:        vendor.tar.gz | ||||
| BuildRequires:  golang(API) go1.22 | ||||
| BuildRequires:  golang(API) go1.24 | ||||
| BuildRequires:  golang-packaging | ||||
| BuildRequires:  gpgme-devel | ||||
| BuildRequires:  device-mapper-devel | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| #!BuildTag: %%IMG_PREFIX%%endpoint-copier-operator-chart:%%CHART_MAJOR%%.0.0_up0.2.1 | ||||
| #!BuildTag: %%IMG_PREFIX%%endpoint-copier-operator-chart:%%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" | ||||
|   | ||||
| @@ -9,8 +9,8 @@ | ||||
|   </service> | ||||
|   <service name="replace_using_env" mode="buildtime"> | ||||
|     <param name="file">Chart.yaml</param> | ||||
|     <param name="eval">IMG_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?img_prefix})</param> | ||||
|     <param name="var">IMG_PREFIX</param> | ||||
|     <param name="eval">CHART_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?chart_prefix})</param> | ||||
|     <param name="var">CHART_PREFIX</param> | ||||
|     <param name="eval">CHART_MAJOR=$(rpm --macros=/root/.rpmmacros -E %{?chart_major})</param> | ||||
|     <param name="var">CHART_MAJOR</param> | ||||
|   </service> | ||||
|   | ||||
| @@ -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> | ||||
| @@ -12,10 +12,8 @@ | ||||
|     <param name="without-version">yes</param> | ||||
|     <param name="versionrewrite-replacement">\1</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="tar" /> | ||||
|   <service mode="buildtime" name="recompress"> | ||||
|     <param name="file">*.tar</param> | ||||
|     <param name="compression">gz</param> | ||||
|   <service mode="buildtime" name="tar"> | ||||
|     <param name="obsinfo">endpoint-copier-operator.obsinfo</param> | ||||
|   </service> | ||||
|   <service name="go_modules"> | ||||
|   </service> | ||||
|   | ||||
| @@ -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.gz | ||||
| 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.4 | ||||
| #!BuildTag: %%IMG_PREFIX%%frr:8.4-%RELEASE% | ||||
| #!BuildVersion: 15.5 | ||||
| #!BuildTag: %%IMG_PREFIX%%frr:10.2.1 | ||||
| #!BuildTag: %%IMG_PREFIX%%frr:10.2.1-%RELEASE% | ||||
| ARG SLE_VERSION | ||||
| FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro | ||||
|  | ||||
| @@ -15,11 +14,11 @@ FROM micro AS final | ||||
| LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)" | ||||
| LABEL org.opencontainers.image.title="FRR Container Image" | ||||
| LABEL org.opencontainers.image.description="frr based on the SLE Base Container Image." | ||||
| LABEL org.opencontainers.image.version="8.4" | ||||
| LABEL org.opencontainers.image.version="10.2.1" | ||||
| LABEL org.opencontainers.image.url="https://www.suse.com/products/server/" | ||||
| LABEL org.opencontainers.image.created="%BUILDTIME%" | ||||
| LABEL org.opencontainers.image.vendor="SUSE LLC" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%frr:8.4-%RELEASE%" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%frr:10.2.1-%RELEASE%" | ||||
| LABEL org.openbuildservice.disturl="%DISTURL%" | ||||
| LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" | ||||
| LABEL com.suse.eula="SUSE Combined EULA February 2024" | ||||
|   | ||||
| @@ -1,26 +1,24 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%ip-address-manager:v%%ip-address-manager_version%% | ||||
| #!BuildTag: %%IMG_PREFIX%%ip-address-manager:%%ip-address-manager_version%% | ||||
| #!BuildTag: %%IMG_PREFIX%%ip-address-manager:%%ip-address-manager_version%%-%RELEASE% | ||||
| #!BuildVersion: 15.6 | ||||
| #!BuildTag: %%IMG_PREFIX%%frr-k8s:v%%frr-k8s_version%% | ||||
| #!BuildTag: %%IMG_PREFIX%%frr-k8s:v%%frr-k8s_version%%-%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 ip-address-manager shadow; zypper -n clean; rm -rf /var/log/* | ||||
| RUN zypper --installroot /installroot --non-interactive install --no-recommends frr-k8s; zypper -n clean; rm -rf /var/log/* | ||||
| 
 | ||||
| FROM micro AS final | ||||
| # Define labels according to https://en.opensuse.org/Building_derived_containers | ||||
| # labelprefix=com.suse.application.ip-address-manager | ||||
| # labelprefix=com.suse.application.endpoint-copier-operator | ||||
| LABEL org.opencontainers.image.authors="SUSE LLC (https://www.suse.com/)" | ||||
| LABEL org.opencontainers.image.title="SLE ip-address-manager Container Image" | ||||
| LABEL org.opencontainers.image.description="ip-address-manager based on the SLE Base Container Image." | ||||
| LABEL org.opencontainers.image.version="%%ip-address-manager_version%%" | ||||
| LABEL org.opencontainers.image.title="SLE frr-k8s Container Image" | ||||
| LABEL org.opencontainers.image.description="frr-k8s based on the SLE Base Container Image." | ||||
| LABEL org.opencontainers.image.version="%%frr-k8s_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%%ip-address-manager:%%ip-address-manager_version%%-%RELEASE%" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%frr-k8s:v%%frr-k8s_version%%-%RELEASE%" | ||||
| LABEL org.openbuildservice.disturl="%DISTURL%" | ||||
| LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%" | ||||
| LABEL com.suse.eula="SUSE Combined EULA February 2024" | ||||
| @@ -29,8 +27,6 @@ LABEL com.suse.image-type="application" | ||||
| LABEL com.suse.release-stage="released" | ||||
| # endlabelprefix | ||||
| 
 | ||||
| #Install frr-k8s | ||||
| COPY --from=base /installroot / | ||||
| RUN mv /usr/bin/ip-address-manager /manager | ||||
| # Use uid of nonroot user (65532) because kubernetes expects numeric user when applying pod security policies | ||||
| USER 65532 | ||||
| ENTRYPOINT [ "/manager" ] | ||||
| ENTRYPOINT ["/frr-k8s"] | ||||
| @@ -3,8 +3,8 @@ | ||||
|   <service mode="buildtime" name="docker_label_helper"/> | ||||
|   <service name="replace_using_package_version" mode="buildtime"> | ||||
|     <param name="file">Dockerfile</param> | ||||
|     <param name="regex">%%ip-address-manager_version%%</param> | ||||
|     <param name="package">ip-address-manager</param> | ||||
|     <param name="regex">%%frr-k8s_version%%</param> | ||||
|     <param name="package">frr-k8s</param> | ||||
|     <param name="parse-version">patch</param> | ||||
|   </service> | ||||
|   <service name="replace_using_env" mode="buildtime"> | ||||
| @@ -2,7 +2,7 @@ | ||||
|  <service name="obs_scm"> | ||||
|     <param name="url">https://github.com/metallb/frr-k8s</param> | ||||
|     <param name="scm">git</param> | ||||
|     <param name="revision">v0.0.14</param> | ||||
|     <param name="revision">v0.0.20</param> | ||||
|     <param name="version">_auto_</param> | ||||
|     <param name="versionformat">@PARENT_TAG@</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
| @@ -12,10 +12,8 @@ | ||||
|     <param name="without-version">yes</param> | ||||
|     <param name="versionrewrite-replacement">\1</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="tar" /> | ||||
|   <service mode="buildtime" name="recompress"> | ||||
|     <param name="file">*.tar</param> | ||||
|     <param name="compression">gz</param> | ||||
|   <service mode="buildtime" name="tar"> | ||||
|     <param name="obsinfo">frr-k8s.obsinfo</param> | ||||
|   </service> | ||||
|   <service name="go_modules"> | ||||
|   </service> | ||||
|   | ||||
| @@ -17,14 +17,14 @@ | ||||
|  | ||||
|  | ||||
| Name:           frr-k8s | ||||
| Version:        0.0.14 | ||||
| Release:        0.0.14 | ||||
| Version:        0.0.20 | ||||
| Release:        0.0.20 | ||||
| Summary:        A kubernetes based daemonset that exposes a subset of the FRR API in a kubernetes compliant manner. | ||||
| License:        Apache-2.0 | ||||
| URL:            https://github.com/metallb/frr-k8s | ||||
| Source:         frr-k8s-%{version}.tar.gz | ||||
| Source:         frr-k8s-%{version}.tar | ||||
| Source1:        vendor.tar.gz | ||||
| BuildRequires:  golang(API) = 1.22 | ||||
| BuildRequires:  golang(API) = 1.24 | ||||
| ExcludeArch:    s390 | ||||
| ExcludeArch:    %{ix86} | ||||
|  | ||||
|   | ||||
| @@ -4,17 +4,24 @@ | ||||
|     <param name="versionformat">@PARENT_TAG@</param> | ||||
|     <param name="scm">git</param> | ||||
|     <param name="exclude">.get</param> | ||||
|     <param name="revision">v1.0.7</param> | ||||
|     <param name="revision">v1.2.5</param> | ||||
|     <param name="versionrewrite-pattern">v(.*)</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="tar" /> | ||||
|   <service mode="buildtime" name="recompress"> | ||||
|     <param name="file">*.tar</param> | ||||
|     <param name="compression">gz</param> | ||||
|   <service mode="buildtime" name="tar"> | ||||
|     <param name="obsinfo">hauler.obsinfo</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="set_version" /> | ||||
|   <service name="go_modules"> | ||||
|      <param name="compression">gz</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="replace_using_env"> | ||||
|     <param name="file">hauler.spec</param> | ||||
|     <param name="var">SOURCE_COMMIT</param> | ||||
|     <param name="eval"> | ||||
|       SOURCE_COMMIT=$(grep commit hauler.obsinfo | cut -d" " -f2) | ||||
|     </param> | ||||
|     <param name="verbose">1</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="set_version" /> | ||||
| </services> | ||||
|   | ||||
| @@ -18,15 +18,14 @@ | ||||
| %define project github.com/hauler-dev/hauler | ||||
|  | ||||
| Name:           hauler | ||||
| Version:        1.0.7 | ||||
| Version:        1.2.5 | ||||
| Release:        0 | ||||
| Summary:        Airgap Swiss Army Knife | ||||
| License:        Apache-2.0 | ||||
| URL:            https://github.com/hauler-dev/hauler | ||||
| Source:         hauler-%{version}.tar.gz | ||||
| Source:         hauler-%{version}.tar | ||||
| Source1:        vendor.tar.gz | ||||
| BuildRequires:  golang-packaging | ||||
| BuildRequires:  cosign | ||||
|  | ||||
| %description | ||||
|  | ||||
| @@ -38,10 +37,18 @@ BuildRequires:  cosign | ||||
|  | ||||
| tar -xf %{SOURCE1} | ||||
|  | ||||
| mkdir cmd/hauler/binaries | ||||
| cp `which cosign` cmd/hauler/binaries/cosign-linux-%{go_arch} | ||||
| MODULE=hauler.dev/go/hauler | ||||
| %define buildtime %(date +%%Y-%%m-%%dT%%H:%%M:%%S%%z) | ||||
| %define buildcommit %%SOURCE_COMMIT%% | ||||
|  | ||||
| go build -mod=vendor -buildmode=pie -o hauler ./cmd/hauler | ||||
|  | ||||
| go build \ | ||||
| -mod=vendor \ | ||||
| -buildmode=pie \ | ||||
| -o hauler \ | ||||
| -ldflags \ | ||||
| "-X $MODULE/internal/version.gitVersion=v%{version} -X $MODULE/internal/version.gitCommit=%{buildcommit} -X $MODULE/internal/version.buildDate=%{buildtime}" \ | ||||
| ./cmd/hauler | ||||
|  | ||||
| %install | ||||
|  | ||||
|   | ||||
| @@ -1,23 +0,0 @@ | ||||
| <services> | ||||
|  <service name="obs_scm"> | ||||
|     <param name="url">https://github.com/metal3-io/ip-address-manager</param> | ||||
|     <param name="scm">git</param> | ||||
|     <param name="revision">v1.7.2</param> | ||||
|     <param name="version">_auto_</param> | ||||
|     <param name="versionformat">@PARENT_TAG@</param> | ||||
|     <param name="changesgenerate">enable</param> | ||||
|     <param name="changesauthor">steven.hardy@suse.com</param> | ||||
|     <param name="match-tag">v*</param> | ||||
|     <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param> | ||||
|     <param name="without-version">yes</param> | ||||
|     <param name="versionrewrite-replacement">\1</param> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="tar" /> | ||||
|   <service mode="buildtime" name="recompress"> | ||||
|     <param name="file">*.tar</param> | ||||
|     <param name="compression">gz</param> | ||||
|   </service> | ||||
|    <service name="go_modules"> | ||||
|   </service> | ||||
|   <service mode="buildtime" name="set_version" /> | ||||
| </services> | ||||
| @@ -1,51 +0,0 @@ | ||||
| # | ||||
| # spec file for package ip-address-manager | ||||
| # | ||||
| # Copyright (c) 2023 SUSE LLC | ||||
| # | ||||
| # All modifications and additions to the file contributed by third parties | ||||
| # remain the property of their copyright owners, unless otherwise agreed | ||||
| # upon. The license for this file, and modifications and additions to the | ||||
| # file, is the same license as for the pristine package itself (unless the | ||||
| # license for the pristine package is not an Open Source License, in which | ||||
| # case the license is the MIT License). An "Open Source License" is a | ||||
| # license that conforms to the Open Source Definition (Version 1.9) | ||||
| # published by the Open Source Initiative. | ||||
|  | ||||
| # Please submit bugfixes or comments via https://bugs.opensuse.org/ | ||||
| # | ||||
|  | ||||
|  | ||||
| Name:           ip-address-manager | ||||
| Version:        1.7.2 | ||||
| Release:        0 | ||||
| Summary:        Metal3 IPAM controller | ||||
| License:        Apache-2.0 | ||||
| URL:            https://github.com/metal3-io/ip-address-manager | ||||
| Source:         ip-address-manager-%{version}.tar.gz | ||||
| Source1:        vendor.tar.gz | ||||
| BuildRequires:  golang(API) = 1.22 | ||||
| ExcludeArch:    s390 | ||||
| ExcludeArch:    %{ix86} | ||||
|  | ||||
| %description | ||||
|  | ||||
| Metal3 IPAM controller | ||||
|  | ||||
| %prep | ||||
| %autosetup -a1 -n ip-address-manager-%{version} | ||||
|  | ||||
| %build | ||||
| go build \ | ||||
|    -mod=vendor \ | ||||
|    -buildmode=pie \ | ||||
|  | ||||
| %install | ||||
| install -D -m0755 ip-address-manager %{buildroot}%{_bindir}/ip-address-manager | ||||
|  | ||||
| %files | ||||
| %license LICENSE | ||||
| %doc README.md | ||||
| %{_bindir}/ip-address-manager | ||||
|  | ||||
| %changelog | ||||
| @@ -1,14 +1,14 @@ | ||||
| # SPDX-License-Identifier: Apache-2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic:26.1.2.0 | ||||
| #!BuildTag: %%IMG_PREFIX%%ironic:26.1.2.0-%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 | ||||
|  | ||||
| FROM registry.suse.com/bci/bci-base:$SLE_VERSION AS base | ||||
|  | ||||
| RUN set -euo pipefail; zypper -n  in --no-recommends gcc git make xz-devel shim dosfstools mtools glibc-extra grub2-x86_64-efi grub2; zypper -n clean; rm -rf /var/log/* | ||||
| RUN zypper -n in --no-recommends shim-x86_64 shim-aarch64 grub2-x86_64-efi grub2-arm64-efi dosfstools mtools | ||||
|  | ||||
| WORKDIR /tmp | ||||
| COPY prepare-efi.sh /bin/ | ||||
| RUN set -euo pipefail; chmod +x /bin/prepare-efi.sh | ||||
| @@ -16,14 +16,24 @@ RUN /bin/prepare-efi.sh | ||||
|  | ||||
| COPY --from=micro / /installroot/ | ||||
| RUN sed -i -e 's%^# rpm.install.excludedocs = no.*%rpm.install.excludedocs = yes%g' /etc/zypp/zypp.conf | ||||
| RUN 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 inotify-tools ipcalc ipmitool iproute2 procps qemu-tools sqlite3 util-linux xorriso tftp syslinux ipxe-bootimgs crudini openstack-ironic | ||||
|  | ||||
| #!ArchExclusiveLine: x86_64 | ||||
| RUN if [ "$(uname -m)" = "x86_64" ];then \ | ||||
|       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 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 | ||||
| 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" | ||||
| @@ -31,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.0" | ||||
| LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%ironic:26.1.2.0-%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" | ||||
| @@ -53,37 +63,44 @@ 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 | ||||
| RUN cp /usr/share/ipxe/ipxe-x86_64.efi /tftpboot/ipxe.efi | ||||
| COPY --from=base /tmp/esp.img /tmp/uefi_esp.img | ||||
| #!ArchExclusiveLine: x86_64 | ||||
| RUN if [ "$(uname -m)" = "x86_64" ];then \ | ||||
|       cp /usr/share/ipxe/ipxe-x86_64.efi /tftpboot/ipxe.efi ;\ | ||||
|     fi | ||||
| #!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 ;\ | ||||
|     fi | ||||
|      | ||||
| 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/ | ||||
| COPY --from=base /tmp/uefi_esp_*.img /templates/ | ||||
|  | ||||
| # 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,29 +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/html"> | ||||
|          Order deny,allow | ||||
|          deny from all | ||||
|     </Directory> | ||||
|     <Directory ~ "/shared/html/(redfish|ilo)/"> | ||||
|          Order allow,deny | ||||
|          allow from all | ||||
|     </Directory> | ||||
|     <Directory ~ "/shared/html/images/"> | ||||
|          Order allow,deny | ||||
|          allow from all | ||||
|     </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 | ||||
| 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.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.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 | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user