| 
									
										
										
										
											2020-02-11 01:23:07 +08:00
										 |  |  | #!/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= | 
					
						
							| 
									
										
										
										
											2020-03-13 04:11:30 +08:00
										 |  |  | if expr "$ME" : ".*-dup" &>/dev/null; then | 
					
						
							| 
									
										
										
										
											2020-02-11 01:23:07 +08:00
										 |  |  |     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" | 
					
						
							| 
									
										
										
										
											2020-03-13 04:11:30 +08:00
										 |  |  | buildah tag interim2 my_image | 
					
						
							| 
									
										
										
										
											2020-02-11 01:23:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | ############################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-13 04:11:30 +08:00
										 |  |  | 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 01:23:07 +08:00
										 |  |  | # Reload the image | 
					
						
							|  |  |  | (cd $TMPDIR && buildah pull dir:${IMGNAME}) | 
					
						
							| 
									
										
										
										
											2020-03-13 04:11:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Leave the tmpdir behind for the -dup image! | 
					
						
							|  |  |  | if [ -z "$dup" ]; then | 
					
						
							|  |  |  |     rm -rf ${TMPDIR} | 
					
						
							|  |  |  | fi | 
					
						
							| 
									
										
										
										
											2020-02-11 01:23:07 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | ############################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-13 04:11:30 +08:00
										 |  |  |     echo "Image localhost/${IMGNAME} looks OK; feel free to:" | 
					
						
							|  |  |  |     echo | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 01:23:07 +08:00
										 |  |  |     if [ -n "$dup" ]; then | 
					
						
							| 
									
										
										
										
											2020-03-13 04:11:30 +08:00
										 |  |  |         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" | 
					
						
							| 
									
										
										
										
											2020-02-11 01:23:07 +08:00
										 |  |  |     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." | 
					
						
							| 
									
										
										
										
											2020-03-13 04:11:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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 | 
					
						
							| 
									
										
										
										
											2020-02-11 01:23:07 +08:00
										 |  |  | else | 
					
						
							|  |  |  |     echo "WARNING: 'jq' not found; unable to verify built image" >&2 | 
					
						
							|  |  |  | fi |