1
- # Gross workaround because the workflow hasn't been run from the main branch.
2
- # DO NOT MERGE, just overriding this for testing
3
- name : Update overcloud host image tags
4
-
1
+ ---
2
+ name : Build Amphora image
5
3
on :
6
4
workflow_dispatch :
7
5
inputs :
8
- rocky9_tag :
9
- description : Overcloud host image tag for Rocky 9
10
- type : string
11
- ubuntu_noble_tag :
12
- description : Overcloud host image tag for Ubuntu
13
- type : string
6
+ runner_env :
7
+ description : Which cloud to run on?
8
+ type : choice
9
+ default : SMS Lab
10
+ options :
11
+ - SMS Lab
12
+ - Leafcloud
13
+ secrets :
14
+ KAYOBE_VAULT_PASSWORD :
15
+ required : true
16
+ CLOUDS_YAML :
17
+ required : true
18
+ OS_APPLICATION_CREDENTIAL_ID :
19
+ required : true
20
+ OS_APPLICATION_CREDENTIAL_SECRET :
21
+ required : true
14
22
23
+ env :
24
+ ANSIBLE_FORCE_COLOR : True
25
+ KAYOBE_ENVIRONMENT : ci-builder
26
+ KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD }}
15
27
jobs :
16
- propose_overcloud_host_image_tag_updates :
28
+ runner-selection :
29
+ uses : ./.github/workflows/runner-selector.yml
30
+ with :
31
+ runner_env : ${{ inputs.runner_env }}
32
+ amphora-image-build :
33
+ name : Build Amphora image
17
34
if : github.repository == 'stackhpc/stackhpc-kayobe-config'
18
- runs-on : ubuntu-22.04
19
- permissions :
20
- contents : write
21
- pull-requests : write
22
- name : Update overcloud host image tags
35
+ environment : ${{ inputs.runner_env }}
36
+ runs-on : ${{ needs.runner-selection.outputs.runner_name_image_build }}
37
+ needs :
38
+ - runner-selection
39
+ permissions : {}
23
40
steps :
41
+
42
+ - name : Install Package
43
+ uses : ConorMacBride/install-package@main
44
+ with :
45
+ apt : git unzip nodejs python3-pip python3-venv openssh-server openssh-client jq
46
+
47
+ - name : Start the SSH service
48
+ run : |
49
+ sudo /etc/init.d/ssh start
50
+
24
51
- name : Checkout
25
52
uses : actions/checkout@v4
26
53
with :
27
- ref : stackhpc/2025.1
28
- path : ${{ github.workspace }}/src/kayobe-config
54
+ path : src/kayobe-config
29
55
30
- - name : Update Rocky 9 overcloud host image tag
56
+ - name : Determine OpenStack release
57
+ id : openstack_release
31
58
run : |
32
- sed -i "/stackhpc_rocky_9_overcloud_host_image_version/s/.*/stackhpc_rocky_9_overcloud_host_image_version: ${{ inputs.rocky9_tag }}/" ${{ github.workspace }}/src/kayobe-config/etc/kayobe/pulp-host-image-versions.yml
33
- if : " ${{ inputs.rocky9_tag != '' }}"
59
+ BRANCH=$(awk -F'=' '/defaultbranch/ {print $2}' src/kayobe-config/.gitreview)
60
+ echo "BRANCH=$BRANCH" >> $GITHUB_OUTPUT
61
+ echo "openstack_release=${BRANCH}" | sed -E "s,(stable|unmaintained)/,," >> $GITHUB_OUTPUT
34
62
35
- - name : Update Ubuntu Noble overcloud host image tag
63
+ # Generate a tag to apply to all built Amphora image.
64
+ - name : Generate Amphora image tag
65
+ id : image_tag
36
66
run : |
37
- sed -i "/stackhpc_ubuntu_noble_overcloud_host_image_version/s/.*/stackhpc_ubuntu_noble_overcloud_host_image_version: ${{ inputs.ubuntu_noble_tag }}/" ${{ github.workspace }}/src/kayobe-config/etc/kayobe/pulp-host-image-versions.yml
38
- if : " ${{ inputs.ubuntu_noble_tag != '' }}"
67
+ echo "image_tag=$(date +${{ steps.openstack_release.outputs.openstack_release }}-%Y%m%dT%H%M%S)" >> $GITHUB_OUTPUT
68
+
69
+ - name : Display Amphora image tag
70
+ run : |
71
+ echo "${{ steps.image_tag.outputs.image_tag }}"
72
+
73
+ - name : Install Kayobe
74
+ run : |
75
+ mkdir -p venvs &&
76
+ pushd venvs &&
77
+ python3 -m venv kayobe &&
78
+ source kayobe/bin/activate &&
79
+ pip install -U pip &&
80
+ pip install -r ../src/kayobe-config/requirements.txt
81
+
82
+ - name : Install terraform
83
+ uses : hashicorp/setup-terraform@v2
84
+
85
+ - name : Initialise terraform
86
+ run : terraform init
87
+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
88
+
89
+ - name : Generate SSH keypair
90
+ run : ssh-keygen -f id_rsa -N ''
91
+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
39
92
40
- - name : Propose changes via PR if required
41
- uses : peter-evans/create-pull-request@v7
93
+ - name : Generate clouds.yaml
94
+ run : |
95
+ cat << EOF > clouds.yaml
96
+ ${{ secrets.CLOUDS_YAML }}
97
+ EOF
98
+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
99
+
100
+ - name : Generate terraform.tfvars
101
+ run : |
102
+ cat << EOF > terraform.tfvars
103
+ ssh_public_key = "id_rsa.pub"
104
+ ssh_username = "ubuntu"
105
+ aio_vm_name = "skc-amphora-image-builder"
106
+ # Must be an Ubuntu Jammy host to successfully build all images
107
+ # This MUST NOT be an LVM image. It can cause confusing conficts with the built image.
108
+ aio_vm_image = "${{ vars.HOST_IMAGE_BUILD_IMAGE }}"
109
+ aio_vm_flavor = "${{ vars.HOST_IMAGE_BUILD_FLAVOR }}"
110
+ aio_vm_network = "${{ vars.HOST_IMAGE_BUILD_NETWORK }}"
111
+ aio_vm_subnet = "${{ vars.HOST_IMAGE_BUILD_SUBNET }}"
112
+ aio_vm_interface = "ens3"
113
+ EOF
114
+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
115
+
116
+ - name : Terraform Plan
117
+ run : terraform plan
118
+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
119
+ env :
120
+ OS_CLOUD : " openstack"
121
+ OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
122
+ OS_APPLICATION_CREDENTIAL_SECRET : ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }}
123
+
124
+ - name : Terraform Apply
125
+ run : |
126
+ for attempt in $(seq 5); do
127
+ if terraform apply -auto-approve; then
128
+ echo "Created infrastructure on attempt $attempt"
129
+ exit 0
130
+ fi
131
+ echo "Failed to create infrastructure on attempt $attempt"
132
+ sleep 10
133
+ terraform destroy -auto-approve
134
+ sleep 60
135
+ done
136
+ echo "Failed to create infrastructure after $attempt attempts"
137
+ exit 1
138
+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
139
+ env :
140
+ OS_CLOUD : ${{ vars.OS_CLOUD }}
141
+ OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
142
+ OS_APPLICATION_CREDENTIAL_SECRET : ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }}
143
+
144
+ - name : Get Terraform outputs
145
+ id : tf_outputs
146
+ run : |
147
+ terraform output -json
148
+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
149
+
150
+ - name : Write Terraform outputs
151
+ run : |
152
+ cat << EOF > src/kayobe-config/etc/kayobe/environments/ci-builder/tf-outputs.yml
153
+ ${{ steps.tf_outputs.outputs.stdout }}
154
+ EOF
155
+
156
+ - name : Write Terraform network config
157
+ run : |
158
+ cat << EOF > src/kayobe-config/etc/kayobe/environments/ci-builder/tf-network-allocation.yml
159
+ ---
160
+ aio_ips:
161
+ builder: "{{ access_ip_v4.value }}"
162
+ EOF
163
+
164
+ - name : Write Terraform network interface config
165
+ run : |
166
+ mkdir -p src/kayobe-config/etc/kayobe/environments/$KAYOBE_ENVIRONMENT/inventory/group_vars/seed
167
+ rm -f src/kayobe-config/etc/kayobe/environments/$KAYOBE_ENVIRONMENT/inventory/group_vars/seed/network-interfaces
168
+ cat << EOF > src/kayobe-config/etc/kayobe/environments/$KAYOBE_ENVIRONMENT/inventory/group_vars/seed/network-interfaces
169
+ admin_interface: "{{ access_interface.value }}"
170
+ aio_interface: "{{ access_interface.value }}"
171
+ EOF
172
+
173
+ - name : Manage SSH keys
174
+ run : |
175
+ mkdir -p ~/.ssh
176
+ touch ~/.ssh/authorized_keys
177
+ cat src/kayobe-config/terraform/aio/id_rsa.pub >> ~/.ssh/authorized_keys
178
+ cp src/kayobe-config/terraform/aio/id_rsa* ~/.ssh/
179
+
180
+ - name : Bootstrap the control host
181
+ run : |
182
+ source venvs/kayobe/bin/activate &&
183
+ source src/kayobe-config/kayobe-env --environment ci-builder &&
184
+ kayobe control host bootstrap
185
+
186
+ - name : Configure the seed host (Builder VM)
187
+ run : |
188
+ source venvs/kayobe/bin/activate &&
189
+ source src/kayobe-config/kayobe-env --environment ci-builder &&
190
+ kayobe seed host configure -e seed_bootstrap_user=ubuntu --skip-tags network
191
+
192
+ - name : Install dependencies
193
+ run : |
194
+ source venvs/kayobe/bin/activate &&
195
+ source src/kayobe-config/kayobe-env --environment ci-builder &&
196
+ kayobe seed host command run \
197
+ --command "sudo apt update && sudo apt -y install gcc git libffi-dev python3-dev python-is-python3 python3-venv" --show-output
198
+ env :
199
+ KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD }}
200
+
201
+ - name : Create Amphora image output directory
202
+ run : |
203
+ source venvs/kayobe/bin/activate &&
204
+ source src/kayobe-config/kayobe-env --environment ci-builder &&
205
+ kayobe seed host command run \
206
+ --command "mkdir -p /opt/kayobe/images/amphora" --show-output
207
+ env :
208
+ KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD }}
209
+
210
+ - name : Build Octavia Amphora image
211
+ id : build_amphora
212
+ run : |
213
+ source venvs/kayobe/bin/activate &&
214
+ source src/kayobe-config/kayobe-env --environment ci-builder &&
215
+ kayobe playbook run src/kayobe-config/etc/kayobe/ansible/octavia-amphora-image-build.yml -e amphora_image_dest=/opt/kayobe/images/amphora/amphora-x64-haproxy.qcow2
216
+ env :
217
+ KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD }}
218
+
219
+ - name : Show last error logs
220
+ continue-on-error : true
221
+ run : |
222
+ source venvs/kayobe/bin/activate &&
223
+ source src/kayobe-config/kayobe-env --environment ci-builder &&
224
+ kayobe seed host command run --command "tail -200 /var/log/octavia-amphora-image-build.log" --show-output
225
+ env :
226
+ KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD }}
227
+ if : steps.build_amphora.outcome == 'failure'
228
+
229
+ - name : Upload Octavia Amphora image to Ark
230
+ run : |
231
+ source venvs/kayobe/bin/activate &&
232
+ source src/kayobe-config/kayobe-env --environment ci-builder &&
233
+ kayobe playbook run \
234
+ src/kayobe-config/etc/kayobe/ansible/pulp-artifact-upload.yml \
235
+ -e artifact_path=/opt/kayobe/images/amphora \
236
+ -e artifact_tag=${{ steps.image_tag.outputs.image_tag }} \
237
+ -e file_regex="*.qcow2" \
238
+ -e repository_name="amphora-images-${{ steps.openstack_release.outputs.openstack_release }}" \
239
+ -e pulp_base_path="amphora-images/${{ steps.openstack_release.outputs.openstack_release }}"
240
+ env :
241
+ KAYOBE_VAULT_PASSWORD : ${{ secrets.KAYOBE_VAULT_PASSWORD }}
242
+ if : steps.build_amphora.outcome == 'success'
243
+
244
+ - name : Copy logs back to runner
245
+ continue-on-error : true
246
+ run : |
247
+ mkdir artifact
248
+ scp stack@$(jq -r .access_ip_v4.value src/kayobe-config/etc/kayobe/environments/ci-builder/tf-outputs.yml):/var/log/octavia-amphora-image-build.log ./artifact
249
+ if : always()
250
+
251
+ - name : Fail if Amphora image builds failed
252
+ run : |
253
+ echo "Builds failed. See workflow artifacts for details." &&
254
+ exit 1
255
+ if : steps.build_amphora.outcome == 'failure'
256
+
257
+ - name : Upload logs & image artifact
258
+ uses : actions/upload-artifact@v4
42
259
with :
43
- path : ${{ github.workspace }}/src/kayobe-config
44
- commit-message : >-
45
- Bump overcloud host image tags
46
- author :
stackhpc-ci <[email protected] >
47
- branch : bump-overcloud-host-images-${{ inputs.rocky9_tag }}-${{ inputs.ubuntu_noble_tag }}
48
- delete-branch : true
49
- title : >-
50
- DNM test PR: Bump overcloud host image tags
51
- body : |
52
- This PR was created automatically to update the overcloud host image
53
- tags.
54
- Rocky 9: ${{ inputs.rocky9_tag }}
55
- Ubuntu Noble: ${{ inputs.ubuntu_noble_tag }}
56
- labels : |
57
- automated
260
+ name : amphora-image-build-log
261
+ path : ./artifact
262
+ if : always()
263
+
264
+ - name : Destroy
265
+ run : terraform destroy -auto-approve
266
+ working-directory : ${{ github.workspace }}/src/kayobe-config/terraform/aio
267
+ env :
268
+ OS_CLOUD : ${{ vars.OS_CLOUD }}
269
+ OS_APPLICATION_CREDENTIAL_ID : ${{ secrets.OS_APPLICATION_CREDENTIAL_ID }}
270
+ OS_APPLICATION_CREDENTIAL_SECRET : ${{ secrets.OS_APPLICATION_CREDENTIAL_SECRET }}
271
+ if : always()
0 commit comments