|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# This script does |
| 4 | +# 1. detect arch from template if not provided |
| 5 | +# 2. extract location by parsing template using arch |
| 6 | +# 3. get the image location |
| 7 | +# 4. check the image location is supported |
| 8 | +# 5. build the kernel and initrd location, digest, and cmdline |
| 9 | +# 6. inject the kernel and initrd location, digest, and cmdline to the template |
| 10 | +# 7. output kernel_location, kernel_digest, cmdline, initrd_location, initrd_digest |
| 11 | + |
| 12 | +set -eu -o pipefail |
| 13 | + |
| 14 | +template="$1" |
| 15 | +appending_options="$2" |
| 16 | +# 1. detect arch from template if not provided |
| 17 | +arch="${3:-$(yq '.arch // ""' "${template}")}" |
| 18 | +arch="${arch:-$(uname -m)}" |
| 19 | + |
| 20 | +# normalize arch. amd64 -> x86_64, arm64 -> aarch64 |
| 21 | +case "${arch}" in |
| 22 | +amd64 | x86_64) arch=x86_64 ;; |
| 23 | +aarch64 | arm64) arch=aarch64 ;; |
| 24 | +*) |
| 25 | + echo "Unsupported arch: ${arch}" >&2 |
| 26 | + exit 1 |
| 27 | + ;; |
| 28 | +esac |
| 29 | + |
| 30 | +# 2. extract location by parsing template using arch |
| 31 | +readonly yq_filter=" |
| 32 | +[ |
| 33 | + .images | map(select(.arch == \"${arch}\")) | [.[].location] |
| 34 | +]|flatten|.[] |
| 35 | +" |
| 36 | +parsed=$(yq eval "${yq_filter}" "${template}") |
| 37 | + |
| 38 | +# 3. get the image location |
| 39 | +while IFS= read -r line; do arr+=("${line}"); done <<<"${parsed}" |
| 40 | +readonly locations=("${arr[@]}") |
| 41 | +for ((i = 0; i < ${#locations[@]}; i++)); do |
| 42 | + [[ ${locations[i]} != "null" ]] || continue |
| 43 | + http_code=$(curl -sIL -w "%{http_code}" "${locations[i]}" -o /dev/null) |
| 44 | + if [[ ${http_code} -eq 200 ]]; then |
| 45 | + location=${locations[i]} |
| 46 | + index=${i} |
| 47 | + break |
| 48 | + fi |
| 49 | +done |
| 50 | + |
| 51 | +# 4. check the image location is supported |
| 52 | +if [[ -z ${location} ]]; then |
| 53 | + echo "Failed to get the image location for ${template}" >&2 |
| 54 | + exit 1 |
| 55 | +elif [[ ${location} == https://cloud-images.ubuntu.com/* ]]; then |
| 56 | + readonly default_cmdline="root=LABEL=cloudimg-rootfs ro console=tty1 console=ttyAMA0" |
| 57 | +else |
| 58 | + echo "Unsupported image location: ${location}" >&2 |
| 59 | + exit 1 |
| 60 | +fi |
| 61 | + |
| 62 | +# 5. build the kernel and initrd location, digest, and cmdline |
| 63 | +location_dirname=$(dirname "${location}")/unpacked |
| 64 | +sha256sums=$(curl -sSLf "${location_dirname}/SHA256SUMS") |
| 65 | +location_basename=$(basename "${location}") |
| 66 | + |
| 67 | +# cmdline |
| 68 | +cmdline="${default_cmdline} ${appending_options}" |
| 69 | + |
| 70 | +# kernel |
| 71 | +kernel_basename="${location_basename/.img/-vmlinuz-generic}" |
| 72 | +kernel_digest=$(awk "/${kernel_basename}/{print \"sha256:\"\$1}" <<<"${sha256sums}") |
| 73 | +kernel_location="${location_dirname}/${kernel_basename}" |
| 74 | + |
| 75 | +# initrd |
| 76 | +initrd_basename="${location_basename/.img/-initrd-generic}" |
| 77 | +initrd_digest=$(awk "/${initrd_basename}/{print \"sha256:\"\$1}" <<<"${sha256sums}") |
| 78 | +initrd_location="${location_dirname}/${initrd_basename}" |
| 79 | + |
| 80 | +# 6. inject the kernel and initrd location, digest, and cmdline to the template |
| 81 | +yq -i eval " |
| 82 | + [(.images.[] | select(.arch == \"${arch}\") | path)].[${index}] + \"kernel\" as \$path| |
| 83 | + setpath(\$path; { \"location\": \"${kernel_location}\", \"digest\": \"${kernel_digest}\", \"cmdline\": \"${cmdline}\" }) |
| 84 | +" "${template}" |
| 85 | +yq -i eval " |
| 86 | + [(.images.[] | select(.arch == \"${arch}\") | path)].[${index}] + \"initrd\" as \$path| |
| 87 | + setpath(\$path ; { \"location\": \"${initrd_location}\", \"digest\": \"${initrd_digest}\" }) |
| 88 | +" "${template}" |
| 89 | + |
| 90 | +# 7. output kernel_location, kernel_digest, cmdline, initrd_location, initrd_digest |
| 91 | +readonly outputs=(kernel_location kernel_digest cmdline initrd_location initrd_digest) |
| 92 | +for output in "${outputs[@]}"; do |
| 93 | + echo "${output}=${!output}" |
| 94 | +done |
0 commit comments