diff options
Diffstat (limited to 'packaging/run-in-container')
-rwxr-xr-x | packaging/run-in-container | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/packaging/run-in-container b/packaging/run-in-container new file mode 100755 index 00000000..6d750078 --- /dev/null +++ b/packaging/run-in-container @@ -0,0 +1,145 @@ +#!/bin/sh + +set -eu + +this="$(readlink -e "${0}")" + +# assign defaults +project_dir="$(dirname "$(dirname "${this}")")" +debian_tag="${DEBIAN_TAG:-sid}" + +usage() { + cat << EOF +Usage: $(basename "${this}") [OPTION]... [ACTION] +Run tests or create package in a podman (or docker) container + +Options: + -h print this usage and exit + -C PROJECT_DIR change to PROJECT_DIR (default: ${project_dir}) + -t DEBIAN_TAG debian release tag (default: ${debian_tag}) + -c CONTAINER_CMD container runner command (default: podman) + +Actions: + help print this usage and exit + package create debian package artifacts + test run tests (default) + +Example: + $(basename "${this}") -C ~/code/git-buildpackage -t stretch package +EOF +} + +die() { { echo "ERROR: ${*}"; usage; } >&2; exit 1; } + +# convenience wrapper +# shellcheck disable=SC2068 # re-splitting command arguments intentional +container_build() { + ${container_cmd} build \ + --force-rm="${DOCKER_BUILD_FORCE_RM:-false}" \ + --no-cache="${DOCKER_BUILD_NO_CACHE:-false}" \ + ${@} +} + +# take path to project dir; build docker image for base +base_build() { + ( + cd "${project_dir}" + [ -f .gitignore ] && cat .gitignore + [ -f .gitmodules ] && sed -nr 's|\s+path = (.+)|\1|gp' .gitmodules + cat <<EOF +${this##${PWD}/} +*.buildinfo +*.changes +*.deb +*.dsc +*.tar.xz +.dockerignore +.git* +EOF + ) > "${project_dir}/.dockerignore" + container_build \ + --pull="${DOCKER_BUILD_PULL:-false}" \ + --build-arg="FROM_IMAGE=debian:${debian_tag}" \ + -t "gbp-base:${debian_tag}" -f- "${project_dir}" <<'EOF' +ARG FROM_IMAGE +FROM ${FROM_IMAGE} +ENV DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true +WORKDIR /workdir/project +RUN set -euvx \ +&& apt-get update -y \ +&& apt-get -y --no-install-recommends install \ +build-essential devscripts equivs +COPY debian debian +RUN mk-build-deps -r -i debian/control -t 'apt-get -y -o Debug::pkgProblemResolver=yes --no-install-recommends' +# To avoid constantly invalidating previous container layers, run the slow +# dependency installation early and copy files (along with any changed files) +# later +COPY . . +RUN groupadd luser && useradd -g luser luser && chown -R luser:luser .. +USER luser +EOF + rm -vf "${project_dir}/.dockerignore" +} + + +# run tests +gbp_test() { + base_build + for L in C.UTF-8 C; do + ${container_cmd} run --rm -ie"TEST_LOCALE=${L}" \ + "gbp-base:${debian_tag}" sh <<'EOF' +set -euvx +make all+net +make -C docs +EOF + done +} + +# create debian package artifacts, copy to host +gbp_package() { + base_build + container_build \ + --build-arg="FROM_IMAGE=gbp-base:${debian_tag}" \ + -t "gbp-package:${debian_tag}" -f- "${project_dir}" <<'EOF' +ARG FROM_IMAGE +FROM ${FROM_IMAGE} +RUN dpkg-buildpackage -j$(nproc) -sa -us -uc +EOF + ${container_cmd} run --rm -iu0:0 \ + --mount="type=bind,source=${PWD},target=/mnt/host-volume" \ + "gbp-package:${debian_tag}" sh <<EOF +set -euvx +find .. -maxdepth 1 -mindepth 1 -type f \ + -exec chown -v $(id -u):$(id -g) {} + \ + -a -exec cp -vat /mnt/host-volume {} + +EOF +} + +while getopts ":hC:t:c:" opt; do + case $opt in + h) usage; exit 0;; + C) project_dir="$(readlink -e "${OPTARG}")" + [ -d "${project_dir}" ] || die "bad project dir ${OPTARG}";; + t) debian_tag="${OPTARG}";; + c) container_cmd="${OPTARG}";; + :) die "missing argument: -${OPTARG}";; + \?) die "bad option: -${OPTARG}";; + esac +done + +# Set default container command +container_cmd="${container_cmd:-podman}" + +# Set default container command value if none set +case "${container_cmd}" in + docker|podman) ;; + *) die "container command is expected to be one of 'docker' or 'podman'" ;; +esac + +shift $((OPTIND - 1)) +case "${1:-test}" in + 'help') usage; exit 0;; + 'test') gbp_test; exit ${?};; + 'package') gbp_package; exit ${?};; + *) die "bad action: ${1}";; +esac |