uci-docker-build/build

192 lines
5.5 KiB
Bash
Executable File

#!/bin/bash
declare targets=(dev arm amd deploy private multi)
declare OPTION; declare OPTARG; declare OPTIND
SDIR=$(pwd)
BDIR=$(dirname "$(realpath "$0")")
pushd $BDIR > /dev/null
if [ $1 == "try" ]; then
./try $2 $SDIR
exit
fi
usage() { # Function: Print a help message.
echo "Image Build Script: Creates one or more images using a target in the docker-bake.hcl file"
echo "USAGE: $0 <setup options> buildtarget <imagename, imageuser>"
echo "valid targets: ${targets[*]}; default: dev"
echo no argument options:
echo "-c try out the image by starting a container terminal therein, for dev target this is the default;"
echo "-x exclude distro from image name;"
echo "-n for --no_cache"
echo "-p push to repository; after build push to repository default is hub.docker.common (not need for deploy target)"
echo required argument options:
echo "-d <LINUX_DISTRO> supported: alpine, debian, ubuntu, default: alpine; if base image set distro will be determined"
echo "-t <TAG> tag following : in output image name (i.e. REPO/USER/NAME:TAG), default: latest"
echo "-u <USER>; repository user prefix in output image name (i.e. REPO/USER/NAME:TAG)"
echo "-r <REPO>; private repo name, do not use for hub.docker.com (docker.io)"
echo "-b <BASE_IMAGE>; used in FROM in Dockerfile, default is official distro image (e.g. alpine:latest)"
echo "-w <SCRIPTS>; set a custom WORKDIR in Dockerfile, default is /opt/build"
}
exit_abnormal() { # Function: Exit with error.
usage
exit ${1:-1}
}
source $BDIR/helpers.lib
scripts_dir=$SDIR/src
while getopts ':b:d:t:ncr:u:pxhs:w:ak' OPTION; do
# echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
case "$OPTION" in
a)
# automated - script is to be run without prompt (non-interactive)
no_prompt=true
;;
k)
# keep the build scripts in the image, by default they are removed
KEEP=true
;;
w)
# the work directory to put the build scripts in container (default is /opt/build)
SCRIPTS=$OPTARG
;;
b)
# CUSTOM BASE IMAGE
BASE_IMAGE=$OPTARG
;;
s)
# scripts subdirectory from which to bind to scripts/, default is src/
if isAbsPath $OPTARG; then
scripts_dir=$OPTARG
elif [ "$OPTARG" == "_base_" ]; then
scripts_dir=$BDIR/src
else
scripts_dir=$SDIR/$OPTARG
fi
;;
d)
# LINUX_DISTRO=$OPTARG
LINUX_DISTRO=$OPTARG
;;
x)
# Exclude distro from image name
exclude_distro=true
;;
t)
TAG=$OPTARG
;;
u)
RUSER=$OPTARG
;;
c)
try=true
;;
p)
push=true
;;
n)
nocache="--no-cache"
;;
r)
REPO=$OPTARG
;;
h)
exit_abnormal 0
;;
*)
echo "unknown $0 option -$OPTARG"
exit_abnormal 4
;;
esac
done
shift $((OPTIND - 1))
target=${1:-dev}
LINUX_DISTRO=${LINUX_DISTRO:-alpine}
name=$2
RUSER=${3:-$RUSER}
IMAGE_NAME=$([[ $RUSER ]] && echo ${RUSER}/)${name}$([[ (! $exclude_distro) && $name ]] && echo "-")$([[ ! $exclude_distro ]] && echo ${LINUX_DISTRO})
if [[ $BASE_IMAGE ]]; then
echo determining DISTRO of base image: $BASE_IMAGE
LINUX_DISTRO=$(get_distro -d $BASE_IMAGE)
[[ ! $LINUX_DISTRO ]] && echo "unable to get base image OS for: $BASE_IMAGE, aborting build" && exit 1
else
BASE_IMAGE=$LINUX_DISTRO
fi
# BASE_IMAGE=$([[ $BASE_IMAGE == *:* ]] && echo $BASE_IMAGE || echo $BASE_IMAGE:latest)
#$([[ ! $BASE_IMAGE == *:* ]] && echo :latest)
export BASE_IMAGE
export TAG
export IMAGE_NAME
export LINUX_DISTRO
export SCRIPTS
export KEEP
echo " ******************************************"
echo "Building with base image: $BASE_IMAGE, output image name => $IMAGE_NAME"
echo "Linux Distro: $LINUX_DISTRO"
echo "Using build target: $target"
docker buildx bake --print $target
echo -e "\n---------------------------------"
echo "build scripts at $scripts_dir to be copied to ${SCRIPTS:-/opt/build} in container ***** "
ls -la $scripts_dir
echo -e "\n----- base init script init.sh ------"
cat $scripts_dir/init.sh
echo -e "\n---------------------------------"
echo -e "\n***************************************"
if [[ ! $no_prompt ]]; then
read -n 1 -p "do you want to continue [y]=>" REPLY
[[ $REPLY != "y" ]] && echo -e "\n" && exit 0
fi
[[ ! "${targets[@]}" =~ $target ]] && echo $target is not a valid target && echo valid targets are: ${targets[@]} && exit 4
builder=default
if [ $target == "deploy" ]; then
builder=deploy
if ! docker buildx ls | grep -q deploy ; then
echo multiarch deploy builder does not exist, creating with docker-container driver
docker buildx create --name deploy --driver docker-container >/dev/null
docker buildx ls | grep deploy
fi
fi
[[ $target == "private" && ! $REPO ]] && echo "must use '-r <private repo>' if building to private repo" && exit 3
# mount source directory to temporary .src/ subdirectory
fusermount -u .src > /dev/null 2>&1
mkdir .src
bindfs ${scripts_dir:-src} .src
docker buildx --builder ${builder} bake ${nocache} ${target} 2>&1 | tee build.log
fusermount -u .src > /dev/null 2>&1
rm -rf .src/
[[ $? == 0 ]] && echo succcess building image $IMAGE_NAME || exit_abnormal 1
if [[ $target == "private" ]]; then
./push -a -r $REPO $IMAGE_NAME
./push -r $REPO $IMAGE_NAME
else
if [[ $push && (! $target == "dev") ]];then
echo pushing now
./push $([[ $target == "arm" ]] && echo -a) -r $REPO $IMAGE_NAME
fi
fi
[[ ($try || $target == "dev") ]] && ./try $([[ $target == "deploy" ]] && echo -p) $IMAGE_NAME
popd > /dev/null
#echo reset to calling directory $PWD