You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

172 lines
4.8 KiB

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