2
1

docker-run 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #!/usr/bin/env bash
  2. set -o errexit -o pipefail
  3. DIR=$(dirname "${0}")
  4. MAIN_DIR=$(readlink -f "${DIR}/..")
  5. if [ -L "${MAIN_DIR}/.git/config" ]; then
  6. # Support git-new-workdir
  7. GIT_DIR="$(dirname "$(realpath "${MAIN_DIR}/.git/config")")"
  8. else
  9. # Support git-worktree
  10. GIT_DIR="$(cd "${MAIN_DIR}" && git rev-parse --no-flags --git-common-dir)"
  11. fi
  12. if test -z "${IMAGE}" ; then
  13. # shellcheck disable=SC2016
  14. IMAGE=$(grep ^image: "${MAIN_DIR}/.gitlab-ci.yml" | \
  15. sed -e 's,^image: ,,g' | sed -e 's,\$CI_REGISTRY,registry.gitlab.com,g')
  16. fi
  17. declare -a docker_opts=(
  18. -i
  19. --rm
  20. --user "$(id -u):$(id -g)"
  21. --workdir "$(pwd)"
  22. --security-opt label=disable
  23. --network host
  24. )
  25. declare -a mountpoints=(
  26. "${MAIN_DIR}"
  27. "$(pwd)"
  28. )
  29. # We use the PODMAN_USERNS environment variable rather than using the
  30. # --userns command line argument because Fedora system may have the
  31. # podman-docker package installed, providing the "docker"
  32. # compatibility command.
  33. export PODMAN_USERNS="keep-id"
  34. if [ "${BR2_DOCKER}" ]; then
  35. if command -v "${BR2_DOCKER}" >/dev/null; then
  36. DOCKER="${BR2_DOCKER}"
  37. else
  38. printf 'ERROR: Command "%s" (from env BR2_DOCKER) not found.\n' "${BR2_DOCKER}" >&2
  39. exit 1
  40. fi
  41. elif command -v docker >/dev/null; then
  42. DOCKER="docker"
  43. elif command -v podman >/dev/null; then
  44. DOCKER="podman"
  45. else
  46. echo "ERROR: Neither docker nor podman available!" >&2
  47. exit 1
  48. fi
  49. # curl lists (and recognises and uses) other types of *_proxy variables,
  50. # but only those make sense for Buildroot:
  51. for env in all_proxy http_proxy https_proxy ftp_proxy no_proxy; do
  52. if [ "${!env}" ]; then
  53. docker_opts+=( --env "${env}" )
  54. # The lower-case variant takes precedence on the upper-case one
  55. # (dixit curl)
  56. continue
  57. fi
  58. # http_proxy is only lower-case (dixit curl)
  59. if [ "${env}" = http_proxy ]; then
  60. continue
  61. fi
  62. # All the others also exist in the upper-case variant
  63. env="${env^^}"
  64. if [ "${!env}" ]; then
  65. docker_opts+=( --env "${env}" )
  66. fi
  67. done
  68. # Empty GIT_DIR means that we are not in a workdir, *and* git is too old
  69. # to know about worktrees, so we're not in a worktree either. So it means
  70. # we're in the main git working copy, and thus we don't need to mount the
  71. # .git directory.
  72. if [ "${GIT_DIR}" ]; then
  73. # GIT_DIR in the main working copy (when git supports worktrees) will
  74. # be just '.git', but 'docker run' needs an absolute path. If it is
  75. # not absolute, GIT_DIR is relative to MAIN_DIR. If it's an absolute
  76. # path already (in a wordir), then that's a noop.
  77. GIT_DIR="$(cd "${MAIN_DIR}"; readlink -e "${GIT_DIR}")"
  78. mountpoints+=( "${GIT_DIR}" )
  79. # 'repo' stores .git/objects separately.
  80. if [ -L "${GIT_DIR}/objects" ]; then
  81. # GITDIR is already an absolute path, but for symmetry
  82. # with the above, keep the same cd+readlink construct.
  83. OBJECTS_DIR="$(cd "${MAIN_DIR}"; readlink -e "${GIT_DIR}/objects")"
  84. mountpoints+=( "${OBJECTS_DIR}" )
  85. fi
  86. fi
  87. if [ "${BR2_DL_DIR}" ]; then
  88. mountpoints+=( "${BR2_DL_DIR}" )
  89. docker_opts+=( --env BR2_DL_DIR )
  90. fi
  91. # shellcheck disable=SC2013 # can't use while-read because of the assignment
  92. for dir in $(printf '%s\n' "${mountpoints[@]}" |LC_ALL=C sort -u); do
  93. docker_opts+=( --mount "type=bind,src=${dir},dst=${dir}" )
  94. done
  95. if tty -s; then
  96. docker_opts+=( -t )
  97. fi
  98. exec ${DOCKER} run "${docker_opts[@]}" "${IMAGE}" "${@}"