Skip to content

Commit ac175d3

Browse files
committed
ci: cache downloads
We're seeing 429 from Github trying to download gen_init_cpio, so cache it using actions and curl's ETag support. Since I'm here add this for kernel images as well to save time waiting on slow Debian servers.
1 parent 1dfcfbc commit ac175d3

File tree

4 files changed

+56
-12
lines changed

4 files changed

+56
-12
lines changed

.github/scripts/download_kernel_images.sh

+21-2
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,24 @@ for VERSION in "${VERSIONS[@]}"; do
2929
)"
3030
done
3131

32-
printf '%s\n' "${FILES[@]}" \
33-
| xargs -t curl -sfSL --create-dirs --output-dir "$OUTPUT_DIR" --parallel --remote-name-all
32+
# TODO(https://github.com/curl/curl/issues/15729): restore --parallel here if and when it properly
33+
# supports ETags.
34+
# TODO(https://github.com/curl/curl/issues/15730): restore --create-dirs when it works in the
35+
# presence of `--etag-save`.`
36+
mkdir -p "$OUTPUT_DIR"
37+
KEEP=()
38+
for FILE in "${FILES[@]}"; do
39+
name=$(basename "$FILE")
40+
etag_name="$name.etag"
41+
KEEP+=("$name" "$etag_name")
42+
43+
etag="$OUTPUT_DIR/$etag_name"
44+
curl -sfSL --output-dir "$OUTPUT_DIR" --remote-name-all --etag-compare "$etag" --etag-save "$etag" "$FILE"
45+
done
46+
47+
# Remove any files that were previously downloaded that are no longer needed.
48+
FIND_ARGS=()
49+
for FILE in "${KEEP[@]}"; do
50+
FIND_ARGS+=("!" "-name" "$FILE")
51+
done
52+
find "$OUTPUT_DIR" -type f "${FIND_ARGS[@]}" -exec rm {} +

.github/workflows/ci.yml

+17-5
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,9 @@ jobs:
226226
227227
- name: Install prerequisites
228228
if: runner.os == 'macOS'
229-
# The xargs shipped on macOS always exits 0 with -P0, so we need GNU findutils.
229+
# The curl shipped on macOS doesn't contain
230+
# https://github.com/curl/curl/commit/85efbb92b8e6679705e122cee45ce76c56414a3e which is
231+
# needed for proper handling of `--etag-{compare,save}`.
230232
#
231233
# The tar shipped on macOS doesn't support --wildcards, so we need GNU tar.
232234
#
@@ -237,9 +239,10 @@ jobs:
237239
# https://github.com/actions/setup-python/issues/577
238240
find /usr/local/bin -type l -exec sh -c 'readlink -f "$1" \
239241
| grep -q ^/Library/Frameworks/Python.framework/Versions/' _ {} \; -exec rm -v {} \;
240-
brew install --formula dpkg gnu-tar llvm lynx pkg-config qemu
241-
echo $(brew --prefix)/opt/gnu-tar/libexec/gnubin >> $GITHUB_PATH
242-
echo $(brew --prefix)/opt/llvm/bin >> $GITHUB_PATH
242+
brew install --formula curl dpkg gnu-tar llvm lynx pkg-config qemu
243+
echo $(brew --prefix curl)/bin >> $GITHUB_PATH
244+
echo $(brew --prefix gnu-tar)/libexec/gnubin >> $GITHUB_PATH
245+
echo $(brew --prefix llvm)/bin >> $GITHUB_PATH
243246
244247
- uses: dtolnay/rust-toolchain@nightly
245248
with:
@@ -278,6 +281,12 @@ jobs:
278281
# Do this on all system (not just macOS) to avoid relying on rustc-provided libLLVM.so.
279282
run: cargo install --force bpf-linker --git https://github.com/aya-rs/bpf-linker.git --no-default-features
280283

