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
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!"
|
|
|
|
|