naughty-from.sh 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #!/usr/bin/env bash
  2. set -Eeuo pipefail
  3. export BASHBREW_ARCH= BASHBREW_NAMESPACE=
  4. if [ "$#" -eq 0 ]; then
  5. set -- '--all'
  6. fi
  7. externalPinsDir="$(dirname "$BASH_SOURCE")/.external-pins"
  8. declare -A externalPinsArchesCache=(
  9. #[img:tag]='["arch","arch",...]' # (json array of strings)
  10. )
  11. # custom error message (for why Ubuntu 25.10+ does not support riscv64)
  12. message=''
  13. _is_naughty() {
  14. local from="$1"; shift
  15. # DOI cannot support riscv64 on Ubuntu 25.10+ since it uses RVA23 and hardware does not exist yet
  16. # > For Ubuntu 25.10 release we plan to raise the required RISC-V ISA profile family to RVA23
  17. # https://bugs.launchpad.net/ubuntu/+source/ubuntu-release-upgrader/+bug/2111715
  18. if [ "$BASHBREW_ARCH" = 'riscv64' ] && [[ "$from" == 'ubuntu:'* ]]; then
  19. normalized="$(bashbrew list --uniq "$from")" # catch when latest changes
  20. case "$normalized" in
  21. ubuntu:22.04 | ubuntu:24.04 | ubuntu:25.04 | ubuntu:jammy* | ubuntu:noble* | ubuntu:plucky*)
  22. # these are fine, let the rest of the tests try them
  23. ;;
  24. *)
  25. # ubuntu 25.10+, uses riscv64 with RVA23
  26. # unsupported in DOI until hardware is acquired
  27. message='DOI cannot support riscv64 on Ubuntu 25.10+ since it uses RVA23 and hardware does not exist yet'
  28. return 0
  29. ;;
  30. esac
  31. fi
  32. case "$from" in
  33. # "scratch" isn't a real image and is always permissible (on non-Windows)
  34. scratch)
  35. case "$BASHBREW_ARCH" in
  36. windows-*) return 0 ;; # can't use "FROM scratch" on Windows
  37. *) return 1 ;; # can use "FROM scratch" everywhere else
  38. esac
  39. ;;
  40. */*)
  41. # must be external, let's check our pins for acceptability
  42. local externalPinFile="$externalPinsDir/${from/:/___}" # see ".external-pins/list.sh"
  43. if [ -s "$externalPinFile" ]; then
  44. local digest
  45. digest="$(< "$externalPinFile")"
  46. from+="@$digest"
  47. else
  48. # not pinned, must not be acceptable
  49. return 0
  50. fi
  51. ;;
  52. esac
  53. case "$from" in
  54. */*@sha256:*)
  55. if [ -z "${externalPinsArchesCache["$from"]:-}" ]; then
  56. local remoteArches
  57. if remoteArches="$(bashbrew remote arches --json "$from" | jq -c '.arches | keys')"; then
  58. externalPinsArchesCache["$from"]="$remoteArches"
  59. else
  60. echo >&2 "warning: failed to query supported architectures of '$from'"
  61. externalPinsArchesCache["$from"]='[]'
  62. fi
  63. fi
  64. if jq <<<"${externalPinsArchesCache["$from"]}" -e 'index(env.BASHBREW_ARCH)' > /dev/null; then
  65. # hooray, a supported architecture!
  66. return 1
  67. fi
  68. ;;
  69. *)
  70. # must be some other official image AND support our current architecture
  71. local archSupported
  72. if archSupported="$(bashbrew cat --format '{{ .TagEntry.HasArchitecture arch | ternary arch "" }}' "$from")" && [ -n "$archSupported" ]; then
  73. return 1
  74. fi
  75. ;;
  76. esac
  77. return 0
  78. }
  79. _arches() {
  80. bashbrew cat --format '
  81. {{- range .TagEntries -}}
  82. {{- .Architectures | join "\n" -}}
  83. {{- "\n" -}}
  84. {{- end -}}
  85. ' "$@" | sort -u
  86. }
  87. _froms() {
  88. bashbrew cat --format '
  89. {{- range .TagEntries -}}
  90. {{- $.DockerFroms . | join "\n" -}}
  91. {{- "\n" -}}
  92. {{- end -}}
  93. ' "$@" | sort -u
  94. }
  95. declare -A naughtyFromsArches=(
  96. #[img:tag=from:tag]='arch arch ...'
  97. )
  98. naughtyFroms=()
  99. declare -A allNaughty=(
  100. #[img:tag]=1
  101. )
  102. tags="$(bashbrew --namespace '' list --uniq "$@" | sort -u)"
  103. for img in $tags; do
  104. arches="$(_arches "$img")"
  105. hasNice= # do we have _any_ arches that aren't naughty? (so we can make the message better if not)
  106. for BASHBREW_ARCH in $arches; do
  107. export BASHBREW_ARCH
  108. froms="$(_froms "$img")"
  109. [ -n "$froms" ] # rough sanity check
  110. for from in $froms; do
  111. if _is_naughty "$from"; then
  112. if [ -z "${naughtyFromsArches["$img=$from"]:-}" ]; then
  113. naughtyFroms+=( "$img=$from" )
  114. else
  115. naughtyFromsArches["$img=$from"]+=', '
  116. fi
  117. naughtyFromsArches["$img=$from"]+="$BASHBREW_ARCH"
  118. else
  119. hasNice=1
  120. fi
  121. done
  122. done
  123. if [ -z "$hasNice" ]; then
  124. allNaughty["$img"]=1
  125. fi
  126. done
  127. for naughtyFrom in "${naughtyFroms[@]:-}"; do
  128. [ -n "$naughtyFrom" ] || continue # https://mywiki.wooledge.org/BashFAQ/112#BashFAQ.2F112.line-8 (empty array + "set -u" + bash 4.3 == sad day)
  129. img="${naughtyFrom%%=*}"
  130. from="${naughtyFrom#$img=}"
  131. if [ -n "${allNaughty["$img"]:-}" ]; then
  132. echo " - $img (FROM $from) -- completely unsupported base!"
  133. else
  134. arches="${naughtyFromsArches[$naughtyFrom]}"
  135. echo " - $img (FROM $from) [$arches]"
  136. fi
  137. done
  138. if [ -n "$message" ]; then
  139. echo " - $message"
  140. fi