181 lines
5.9 KiB
Bash
Executable File
181 lines
5.9 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# make-v2sN - create a v2sN image, possibly with dups
|
|
#
|
|
# This is a helper script used for creating custom images for buildah testing.
|
|
# The images are used in the digest.bats test.
|
|
#
|
|
ME=$(basename $0)
|
|
|
|
die() {
|
|
echo "$ME: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
###############################################################################
|
|
#
|
|
# From the script name, determine the desired schema version (1 or 2) and
|
|
# whether or not we want duplicate layers.
|
|
|
|
schemaversion=$(expr "$ME" : ".*-v2s\([12]\)")
|
|
test -n "$schemaversion" || die "Could not find 'v2s[12]' in basename"
|
|
test "$schemaversion" = "N" && die "Script must be invoked via symlink"
|
|
|
|
dup=
|
|
if expr "$ME" : ".*-dup" &>/dev/null; then
|
|
dup="_with_dups"
|
|
fi
|
|
|
|
IMGNAME=testdigest_v2s${schemaversion}${dup}
|
|
|
|
###############################################################################
|
|
# Create the image.
|
|
|
|
set -e
|
|
|
|
# First layer
|
|
cid=$(buildah from scratch)
|
|
buildah commit -q $cid interim1
|
|
|
|
# Create a second layer containing this script and a README
|
|
cid2=$(buildah from interim1)
|
|
mp=$(buildah mount $cid2)
|
|
cp $0 $mp/
|
|
cat <<EOF >$mp/README
|
|
This is a test image used for buildah testing.
|
|
|
|
EOF
|
|
|
|
# In the README include creation timestamp, user, script name, git tree state
|
|
function add_to_readme() {
|
|
printf " %-12s : %s\n" "$1" "$2" >>$mp/README
|
|
}
|
|
|
|
add_to_readme "Created" "$(date --iso-8601=seconds)"
|
|
|
|
# FIXME: do we really need to know? Will it ever, in practice, be non-root?
|
|
user=$(id -un)
|
|
if [ -n "$user" -a "$user" != "root" ]; then
|
|
add_to_readme "By (user)" "$user"
|
|
fi
|
|
|
|
create_script=$(cd $(dirname $0) && git ls-files --full-name $ME)
|
|
if [ -z "$create_script" ]; then
|
|
create_script=$0
|
|
fi
|
|
add_to_readme "By (script)" "$create_script"
|
|
|
|
git_state=$(cd $(dirname $0) && git describe --dirty)
|
|
if [ -n "$git_state" ]; then
|
|
add_to_readme "git state" "$git_state"
|
|
fi
|
|
|
|
echo "-----------------------------------------------------------------"
|
|
cat $mp/README
|
|
echo "-----------------------------------------------------------------"
|
|
|
|
buildah umount $cid2
|
|
buildah commit -q $cid2 interim2
|
|
|
|
layers="interim2 interim1"
|
|
buildah tag interim2 my_image
|
|
|
|
###############################################################################
|
|
#
|
|
# Push/pull the image to/from a tempdir. This is a kludge allowing us to
|
|
# clean up interim layers. It's also necessary for dealing with v2s1 layers.
|
|
|
|
TMPDIR=$(mktemp --tmpdir -d $(basename $0).XXXXXXX)
|
|
push_flags=
|
|
if [[ $schemaversion -eq 1 ]]; then
|
|
# buildah can't actually create a v2s1 image; only v2s2. To create v2s1,
|
|
# dir-push it to a tmpdir using '--format v2s1'; that will be inherited
|
|
# when we reload it
|
|
push_flags="--format v2s1"
|
|
fi
|
|
buildah push $push_flags my_image dir:${TMPDIR}/${IMGNAME}
|
|
|
|
# Clean up containers and images
|
|
buildah rm -a
|
|
buildah rmi -f my_image $layers
|
|
|
|
if [ -n "$dup" ]; then
|
|
manifest=${TMPDIR}/${IMGNAME}/manifest.json
|
|
cat $manifest |
|
|
jq -c '.fsLayers |= [.[0]] + .' |
|
|
jq -c '.history |= [.[0]] + .' |
|
|
tr -d '\012' >$manifest.tmp
|
|
mv $manifest $manifest.BAK
|
|
mv $manifest.tmp $manifest
|
|
fi
|
|
|
|
# Delete possibly-existing image, because 'buildah pull' will not overwrite it
|
|
buildah rmi -f localhost/${IMGNAME}:latest &>/dev/null || true
|
|
|
|
# Reload the image
|
|
(cd $TMPDIR && buildah pull dir:${IMGNAME})
|
|
|
|
# Leave the tmpdir behind for the -dup image!
|
|
if [ -z "$dup" ]; then
|
|
rm -rf ${TMPDIR}
|
|
fi
|
|
|
|
###############################################################################
|
|
#
|
|
# We should now have a 'localhost/IMGNAME' image with desired SchemaVersion
|
|
# and other features as requested.
|
|
#
|
|
# Now verify what we have what we intended.
|
|
echo
|
|
if type -p jq >&/dev/null; then
|
|
# Manifest is embedded in the image but as a string, not actual JSON;
|
|
# the eval-echo converts it to usable JSON
|
|
manifest=$(eval echo $(buildah inspect ${IMGNAME} | jq .Manifest))
|
|
|
|
# Check desired schema version:
|
|
actual_schemaversion=$(jq .schemaVersion <<<"$manifest")
|
|
if [[ $actual_schemaversion -ne $schemaversion ]]; then
|
|
die "Expected .schemaVersion $schemaversion, got '$actual_schemaversion'"
|
|
fi
|
|
|
|
echo "Image localhost/${IMGNAME} looks OK; feel free to:"
|
|
echo
|
|
|
|
if [ -n "$dup" ]; then
|
|
echo " \$SKOPEO copy dir:${TMPDIR}/${IMGNAME} docker://quay.io/libpod/${IMGNAME}:\$(date +%Y%m%d)"
|
|
echo " ^^^^^^^--- must be specially-crafted skopeo(*), see below"
|
|
else
|
|
echo " buildah push localhost/${IMGNAME} quay.io/libpod/${IMGNAME}:$(date +%Y%m%d)"
|
|
echo " buildah push localhost/${IMGNAME} quay.io/libpod/${IMGNAME}:latest"
|
|
fi
|
|
|
|
echo
|
|
echo "You may then need to log in to the https://quay.io/ web UI"
|
|
echo "make those images public, then update tags and/or SHAs"
|
|
echo "in test/digest.bats."
|
|
echo
|
|
echo "Note that the Digest SHA on quay.io != the SHA on the locally"
|
|
echo "created image. You can get the real SHA on quay.io by clicking"
|
|
echo "on the image name, then the luggage-tag icon on the left,"
|
|
echo "then the gray box with the text 'SHA256' (not the actual"
|
|
echo "hash shown in blue to its right), and copy-pasting the SHA"
|
|
echo "from the popup window."
|
|
echo
|
|
echo "NOTE: the first push to quay.io sometimes fails with some sort of"
|
|
echo "500 error, trying to reuse blob, blah blah. Just ignore it and"
|
|
echo "retry. IME it works the second time."
|
|
|
|
if [ -n "$dup" ]; then
|
|
echo
|
|
echo "(*) skopeo WILL NOT push an image with dup layers. To get it to"
|
|
echo " do that, build a custom skopeo using the patch here:"
|
|
echo " https://gist.github.com/nalind/b491204ff05c3c3f3b6ef014b333a60c"
|
|
echo " ...then use that skopeo in the above 'copy' command."
|
|
# And, for posterity should the gist ever disappear:
|
|
# vendor/github.com/containers/image/v5/manifest/docker_schema1.go
|
|
# - remove lines 66-68 ('if ... s1.fixManifestLayers()...')
|
|
fi
|
|
else
|
|
echo "WARNING: 'jq' not found; unable to verify built image" >&2
|
|
fi
|