瀏覽代碼

Add "naughty-from.sh" script inspired by the report of the same name

This verifies that the "Architectures" field of each entry in a given pull request is a subset of its parent.
Tianon Gravi 7 年之前
父節點
當前提交
cedc7b7a7d
共有 3 個文件被更改,包括 95 次插入14 次删除
  1. 2 0
      README.md
  2. 21 14
      bashbrew/travis.sh
  3. 72 0
      naughty-from.sh

+ 2 - 0
README.md

@@ -290,6 +290,8 @@ Each repo can specify multiple architectures for any and all tags. If no archite
 -	`s390x`
 -	`windows-amd64`
 
+The `Architectures` of any given tag must be a strict subset of the `Architectures` of the tag it is `FROM`.
+
 We strongly recommend that most images create a single `Dockerfile` per entry in the library file that can be used for multiple architectures. This means that each supported architecture will have the same `FROM` line (e.g. `FROM debian:jessie`). While official images are in the process of completing [image indexes](https://github.com/opencontainers/image-spec/blob/v1.0.0-rc6/image-index.md) to make this work naturally, the servers that build for non-amd64 architectures will pull the correct architecture-specific base and `docker tag` the base image to make the `FROM` work correctly. See [`golang`](https://github.com/docker-library/official-images/blob/master/library/golang), [`docker`](https://github.com/docker-library/official-images/blob/master/library/docker), [`haproxy`](https://github.com/docker-library/official-images/blob/master/library/haproxy), and [`php`](https://github.com/docker-library/official-images/blob/master/library/php) for examples of library files using one `Dockerfile` per entry and see their respective git repos for example `Dockerfile`s.
 
 For images that are `FROM scratch` like `debian` it will be necessary to have a different `Dockerfile` and build context in order to `ADD` architecture specific binaries. Since these images use the same `Tags`, they need to be in the same entry. Use the architecture specific fields for `GitRepo`, `GitFetch`, `GitCommit`, and `Directory`, which are the architecture concatenated with hyphen (`-`) and the field (e.g. `arm32v7-GitCommit`). Any architecture that does not have an architecture-specific field will use the default field (e.g. no `arm32v7-Directory` means `Directory` will be used for `arm32v7`). See the [`debian`](https://github.com/docker-library/official-images/blob/master/library/debian) or [`ubuntu`](https://github.com/docker-library/official-images/blob/master/library/ubuntu) files in the library for examples. The following is an example for [`hello-world`](https://github.com/docker-library/official-images/blob/master/library/hello-world):

+ 21 - 14
bashbrew/travis.sh

@@ -47,20 +47,27 @@ if badTags="$(bashbrew list "${repos[@]}" | grep -E ':.+latest.*|:.*latest.+')"
 	exit 1
 fi
 
-cmds=(
-	'list'
-	'list --uniq'
-	'cat'
-)
-if [ "$extraCommands" ]; then
-	cmds+=(
-		'list --build-order'
-		'from --apply-constraints'
-	)
+if [ -n "$extraCommands" ] && naughtyFrom="$(../naughty-from.sh "${repos[@]}")" && [ -n "$naughtyFrom" ]; then
+	echo >&2
+	echo >&2 "Invalid 'FROM' + 'Architectures' combinations detected:"
+	echo >&2
+	echo >&2 "$naughtyFrom"
+	echo >&2
+	echo >&2 'Read https://github.com/docker-library/official-images#multiple-architectures for more details.'
+	echo >&2
+	exit 1
 fi
 
-export PS4=$'\n\n$ '
-for cmd in "${cmds[@]}"; do
-	( set -x && bashbrew $cmd "${repos[@]}" )
-done
+_bashbrew() {
+	echo $'\n\n$ bashbrew' "$@" "${repos[@]}"
+	bashbrew "$@" "${repos[@]}"
+}
+
+_bashbrew list
+_bashbrew list --uniq
+_bashbrew cat
+if [ -n "$extraCommands" ]; then
+	_bashbrew list --build-order
+	_bashbrew from --apply-constraints
+fi
 echo; echo

+ 72 - 0
naughty-from.sh

@@ -0,0 +1,72 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+: "${BASHBREW_CACHE:=$HOME/.cache/bashbrew}"
+export BASHBREW_CACHE BASHBREW_ARCH=
+
+if [ ! -d "$BASHBREW_CACHE/git" ]; then
+	# initialize the "bashbrew cache"
+	bashbrew --arch amd64 from --uniq --apply-constraints hello-world:linux > /dev/null
+fi
+
+if [ "$#" -eq 0 ]; then
+	set -- '--all'
+fi
+
+declare -A naughtyFromsArches=(
+	#[img:tag=from:tag]='arch arch ...'
+)
+naughtyFroms=()
+
+tags="$(bashbrew list --uniq "$@" | sort -u)"
+for img in $tags; do
+	for BASHBREW_ARCH in $(bashbrew cat --format '{{ join " " .TagEntry.Architectures }}' "$img"); do
+		export BASHBREW_ARCH
+
+		if ! from="$(bashbrew cat --format '{{ $.DockerFrom .TagEntry }}' "$img" 2>/dev/null)"; then
+			# if we can't fetch the tags from their real locations, let's try the warehouse
+			refsList="$(
+				bashbrew list --uniq "$img" \
+				| sed \
+					-e 's!:!/!' \
+					-e "s!^!refs/tags/$BASHBREW_ARCH/!" \
+					-e 's!$!:!'
+			)"
+			[ -n "$refsList" ]
+			git -C "$BASHBREW_CACHE/git" \
+				fetch --no-tags --quiet \
+				https://github.com/docker-library/commit-warehouse.git \
+				$refsList
+			from="$(bashbrew cat --format '{{ $.DockerFrom .TagEntry }}' "$img")"
+		fi
+
+		case "$BASHBREW_ARCH=$from" in
+			# a few explicitly permissible exceptions to Santa's naughty list
+			*=scratch \
+			| amd64=docker.elastic.co/elasticsearch/elasticsearch:* \
+			| amd64=docker.elastic.co/kibana/kibana:* \
+			| amd64=docker.elastic.co/logstash/logstash:* \
+			| windows-*=microsoft/nanoserver \
+			| windows-*=microsoft/nanoserver:* \
+			| windows-*=microsoft/windowsservercore \
+			| windows-*=microsoft/windowsservercore:* \
+			) continue ;;
+		esac
+
+		if ! listOutput="$(bashbrew cat --format '{{ .TagEntry.HasArchitecture arch | ternary arch "" }}' "$from")" || [ -z "$listOutput" ]; then
+			if [ -z "${naughtyFromsArches["$img=$from"]:-}" ]; then
+				naughtyFroms+=( "$img=$from" )
+			else
+				naughtyFromsArches["$img=$from"]+=', '
+			fi
+			naughtyFromsArches["$img=$from"]+="$BASHBREW_ARCH"
+		fi
+	done
+done
+
+for naughtyFrom in "${naughtyFroms[@]}"; do
+	img="${naughtyFrom%%=*}"
+	from="${naughtyFrom#$img=}"
+	arches="${naughtyFromsArches[$naughtyFrom]}"
+	echo " - $img (FROM $from) [$arches]"
+done