build files for making podman containers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

156 lines
4.2 KiB

#!/bin/bash
################################################################################
set -eEuo pipefail
err=0
trap 'err=$?' ERR
trap 'cleanup' EXIT
epoch=$(date +%s.%3N)
today=$(date +%Y-%m-%d-T%H%M)
notopt() {
case $1 in
1) return 0;;
0) return 1;;
*) return $1;;
esac
}
badarg() {
echo -n "$(basename $0): " >&2
echo "$1" >&2
echo "Try '$(basename $0) -h' for more information." >&2
exit 2
}
cleanup() {
if [[ $err -eq 0 || $opt_debug -eq 0 ]]; then
podman rm -i -f tmp-$epoch 2>&1 > /dev/null
fi
}
help="Usage: $(basename $0) [-sdh] [-t tag] [-v vol] [directory] [name]
Builds an image from files in a directory, and assigns it a name.
Files used are 'Containerfile' and optionally 'Initfile'. If first argument
is omitted, script assumes files can be found in the current working directory.
If second argument is omitted, the directory where the files were found is used
as the image name.
Options:
-d Debug mode: don't delete the temporary container created by the script
-r Redo build from scratch instead of using cached layers
-s Squash all layers in the image into a single layer
-t tag Tag the image with the given string. Can be used multiple times to assign
multiple tags
-v vol Mount ~/vol as /vol while building
-h Display this help and exit"
# Handle options
opt_squash=1
opt_redo=0
opt_debug=0
opt_tags=()
opt_vols=()
while getopts ':srdt:v:h' arg; do
case $arg in
s) opt_squash=$(notopt ${opt_squash});;
r) opt_redo=$(notopt ${opt_redo});;
d) opt_debug=$(notopt ${opt_debug});;
t) opt_tags+=("${OPTARG}");;
v) opt_vols+=("${OPTARG}");;
h) echo "$help"; exit 0;;
:) badarg "Argument missing for option '-$OPTARG'";;
?) badarg "Invalid option '-$OPTARG'";;
esac
done
shift $((OPTIND -1))
# Handle non-option arguments
if [[ $# -gt 2 ]]; then
badarg "Too many arguments"
fi
if [[ $# -ge 1 ]]; then
directory="$1"
else
directory=$(pwd)
fi
if [[ $# -ge 2 ]]; then
name="$2"
else
name=$(basename "$directory")
fi
# Main
if [[ ! -d "$directory" ]]; then
echo "Error: directory '$directory' not found"
exit 1
else
cd "$directory"
fi
buildopts="--build-arg EXT_HOME=$HOME"
runopts=""
if [[ $opt_squash -eq 1 ]]; then
buildopts="$buildopts --squash-all"
fi
if [[ $opt_redo -eq 1 ]]; then
buildopts="$buildopts --no-cache"
fi
for vol in "${opt_vols[@]}"; do
buildopts="$buildopts -v $HOME/vol/${name}/${vol}:/vol/${vol}"
runopts="$runopts -v $HOME/vol/${name}/${vol}:/vol/${vol}"
done
# tell buildah to build images in docker format instead of the default OCI format
# because only docker-format images can use the SHELL directive in Containerfiles
### export BUILDAH_FORMAT=docker
# build image
echo "Building image tmp-$epoch ..."
podman build -f Containerfile -t tmp-$epoch $buildopts
# Initfile is for commands that need systemd to execute
if [[ -f Initfile ]]; then
echo "Running initialization ..."
echo "Creating temporary container tmp-$epoch ..."
podman create --name tmp-$epoch $runopts tmp-$epoch
podman start tmp-$epoch
echo "Copying script to container tmp-$epoch ..."
podman cp Initfile tmp-$epoch:/root/
echo "Running Initfile script ..."
podman exec tmp-$epoch bash -c "chmod +x /root/Initfile && /root/Initfile"
echo "Committing container tmp-$epoch to image $name:$today ..."
podman commit tmp-$epoch "$name:$today"
if [[ $opt_debug -eq 0 ]]; then
echo "Removing temporary container tmp-$epoch ..."
podman rm -i -f tmp-$epoch
fi
else
echo "Initfile not found, skipping temporary container step ..."
# tag image we already built with appropriate tag, and untag with tmp
echo "Tagging image tmp-$epoch as $name:$today ..."
podman tag tmp-$epoch "$name:$today"
fi
if ! podman container exists tmp-$epoch ; then
echo "Removing temporary image tmp-$epoch ..."
podman rmi tmp-$epoch
fi
# tag image as latest
echo "Adding latest tag to image $name:$today ..."
podman tag "$name:$today" "$name:latest"
# assign any extra tags
for tag in "${opt_tags[@]}"; do
echo "Adding tag $tag to image $name:$today ..."
podman tag "$name:$today" "$name:$tag"
done
echo "... Done!"