Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability for build-docker.sh to externalize build steps and configuration #507

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ RUN apt-get -y update && \
quilt coreutils qemu-user-static debootstrap zerofree zip dosfstools \
bsdtar libcap2-bin rsync grep udev xz-utils curl xxd file kmod bc\
binfmt-support ca-certificates qemu-utils kpartx \
wpasupplicant \
&& rm -rf /var/lib/apt/lists/*

COPY . /pi-gen/
Expand Down
105 changes: 89 additions & 16 deletions build-docker.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash -eu

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"

BUILD_OPTS="$*"

Expand All @@ -20,39 +20,108 @@ if [ -f "${DIR}/config" ]; then
CONFIG_FILE="${DIR}/config"
fi

while getopts "c:" flag
do
while getopts "c:" flag; do
case "${flag}" in
c)
CONFIG_FILE="${OPTARG}"
;;
*)
;;
c)
CONFIG_FILE="${OPTARG}"
;;
*) ;;

esac
done

# Ability to pass in name=value pairs that will be available to config
# as well as sent to the docker run command as environment variables.
# This is so we can use command line arguments (or workflow secrets)
# to build a ready-to-use image without mucking around with saved configs
# and thus expose private information

# Process from command-line
CMDLINE_ENV=()

# Get rest of unparsed arguments
shift $(expr $OPTIND - 1)

# Append to our array
while test $# -gt 0; do
CMDLINE_ENV+=($1)
shift
done

# Either way, we may have some key=value pairs now
# parse and export them so config can get them
echo "Exporting command-line environment variables..."
while IFS='=' read -r name value; do

# Handle double-quoted ("...") values.
if [[ $value =~ ^\"(.*)\"$ ]]; then
# Using `read` without `-r` removes the \ from embedded \<char> sequences.
IFS= read value <<<"${BASH_REMATCH[1]}"
fi

# Export so config can access these values
export "${name}=${value}"
done <<<$(
IFS=$'\n'
echo "${CMDLINE_ENV[*]}"
)

# 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"
echo "Configuration file needs to be present in '${DIR}/config', or path passed as parameter with -c"
exit 1
else
# shellcheck disable=SC1090
source ${CONFIG_FILE}
fi

# Concatenate any command line env to DOCKER_ADDL_ENV
export DOCKER_ADDL_ENV+=("${CMDLINE_ENV[@]}")

# Convert additional env into docker format
# so we can pass it to docker run
ADDL_ENV=""
echo "Processing additional environment for docker run..."
while IFS='=' read -r name value; do
# Handle double-quoted ("...") values.
if [[ $value =~ ^\"(.*)\"$ ]]; then
# Using `read` without `-r` removes the \ from embedded \<char> sequences.
IFS= read value <<<"${BASH_REMATCH[1]}"
fi
# Append to a string in docker env format
ADDL_ENV="${ADDL_ENV} -e ${name}=${value}"
done <<<$(
IFS=$'\n'
echo "${DOCKER_ADDL_ENV[*]}"
)

# Ability to add additional mounts so that custom stages can be mounted into the build process
# without modifying the pi-gen repository
# Note: Mounts cannot be passed in via the command line
ADDL_MOUNTS=""
if [[ ! -z ${DOCKER_ADDL_MOUNTS:=""} ]]; then
echo "Processing additional mounts for docker run..."
while IFS=' ' read -r mount; do
ADDL_MOUNTS="${ADDL_MOUNTS} -v ${mount}"
done <<<$(
IFS=$'\n'
echo "${DOCKER_ADDL_MOUNTS[*]}"
)
fi

CONTAINER_NAME=${CONTAINER_NAME:-pigen_work}
CONTINUE=${CONTINUE:-0}
PRESERVE_CONTAINER=${PRESERVE_CONTAINER:-0}

if [ -z "${IMG_NAME}" ]; then
echo "IMG_NAME not set in 'config'" 1>&2
echo 1>&2
exit 1
exit 1
fi

# Ensure the Git Hash is recorded before entering the docker container
Expand All @@ -76,12 +145,12 @@ 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:buster
;;
*)
BASE_IMAGE=debian:buster
;;
x86_64 | aarch64)
BASE_IMAGE=i386/debian:buster
;;
*)
BASE_IMAGE=debian:buster
;;
esac
${DOCKER} build --build-arg BASE_IMAGE=${BASE_IMAGE} -t pi-gen "${DIR}"

Expand All @@ -92,6 +161,8 @@ if [ "${CONTAINER_EXISTS}" != "" ]; then
-v /dev:/dev \
-v /lib/modules:/lib/modules \
--volume "${CONFIG_FILE}":/config:ro \
${ADDL_MOUNTS} \
${ADDL_ENV} \
-e "GIT_HASH=${GIT_HASH}" \
--volumes-from="${CONTAINER_NAME}" --name "${CONTAINER_NAME}_cont" \
pi-gen \
Expand All @@ -106,6 +177,8 @@ else
-v /dev:/dev \
-v /lib/modules:/lib/modules \
--volume "${CONFIG_FILE}":/config:ro \
${ADDL_MOUNTS} \
${ADDL_ENV} \
-e "GIT_HASH=${GIT_HASH}" \
pi-gen \
bash -e -o pipefail -c "dpkg-reconfigure qemu-user-static &&
Expand Down