您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

build-docker.sh 4.9 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #!/usr/bin/env bash
  2. # Note: Avoid usage of arrays as MacOS users have an older version of bash (v3.x) which does not supports arrays
  3. set -eu
  4. DIR="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)"
  5. BUILD_OPTS="$*"
  6. # Allow user to override docker command
  7. DOCKER=${DOCKER:-docker}
  8. # Ensure that default docker command is not set up in rootless mode
  9. if \
  10. ! ${DOCKER} ps >/dev/null 2>&1 || \
  11. ${DOCKER} info 2>/dev/null | grep -q rootless \
  12. ; then
  13. DOCKER="sudo ${DOCKER}"
  14. fi
  15. if ! ${DOCKER} ps >/dev/null; then
  16. echo "error connecting to docker:"
  17. ${DOCKER} ps
  18. exit 1
  19. fi
  20. CONFIG_FILE=""
  21. if [ -f "${DIR}/config" ]; then
  22. CONFIG_FILE="${DIR}/config"
  23. fi
  24. while getopts "c:" flag
  25. do
  26. case "${flag}" in
  27. c)
  28. CONFIG_FILE="${OPTARG}"
  29. ;;
  30. *)
  31. ;;
  32. esac
  33. done
  34. # Ensure that the configuration file is an absolute path
  35. if test -x /usr/bin/realpath; then
  36. CONFIG_FILE=$(realpath -s "$CONFIG_FILE" || realpath "$CONFIG_FILE")
  37. fi
  38. # Ensure that the confguration file is present
  39. if test -z "${CONFIG_FILE}"; then
  40. echo "Configuration file need to be present in '${DIR}/config' or path passed as parameter"
  41. exit 1
  42. else
  43. # shellcheck disable=SC1090
  44. source ${CONFIG_FILE}
  45. fi
  46. CONTAINER_NAME=${CONTAINER_NAME:-pigen_work}
  47. CONTINUE=${CONTINUE:-0}
  48. PRESERVE_CONTAINER=${PRESERVE_CONTAINER:-0}
  49. PIGEN_DOCKER_OPTS=${PIGEN_DOCKER_OPTS:-""}
  50. if [ -z "${IMG_NAME}" ]; then
  51. echo "IMG_NAME not set in 'config'" 1>&2
  52. echo 1>&2
  53. exit 1
  54. fi
  55. # Ensure the Git Hash is recorded before entering the docker container
  56. GIT_HASH=${GIT_HASH:-"$(git rev-parse HEAD)"}
  57. CONTAINER_EXISTS=$(${DOCKER} ps -a --filter name="${CONTAINER_NAME}" -q)
  58. CONTAINER_RUNNING=$(${DOCKER} ps --filter name="${CONTAINER_NAME}" -q)
  59. if [ "${CONTAINER_RUNNING}" != "" ]; then
  60. echo "The build is already running in container ${CONTAINER_NAME}. Aborting."
  61. exit 1
  62. fi
  63. if [ "${CONTAINER_EXISTS}" != "" ] && [ "${CONTINUE}" != "1" ]; then
  64. echo "Container ${CONTAINER_NAME} already exists and you did not specify CONTINUE=1. Aborting."
  65. echo "You can delete the existing container like this:"
  66. echo " ${DOCKER} rm -v ${CONTAINER_NAME}"
  67. exit 1
  68. fi
  69. # Modify original build-options to allow config file to be mounted in the docker container
  70. BUILD_OPTS="$(echo "${BUILD_OPTS:-}" | sed -E 's@\-c\s?([^ ]+)@-c /config@')"
  71. ${DOCKER} build --build-arg BASE_IMAGE=debian:bullseye -t pi-gen "${DIR}"
  72. if [ "${CONTAINER_EXISTS}" != "" ]; then
  73. DOCKER_CMDLINE_NAME="${CONTAINER_NAME}_cont"
  74. DOCKER_CMDLINE_PRE="--rm"
  75. DOCKER_CMDLINE_POST="--volumes-from=\"${CONTAINER_NAME}\""
  76. else
  77. DOCKER_CMDLINE_NAME="${CONTAINER_NAME}"
  78. DOCKER_CMDLINE_PRE=""
  79. DOCKER_CMDLINE_POST=""
  80. fi
  81. # Check if binfmt_misc is required
  82. binfmt_misc_required=1
  83. case $(uname -m) in
  84. aarch64)
  85. binfmt_misc_required=0
  86. ;;
  87. arm*)
  88. binfmt_misc_required=0
  89. ;;
  90. esac
  91. # Check if qemu-aarch64-static and /proc/sys/fs/binfmt_misc are present
  92. if [[ "${binfmt_misc_required}" == "1" ]]; then
  93. if ! qemu_arm=$(which qemu-aarch64-static) ; then
  94. echo "qemu-aarch64-static not found (please install qemu-user-static)"
  95. exit 1
  96. fi
  97. if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
  98. echo "binfmt_misc required but not mounted, trying to mount it..."
  99. if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc ; then
  100. echo "mounting binfmt_misc failed"
  101. exit 1
  102. fi
  103. echo "binfmt_misc mounted"
  104. fi
  105. if ! grep -q "^interpreter ${qemu_arm}" /proc/sys/fs/binfmt_misc/qemu-aarch64* ; then
  106. # Register qemu-aarch64 for binfmt_misc
  107. reg="echo ':qemu-aarch64-rpi:M::"\
  108. "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:"\
  109. "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:"\
  110. "${qemu_arm}:F' > /proc/sys/fs/binfmt_misc/register"
  111. echo "Registering qemu-aarch64 for binfmt_misc..."
  112. sudo bash -c "${reg}" 2>/dev/null || true
  113. fi
  114. fi
  115. trap 'echo "got CTRL+C... please wait 5s" && ${DOCKER} stop -t 5 ${DOCKER_CMDLINE_NAME}' SIGINT SIGTERM
  116. time ${DOCKER} run \
  117. $DOCKER_CMDLINE_PRE \
  118. --name "${DOCKER_CMDLINE_NAME}" \
  119. --privileged \
  120. --cap-add=ALL \
  121. -v /dev:/dev \
  122. -v /lib/modules:/lib/modules \
  123. ${PIGEN_DOCKER_OPTS} \
  124. --volume "${CONFIG_FILE}":/config:ro \
  125. -e "GIT_HASH=${GIT_HASH}" \
  126. $DOCKER_CMDLINE_POST \
  127. pi-gen \
  128. bash -e -o pipefail -c "
  129. dpkg-reconfigure qemu-user-static &&
  130. # binfmt_misc is sometimes not mounted with debian bullseye image
  131. (mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc || true) &&
  132. cd /pi-gen; ./build.sh ${BUILD_OPTS} &&
  133. rsync -av work/*/build.log deploy/
  134. " &
  135. wait "$!"
  136. # Ensure that deploy/ is always owned by calling user
  137. echo "copying results from deploy/"
  138. ${DOCKER} cp "${CONTAINER_NAME}":/pi-gen/deploy - | tar -xf -
  139. echo "copying log from container ${CONTAINER_NAME} to depoy/"
  140. ${DOCKER} logs --timestamps "${CONTAINER_NAME}" &>deploy/build-docker.log
  141. ls -lah deploy
  142. # cleanup
  143. if [ "${PRESERVE_CONTAINER}" != "1" ]; then
  144. ${DOCKER} rm -v "${CONTAINER_NAME}"
  145. fi
  146. echo "Done! Your image(s) should be in deploy/"