Skip to content

Commit 99c1247

Browse files
committed
setup_cache_for_template: Improve caching mechanism for images and nerdctl archives
- Change cache key to `url-sha256:$sha256` for caching images without a digest - Include image basename in the cache key - Use `limactl validate --fill` to retrieve nerdctl archive info and set cache if needed - `test.yml`: Change cache configuration to run after `make install` Signed-off-by: Norio Nomura <[email protected]> test.yml: Remove `normalize_template_path` since `hashFile` is no longer used. Signed-off-by: Norio Nomura <[email protected]>
1 parent cd30aaa commit 99c1247

File tree

2 files changed

+110
-42
lines changed

2 files changed

+110
-42
lines changed

.github/actions/setup_cache_for_template/action.yml

+93-18
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ inputs:
77
template:
88
description: template yaml file
99
required: true
10+
detect-containerd:
11+
description: detect containerd usage from template by using limactl validate
12+
required: false
13+
default: 'true'
1014
runs:
1115
using: "composite"
1216
steps:
@@ -27,10 +31,15 @@ runs:
2731
set -eux
2832
arch="${{ inputs.arch }}"
2933
template="${{ inputs.template }}"
34+
detect_containerd="${{ inputs.detect-containerd }}"
35+
if [[ $detect_containerd == "true" ]] && ! command -v limactl &>/dev/null; then
36+
echo "containerd detection is disabled because limactl is not found" >&2
37+
detect_containerd="false"
38+
fi
3039
case "$template" in
3140
https://*)
3241
tmp_yaml=$(mktemp -d)/template.yaml
33-
curl -sSLf "$template" > $tmp_yaml || exit 1
42+
curl -sSLf "$template" > "$tmp_yaml" || exit 1
3443
template=$tmp_yaml
3544
;;
3645
*)
@@ -47,27 +56,85 @@ runs:
4756
arm64) arch=aarch64 ;;
4857
esac
4958
50-
# extract digest and location from template using arch
51-
digest="$(yq ".images | map(select(.arch == \"$arch\")) | .[0].digest // \"\"" "$template")"
52-
location="$(yq ".images | map(select(.arch == \"$arch\")) | .[0].location // \"\"" "$template")"
53-
test -n "$location" || exit 1
54-
55-
# path to cache
56-
if command -v sha256sum > /dev/null; then
57-
sha256="$(echo -n "$location" | sha256sum | cut -d' ' -f1)"
58-
elif command -v shasum > /dev/null; then
59-
sha256="$(echo -n "$location" | shasum -a 256 | cut -d' ' -f1)"
59+
# extract digest, location and size by parsing template using arch
60+
readonly yq_filter="
61+
[
62+
.images | map(select(.arch == \"${arch}\")) | [.[0,1].location, .[0,1].digest],
63+
.containerd|[.system or .user],
64+
.containerd.archives | map(select(.arch == \"${arch}\")) | [.[0].location, .[0].digest]
65+
]|flatten|.[]
66+
"
67+
if [[ $detect_containerd == "true" ]]; then
68+
parsed=$(LIMA_HOME=$(mktemp -d) limactl validate "$template" --fill 2>/dev/null | yq eval "${yq_filter}")
6069
else
61-
echo "sha256sum or shasum not found" >&2
70+
parsed=$(yq eval "${yq_filter}" "$template")
71+
fi
72+
# macOS earlier than 15.0 uses bash 3.2.57, which does not support readarray -t
73+
# readarray -t arr <<<"$parsed"
74+
while IFS= read -r line; do arr+=("$line"); done <<<"${parsed}"
75+
readonly locations=("${arr[@]:0:2}") digests=("${arr[@]:2:2}")
76+
readonly containerd="${arr[4]}" containerd_location="${arr[5]}" containerd_digest="${arr[6]}"
77+
for ((i = 0; i < ${#locations[@]}; i++)); do
78+
[[ ${locations[i]} != "null" ]] || continue
79+
http_code=$(curl -sIL -w "%{http_code}" "${locations[i]}" -o /dev/null)
80+
if [[ ${http_code} -eq 200 ]]; then
81+
location=${locations[i]}
82+
digest=${digests[i]}
83+
break
84+
fi
85+
done
86+
if [[ -z ${location} ]]; then
87+
echo "Failed to get the image location for ${template}" >&2
6288
exit 1
6389
fi
64-
echo "path=.download/by-url-sha256/$sha256" >> "$GITHUB_OUTPUT"
90+
91+
function location_to_sha256() {
92+
local location=$1
93+
if command -v sha256sum > /dev/null; then
94+
sha256="$(echo -n "$location" | sha256sum | cut -d' ' -f1)"
95+
elif command -v shasum > /dev/null; then
96+
sha256="$(echo -n "$location" | shasum -a 256 | cut -d' ' -f1)"
97+
else
98+
echo "sha256sum or shasum not found" >&2
99+
exit 1
100+
fi
101+
echo "$sha256"
102+
}
103+
104+
function location_to_cache_path() {
105+
local location=$1
106+
sha256=$(location_to_sha256 "$location") && echo ".download/by-url-sha256/$sha256"
107+
}
108+
109+
# path to cache
110+
image_cache_path=$(location_to_cache_path "$location")
111+
echo "path=$image_cache_path" >> "$GITHUB_OUTPUT"
65112
66113
# key for cache
67-
key="${digest:+image-$digest}"
68-
# fallback to os and hash of template file if digest not found
69-
key="${key:-${{ runner.os }}-${{ hashFiles(inputs.template) }}}"
114+
image_basename=$(basename "$location")
115+
if [[ "$digest" != "null" ]]; then
116+
key="image:$image_basename-$digest"
117+
else
118+
# use sha256 of location as key if digest is not available
119+
key="image:$image_basename-url-sha256:$(location_to_sha256 "$location")"
120+
fi
70121
echo "key=$key" >> "$GITHUB_OUTPUT"
122+
123+
# containerd path and key for cache
124+
if [[ $containerd == "true" && "$containerd_location" != "null" ]]; then
125+
containerd_basename=$(basename "$containerd_location")
126+
if [[ ${containerd_digest} != "null" ]]; then
127+
containerd_key="containerd:$containerd_basename-$containerd_digest"
128+
else
129+
containerd_key="containerd:$containerd_basename-url-sha256:$(sha256 "$containerd_location")"
130+
fi
131+
echo "containerd-key=$containerd_key" >> "$GITHUB_OUTPUT"
132+
containerd_cache_path=$(location_to_cache_path "$containerd_location")
133+
echo "containerd-path=$containerd_cache_path" >> "$GITHUB_OUTPUT"
134+
else
135+
echo "containerd-key=" >> "$GITHUB_OUTPUT"
136+
echo "containerd-path=" >> "$GITHUB_OUTPUT"
137+
fi
71138
shell: bash
72139

73140
- name: "Cache ${{ steps.cache-params-from-template.outputs.path }}"
@@ -78,11 +145,19 @@ runs:
78145
key: ${{ steps.cache-params-from-template.outputs.key }}
79146
enableCrossOsArchive: true
80147

148+
- name: "Cache ${{ steps.cache-params-from-template.outputs.containerd-key }}"
149+
if: ${{ steps.cache-params-from-template.outputs.containerd-key != '' }}
150+
uses: actions/cache@v4
151+
with:
152+
path: ${{ steps.cache-params-from-template.outputs.containerd-path }}
153+
key: ${{ steps.cache-params-from-template.outputs.containerd-key }}
154+
enableCrossOsArchive: true
155+
81156
- name: "Create symbolic link named ${{ steps.detect-platform.outputs.download-dir }} pointing to .download"
82157
run: |
83158
set -eux
84159
[ -d .download ] || mkdir -p .download
85160
path_to_cache=${{ steps.detect-platform.outputs.download-dir }}
86-
mkdir -p $(dirname $path_to_cache)
87-
ln -sfn $PWD/.download $path_to_cache
161+
mkdir -p "$(dirname "$path_to_cache")"
162+
ln -sfn "$PWD/.download" "$path_to_cache"
88163
shell: bash

.github/workflows/test.yml

+17-24
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,16 @@ jobs:
157157
- uses: actions/setup-go@v5
158158
with:
159159
go-version: 1.23.x
160-
- name: Cache image used by default.yaml
161-
uses: ./.github/actions/setup_cache_for_template
162-
with:
163-
template: templates/default.yaml
164160
- name: Unit tests
165161
run: go test -v ./...
166162
- name: Make
167163
run: make
168164
- name: Install
169165
run: make install
166+
- name: Cache image used by default.yaml
167+
uses: ./.github/actions/setup_cache_for_template
168+
with:
169+
template: templates/default.yaml
170170
- name: Validate templates
171171
run: find -L templates -name '*.yaml' | xargs limactl validate
172172
- name: Install test dependencies
@@ -228,18 +228,14 @@ jobs:
228228
- uses: actions/setup-go@v5
229229
with:
230230
go-version: 1.23.x
231-
- name: normalize template path
232-
id: normalize_template_path
233-
# `hashFiles` cannot use `..` as a path component, so generate a normalized path here.
234-
run: echo "NORMALIZED=$(realpath templates/${{ matrix.template }})" >> "$GITHUB_OUTPUT"
235-
- name: Cache image used by ${{ steps.normalize_template_path.outputs.NORMALIZED }}
236-
uses: ./.github/actions/setup_cache_for_template
237-
with:
238-
template: ${{ steps.normalize_template_path.outputs.NORMALIZED }}
239231
- name: Make
240232
run: make
241233
- name: Install
242234
run: sudo make install
235+
- name: Cache image used by templates/${{ matrix.template }}
236+
uses: ./.github/actions/setup_cache_for_template
237+
with:
238+
template: templates/${{ matrix.template }}
243239
- name: Install test dependencies
244240
run: |
245241
sudo apt-get update
@@ -328,14 +324,14 @@ jobs:
328324
- uses: actions/setup-go@v5
329325
with:
330326
go-version: 1.23.x
331-
- name: Cache image used by vmnet.yaml
332-
uses: ./.github/actions/setup_cache_for_template
333-
with:
334-
template: templates/vmnet.yaml
335327
- name: Make
336328
run: make
337329
- name: Install
338330
run: make install
331+
- name: Cache image used by vmnet.yaml
332+
uses: ./.github/actions/setup_cache_for_template
333+
with:
334+
template: templates/vmnet.yaml
339335
- name: Install test dependencies
340336
run: brew install qemu bash coreutils iperf3
341337
- name: Install socket_vmnet
@@ -385,6 +381,7 @@ jobs:
385381
uses: ./.github/actions/setup_cache_for_template
386382
with:
387383
template: https://raw.githubusercontent.com/lima-vm/lima/${{ matrix.oldver }}/examples/ubuntu-lts.yaml
384+
detect-containerd: "false"
388385
- name: Install test dependencies
389386
run: brew install qemu bash coreutils
390387
- name: Test
@@ -414,18 +411,14 @@ jobs:
414411
- uses: actions/setup-go@v5
415412
with:
416413
go-version: 1.23.x
417-
- name: normalize template path
418-
id: normalize_template_path
419-
# `hashFiles` cannot use `..` as a path component, so generate a normalized path here.
420-
run: echo "NORMALIZED=$(realpath templates/${{ matrix.template }})" >> "$GITHUB_OUTPUT"
421-
- name: Cache image used by ${{ steps.normalize_template_path.outputs.NORMALIZED }}
422-
uses: ./.github/actions/setup_cache_for_template
423-
with:
424-
template: ${{ steps.normalize_template_path.outputs.NORMALIZED }}
425414
- name: Make
426415
run: make
427416
- name: Install
428417
run: make install
418+
- name: Cache image used by templates/${{ matrix.template }}
419+
uses: ./.github/actions/setup_cache_for_template
420+
with:
421+
template: templates/${{ matrix.template }}
429422
- name: Install test dependencies
430423
run: brew install bash coreutils jq
431424
- name: Uninstall qemu

0 commit comments

Comments
 (0)