| #!/usr/bin/env bash | |
| set -o errexit -o pipefail | |
| DIR=$(dirname "${0}") | |
| MAIN_DIR=$(readlink -f "${DIR}/..") | |
| if [ -L "${MAIN_DIR}/.git/config" ]; then | |
| # Support git-new-workdir | |
| GIT_DIR="$(dirname "$(realpath "${MAIN_DIR}/.git/config")")" | |
| else | |
| # Support git-worktree | |
| GIT_DIR="$(cd "${MAIN_DIR}" && git rev-parse --no-flags --git-common-dir)" | |
| fi | |
| if test -z "${IMAGE}" ; then | |
| # shellcheck disable=SC2016 | |
| IMAGE=$(grep ^image: "${MAIN_DIR}/.gitlab-ci.yml" | \ | |
| sed -e 's,^image: ,,g' | sed -e 's,\$CI_REGISTRY,registry.gitlab.com,g') | |
| fi | |
| declare -a docker_opts=( | |
| -i | |
| --rm | |
| --user "$(id -u):$(id -g)" | |
| --workdir "$(pwd)" | |
| --security-opt label=disable | |
| --network "$([ "${NO_NETWORK:-0}" -eq 1 ] && echo none || echo host)" | |
| ) | |
| declare -a mountpoints=( | |
| "${MAIN_DIR}" | |
| "$(pwd)" | |
| ) | |
| # We use the PODMAN_USERNS environment variable rather than using the | |
| # --userns command line argument because Fedora system may have the | |
| # podman-docker package installed, providing the "docker" | |
| # compatibility command. | |
| export PODMAN_USERNS="keep-id" | |
| if [ "${BR2_DOCKER}" ]; then | |
| if command -v "${BR2_DOCKER}" >/dev/null; then | |
| DOCKER="${BR2_DOCKER}" | |
| else | |
| printf 'ERROR: Command "%s" (from env BR2_DOCKER) not found.\n' "${BR2_DOCKER}" >&2 | |
| exit 1 | |
| fi | |
| elif command -v docker >/dev/null; then | |
| DOCKER="docker" | |
| elif command -v podman >/dev/null; then | |
| DOCKER="podman" | |
| else | |
| echo "ERROR: Neither docker nor podman available!" >&2 | |
| exit 1 | |
| fi | |
| # curl lists (and recognises and uses) other types of *_proxy variables, | |
| # but only those make sense for Buildroot: | |
| for env in all_proxy http_proxy https_proxy ftp_proxy no_proxy; do | |
| if [ "${!env}" ]; then | |
| docker_opts+=( --env "${env}" ) | |
| # The lower-case variant takes precedence on the upper-case one | |
| # (dixit curl) | |
| continue | |
| fi | |
| # http_proxy is only lower-case (dixit curl) | |
| if [ "${env}" = http_proxy ]; then | |
| continue | |
| fi | |
| # All the others also exist in the upper-case variant | |
| env="${env^^}" | |
| if [ "${!env}" ]; then | |
| docker_opts+=( --env "${env}" ) | |
| fi | |
| done | |
| # Empty GIT_DIR means that we are not in a workdir, *and* git is too old | |
| # to know about worktrees, so we're not in a worktree either. So it means | |
| # we're in the main git working copy, and thus we don't need to mount the | |
| # .git directory. | |
| if [ "${GIT_DIR}" ]; then | |
| # GIT_DIR in the main working copy (when git supports worktrees) will | |
| # be just '.git', but 'docker run' needs an absolute path. If it is | |
| # not absolute, GIT_DIR is relative to MAIN_DIR. If it's an absolute | |
| # path already (in a wordir), then that's a noop. | |
| GIT_DIR="$(cd "${MAIN_DIR}"; readlink -e "${GIT_DIR}")" | |
| mountpoints+=( "${GIT_DIR}" ) | |
| # 'repo' stores .git/objects separately. | |
| if [ -L "${GIT_DIR}/objects" ]; then | |
| # GITDIR is already an absolute path, but for symmetry | |
| # with the above, keep the same cd+readlink construct. | |
| OBJECTS_DIR="$(cd "${MAIN_DIR}"; readlink -e "${GIT_DIR}/objects")" | |
| mountpoints+=( "${OBJECTS_DIR}" ) | |
| fi | |
| fi | |
| if [ "${BR2_DL_DIR}" ]; then | |
| mountpoints+=( "${BR2_DL_DIR}" ) | |
| docker_opts+=( --env BR2_DL_DIR ) | |
| fi | |
| # Testing the existence of the variable instead of a non-empty value | |
| # allows passing an empty BR2_EXTERNAL variable to disable currently | |
| # set external trees. | |
| if [ "${BR2_EXTERNAL+set}" ]; then | |
| docker_opts+=( --env BR2_EXTERNAL ) | |
| for br2_ext in ${BR2_EXTERNAL//:/ }; do | |
| # bind volume source paths must be absolute | |
| mountpoints+=( "$(cd "${br2_ext}" && pwd)" ) | |
| done | |
| fi | |
| # shellcheck disable=SC2013 # can't use while-read because of the assignment | |
| for dir in $(printf '%s\n' "${mountpoints[@]}" |LC_ALL=C sort -u); do | |
| docker_opts+=( --mount "type=bind,src=${dir},dst=${dir}" ) | |
| done | |
| if tty -s; then | |
| docker_opts+=( -t ) | |
| fi | |
| exec ${DOCKER} run "${docker_opts[@]}" "${IMAGE}" "${@}" |