mirror of https://github.com/RPi-Distro/pi-gen
Mirror of https://github.com/RPi-Distro/pi-gen
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.
175 lines
5.0 KiB
175 lines
5.0 KiB
#!/usr/bin/env bash |
|
# Note: Avoid usage of arrays as MacOS users have an older version of bash (v3.x) which does not supports arrays |
|
set -eu |
|
|
|
DIR="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)" |
|
|
|
BUILD_OPTS="$*" |
|
|
|
# Allow user to override docker command |
|
DOCKER=${DOCKER:-docker} |
|
|
|
# Ensure that default docker command is not set up in rootless mode |
|
if \ |
|
! ${DOCKER} ps >/dev/null 2>&1 || \ |
|
${DOCKER} info 2>/dev/null | grep -q rootless \ |
|
; then |
|
DOCKER="sudo ${DOCKER}" |
|
fi |
|
if ! ${DOCKER} ps >/dev/null; then |
|
echo "error connecting to docker:" |
|
${DOCKER} ps |
|
exit 1 |
|
fi |
|
|
|
CONFIG_FILE="" |
|
if [ -f "${DIR}/config" ]; then |
|
CONFIG_FILE="${DIR}/config" |
|
fi |
|
|
|
while getopts "c:" flag |
|
do |
|
case "${flag}" in |
|
c) |
|
CONFIG_FILE="${OPTARG}" |
|
;; |
|
*) |
|
;; |
|
esac |
|
done |
|
|
|
# Ensure that the configuration file is an absolute path |
|
if test -x /usr/bin/realpath; then |
|
CONFIG_FILE=$(realpath -s "$CONFIG_FILE" || realpath "$CONFIG_FILE") |
|
fi |
|
|
|
# Ensure that the confguration file is present |
|
if test -z "${CONFIG_FILE}"; then |
|
echo "Configuration file need to be present in '${DIR}/config' or path passed as parameter" |
|
exit 1 |
|
else |
|
# shellcheck disable=SC1090 |
|
source ${CONFIG_FILE} |
|
fi |
|
|
|
CONTAINER_NAME=${CONTAINER_NAME:-pigen_work} |
|
CONTINUE=${CONTINUE:-0} |
|
PRESERVE_CONTAINER=${PRESERVE_CONTAINER:-0} |
|
PIGEN_DOCKER_OPTS=${PIGEN_DOCKER_OPTS:-""} |
|
|
|
if [ -z "${IMG_NAME}" ]; then |
|
echo "IMG_NAME not set in 'config'" 1>&2 |
|
echo 1>&2 |
|
exit 1 |
|
fi |
|
|
|
# Ensure the Git Hash is recorded before entering the docker container |
|
GIT_HASH=${GIT_HASH:-"$(git rev-parse HEAD)"} |
|
|
|
CONTAINER_EXISTS=$(${DOCKER} ps -a --filter name="${CONTAINER_NAME}" -q) |
|
CONTAINER_RUNNING=$(${DOCKER} ps --filter name="${CONTAINER_NAME}" -q) |
|
if [ "${CONTAINER_RUNNING}" != "" ]; then |
|
echo "The build is already running in container ${CONTAINER_NAME}. Aborting." |
|
exit 1 |
|
fi |
|
if [ "${CONTAINER_EXISTS}" != "" ] && [ "${CONTINUE}" != "1" ]; then |
|
echo "Container ${CONTAINER_NAME} already exists and you did not specify CONTINUE=1. Aborting." |
|
echo "You can delete the existing container like this:" |
|
echo " ${DOCKER} rm -v ${CONTAINER_NAME}" |
|
exit 1 |
|
fi |
|
|
|
# Modify original build-options to allow config file to be mounted in the docker container |
|
BUILD_OPTS="$(echo "${BUILD_OPTS:-}" | sed -E 's@\-c\s?([^ ]+)@-c /config@')" |
|
|
|
# Check the arch of the machine we're running on. If it's 64-bit, use a 32-bit base image instead |
|
case "$(uname -m)" in |
|
x86_64|aarch64) |
|
BASE_IMAGE=i386/debian:bullseye |
|
;; |
|
*) |
|
BASE_IMAGE=debian:bullseye |
|
;; |
|
esac |
|
${DOCKER} build --build-arg BASE_IMAGE=${BASE_IMAGE} -t pi-gen "${DIR}" |
|
|
|
if [ "${CONTAINER_EXISTS}" != "" ]; then |
|
DOCKER_CMDLINE_NAME="${CONTAINER_NAME}_cont" |
|
DOCKER_CMDLINE_PRE="--rm" |
|
DOCKER_CMDLINE_POST="--volumes-from=${CONTAINER_NAME}" |
|
else |
|
DOCKER_CMDLINE_NAME="${CONTAINER_NAME}" |
|
DOCKER_CMDLINE_PRE="" |
|
DOCKER_CMDLINE_POST="" |
|
fi |
|
|
|
# Check if binfmt_misc is required |
|
binfmt_misc_required=1 |
|
case $(uname -m) in |
|
aarch64) |
|
binfmt_misc_required=0 |
|
;; |
|
arm*) |
|
binfmt_misc_required=0 |
|
;; |
|
esac |
|
|
|
# Check if qemu-arm-static and /proc/sys/fs/binfmt_misc are present |
|
if [[ "${binfmt_misc_required}" == "1" ]]; then |
|
if ! qemu_arm=$(which qemu-arm-static) ; then |
|
echo "qemu-arm-static not found (please install qemu-user-static)" |
|
exit 1 |
|
fi |
|
if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then |
|
echo "binfmt_misc required but not mounted, trying to mount it..." |
|
if ! mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc ; then |
|
echo "mounting binfmt_misc failed" |
|
exit 1 |
|
fi |
|
echo "binfmt_misc mounted" |
|
fi |
|
if ! grep -q "^interpreter ${qemu_arm}" /proc/sys/fs/binfmt_misc/qemu-arm* ; then |
|
# Register qemu-arm for binfmt_misc |
|
reg="echo ':qemu-arm-rpi:M::"\ |
|
"\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:"\ |
|
"\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:"\ |
|
"${qemu_arm}:F' > /proc/sys/fs/binfmt_misc/register" |
|
echo "Registering qemu-arm for binfmt_misc..." |
|
sudo bash -c "${reg}" 2>/dev/null || true |
|
fi |
|
fi |
|
|
|
trap 'echo "got CTRL+C... please wait 5s" && ${DOCKER} stop -t 5 ${DOCKER_CMDLINE_NAME}' SIGINT SIGTERM |
|
time ${DOCKER} run \ |
|
$DOCKER_CMDLINE_PRE \ |
|
--name "${DOCKER_CMDLINE_NAME}" \ |
|
--privileged \ |
|
${PIGEN_DOCKER_OPTS} \ |
|
--volume "${CONFIG_FILE}":/config:ro \ |
|
-e "GIT_HASH=${GIT_HASH}" \ |
|
$DOCKER_CMDLINE_POST \ |
|
pi-gen \ |
|
bash -e -o pipefail -c " |
|
dpkg-reconfigure qemu-user-static && |
|
# binfmt_misc is sometimes not mounted with debian bullseye image |
|
(mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc || true) && |
|
cd /pi-gen; ./build.sh ${BUILD_OPTS} && |
|
rsync -av work/*/build.log deploy/ |
|
" & |
|
wait "$!" |
|
|
|
# Ensure that deploy/ is always owned by calling user |
|
echo "copying results from deploy/" |
|
${DOCKER} cp "${CONTAINER_NAME}":/pi-gen/deploy - | tar -xf - |
|
|
|
echo "copying log from container ${CONTAINER_NAME} to deploy/" |
|
${DOCKER} logs --timestamps "${CONTAINER_NAME}" &>deploy/build-docker.log |
|
|
|
ls -lah deploy |
|
|
|
# cleanup |
|
if [ "${PRESERVE_CONTAINER}" != "1" ]; then |
|
${DOCKER} rm -v "${CONTAINER_NAME}" |
|
fi |
|
|
|
echo "Done! Your image(s) should be in deploy/"
|
|
|