Fix "docker-build.sh" wrapper to handle images with ONBUILD instructions more automatically
The way we handle this semi-gracefully is to create a fake "docker save" tarball that contains just a single layer whose parent is the image we're wanting to test, and whose "config" is the same as the parent image, but with "OnBuild" nulled out, and adjust the build to use that new layer as the base for the build instead.
This commit is contained in:
parent
32c3a0b1b8
commit
c16b7e1cc2
|
|
@ -3,11 +3,11 @@ set -e
|
|||
|
||||
# wrapper around "docker build" that creates a temporary directory and copies files into it first so that arbitrary host directories can be copied into containers without bind mounts, but accepts a Dockerfile on stdin
|
||||
|
||||
# usage: ./docker-build.sh some-host-directory -t some-new-image:some-tag <<EOD
|
||||
# usage: ./docker-build.sh some-host-directory some-new-image:some-tag <<EOD
|
||||
# FROM ...
|
||||
# COPY dir/... /.../
|
||||
# EOD
|
||||
# ie: ./docker-build.sh .../hylang-hello-world -t librarytest/hylang <<EOD
|
||||
# ie: ./docker-build.sh .../hylang-hello-world librarytest/hylang <<EOD
|
||||
# FROM hylang
|
||||
# COPY dir/container.hy /dir/
|
||||
# CMD ["hy", "/dir/container.hy"]
|
||||
|
|
@ -16,9 +16,24 @@ set -e
|
|||
dir="$1"; shift
|
||||
[ -d "$dir" ]
|
||||
|
||||
imageTag="$1"; shift
|
||||
|
||||
tmp="$(mktemp -t -d docker-library-test-build-XXXXXXXXXX)"
|
||||
trap "rm -rf '$tmp'" EXIT
|
||||
|
||||
cat > "$tmp/Dockerfile"
|
||||
|
||||
from="$(awk -F '[[:space:]]+' 'toupper($1) == "FROM" { print $2; exit }' "$tmp/Dockerfile")"
|
||||
onbuilds="$(docker inspect -f '{{len .Config.OnBuild}}' "$from")"
|
||||
if [ "$onbuilds" -gt 0 ]; then
|
||||
# crap, the image we want to build has some ONBUILD instructions
|
||||
# those are kind of going to ruin our day
|
||||
# let's do some hacks to strip those bad boys out in a new fake layer
|
||||
"$(dirname "$(readlink -f "$BASH_SOURCE")")/remove-onbuild.sh" "$from" "$imageTag"
|
||||
awk -F '[[:space:]]+' 'toupper($1) == "FROM" { $2 = "'"$imageTag"'" } { print }' "$tmp/Dockerfile" > "$tmp/Dockerfile.new"
|
||||
mv "$tmp/Dockerfile.new" "$tmp/Dockerfile"
|
||||
fi
|
||||
|
||||
cp -a "$dir" "$tmp/dir"
|
||||
docker build "$@" "$tmp" > /dev/null
|
||||
|
||||
docker build -t "$imageTag" "$tmp" > /dev/null
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ clientImage="$image"
|
|||
|
||||
# Create an instance of the container-under-test
|
||||
serverImage="$("$dir/../image-name.sh" librarytest/jetty-hello-web "$image")"
|
||||
"$dir/../docker-build.sh" "$dir" -t "$serverImage" <<EOD
|
||||
"$dir/../docker-build.sh" "$dir" "$serverImage" <<EOD
|
||||
FROM $image
|
||||
COPY dir/index.jsp /var/lib/jetty/webapps/ROOT/
|
||||
EOD
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ dir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
|
|||
image="$1"
|
||||
|
||||
serverImage="$("$dir/../image-name.sh" librarytest/mysql-initdb "$image")"
|
||||
"$dir/../docker-build.sh" "$dir" -t "$serverImage" <<EOD
|
||||
"$dir/../docker-build.sh" "$dir" "$serverImage" <<EOD
|
||||
FROM $image
|
||||
COPY dir/initdb.sql /docker-entrypoint-initdb.d/
|
||||
EOD
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ ENTRYPOINT ["cgi-fcgi"]
|
|||
EOF
|
||||
|
||||
serverImage="$("$dir/../image-name.sh" librarytest/php-fpm-hello-web "$image")"
|
||||
"$dir/../docker-build.sh" "$dir" -t "$serverImage" <<EOD
|
||||
"$dir/../docker-build.sh" "$dir" "$serverImage" <<EOD
|
||||
FROM $image
|
||||
COPY dir/index.php /var/www/html/
|
||||
EOD
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ dir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
|
|||
image="$1"
|
||||
|
||||
serverImage="$("$dir/../image-name.sh" librarytest/postgres-initdb "$image")"
|
||||
"$dir/../docker-build.sh" "$dir" -t "$serverImage" <<EOD
|
||||
"$dir/../docker-build.sh" "$dir" "$serverImage" <<EOD
|
||||
FROM $image
|
||||
COPY dir/initdb.sql /docker-entrypoint-initdb.d/
|
||||
EOD
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# do some hacks to strip out onbuilds in a new faked layer
|
||||
# usage: ./remove-onbuild.sh input-image output-image
|
||||
# ie: ./remove-onbuild.sh rails:onbuild librarytest/rails-onbuild-without-onbuild
|
||||
|
||||
in="$1"; shift
|
||||
out="$1"; shift
|
||||
|
||||
outImage="${out%%:*}"
|
||||
outTag="${out#*:}"
|
||||
[ "$outImage" != "$outTag" ] || outTag='latest'
|
||||
|
||||
tmp="$(mktemp -t -d docker-library-test-remove-onbuild-XXXXXXXXXX)"
|
||||
trap "rm -rf '$tmp'" EXIT
|
||||
|
||||
declare -A json=(
|
||||
[Size]=0
|
||||
)
|
||||
declare -A mappings=(
|
||||
[parent]='.Id'
|
||||
[created]='.Created'
|
||||
[container]='.Container'
|
||||
[container_config]='.ContainerConfig'
|
||||
[config]='.Config'
|
||||
[docker_version]='.DockerVersion'
|
||||
[architecture]='.Architecture'
|
||||
[os]='.Os'
|
||||
)
|
||||
for key in "${!mappings[@]}"; do
|
||||
val="$(docker inspect -f '{{json '"${mappings[$key]}"'}}' "$in")"
|
||||
json["$key"]="$val"
|
||||
done
|
||||
onbuildConfig="$(docker inspect -f '{{json .Config.OnBuild}}' "$in" | sed 's/[]\/$*.^|[]/\\&/g')" # pre-escaped for use within "sed"
|
||||
json[config]="$(echo "${json[config]}" | sed -r "s/$onbuildConfig/null/g")" # grab the image config, but scrub the onbuilds
|
||||
jsonString='{'
|
||||
first=1
|
||||
for key in "${!json[@]}"; do
|
||||
[ "$first" ] || jsonString+=','
|
||||
first=
|
||||
jsonString+='"'"$key"'":'"${json[$key]}"
|
||||
done
|
||||
newId="$(echo "$jsonString" | sha256sum | cut -d' ' -f1)" # lol, this is hacky
|
||||
jsonString+=',"id":"'"$newId"'"}'
|
||||
mkdir -p "$tmp/$newId"
|
||||
echo "$jsonString" > "$tmp/$newId/json"
|
||||
echo -n '1.0' > "$tmp/$newId/VERSION"
|
||||
dd if=/dev/zero of="$tmp/$newId/layer.tar" bs=1k count=1 &> /dev/null # empty tar file
|
||||
cat > "$tmp/repositories" <<EOF
|
||||
{"$outImage":{"$outTag":"$newId"}}
|
||||
EOF
|
||||
tar -cC "$tmp" . | docker load
|
||||
|
|
@ -22,7 +22,7 @@ workdir="$containerMount/$testBase"
|
|||
# TODO should we be doing something fancy with $BASH_SOURCE instead so we can be arbitrarily deep and mount the top level always?
|
||||
|
||||
newImage="$("$thisDir/image-name.sh" librarytest/run-in-container "$image--$testBase")"
|
||||
"$thisDir/docker-build.sh" "$hostMount" -t "$newImage" <<EOD
|
||||
"$thisDir/docker-build.sh" "$hostMount" "$newImage" <<EOD
|
||||
FROM $image
|
||||
COPY dir $containerMount
|
||||
WORKDIR $workdir
|
||||
|
|
|
|||
Loading…
Reference in New Issue