naughty-from.sh 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #!/usr/bin/env bash
  2. set -Eeuo pipefail
  3. export BASHBREW_ARCH=
  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. _is_naughty() {
  12. local from="$1"; shift
  13. case "$from" in
  14. # "scratch" isn't a real image and is always permissible (on non-Windows)
  15. scratch)
  16. case "$BASHBREW_ARCH" in
  17. windows-*) return 0 ;; # can't use "FROM scratch" on Windows
  18. *) return 1 ;; # can use "FROM scratch" everywhere else
  19. esac
  20. ;;
  21. */*)
  22. # must be external, let's check our pins for acceptability
  23. local externalPinFile="$externalPinsDir/${from/:/___}" # see ".external-pins/list.sh"
  24. if [ -s "$externalPinFile" ]; then
  25. local digest
  26. digest="$(< "$externalPinFile")"
  27. from+="@$digest"
  28. else
  29. # not pinned, must not be acceptable
  30. return 0
  31. fi
  32. ;;
  33. esac
  34. case "$from" in
  35. */*@sha256:*)
  36. if [ -z "${externalPinsArchesCache["$from"]:-}" ]; then
  37. local remoteArches
  38. if remoteArches="$(bashbrew remote arches --json "$from" | jq -c '.arches | keys')"; then
  39. externalPinsArchesCache["$from"]="$remoteArches"
  40. else
  41. echo >&2 "warning: failed to query supported architectures of '$from'"
  42. externalPinsArchesCache["$from"]='[]'
  43. fi
  44. fi
  45. if jq <<<"${externalPinsArchesCache["$from"]}" -e 'index(env.BASHBREW_ARCH)' > /dev/null; then
  46. # hooray, a supported architecture!
  47. return 1
  48. fi
  49. ;;
  50. *)
  51. # must be some other official image AND support our current architecture
  52. local archSupported
  53. if archSupported="$(bashbrew cat --format '{{ .TagEntry.HasArchitecture arch | ternary arch "" }}' "$from")" && [ -n "$archSupported" ]; then
  54. return 1
  55. fi
  56. ;;
  57. esac
  58. return 0
  59. }
  60. _arches() {
  61. bashbrew cat --format '
  62. {{- range .TagEntries -}}
  63. {{- .Architectures | join "\n" -}}
  64. {{- "\n" -}}
  65. {{- end -}}
  66. ' "$@" | sort -u
  67. }
  68. _froms() {
  69. bashbrew cat --format '
  70. {{- range .TagEntries -}}
  71. {{- $.DockerFroms . | join "\n" -}}
  72. {{- "\n" -}}
  73. {{- end -}}
  74. ' "$@" | sort -u
  75. }
  76. declare -A naughtyFromsArches=(
  77. #[img:tag=from:tag]='arch arch ...'
  78. )
  79. naughtyFroms=()
  80. declare -A allNaughty=(
  81. #[img:tag]=1
  82. )
  83. tags="$(bashbrew --namespace '' list --uniq "$@" | sort -u)"
  84. for img in $tags; do
  85. arches="$(_arches "$img")"
  86. hasNice= # do we have _any_ arches that aren't naughty? (so we can make the message better if not)
  87. for BASHBREW_ARCH in $arches; do
  88. export BASHBREW_ARCH
  89. froms="$(_froms "$img")"
  90. [ -n "$froms" ] # rough sanity check
  91. for from in $froms; do
  92. if _is_naughty "$from"; then
  93. if [ -z "${naughtyFromsArches["$img=$from"]:-}" ]; then
  94. naughtyFroms+=( "$img=$from" )
  95. else
  96. naughtyFromsArches["$img=$from"]+=', '
  97. fi
  98. naughtyFromsArches["$img=$from"]+="$BASHBREW_ARCH"
  99. else
  100. hasNice=1
  101. fi
  102. done
  103. done
  104. if [ -z "$hasNice" ]; then
  105. allNaughty["$img"]=1
  106. fi
  107. done
  108. for naughtyFrom in "${naughtyFroms[@]:-}"; do
  109. [ -n "$naughtyFrom" ] || continue # https://mywiki.wooledge.org/BashFAQ/112#BashFAQ.2F112.line-8 (empty array + "set -u" + bash 4.3 == sad day)
  110. img="${naughtyFrom%%=*}"
  111. from="${naughtyFrom#$img=}"
  112. if [ -n "${allNaughty["$img"]:-}" ]; then
  113. echo " - $img (FROM $from) -- completely unsupported base!"
  114. else
  115. arches="${naughtyFromsArches[$naughtyFrom]}"
  116. echo " - $img (FROM $from) [$arches]"
  117. fi
  118. done