5
5
6
6
name : Multinode
7
7
on :
8
+ push :
8
9
workflow_call :
9
10
inputs :
10
11
multinode_name :
85
86
jobs :
86
87
multinode :
87
88
name : Multinode
88
- runs-on : arc-skc-aio-runner
89
+ runs-on : ubuntu-latest
89
90
environment : Leafcloud
90
91
permissions : {}
91
92
timeout-minutes : 2880
@@ -94,276 +95,25 @@ jobs:
94
95
KAYOBE_ENVIRONMENT : ci-multinode
95
96
KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD_CI_MULTINODE }}
96
97
steps :
97
- - name : Fail if previous version is not defined
98
- run : |
99
- echo "StackHPC Kayobe Configuration previous version must be defined for upgrades"
100
- exit 1
101
- if : ${{ inputs.upgrade && inputs.stackhpc_kayobe_config_previous_version == '' }}
102
-
103
- - name : Fail if no SSH key is provided for break_on
104
- run : |
105
- echo "break_on is set to ${{ inputs.break_on }} but an SSH public key has not been provided"
106
- exit 1
107
- if : ${{ inputs.break_on != 'never' && inputs.ssh_key == '' }}
108
-
109
- - name : Install Package
110
- uses : ConorMacBride/install-package@main
98
+ - name : Create some files
99
+ run : |
100
+ mkdir -p logs/dir logs/colon:dir 'logs/angle<dir' logs/colon:dir/colon:dir2
101
+ touch logs/{file,colon:file}
102
+ touch logs/dir/{file,colon:file}
103
+ touch logs/colon:dir/{file,colon:file}
104
+ touch logs/'angle<dir'/{file,colon:file}
105
+ touch logs/colon:dir/colon:dir2/{file,colon:file}
106
+
107
+ # GitHub Actions does not accept filenames with certain characters, and
108
+ # fails the upload-artifact action if any exist. The tmux log file
109
+ # contains a colon, as do previous Tempest results directories.
110
+ - name : Sanitise artifact filenames
111
+ # FIXME: 1.1.0
112
+ uses : stackhpc/stackhpc-openstack-gh-workflows/sanitise-artifact-filenames@sanitise-artifact-filenames
111
113
with :
112
- apt : git unzip nodejs python3-pip python3-venv rsync
113
-
114
- # If testing upgrade, checkout previous release, otherwise checkout current branch
115
- - name : Checkout ${{ inputs.upgrade && 'previous release' || 'current' }} config
116
- uses : actions/checkout@v4
117
- with :
118
- repository : stackhpc/stackhpc-kayobe-config
119
- ref : ${{ inputs.upgrade && inputs.stackhpc_kayobe_config_previous_version || inputs.stackhpc_kayobe_config_version }}
120
-
121
- - name : Checkout terraform-kayobe-multinode
122
- uses : actions/checkout@v4
123
- with :
124
- repository : stackhpc/terraform-kayobe-multinode
125
- ref : ${{ inputs.terraform_kayobe_multinode_version }}
126
- path : terraform-kayobe-multinode
127
-
128
- - name : Make sure dockerd is running and test Docker
129
- run : |
130
- docker ps
131
-
132
- - name : Output image tag
133
- id : image_tag
134
- run : |
135
- echo image_tag=$(grep stackhpc_${{ inputs.os_distribution }}_$(sed s/-/_/ <(echo "${{ inputs.os_release }}"))_overcloud_host_image_version: etc/kayobe/pulp-host-image-versions.yml | awk '{print $2}') >> $GITHUB_OUTPUT
136
-
137
- # Use the image override if set, otherwise use overcloud-os_distribution-os_release-tag
138
- - name : Output image name
139
- id : image_name
140
- run : |
141
- if [ -z "${{ inputs.multinode_image_override }}" ]; then
142
- echo image_name=overcloud-${{ inputs.os_distribution }}-${{ inputs.os_release }}-${{ steps.image_tag.outputs.image_tag }} >> $GITHUB_OUTPUT
143
- else
144
- echo image_name=${{ inputs.multinode_image_override }} >> $GITHUB_OUTPUT
145
- fi
146
-
147
- - name : Install terraform
148
- uses : hashicorp/setup-terraform@v2
149
- with :
150
- terraform_wrapper : false
151
-
152
- - name : Setup Ansible
153
- run : |
154
- python3 -m venv venv &&
155
- source venv/bin/activate &&
156
- pip install -U pip &&
157
- pip install ansible &&
158
- mkdir -p ansible/{collections,roles} &&
159
- ansible-galaxy role install -r ansible/requirements.yml -p ansible/roles &&
160
- ansible-galaxy collection install -r ansible/requirements.yml -p ansible/collections
161
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
162
-
163
- - name : Generate a VXLAN VNI
164
- id : vxlan_vni
165
- run : |
166
- # There is an undocumented restriction limiting us to a max VNI of
167
- # 100,000.
168
- max_vni=100000
169
- timestamp=$(date +%s)
170
- vni=$(((timestamp % max_vni) + 1))
171
- echo vxlan_vni=$vni >> $GITHUB_OUTPUT
172
-
173
- - name : Generate SSH keypair
174
- run : ssh-keygen -f id_rsa -N ''
175
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
176
-
177
- # NOTE: In Ansible 2.10 and lower the synchronize module used in the
178
- # ansible/fetch-logs.yml playbook does not respect SSH connection
179
- # variables. This may result in Permission Denied issues if using an SSH
180
- # key that is not in ~/.ssh.
181
- - name : Copy SSH keypair to .ssh/
182
- run : |
183
- install -d ~/.ssh -m 700 &&
184
- cp id_rsa* ~/.ssh/
185
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
186
-
187
- - name : Generate clouds.yaml
188
- run : |
189
- cat << EOF > clouds.yaml
190
- ${{ secrets.CLOUDS_YAML }}
191
- EOF
192
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
193
-
194
- - name : Generate terraform.tfvars
195
- run : |
196
- cat << EOF > terraform.tfvars
197
-
198
- prefix = "${{ env.MULTINODE_NAME }}"
199
-
200
- ansible_control_vm_flavor = "${{ env.MULTINODE_ANSIBLE_CONTROL_VM_FLAVOR }}"
201
- ansible_control_vm_name = "ansible-control"
202
- ansible_control_disk_size = 100
203
-
204
- seed_vm_flavor = "${{ env.MULTINODE_SEED_VM_FLAVOR }}"
205
- seed_disk_size = 100
206
-
207
- multinode_flavor = "${{ env.MULTINODE_FLAVOR }}"
208
- multinode_image = "${{ env.MULTINODE_IMAGE }}"
209
- multinode_keypair = "${{ env.MULTINODE_NAME }}"
210
- multinode_vm_network = "${{ env.MULTINODE_NETWORK }}"
211
- multinode_vm_subnet = "${{ env.MULTINODE_SUBNET }}"
212
- compute_count = "${{ env.MULTINODE_COMPUTE_COUNT }}"
213
- controller_count = "${{ env.MULTINODE_CONTROLLER_COUNT }}"
214
- compute_disk_size = 100
215
- controller_disk_size = 100
216
-
217
- ssh_public_key = "id_rsa.pub"
218
- ssh_user = "${{ env.SSH_USERNAME }}"
219
-
220
- storage_count = "${{ env.MULTINODE_STORAGE_COUNT }}"
221
- storage_flavor = "${{ env.MULTINODE_STORAGE_FLAVOR }}"
222
- storage_disk_size = 100
223
-
224
- deploy_wazuh = false
225
- infra_vm_flavor = "${{ env.MULTINODE_INFRA_VM_FLAVOR }}"
226
- infra_vm_disk_size = 100
227
- EOF
228
-
229
- if [[ "${{ inputs.ssh_key }}" != "" ]]; then
230
- cat << EOF >> terraform.tfvars
231
- add_ansible_control_fip = true
232
- ansible_control_fip_pool = "${{ env.MULTINODE_FIP_POOL }}"
233
- EOF
234
- fi
235
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
236
- env :
237
- MULTINODE_NAME : " ${{ inputs.multinode_name }}"
238
- MULTINODE_ANSIBLE_CONTROL_VM_FLAVOR : ${{ vars.multinode_ansible_control_vm_flavor }} # en1.xsmall
239
- MULTINODE_SEED_VM_FLAVOR : ${{ vars.multinode_seed_vm_flavor }} # en1.xsmall
240
- MULTINODE_INFRA_VM_FLAVOR : ${{ vars.multinode_infra_vm_flavor }} # en1.xsmall
241
- MULTINODE_FLAVOR : ${{ vars.multinode_flavor }} # en1.large
242
- MULTINODE_STORAGE_FLAVOR : ${{ vars.multinode_storage_flavor }} # en1.medium
243
- MULTINODE_COMPUTE_COUNT : " ${{ inputs.multinode_compute_count }}"
244
- MULTINODE_CONTROLLER_COUNT : " ${{ inputs.multinode_controller_count }}"
245
- MULTINODE_STORAGE_COUNT : " ${{ inputs.multinode_storage_count }}"
246
- MULTINODE_IMAGE : ${{ steps.image_name.outputs.image_name }}
247
- MULTINODE_NETWORK : ${{ vars.multinode_network }}
248
- MULTINODE_SUBNET : ${{ vars.multinode_subnet }}
249
- MULTINODE_FIP_POOL : ${{ vars.multinode_fip_pool }}
250
- SSH_USERNAME : " ${{ inputs.ssh_username }}"
251
-
252
- - name : Initialise terraform
253
- run : terraform init
254
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
255
-
256
- - name : Validate terraform
257
- id : tf_validate
258
- run : terraform validate
259
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
260
-
261
- - name : Configure Ansible
262
- run : |
263
- echo '${{ env.KAYOBE_VAULT_PASSWORD }}' > vault-pw
264
-
265
- cat << EOF >> ansible/vars/defaults.yml
266
- kayobe_config_version: ${{ inputs.upgrade && inputs.stackhpc_kayobe_config_previous_version || inputs.stackhpc_kayobe_config_version }}
267
- ssh_key_path: ${{ github.workspace }}/terraform-kayobe-multinode/id_rsa
268
- vxlan_vni: ${{ steps.vxlan_vni.outputs.vxlan_vni }}
269
- vault_password_path: ${{ github.workspace }}/terraform-kayobe-multinode/vault-pw
270
- kayobe_config_custom:
271
- - path: zz-multinode.yml
272
- block: |
273
- os_distribution: ${{ env.OS_DISTRIBUTION }}
274
- os_release: "${{ env.OS_RELEASE }}"
275
- kolla_enable_ovn: ${{ env.ENABLE_OVN }}
276
- EOF
277
-
278
- if [[ "${{ env.SSH_KEY }}" != "" ]]; then
279
- cat << EOF >> ansible/vars/defaults.yml
280
- extra_ssh_public_keys:
281
- - "${{ env.SSH_KEY }}"
282
- EOF
283
- fi
284
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
285
- env :
286
- ENABLE_OVN : ${{ inputs.neutron_plugin == 'ovn' }}
287
- OS_DISTRIBUTION : ${{ inputs.os_distribution }}
288
- OS_RELEASE : ${{ inputs.os_release }}
289
- SSH_KEY : ${{ inputs.ssh_key }}
290
-
291
- - name : Terraform Plan
292
- run : terraform plan -input=false
293
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
294
- env :
295
- OS_CLOUD : ${{ vars.OS_CLOUD }}
296
- OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
297
- OS_APPLICATION_CREDENTIAL_SECRET : ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }}
298
-
299
- - name : Terraform Apply
300
- run : |
301
- for attempt in $(seq 3); do
302
- if terraform apply -auto-approve -input=false; then
303
- echo "Created infrastructure on attempt $attempt"
304
- exit 0
305
- fi
306
- echo "Failed to create infrastructure on attempt $attempt"
307
- sleep 60
308
- done
309
- echo "Failed to create infrastructure after $attempt attempts"
310
- exit 1
311
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
312
- env :
313
- OS_CLOUD : ${{ vars.OS_CLOUD }}
314
- OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
315
- OS_APPLICATION_CREDENTIAL_SECRET : ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }}
316
-
317
- - name : Configure Ansible control host
318
- id : config_ach
319
- run : |
320
- source venv/bin/activate &&
321
- ansible-playbook -v -i ansible/inventory.yml ansible/configure-hosts.yml
322
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
323
-
324
- - name : Deploy OpenStack
325
- run : |
326
- source venv/bin/activate &&
327
- ansible-playbook -v -i ansible/inventory.yml ansible/deploy-openstack.yml
328
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
329
-
330
- - name : Upgrade Ansible control host
331
- run : |
332
- source venv/bin/activate &&
333
- ansible-playbook -v -i ansible/inventory.yml ansible/deploy-openstack-config.yml -e upgrade=true -e kayobe_config_version=${{ inputs.stackhpc_kayobe_config_version }}
334
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
335
- if : inputs.upgrade
336
-
337
- - name : Upgrade OpenStack
338
- run : |
339
- source venv/bin/activate &&
340
- ansible-playbook -v -i ansible/inventory.yml ansible/deploy-openstack.yml -e multinode_command=upgrade_overcloud
341
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
342
- if : inputs.upgrade
343
-
344
- - name : Run Tempest tests
345
- run : |
346
- source venv/bin/activate &&
347
- ansible-playbook -v -i ansible/inventory.yml ansible/deploy-openstack.yml -e multinode_command=run_tempest
348
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
349
- if : inputs.upgrade
350
-
351
- - name : Download deployment logs
352
- run : |
353
- mkdir -p ${{ github.workspace }}/logs &&
354
- source venv/bin/activate &&
355
- ansible-playbook -v -i ansible/inventory.yml ansible/fetch-logs.yml -e fetch_logs_dest=${{ github.workspace }}/logs
356
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
357
- if : ${{ always() && steps.config_ach.outcome == 'success' }}
358
-
359
- # NOTE: The tmux log rename is due to GitHub Actions not accepting files with a colon as artifacts.
360
- - name : Fix up deployment log filename
361
- run : |
362
- if [[ -f ${{ github.workspace }}/logs/tmux.kayobe:0.log ]]; then
363
- mv ${{ github.workspace }}/logs/tmux.kayobe:0.log ${{ github.workspace }}/logs/tmux.kayobe.log
364
- fi
365
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
366
- if : ${{ always() && steps.config_ach.outcome == 'success' }}
114
+ path : |
115
+ ${{ github.workspace }}/logs/
116
+ # if: ${{ always() && steps.config_ach.outcome == 'success' }}
367
117
368
118
- name : Upload test result artifacts
369
119
id : upload-results
@@ -372,68 +122,3 @@ jobs:
372
122
name : test-results-multinode-${{ inputs.os_distribution }}-${{ inputs.os_release }}-${{ inputs.neutron_plugin }}${{ inputs.upgrade && '-upgrade' || '' }}
373
123
path : |
374
124
${{ github.workspace }}/logs/
375
- if : ${{ always() && steps.config_ach.outcome == 'success' }}
376
-
377
- - name : Send message to Slack via Workflow Builder
378
- uses : slackapi/slack-github-action@v1.26.0
379
- with :
380
- payload : |
381
- {
382
- "channel-id": "${{ env.SLACK_CHANNEL_ID }}",
383
- "inputs": "${{ env.INPUTS }}",
384
- "message": "${{ env.MESSAGE }}",
385
- "results-url": "${{ env.RESULTS_URL }}",
386
- "workflow-url": "${{ env.WORKFLOW_URL }}"
387
- }
388
- env :
389
- SLACK_WEBHOOK_URL : ${{ secrets.SLACK_WEBHOOK_URL }}
390
- # #release-train-alerts
391
- SLACK_CHANNEL_ID : C03B28HRP53
392
- INPUTS : >-
393
- name: ${{ inputs.multinode_name }}\n
394
- controllers: ${{ inputs.multinode_controller_count }}\n
395
- computes: ${{ inputs.multinode_compute_count }}\n
396
- storage: ${{ inputs.multinode_storage_count }}\n
397
- os_distribution: ${{ inputs.os_distribution }}\n
398
- os_release: ${{ inputs.os_release }}\n
399
- ssh_username: ${{ inputs.ssh_username }}\n
400
- neutron_plugin: ${{ inputs.neutron_plugin }}\n
401
- stackhpc_kayobe_config_version: ${{ inputs.stackhpc_kayobe_config_version }}\n
402
- stackhpc_kayobe_config_previous_version: ${{ inputs.stackhpc_kayobe_config_previous_version }}\n
403
- terraform_kayobe_multinode_version: ${{ inputs.terraform_kayobe_multinode_version }}\n
404
- upgrade: ${{ inputs.upgrade }}\n
405
- MESSAGE : " Multinode workflow failed :sob:"
406
- RESULTS_URL : " ${{ steps.upload-results.outputs.artifact-url || 'N/A' }}"
407
- WORKFLOW_URL : " ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
408
- if : ${{ failure() && inputs.enable_slack_alert }}
409
-
410
- - name : Break on failure
411
- run : |
412
- sleep ${{ inputs.break_duration }}m
413
- if : ${{ failure() && steps.config_ach.outcome == 'success' && contains(fromJSON('["failure", "always"]'), inputs.break_on) }}
414
-
415
- - name : Break on success
416
- run : |
417
- sleep ${{ inputs.break_duration }}m
418
- if : ${{ steps.config_ach.outcome == 'success' && contains(fromJSON('["success", "always"]'), inputs.break_on) }}
419
-
420
- - name : Destroy
421
- run : |
422
- for attempt in $(seq 5); do
423
- if terraform destroy -auto-approve -input=false -lock-timeout=200s; then
424
- echo "Destroyed infrastructure on attempt $attempt"
425
- exit 0
426
- fi
427
- echo "Failed to destroy infrastructure on attempt $attempt"
428
- sleep 120
429
- done
430
- echo "Failed to destroy infrastructure after $attempt attempts"
431
- echo "Forcefully destroying infrastructure"
432
- terraform destroy -auto-approve -input=false -lock=false
433
- exit 1
434
- working-directory : ${{ github.workspace }}/terraform-kayobe-multinode
435
- env :
436
- OS_CLOUD : ${{ vars.OS_CLOUD }}
437
- OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
438
- OS_APPLICATION_CREDENTIAL_SECRET : ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }}
439
- if : always() && steps.tf_validate.outcome == 'success'
0 commit comments