-
Notifications
You must be signed in to change notification settings - Fork 137
262 lines (236 loc) · 10.9 KB
/
Copy pathupload-cloud-images.yaml
File metadata and controls
262 lines (236 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
name: Upload cloud images
on:
push:
tags:
- 'v*' # Triggers on any tag that starts with 'v'
schedule:
# Everyday at 2am
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
force:
description: 'Force pushing even if already pushed'
required: false
type: boolean
permissions: read-all
jobs:
upload-gcp:
name: Upload to GCP
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- name: "Checkout code"
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- run: |
git fetch --prune --unshallow
# https://github.com/google-github-actions/auth?tab=readme-ov-file#authenticate-to-google-cloud-from-github-actions
# https://github.com/google-github-actions/auth/blob/main/docs/EXAMPLES.md#service-account-key-json
- id: "auth"
name: "Authenticate to GCP"
uses: 'google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093' # v3
with:
create_credentials_file: true
workload_identity_provider: 'projects/908384205599/locations/global/workloadIdentityPools/github/providers/kairos'
service_account: 'github-service-account@palette-kairos.iam.gserviceaccount.com'
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db' # v3
- name: Install deps
run: |
sudo apt update && sudo apt install -y qemu-utils gdisk
- name: Build and push GCP image
env:
GCP_PROJECT: palette-kairos
GCS_BUCKET: kairos-cloud-images
run: |
set -xe
latestTag=$(git describe --tags --abbrev=0)
latestTagSanitized=$(echo "$latestTag" | tr '.' '-')
echo "Fetching all pushed versions"
mapfile -t kairosVersions < <(gcloud compute images list --project=palette-kairos --filter="labels.version:*" --format="value(labels.version)")
echo "Checking if '$latestTag' is already pushed"
echo "Looking among versions: ${kairosVersions[@]}"
alreadyPushed=false
for version in "${kairosVersions[@]}"; do
if [[ $version == $latestTagSanitized ]]; then
stableVersions+=("$version")
alreadyPushed=true
break
fi
done
if [[ "$alreadyPushed" = true && "${{ inputs.force }}" != "true" ]]; then
echo "Image for $latestTag is already pushed and 'force' wasn't true. Exiting."
exit 0
fi
# Resolve the hadron container image this kairos release was built with
# (version discovered from the published hadron tags, not hardcoded).
containerImage=$(.github/public-cloud/resolve-hadron-container-image.sh "$latestTag")
docker run -v /var/run/docker.sock:/var/run/docker.sock --net host \
--privileged \
-v $PWD:/aurora --rm quay.io/kairos/auroraboot:v0.26.2 \
--debug \
--set "disable_http_server=true" \
--set "container_image=docker:${containerImage}" \
--set "disable_netboot=true" \
--set "disk.bios=true" \
--set "disk.state_size=6000" \
--set "state_dir=/aurora"
file=$(ls *.raw)
mv "$file" disk.raw
GB=$((1024*1024*1024))
MB=$((1024*1024))
size=$(qemu-img info -f raw --output json disk.raw | gawk 'match($0, /"virtual-size": ([0-9]+),/, val) {print val[1];exit}')
# shellcheck disable=SC2004
ROUNDED_SIZE=$(echo "$size/$GB+1"|bc)
CURRENT_SIZE=$(echo "$size/$MB"|bc)
echo "Resizing raw image from \"$size\"MB to \"$ROUNDED_SIZE\"GB"
qemu-img resize -f raw disk.raw "$ROUNDED_SIZE"G
# 'qemu-img resize' grows the file but leaves the GPT backup header at the
# old end of the disk. GCP's image import validates the GPT strictly and
# fails ("Internal migration service error") on the stranded backup header,
# so move it to the new end of the disk and verify the table is clean.
sgdisk -e disk.raw
sgdisk -v disk.raw
tar --format=oldgnu -czvf "${file%.*}.tar.gz" disk.raw
.github/public-cloud/upload-image-to-gcp.sh $(ls *.tar.gz) "$latestTag"
# https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services
upload-aws:
name: Upload to AWS
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- name: "Checkout code"
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- run: |
git fetch --prune --unshallow
# https://github.com/aws-actions/configure-aws-credentials?tab=readme-ov-file#assumerole-with-static-iam-credentials-in-repository-secrets
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@517a711dbcd0e402f90c77e7e2f81e849156e31d # v6
with:
audience: sts.amazonaws.com
aws-region: eu-central-1
role-to-assume: arn:aws:iam::171987620676:role/github-actions
role-session-name: AWSCIPush
- name: Build and push AWS image
env:
AWS_S3_BUCKET: kairos-cloud-images
AWS_REGION: eu-central-1
run: |
set -e
latestTag=$(git describe --tags --abbrev=0)
echo "Fetching all pushed versions"
mapfile -t kairosVersions < <(aws --region "$AWS_REGION" ec2 describe-images --owners self --query 'Images[].Tags[?Key==`KairosVersion`].Value' --output text)
echo "Checking if '$latestTag' is already pushed"
echo "Looking among versions: ${kairosVersions[@]}"
for version in "${kairosVersions[@]}"; do
if [[ $version == $latestTag ]]; then
stableVersions+=("$version")
alreadyPushed=true
break
fi
done
if [[ "$alreadyPushed" = true && "${{ inputs.force }}" != "true" ]]; then
echo "Image for $latestTag is already pushed and 'force' wasn't true. Exiting."
exit 0
fi
# Resolve the hadron container image this kairos release was built with
# (version discovered from the published hadron tags, not hardcoded).
containerImage=$(.github/public-cloud/resolve-hadron-container-image.sh "$latestTag")
docker run -v /var/run/docker.sock:/var/run/docker.sock --net host \
--privileged \
-v $PWD:/aurora --rm quay.io/kairos/auroraboot:v0.26.2 \
--debug \
--set "disable_http_server=true" \
--set "container_image=docker:${containerImage}" \
--set "disable_netboot=true" \
--set "disk.raw=true" \
--set "disk.state_size=6000" \
--set "state_dir=/aurora"
.github/public-cloud/upload-image-to-aws.sh $(ls *.raw) "$latestTag"
upload-azure:
permissions:
id-token: write
name: Upload to Azure
runs-on: ubuntu-latest
# https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azp#github-actions
environment: azure-push
outputs:
shouldBuild: ${{ steps.checkPushed.outputs.shouldBuild }}
steps:
- name: "Checkout code"
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- run: |
git fetch --prune --unshallow
# https://github.com/Azure/login?tab=readme-ov-file#azure-login-action
- name: Azure login
uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Find latest stable version
run: |
# Azure only allows "stable" version strings. E.g. "v1.2.3" (not "v1.2.3-beta1")
latestTag=$(git tag --list | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1)
echo $latestTag > LATEST_TAG
- name: Check if already pushed
id: checkPushed
run: |
latestTag=$(cat LATEST_TAG)
echo "Fetching all pushed versions"
mapfile -t kairosVersions < <(az sig image-version list --resource-group kairos-cloud-images --gallery-image-name kairos --gallery-name kairos.io --query '[].name' --output tsv)
echo "Checking if '$latestTag' is already pushed"
echo "Looking among versions: ${kairosVersions[@]}"
for version in "${kairosVersions[@]}"; do
if [[ $version == "${latestTag#v}" ]]; then
stableVersions+=("$version")
alreadyPushed=true
break
fi
done
if [[ "$alreadyPushed" = true && "${{ inputs.force }}" != "true" ]]; then
echo "shouldBuild=false" >> $GITHUB_OUTPUT
echo "Image for $latestTag is already pushed and 'force' wasn't true. Skipping build."
else
echo "shouldBuild=true" >> $GITHUB_OUTPUT
echo "Image for $latestTag is not pushed or 'force' was true. Will build."
fi
- name: Build the image
if: ${{ steps.checkPushed.outputs.shouldBuild == 'true' }}
run: |
latestTag=$(cat LATEST_TAG)
# Resolve the hadron container image this kairos release was built with
# (version discovered from the published hadron tags, not hardcoded).
containerImage=$(.github/public-cloud/resolve-hadron-container-image.sh "$latestTag")
docker run -v /var/run/docker.sock:/var/run/docker.sock --net host \
--privileged \
-v $PWD:/aurora --rm quay.io/kairos/auroraboot:v0.26.2 \
--debug \
--set "disable_http_server=true" \
--set "container_image=docker:${containerImage}" \
--set "disable_netboot=true" \
--set "disk.vhd=true" \
--set "disk.state_size=6000" \
--set "state_dir=/aurora"
- name: Azure CLI script
uses: azure/cli@9eb25b8360668fb0ecbafa808d40e2197b2f5f52 # v3
if: ${{ steps.checkPushed.outputs.shouldBuild == 'true' }}
env:
GCP_PROJECT: palette-kairos
AZURE_RESOURCE_GROUP: "kairos-cloud-images"
AZURE_STORAGE_ACCOUNT: "kairoscloudimages"
AZURE_CONTAINER_NAME: "kairos-cloud-images"
with:
azcliversion: latest
inlineScript: |
# Install openssh-clients to be able to use ssh-keygen
tdnf install -y openssh-clients
latestTag=$(cat LATEST_TAG)
.github/public-cloud/upload-image-to-azure.sh $(ls *.vhd) "$latestTag"