|
1 | 1 | ---
|
| 2 | + |
2 | 3 | name: Build Kolla container images
|
3 | 4 | on:
|
4 | 5 | workflow_dispatch:
|
5 | 6 | inputs:
|
6 |
| - regexes: |
7 |
| - description: Space-separated list of regular expressions matching overcloud images to build |
| 7 | + debug_ssh_key: |
| 8 | + description: 'A key used to login to the AIO for debugging' |
| 9 | + required: true |
8 | 10 | type: string
|
9 |
| - required: false |
10 |
| - default: "" |
11 |
| - overcloud: |
12 |
| - description: Build overcloud images? |
13 |
| - type: boolean |
14 |
| - required: false |
15 |
| - default: true |
16 |
| - seed: |
17 |
| - description: Build seed images? |
18 |
| - type: boolean |
19 |
| - required: false |
20 |
| - default: false |
21 |
| - rocky-linux-9: |
22 |
| - description: Build Rocky Linux 9 images? |
23 |
| - type: boolean |
24 |
| - required: false |
25 |
| - default: true |
26 |
| - ubuntu-jammy: |
27 |
| - description: Build Ubuntu Jammy 22.04 images? |
28 |
| - type: boolean |
29 |
| - required: false |
30 |
| - default: true |
31 |
| - push: |
32 |
| - description: Whether to push images |
33 |
| - type: boolean |
34 |
| - required: false |
35 |
| - default: true |
36 |
| - push-dirty: |
37 |
| - description: Push scanned images that have critical vulnerabilities? |
38 |
| - type: boolean |
39 |
| - required: false |
40 |
| - default: false |
41 |
| - |
42 |
| -env: |
43 |
| - ANSIBLE_FORCE_COLOR: True |
44 | 11 | jobs:
|
45 |
| - generate-tag: |
46 |
| - name: Generate container image tag |
47 |
| - if: github.repository == 'stackhpc/stackhpc-kayobe-config' |
48 |
| - runs-on: ubuntu-latest |
49 |
| - permissions: {} |
50 |
| - outputs: |
51 |
| - datetime_tag: ${{ steps.datetime_tag.outputs.datetime_tag }} |
52 |
| - matrix: ${{ steps.set-matrix.outputs.matrix }} |
53 |
| - openstack_release: ${{ steps.openstack_release.outputs.openstack_release }} |
54 |
| - steps: |
55 |
| - - name: Checkout |
56 |
| - uses: actions/checkout@v4 |
57 |
| - |
58 |
| - - name: Determine OpenStack release |
59 |
| - id: openstack_release |
60 |
| - run: | |
61 |
| - BRANCH=$(awk -F'=' '/defaultbranch/ {print $2}' .gitreview) |
62 |
| - echo "openstack_release=${BRANCH}" | sed -E "s,(stable|unmaintained)/,," >> $GITHUB_OUTPUT |
63 |
| -
|
64 |
| - # Generate a tag to apply to all built container images. |
65 |
| - # Without this, each kayobe * container image build command would use a different tag. |
66 |
| - - name: Generate container datetime tag |
67 |
| - id: datetime_tag |
68 |
| - run: | |
69 |
| - echo "datetime_tag=$(date +%Y%m%dT%H%M%S)" >> $GITHUB_OUTPUT |
70 |
| -
|
71 |
| - # Dynamically define job matrix. |
72 |
| - # We need a separate matrix entry for each distribution, when the relevant input is true. |
73 |
| - # https://stackoverflow.com/questions/65384420/how-do-i-make-a-github-action-matrix-element-conditional |
74 |
| - - name: Generate build matrix |
75 |
| - id: set-matrix |
76 |
| - run: | |
77 |
| - comma="" |
78 |
| - echo -n "matrix={\"distro\": [" >> $GITHUB_OUTPUT |
79 |
| - if [[ ${{ inputs.rocky-linux-9 }} == 'true' ]]; then |
80 |
| - echo -n "$comma\"rocky\"" >> $GITHUB_OUTPUT |
81 |
| - comma=", " |
82 |
| - fi |
83 |
| - if [[ ${{ inputs.ubuntu-jammy }} == 'true' ]]; then |
84 |
| - echo -n "$comma\"ubuntu\"" >> $GITHUB_OUTPUT |
85 |
| - comma=", " |
86 |
| - fi |
87 |
| - echo "]}" >> $GITHUB_OUTPUT |
88 | 12 |
|
89 |
| - - name: Display container datetime tag |
90 |
| - run: | |
91 |
| - echo "${{ steps.datetime_tag.outputs.datetime_tag }}" |
92 |
| -
|
93 |
| - container-image-build: |
94 |
| - name: Build Kolla container images |
95 |
| - if: github.repository == 'stackhpc/stackhpc-kayobe-config' |
96 |
| - runs-on: arc-skc-container-image-builder-runner |
97 |
| - timeout-minutes: 720 |
98 |
| - permissions: {} |
99 |
| - strategy: |
100 |
| - fail-fast: false |
101 |
| - matrix: ${{ fromJson(needs.generate-tag.outputs.matrix) }} |
| 13 | + build-kayobe-image: |
| 14 | + name: Build Kayobe Image |
102 | 15 | needs:
|
103 |
| - - generate-tag |
104 |
| - steps: |
105 |
| - - name: Install package dependencies |
106 |
| - run: | |
107 |
| - sudo apt update |
108 |
| - sudo apt install -y build-essential git unzip nodejs python3-wheel python3-pip python3-venv curl jq wget |
109 |
| -
|
110 |
| - - name: Install gh |
111 |
| - run: | |
112 |
| - sudo mkdir -p -m 755 /etc/apt/keyrings && wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null |
113 |
| - sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg |
114 |
| - echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null |
115 |
| - sudo apt update |
116 |
| - sudo apt install gh -y |
117 |
| -
|
118 |
| - - name: Checkout |
119 |
| - uses: actions/checkout@v4 |
120 |
| - with: |
121 |
| - path: src/kayobe-config |
122 |
| - |
123 |
| - - name: Clone StackHPC Kayobe repository |
124 |
| - uses: actions/checkout@v4 |
125 |
| - with: |
126 |
| - repository: stackhpc/kayobe |
127 |
| - ref: refs/heads/stackhpc/${{ needs.generate-tag.outputs.openstack_release }} |
128 |
| - path: src/kayobe |
129 |
| - |
130 |
| - - name: Make sure dockerd is running and test Docker |
131 |
| - run: | |
132 |
| - docker ps |
133 |
| -
|
134 |
| - - name: Install Trivy |
135 |
| - run: | |
136 |
| - curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin v0.49.0 |
137 |
| -
|
138 |
| - - name: Install yq |
139 |
| - run: | |
140 |
| - curl -sL https://github.com/mikefarah/yq/releases/download/v4.42.1/yq_linux_amd64.tar.gz | tar xz && sudo mv yq_linux_amd64 /usr/bin/yq |
141 |
| -
|
142 |
| - - name: Install Kayobe |
143 |
| - run: | |
144 |
| - mkdir -p venvs && |
145 |
| - pushd venvs && |
146 |
| - python3 -m venv kayobe && |
147 |
| - source kayobe/bin/activate && |
148 |
| - pip install -U pip && |
149 |
| - pip install ../src/kayobe |
150 |
| -
|
151 |
| - # Required for Pulp auth proxy deployment and Docker registry login. |
152 |
| - # Normally installed during host configure. |
153 |
| - - name: Install Docker Python SDK |
154 |
| - run: | |
155 |
| - sudo pip install docker 'requests<2.32.0' |
156 |
| - |
157 |
| - - name: Get Kolla tag |
158 |
| - id: write-kolla-tag |
159 |
| - run: echo "kolla-tag=${{ needs.generate-tag.outputs.openstack_release }}-${{ matrix.distro }}-${{ matrix.distro == 'rocky' && '9' || 'jammy' }}-${{ needs.generate-tag.outputs.datetime_tag }}" >> $GITHUB_OUTPUT |
160 |
| - |
161 |
| - - name: Configure localhost as a seed |
162 |
| - run: | |
163 |
| - cat > src/kayobe-config/etc/kayobe/environments/ci-builder/inventory/hosts << EOF |
164 |
| - # A 'seed' host used for building images. |
165 |
| - # Use localhost for container image builds. |
166 |
| - [seed] |
167 |
| - localhost ansible_connection=local ansible_python_interpreter=/usr/bin/python3 |
168 |
| - EOF |
169 |
| -
|
170 |
| - # See etc/kayobe/ansible/roles/pulp_auth_proxy/README.md for details. |
171 |
| - # NOTE: We override pulp_auth_proxy_conf_path to a path shared by the |
172 |
| - # runner and dind containers. |
173 |
| - - name: Deploy an authenticating package repository mirror proxy |
174 |
| - run: | |
175 |
| - source venvs/kayobe/bin/activate && |
176 |
| - source src/kayobe-config/kayobe-env --environment ci-builder && |
177 |
| - kayobe playbook run $KAYOBE_CONFIG_PATH/ansible/pulp-auth-proxy.yml -e pulp_auth_proxy_conf_path=/home/runner/_work/pulp_proxy |
178 |
| - env: |
179 |
| - KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD }} |
180 |
| - |
181 |
| - - name: Create build logs output directory |
182 |
| - run: mkdir image-build-logs |
183 |
| - |
184 |
| - - name: Build kolla overcloud images |
185 |
| - id: build_overcloud_images |
186 |
| - continue-on-error: true |
187 |
| - run: | |
188 |
| - args="${{ inputs.regexes }}" |
189 |
| - args="$args -e kolla_base_distro=${{ matrix.distro }}" |
190 |
| - args="$args -e kolla_tag=${{ steps.write-kolla-tag.outputs.kolla-tag }}" |
191 |
| - args="$args -e stackhpc_repo_mirror_auth_proxy_enabled=true" |
192 |
| - source venvs/kayobe/bin/activate && |
193 |
| - source src/kayobe-config/kayobe-env --environment ci-builder && |
194 |
| - kayobe overcloud container image build $args |
195 |
| - env: |
196 |
| - KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD }} |
197 |
| - if: inputs.overcloud |
198 |
| - |
199 |
| - - name: Copy overcloud container image build logs to output directory |
200 |
| - run: sudo mv /var/log/kolla-build.log image-build-logs/kolla-build-overcloud.log |
201 |
| - if: inputs.overcloud |
202 |
| - |
203 |
| - - name: Build kolla seed images |
204 |
| - id: build_seed_images |
205 |
| - continue-on-error: true |
206 |
| - run: | |
207 |
| - args="-e kolla_base_distro=${{ matrix.distro }}" |
208 |
| - args="$args -e kolla_tag=${{ steps.write-kolla-tag.outputs.kolla-tag }}" |
209 |
| - args="$args -e stackhpc_repo_mirror_auth_proxy_enabled=true" |
210 |
| - source venvs/kayobe/bin/activate && |
211 |
| - source src/kayobe-config/kayobe-env --environment ci-builder && |
212 |
| - kayobe seed container image build $args |
213 |
| - env: |
214 |
| - KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD }} |
215 |
| - if: inputs.seed |
216 |
| - |
217 |
| - - name: Copy seed container image build logs to output directory |
218 |
| - run: sudo mv /var/log/kolla-build.log image-build-logs/kolla-build-seed.log |
219 |
| - if: inputs.seed |
220 |
| - |
221 |
| - - name: Get built container images |
222 |
| - run: docker image ls --filter "reference=ark.stackhpc.com/stackhpc-dev/*:${{ steps.write-kolla-tag.outputs.kolla-tag }}" > ${{ matrix.distro }}-container-images |
223 |
| - |
224 |
| - - name: Fail if no images have been built |
225 |
| - run: if [ $(wc -l < ${{ matrix.distro }}-container-images) -le 1 ]; then exit 1; fi |
226 |
| - |
227 |
| - - name: Scan built container images |
228 |
| - run: src/kayobe-config/tools/scan-images.sh ${{ matrix.distro }} ${{ steps.write-kolla-tag.outputs.kolla-tag }} |
229 |
| - |
230 |
| - - name: Move image scan logs to output artifact |
231 |
| - run: mv image-scan-output image-build-logs/image-scan-output |
232 |
| - |
233 |
| - - name: Fail if no images have passed scanning |
234 |
| - run: if [ $(wc -l < image-build-logs/image-scan-output/clean-images.txt) -le 0 ]; then exit 1; fi |
235 |
| - if: ${{ !inputs.push-dirty }} |
236 |
| - |
237 |
| - - name: Copy clean images to push-attempt-images list |
238 |
| - run: cp image-build-logs/image-scan-output/clean-images.txt image-build-logs/push-attempt-images.txt |
239 |
| - if: inputs.push |
240 |
| - |
241 |
| - # NOTE(seunghun1ee): This always appends dirty images with CVEs severity lower than critical. |
242 |
| - # This should be reverted when it's decided to filter high level CVEs as well. |
243 |
| - - name: Append dirty images to push list |
244 |
| - run: | |
245 |
| - cat image-build-logs/image-scan-output/dirty-images.txt >> image-build-logs/push-attempt-images.txt |
246 |
| - if: ${{ inputs.push }} |
247 |
| - |
248 |
| - - name: Append images with critical vulnerabilities to push list |
249 |
| - run: | |
250 |
| - cat image-build-logs/image-scan-output/critical-images.txt >> image-build-logs/push-attempt-images.txt |
251 |
| - if: ${{ inputs.push && inputs.push-dirty }} |
252 |
| - |
253 |
| - - name: Push images |
254 |
| - run: | |
255 |
| - touch image-build-logs/push-failed-images.txt |
256 |
| - source venvs/kayobe/bin/activate && |
257 |
| - source src/kayobe-config/kayobe-env --environment ci-builder && |
258 |
| - kayobe playbook run ${KAYOBE_CONFIG_PATH}/ansible/docker-registry-login.yml && |
259 |
| -
|
260 |
| - while read -r image; do |
261 |
| - # Retries! |
262 |
| - for i in {1..5}; do |
263 |
| - if docker push $image; then |
264 |
| - echo "Pushed $image" |
265 |
| - break |
266 |
| - elif [ $i -eq 5 ] ; then |
267 |
| - echo "Failed to push $image" |
268 |
| - echo $image >> image-build-logs/push-failed-images.txt |
269 |
| - else |
270 |
| - echo "Failed on retry $i" |
271 |
| - sleep 5 |
272 |
| - fi; |
273 |
| - done |
274 |
| - done < image-build-logs/push-attempt-images.txt |
275 |
| - shell: bash |
276 |
| - env: |
277 |
| - KAYOBE_VAULT_PASSWORD: ${{ secrets.KAYOBE_VAULT_PASSWORD }} |
278 |
| - if: inputs.push |
279 |
| - |
280 |
| - - name: Upload output artifact |
281 |
| - uses: actions/upload-artifact@v4 |
282 |
| - with: |
283 |
| - name: ${{ matrix.distro }}-logs |
284 |
| - path: image-build-logs |
285 |
| - retention-days: 7 |
286 |
| - if: ${{ !cancelled() }} |
287 |
| - |
288 |
| - - name: Fail when images failed to build |
289 |
| - run: echo "An image build failed. Check the workflow artifact for build logs" && exit 1 |
290 |
| - if: ${{ steps.build_overcloud_images.outcome == 'failure' || steps.build_seed_images.outcome == 'failure' }} |
291 |
| - |
292 |
| - - name: Fail when images failed to push |
293 |
| - run: if [ $(wc -l < image-build-logs/push-failed-images.txt) -gt 0 ]; then cat image-build-logs/push-failed-images.txt && exit 1; fi |
294 |
| - if: ${{ !cancelled() }} |
295 |
| - |
296 |
| - # NOTE(seunghun1ee): Currently we want to mark the job fail only when critical CVEs are detected. |
297 |
| - # This can be used again instead of "Fail when critical vulnerabilities are found" when it's |
298 |
| - # decided to fail the job on detecting high CVEs as well. |
299 |
| - # - name: Fail when images failed scanning |
300 |
| - # run: if [ $(wc -l < image-build-logs/image-scan-output/dirty-images.txt) -gt 0 ]; then cat image-build-logs/image-scan-output/dirty-images.txt && exit 1; fi |
301 |
| - # if: ${{ !inputs.push-dirty && !cancelled() }} |
302 |
| - |
303 |
| - - name: Fail when critical vulnerabilities are found |
304 |
| - run: if [ $(wc -l < image-build-logs/image-scan-output/critical-images.txt) -gt 0 ]; then cat image-build-logs/image-scan-output/critical-images.txt && exit 1; fi |
305 |
| - if: ${{ !inputs.push-dirty && !cancelled() }} |
306 |
| - |
307 |
| - # NOTE(mgoddard): Trigger another CI workflow in the |
308 |
| - # stackhpc-release-train repository. |
309 |
| - - name: Trigger container image repository sync |
310 |
| - run: | |
311 |
| - filter='${{ inputs.regexes }}' |
312 |
| - if [[ -n $filter ]] && [[ ${{ inputs.seed }} == 'true' ]]; then |
313 |
| - filter="$filter bifrost" |
314 |
| - fi |
315 |
| - gh workflow run \ |
316 |
| - container-sync.yml \ |
317 |
| - --repo stackhpc/stackhpc-release-train \ |
318 |
| - --ref main \ |
319 |
| - -f filter="$filter" \ |
320 |
| - -f sync-old-images=false |
321 |
| - env: |
322 |
| - GITHUB_TOKEN: ${{ secrets.STACKHPC_RELEASE_TRAIN_TOKEN }} |
323 |
| - if: ${{ github.repository == 'stackhpc/stackhpc-kayobe-config' && inputs.push && !cancelled() }} |
| 16 | + - check-changes |
| 17 | + uses: ./.github/workflows/stackhpc-build-kayobe-image.yml |
| 18 | + with: |
| 19 | + if: ${{ needs.check-changes.outputs.aio == 'true' }} |
| 20 | + if: github.repository == 'stackhpc/stackhpc-kayobe-config' |
324 | 21 |
|
325 |
| - - name: Display link to container image repository sync workflows |
326 |
| - run: | |
327 |
| - echo "::notice Container image repository sync workflows: https://github.com/stackhpc/stackhpc-release-train/actions/workflows/container-sync.yml" |
328 |
| - if: ${{ github.repository == 'stackhpc/stackhpc-kayobe-config' && inputs.push && !cancelled() }} |
| 22 | + all-in-one-upgrade-ubuntu-jammy-ovs: |
| 23 | + name: aio upgrade (Ubuntu Jammy OVS) |
| 24 | + needs: |
| 25 | + - build-kayobe-image |
| 26 | + uses: ./.github/workflows/stackhpc-all-in-one.yml |
| 27 | + with: |
| 28 | + kayobe_image: ${{ needs.build-kayobe-image.outputs.kayobe_image }} |
| 29 | + os_distribution: ubuntu |
| 30 | + os_release: jammy |
| 31 | + ssh_username: ubuntu |
| 32 | + neutron_plugin: ovs |
| 33 | + OS_CLOUD: openstack |
| 34 | + upgrade: true |
| 35 | + destroy: false |
| 36 | + debug_ssh_key: ${inputs.debug_ssh_key} |
| 37 | + secrets: inherit |
| 38 | + if: ${{ ! failure() && ! cancelled() && github.repository == 'stackhpc/stackhpc-kayobe-config' }} |
0 commit comments