284+
- name: Cache test cache
285+
uses: actions/cache@v4
286+
with:
287+
path: test/.tmp
288+
key: ${{ runner.arch }}-test-cache
289+
281290
- name: Download debian kernels
282291
if: runner.arch == 'ARM64'
283292
# TODO: enable tests on kernels before 6.0.
@@ -299,7 +308,10 @@ jobs:
299308
run: cargo xtask integration-test local
300309

301310
- name: Run virtualized integration tests
302-
run: find test/.tmp -name 'vmlinuz-*' | xargs -t cargo xtask integration-test vm
311+
run: |
312+
set -euxo pipefail
313+
find test/.tmp -name 'vmlinuz-*' -print0 | xargs -t -0 \
314+
cargo xtask integration-test vm --cache-dir test/.tmp
303315
304316
# Provides a single status check for the entire build workflow.
305317
# This is used for merge automation, like Mergify, since GH actions

test/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ cargo xtask integration-test local
2727
### Virtualized
2828

2929
```bash
30-
cargo xtask integration-test vm <KERNEL IMAGE>
30+
cargo xtask integration-test vm --cache-dir <CACHE_DIR> <KERNEL_IMAGE>...
3131
```
3232

3333
### Writing an integration test

xtask/src/run.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{
33
fmt::Write as _,
44
fs::{copy, create_dir_all, OpenOptions},
55
io::{BufRead as _, BufReader, Write as _},
6-
path::{Path, PathBuf},
6+
path::PathBuf,
77
process::{Child, ChildStdin, Command, Output, Stdio},
88
sync::{Arc, Mutex},
99
thread,
@@ -38,6 +38,10 @@ enum Environment {
3838
/// | tar --wildcards --extract '*vmlinuz*' --file -"
3939
#[clap(required = true)]
4040
kernel_image: Vec<PathBuf>,
41+
42+
/// The cache directory in which to store utilities fetched from the internet.
43+
#[clap(short, long)]
44+
cache_dir: PathBuf,
4145
},
4246
}
4347

@@ -167,7 +171,10 @@ pub fn run(opts: Options) -> Result<()> {
167171
Err(anyhow!("failures:\n{}", failures))
168172
}
169173
}
170-
Environment::VM { kernel_image } => {
174+
Environment::VM {
175+
kernel_image,
176+
cache_dir,
177+
} => {
171178
// The user has asked us to run the tests on a VM. This is involved; strap in.
172179
//
173180
// We need tools to build the initramfs; we use gen_init_cpio from the Linux repository,
@@ -185,20 +192,26 @@ pub fn run(opts: Options) -> Result<()> {
185192
// We consume the output of QEMU, looking for the output of our init program. This is
186193
// the only way to distinguish success from failure. We batch up the errors across all
187194
// VM images and report to the user. The end.
188-
let cache_dir = Path::new("test/.tmp");
189-
create_dir_all(cache_dir).context("failed to create cache dir")?;
195+
create_dir_all(&cache_dir).context("failed to create cache dir")?;
190196
let gen_init_cpio = cache_dir.join("gen_init_cpio");
191197
if !gen_init_cpio
192198
.try_exists()
193199
.context("failed to check existence of gen_init_cpio")?
194200
{
201+
let gen_init_cpio_etag = cache_dir.join("gen_init_cpio.etag");
195202
let mut curl = Command::new("curl");
203+
for flag in ["--etag-compare", "--etag-save"] {
204+
curl.arg(flag).arg(&gen_init_cpio_etag);
205+
}
196206
curl.args([
197207
"-sfSL",
198208
"https://raw.githubusercontent.com/torvalds/linux/master/usr/gen_init_cpio.c",
199209
]);
200210
let mut curl_child = curl
211+
// Sent to clang.
201212
.stdout(Stdio::piped())
213+
// Collected for error reporting.
214+
.stderr(Stdio::piped())
202215
.spawn()
203216
.with_context(|| format!("failed to spawn {curl:?}"))?;
204217
let Child { stdout, .. } = &mut curl_child;

0 commit comments

Comments
 (0)