source ../scripts/build-template
readonly BUILD_DIR=build
readonly PROPERTIES="${SCRIPT_DIR}/../src/main/resources/bootstrap.properties"
while IFS='=' read -r key value
do
key=$(echo $key | tr '.' '_')
eval ${key}=\${value}
done < "${PROPERTIES}"
readonly CONTAINER_EXE=podman
readonly CONTAINER_SHORTNAME=typesetter
readonly CONTAINER_VERSION=${container_version}
readonly CONTAINER_NETWORK=host
readonly CONTAINER_FILE="${CONTAINER_SHORTNAME}"
readonly CONTAINER_ARCHIVE_FILE="${CONTAINER_FILE}.tar"
readonly CONTAINER_ARCHIVE_PATH="${BUILD_DIR}/${CONTAINER_ARCHIVE_FILE}"
readonly CONTAINER_COMPRESSED_FILE="${CONTAINER_ARCHIVE_FILE}.gz"
readonly CONTAINER_COMPRESSED_PATH="${BUILD_DIR}/${CONTAINER_ARCHIVE_FILE}.gz"
readonly CONTAINER_DIR_SOURCE="/root/source"
readonly CONTAINER_DIR_TARGET="/root/target"
readonly CONTAINER_DIR_IMAGES="/root/images"
readonly CONTAINER_DIR_FONTS="/root/fonts"
readonly CONTAINER_REPO=ghcr.io
ARG_CONTAINER_NAME="${CONTAINER_SHORTNAME}:${CONTAINER_VERSION}"
ARG_CONTAINER_COMMAND="context --version"
ARG_MOUNTPOINT_SOURCE=""
ARG_MOUNTPOINT_TARGET="."
ARG_MOUNTPOINT_IMAGES=""
ARG_MOUNTPOINT_FONTS="${HOME}/.fonts"
ARG_ACCESS_TOKEN=""
DEPENDENCIES=(
"podman,https://podman.io"
"tar,https://www.gnu.org/software/tar"
"bzip2,https://gitlab.com/bzip2/bzip2"
)
ARGUMENTS+=(
"b,build,Build container"
"c,connect,Connect to container"
"d,delete,Remove all containers"
"s,source,Set mount point for input document (before typesetting)"
"t,target,Set mount point for output file (after typesetting)"
"i,images,Set mount point for image files (to typeset)"
"f,fonts,Set mount point for font files (during typesetting)"
"k,token,Set personal access token (to publish)"
"l,load,Load container (${CONTAINER_COMPRESSED_PATH})"
"p,publish,Publish the container (after logging in)"
"r,run,Run a command in the container (\"${ARG_CONTAINER_COMMAND}\")"
"v,version,Set container version to publish (${CONTAINER_VERSION})"
"x,export,Save container (${CONTAINER_COMPRESSED_PATH})"
)
execute() {
$do_delete
$do_build
$do_publish
$do_export
$do_load
$do_execute
$do_connect
return 1
}
utile_delete() {
$log "Deleting all containers"
${CONTAINER_EXE} rmi --all --force > /dev/null
$log "Containers deleted"
}
utile_build() {
$log "Building"
${CONTAINER_EXE} build \
--network=${CONTAINER_NETWORK} \
--squash \
-t ${ARG_CONTAINER_NAME} . | \
grep ^STEP
}
utile_publish() {
local -r username=$(git config user.name | tr '[A-Z]' '[a-z]')
local -r repo="${CONTAINER_REPO}/${username}/${ARG_CONTAINER_NAME}"
if [ ! -z ${ARG_ACCESS_TOKEN} ]; then
echo ${ARG_ACCESS_TOKEN} | \
${CONTAINER_EXE} login ghcr.io -u $(git config user.name) --password-stdin
$log "Tagging"
${CONTAINER_EXE} tag ${ARG_CONTAINER_NAME} ${repo}
$log "Pushing ${ARG_CONTAINER_NAME} to ${CONTAINER_REPO}"
${CONTAINER_EXE} push ${repo}
$log "Published ${ARG_CONTAINER_NAME} to ${CONTAINER_REPO}"
else
error "Provide a personal access token (-k TOKEN) to publish."
fi
}
get_mountpoint() {
$log "Mounting ${1} as ${2}"
local result=""
local binding="ro"
if [ ! -z "${3+x}" ]; then
binding="Z"
fi
if [ ! -z "${1}" ]; then
result="-v ${1}:${2}:${binding}"
fi
echo "${result}"
}
get_mountpoint_source() {
echo $(get_mountpoint "${ARG_MOUNTPOINT_SOURCE}" "${CONTAINER_DIR_SOURCE}")
}
get_mountpoint_target() {
echo $(get_mountpoint "${ARG_MOUNTPOINT_TARGET}" "${CONTAINER_DIR_TARGET}" 1)
}
get_mountpoint_images() {
echo $(get_mountpoint "${ARG_MOUNTPOINT_IMAGES}" "${CONTAINER_DIR_IMAGES}")
}
get_mountpoint_fonts() {
echo $(get_mountpoint "${ARG_MOUNTPOINT_FONTS}" "${CONTAINER_DIR_FONTS}")
}
utile_connect() {
$log "Connecting to container"
declare -r mount_source=$(get_mountpoint_source)
declare -r mount_target=$(get_mountpoint_target)
declare -r mount_images=$(get_mountpoint_images)
declare -r mount_fonts=$(get_mountpoint_fonts)
${CONTAINER_EXE} run \
--network="${CONTAINER_NETWORK}" \
--rm \
-it \
${mount_source} \
${mount_target} \
${mount_images} \
${mount_fonts} \
"${ARG_CONTAINER_NAME}"
}
utile_execute() {
$log "Running \"${ARG_CONTAINER_COMMAND}\":"
${CONTAINER_EXE} run \
--network=${CONTAINER_NETWORK} \
--rm \
-i \
-t "${ARG_CONTAINER_NAME}" \
/bin/sh --login -c "${ARG_CONTAINER_COMMAND}"
}
utile_export() {
if [[ -f "${CONTAINER_COMPRESSED_PATH}" ]]; then
warning "${CONTAINER_COMPRESSED_PATH} exists, delete before saving."
else
$log "Saving ${CONTAINER_SHORTNAME} image"
mkdir -p "${BUILD_DIR}"
${CONTAINER_EXE} save \
--quiet \
-o "${BUILD_DIR}/${CONTAINER_ARCHIVE_FILE}" \
"${ARG_CONTAINER_NAME}"
$log "Compressing to ${CONTAINER_COMPRESSED_PATH}"
gzip "${CONTAINER_ARCHIVE_PATH}"
$log "Saved ${CONTAINER_SHORTNAME} image"
fi
}
utile_load() {
if [[ -f "${CONTAINER_COMPRESSED_PATH}" ]]; then
$log "Loading ${CONTAINER_SHORTNAME} from ${CONTAINER_COMPRESSED_PATH}"
${CONTAINER_EXE} load \
--quiet \
-i "${CONTAINER_COMPRESSED_PATH}"
$log "Loaded ${CONTAINER_SHORTNAME} image"
else
warning "Missing ${CONTAINER_COMPRESSED_PATH}; use build follwed by save"
fi
}
argument() {
local consume=1
case "$1" in
-b|--build)
do_build=utile_build
;;
-c|--connect)
do_connect=utile_connect
;;
-d|--delete)
do_delete=utile_delete
;;
-k|--token)
if [ ! -z "${2+x}" ]; then
ARG_ACCESS_TOKEN="$2"
consume=2
fi
;;
-l|--load)
do_load=utile_load
;;
-i|--images)
if [ ! -z "${2+x}" ]; then
ARG_MOUNTPOINT_IMAGES="$2"
consume=2
fi
;;
-t|--target)
if [ ! -z "${2+x}" ]; then
ARG_MOUNTPOINT_TARGET="$2"
consume=2
fi
;;
-p|--publish)
do_publish=utile_publish
;;
-r|--run)
do_execute=utile_execute
if [ ! -z "${2+x}" ]; then
ARG_CONTAINER_COMMAND="$2"
consume=2
fi
;;
-s|--source)
if [ ! -z "${2+x}" ]; then
ARG_MOUNTPOINT_SOURCE="$2"
consume=2
fi
;;
-v|--version)
if [ ! -z "${2+x}" ]; then
ARG_CONTAINER_NAME="${CONTAINER_SHORTNAME}:$2"
consume=2
fi
;;
-x|--export)
do_export=utile_export
;;
esac
return ${consume}
}
do_build=:
do_connect=:
do_delete=:
do_execute=:
do_load=:
do_publish=:
do_export=:
main "$@"