From 9fbd1939489bab7d2e55f9924b03b1cbad8d60b9 Mon Sep 17 00:00:00 2001 From: Norio Nomura Date: Sat, 17 Aug 2024 12:22:06 +0900 Subject: [PATCH] test.yml: use `inject-cmdline-to-template.sh` to append `no_timer_check` kernel command line option This change aims to avoid kernel panics in the integration tests and vmnet tests. ```console ==> /Users/runner/.lima/default/serial.log <== [ 0.015000] setup_IO_APIC+0x2c3/0x370 [ 0.015000] ? enable_IO_APIC+0x1af/0x290 [ 0.015000] apic_intr_mode_init+0x61/0x130 [ 0.015000] x86_late_time_init+0x24/0x40 [ 0.015000] start_kernel+0x2be/0x450 [ 0.015000] x86_64_start_reservations+0x18/0x30 [ 0.015000] x86_64_start_kernel+0xbf/0x110 [ 0.015000] secondary_startup_64_no_verify+0x184/0x18b [ 0.015000] [ 0.015000] ---[ end Kernel panic - not syncing: IO-APIC + timer doesn't work! Boot with apic=debug and send a report. Then try booting with the 'noapic' option. ]--- ``` The reason `no_timer_check` is used instead of `noapic`, as shown in the kernel panic log, is because I read the following page. https://lore.kernel.org/all/18354be1-8dba-84f1-bdf5-6821a5013d78@oracle.com/T/ Signed-off-by: Norio Nomura inject-cmdline-to-template.sh: resolve shfmt issue Signed-off-by: Norio Nomura test.yml: add link to issue https://github.com/lima-vm/lima/issues/84 Signed-off-by: Norio Nomura inject-cmdline-to-template.sh: add comment lines to explain what this script does Signed-off-by: Norio Nomura --- .github/workflows/test.yml | 6 ++ hack/inject-cmdline-to-template.sh | 94 ++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100755 hack/inject-cmdline-to-template.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ae49e0f704a..eea519bf499 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -184,6 +184,9 @@ jobs: time brew install qemu bash coreutils curl jq - name: "Show cache" run: ./hack/debug-cache.sh + - name: "Inject `no_timer_check` to kernel cmdline" + # workaround to https://github.com/lima-vm/lima/issues/84 + run: ./hack/inject-cmdline-to-template.sh templates/default.yaml no_timer_check - name: "Test default.yaml" uses: nick-invision/retry@v3 with: @@ -356,6 +359,9 @@ jobs: - name: Unit test (pkg/networks) with socket_vmnet # Set -count=1 to disable cache run: go test -v -count=1 ./pkg/networks/... + - name: "Inject `no_timer_check` to kernel cmdline" + # workaround to https://github.com/lima-vm/lima/issues/84 + run: ./hack/inject-cmdline-to-template.sh templates/vmnet.yaml no_timer_check - name: Test socket_vmnet uses: nick-invision/retry@v3 with: diff --git a/hack/inject-cmdline-to-template.sh b/hack/inject-cmdline-to-template.sh new file mode 100755 index 00000000000..0ff941d69fd --- /dev/null +++ b/hack/inject-cmdline-to-template.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +# +# This script does +# 1. detect arch from template if not provided +# 2. extract location by parsing template using arch +# 3. get the image location +# 4. check the image location is supported +# 5. build the kernel and initrd location, digest, and cmdline +# 6. inject the kernel and initrd location, digest, and cmdline to the template +# 7. output kernel_location, kernel_digest, cmdline, initrd_location, initrd_digest + +set -eu -o pipefail + +template="$1" +appending_options="$2" +# 1. detect arch from template if not provided +arch="${3:-$(yq '.arch // ""' "${template}")}" +arch="${arch:-$(uname -m)}" + +# normalize arch. amd64 -> x86_64, arm64 -> aarch64 +case "${arch}" in +amd64 | x86_64) arch=x86_64 ;; +aarch64 | arm64) arch=aarch64 ;; +*) + echo "Unsupported arch: ${arch}" >&2 + exit 1 + ;; +esac + +# 2. extract location by parsing template using arch +readonly yq_filter=" +[ + .images | map(select(.arch == \"${arch}\")) | [.[].location] +]|flatten|.[] +" +parsed=$(yq eval "${yq_filter}" "${template}") + +# 3. get the image location +while IFS= read -r line; do arr+=("${line}"); done <<<"${parsed}" +readonly locations=("${arr[@]}") +for ((i = 0; i < ${#locations[@]}; i++)); do + [[ ${locations[i]} != "null" ]] || continue + http_code=$(curl -sIL -w "%{http_code}" "${locations[i]}" -o /dev/null) + if [[ ${http_code} -eq 200 ]]; then + location=${locations[i]} + index=${i} + break + fi +done + +# 4. check the image location is supported +if [[ -z ${location} ]]; then + echo "Failed to get the image location for ${template}" >&2 + exit 1 +elif [[ ${location} == https://cloud-images.ubuntu.com/* ]]; then + readonly default_cmdline="root=LABEL=cloudimg-rootfs ro console=tty1 console=ttyAMA0" +else + echo "Unsupported image location: ${location}" >&2 + exit 1 +fi + +# 5. build the kernel and initrd location, digest, and cmdline +location_dirname=$(dirname "${location}")/unpacked +sha256sums=$(curl -sSLf "${location_dirname}/SHA256SUMS") +location_basename=$(basename "${location}") + +# cmdline +cmdline="${default_cmdline} ${appending_options}" + +# kernel +kernel_basename="${location_basename/.img/-vmlinuz-generic}" +kernel_digest=$(awk "/${kernel_basename}/{print \"sha256:\"\$1}" <<<"${sha256sums}") +kernel_location="${location_dirname}/${kernel_basename}" + +# initrd +initrd_basename="${location_basename/.img/-initrd-generic}" +initrd_digest=$(awk "/${initrd_basename}/{print \"sha256:\"\$1}" <<<"${sha256sums}") +initrd_location="${location_dirname}/${initrd_basename}" + +# 6. inject the kernel and initrd location, digest, and cmdline to the template +yq -i eval " + [(.images.[] | select(.arch == \"${arch}\") | path)].[${index}] + \"kernel\" as \$path| + setpath(\$path; { \"location\": \"${kernel_location}\", \"digest\": \"${kernel_digest}\", \"cmdline\": \"${cmdline}\" }) +" "${template}" +yq -i eval " + [(.images.[] | select(.arch == \"${arch}\") | path)].[${index}] + \"initrd\" as \$path| + setpath(\$path ; { \"location\": \"${initrd_location}\", \"digest\": \"${initrd_digest}\" }) +" "${template}" + +# 7. output kernel_location, kernel_digest, cmdline, initrd_location, initrd_digest +readonly outputs=(kernel_location kernel_digest cmdline initrd_location initrd_digest) +for output in "${outputs[@]}"; do + echo "${output}=${!output}" +done