2022-10-20 18:48:17 -07:00
|
|
|
#!/bin/bash
|
2023-01-17 15:20:30 -08:00
|
|
|
|
|
|
|
docker_image_build () {
|
|
|
|
|
|
|
|
local targets=(dev arm amd deploy private multi)
|
2023-03-22 09:10:54 -07:00
|
|
|
local verbose; local scripts_dir; local log_dir;
|
2022-10-20 18:48:17 -07:00
|
|
|
declare OPTION; declare OPTARG; declare OPTIND
|
2022-10-22 08:23:16 -07:00
|
|
|
|
2023-01-17 11:53:24 -08:00
|
|
|
SDIR=$(pwd)
|
2023-01-17 15:20:30 -08:00
|
|
|
BDIR=$(dirname "$(realpath "$BASH_SOURCE")")
|
2023-01-22 15:02:36 -08:00
|
|
|
export SDIR
|
|
|
|
export BDIR
|
2023-01-17 11:53:24 -08:00
|
|
|
pushd $BDIR > /dev/null
|
|
|
|
|
2023-01-17 15:20:30 -08:00
|
|
|
source $BDIR/lib/load.sh
|
2023-01-17 11:53:24 -08:00
|
|
|
|
2023-01-17 15:20:30 -08:00
|
|
|
case "$1" in
|
2023-03-22 09:10:54 -07:00
|
|
|
try)
|
|
|
|
shift 1
|
|
|
|
popd > /dev/null || return 2
|
|
|
|
try_container "$@"
|
|
|
|
return $?
|
|
|
|
;;
|
2023-01-22 15:02:36 -08:00
|
|
|
image_name)
|
2023-01-17 15:20:30 -08:00
|
|
|
shift 1
|
2023-01-22 15:02:36 -08:00
|
|
|
image_name "$@"
|
2023-01-17 15:20:30 -08:00
|
|
|
return $?
|
|
|
|
;;
|
|
|
|
tag)
|
|
|
|
shift 1
|
|
|
|
image_tag "$@"
|
|
|
|
return $?
|
|
|
|
;;
|
2023-01-22 15:02:36 -08:00
|
|
|
push)
|
|
|
|
shift 1
|
|
|
|
image_push "$@"
|
|
|
|
return $?
|
|
|
|
;;
|
2023-01-17 15:20:30 -08:00
|
|
|
info)
|
|
|
|
shift 1
|
|
|
|
[[ $1 == "arch" ]] && { shift 1; image_arch "$@"; return $?; }
|
|
|
|
[[ $1 == "exists" ]] && { shift 1; image_exists "$@"; return $?; }
|
|
|
|
[[ $1 == "id" ]] && { shift 1; image_id "$@"; return $?; }
|
|
|
|
image_info "$@"; return $?
|
|
|
|
;;
|
|
|
|
esac
|
2022-10-22 08:23:16 -07:00
|
|
|
|
|
|
|
exit_abnormal() { # Function: Exit with error.
|
|
|
|
usage
|
2023-01-17 15:20:30 -08:00
|
|
|
return ${1:-1}
|
2022-10-22 08:23:16 -07:00
|
|
|
}
|
|
|
|
|
2023-01-17 11:53:24 -08:00
|
|
|
scripts_dir=$SDIR/src
|
2023-03-22 09:10:54 -07:00
|
|
|
# TODO allow log directory option
|
|
|
|
log_dir=$SDIR/logs
|
|
|
|
mkdir -p $log_dir
|
2023-01-17 15:20:30 -08:00
|
|
|
[[ -z "$PS1" ]] || no_prompt=true
|
2023-01-22 15:02:36 -08:00
|
|
|
overwrite=true
|
|
|
|
target=dev
|
2022-10-22 08:23:16 -07:00
|
|
|
|
2023-01-22 15:02:36 -08:00
|
|
|
while getopts 'g:e:b:d:t:ncr:u:pxhs:w:akvoi' OPTION; do
|
2022-10-22 08:23:16 -07:00
|
|
|
# echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
|
|
|
|
case "$OPTION" in
|
2023-01-22 15:02:36 -08:00
|
|
|
e)
|
2023-03-22 09:10:54 -07:00
|
|
|
local efile=$SDIR/$OPTARG
|
|
|
|
if [[ -f $efile ]]; then
|
|
|
|
source "$efile"
|
|
|
|
[[ ! $? -eq 0 ]] && echo source of $efile failed, exiting && return 2
|
2023-01-22 15:02:36 -08:00
|
|
|
else
|
2023-03-22 09:10:54 -07:00
|
|
|
echo no environment file at $efile, exiting
|
2023-01-22 15:02:36 -08:00
|
|
|
return 2
|
|
|
|
fi
|
|
|
|
echo "----------"
|
2023-03-22 09:10:54 -07:00
|
|
|
echo loaded environment filen $efile
|
|
|
|
cat $efile
|
2023-01-22 15:02:36 -08:00
|
|
|
echo "----------"
|
|
|
|
;;
|
2023-01-17 15:20:30 -08:00
|
|
|
o)
|
2023-01-22 15:02:36 -08:00
|
|
|
unset overwrite
|
2023-01-17 15:20:30 -08:00
|
|
|
;;
|
|
|
|
v)
|
|
|
|
verbose=true
|
|
|
|
;;
|
2023-01-17 11:53:24 -08:00
|
|
|
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)
|
2023-01-22 15:02:36 -08:00
|
|
|
BUILD_DIR=$OPTARG
|
2023-01-17 11:53:24 -08:00
|
|
|
;;
|
2022-10-22 08:23:16 -07:00
|
|
|
b)
|
|
|
|
# CUSTOM BASE IMAGE
|
|
|
|
BASE_IMAGE=$OPTARG
|
2022-10-20 18:48:17 -07:00
|
|
|
;;
|
2023-01-17 11:53:24 -08:00
|
|
|
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
|
|
|
|
;;
|
2022-10-22 08:23:16 -07:00
|
|
|
d)
|
2023-01-17 11:53:24 -08:00
|
|
|
# LINUX_DISTRO=$OPTARG
|
2022-10-22 08:23:16 -07:00
|
|
|
LINUX_DISTRO=$OPTARG
|
2022-10-20 18:48:17 -07:00
|
|
|
;;
|
2022-10-22 08:23:16 -07:00
|
|
|
x)
|
|
|
|
# Exclude distro from image name
|
|
|
|
exclude_distro=true
|
2022-10-20 18:48:17 -07:00
|
|
|
;;
|
2022-10-22 08:23:16 -07:00
|
|
|
t)
|
2023-01-22 15:02:36 -08:00
|
|
|
target=$OPTARG
|
|
|
|
;;
|
|
|
|
g)
|
2022-10-22 08:23:16 -07:00
|
|
|
TAG=$OPTARG
|
|
|
|
;;
|
|
|
|
u)
|
|
|
|
RUSER=$OPTARG
|
|
|
|
;;
|
|
|
|
c)
|
|
|
|
try=true
|
|
|
|
;;
|
|
|
|
p)
|
|
|
|
push=true
|
|
|
|
;;
|
|
|
|
n)
|
|
|
|
nocache="--no-cache"
|
|
|
|
;;
|
|
|
|
r)
|
|
|
|
REPO=$OPTARG
|
|
|
|
;;
|
|
|
|
h)
|
|
|
|
exit_abnormal 0
|
2023-01-17 15:42:56 -08:00
|
|
|
return 0
|
2022-10-22 08:23:16 -07:00
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "unknown $0 option -$OPTARG"
|
|
|
|
exit_abnormal 4
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
2022-10-20 18:48:17 -07:00
|
|
|
|
2022-10-22 08:23:16 -07:00
|
|
|
shift $((OPTIND - 1))
|
2022-10-20 18:48:17 -07:00
|
|
|
|
2023-01-21 22:41:14 -08:00
|
|
|
if [[ ! -d $scripts_dir ]]; then
|
|
|
|
if [[ ! $no_prompt ]]; then
|
|
|
|
echo -e "\e[1;31mWARNING: build scripts directory$scripts_dir does not exist.\e[1;37m"
|
|
|
|
echo "Do you want to use the base scripts"
|
|
|
|
read -n 1 -p "directory at $BDIR/src? to continue [y]=>" REPLY
|
|
|
|
[[ $REPLY != "y" ]] && echo -e "\n" && return 0
|
|
|
|
echo
|
|
|
|
fi
|
|
|
|
echo -e "\e[1;31mscripts directory $scripts_dir was not found using base build scripts at $BDIR/src\e[1;37m"
|
|
|
|
scripts_dir=$BDIR/src
|
|
|
|
fi
|
|
|
|
|
2023-01-22 15:02:36 -08:00
|
|
|
[[ ! "${targets[@]}" =~ $target ]] && echo $target is not a valid target && echo valid targets are: ${targets[@]} && exit 4
|
|
|
|
|
2022-10-20 18:48:17 -07:00
|
|
|
LINUX_DISTRO=${LINUX_DISTRO:-alpine}
|
2023-03-22 09:10:54 -07:00
|
|
|
|
|
|
|
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
|
|
|
|
echo $BASE_IMAGE is built from distro $LINUX_DISTRO
|
|
|
|
else
|
|
|
|
BASE_IMAGE=$LINUX_DISTRO
|
|
|
|
fi
|
|
|
|
|
2023-01-22 15:02:36 -08:00
|
|
|
name=$1
|
|
|
|
RUSER=${2:-$RUSER}
|
2022-10-20 18:48:17 -07:00
|
|
|
|
2023-03-22 09:10:54 -07:00
|
|
|
IMAGE_NAME=$([[ $RUSER ]] && echo ${RUSER}/)${name}$([[ ! $exclude_distro ]] && echo -${LINUX_DISTRO})
|
2023-01-17 15:20:30 -08:00
|
|
|
# TODO writing to existing tag untags existing image so write a new tag to that image then continue
|
2023-01-21 22:41:14 -08:00
|
|
|
|
|
|
|
# retag existing image and remove former tag
|
|
|
|
if [[ $(image_exists $IMAGE_NAME) ]]; then
|
|
|
|
if [[ $overwrite ]]; then
|
|
|
|
image_delete $IMAGE_NAME
|
|
|
|
else
|
|
|
|
newtag=$(date +'%d%H%M%S')
|
2023-01-22 15:02:36 -08:00
|
|
|
echo image exists retaging $(image_name $IMAGE_NAME) with tag :$newtag
|
2023-01-21 22:41:14 -08:00
|
|
|
image_tag $IMAGE_NAME $IMAGE_NAME:$newtag
|
|
|
|
image_tag -r $IMAGE_NAME
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2022-10-20 18:48:17 -07:00
|
|
|
# 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
|
2023-01-22 15:02:36 -08:00
|
|
|
export BUILD_DIR
|
2023-01-17 11:53:24 -08:00
|
|
|
export KEEP
|
2023-01-21 22:41:14 -08:00
|
|
|
export SYSADMIN_PW
|
|
|
|
export BUST_INIT_CACHE
|
2022-10-20 18:48:17 -07:00
|
|
|
|
2023-01-17 15:20:30 -08:00
|
|
|
echo "******************************************"
|
|
|
|
echo "Building with base image: $BASE_IMAGE"
|
2023-01-22 15:02:36 -08:00
|
|
|
echo "Outputing to image name => $IMAGE_NAME<-arch>:${TAG:-latest}"
|
2022-10-20 18:48:17 -07:00
|
|
|
echo "Linux Distro: $LINUX_DISTRO"
|
2023-01-17 11:53:24 -08:00
|
|
|
echo "Using build target: $target"
|
2023-03-22 09:10:54 -07:00
|
|
|
echo "Build Command: docker buildx --builder ${builder} bake ${nocache} ${target}"
|
2023-01-17 15:20:30 -08:00
|
|
|
if [[ $verbose ]]; then
|
|
|
|
echo -e "\n---------------------------------"
|
|
|
|
docker buildx bake --print $target
|
|
|
|
echo -e "\n---------------------------------"
|
2023-01-22 15:02:36 -08:00
|
|
|
echo "build scripts at $scripts_dir to be copied to ${BUILD_DIR:-/build} in container ***** "
|
2023-01-17 15:20:30 -08:00
|
|
|
ls -la $scripts_dir
|
|
|
|
echo -e "\n----- base init script init.sh ------"
|
|
|
|
cat $scripts_dir/init.sh
|
|
|
|
echo -e "\n---------------------------------"
|
|
|
|
fi
|
2023-01-17 11:53:24 -08:00
|
|
|
echo -e "\n***************************************"
|
2023-01-17 15:20:30 -08:00
|
|
|
|
2023-01-17 11:53:24 -08:00
|
|
|
if [[ ! $no_prompt ]]; then
|
|
|
|
read -n 1 -p "do you want to continue [y]=>" REPLY
|
|
|
|
[[ $REPLY != "y" ]] && echo -e "\n" && exit 0
|
|
|
|
fi
|
2022-10-20 18:48:17 -07:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2023-03-22 09:10:54 -07:00
|
|
|
# copy source directory to temporary .src/ subdirectory
|
|
|
|
# MUST either be readable by all or group readable by docker group
|
|
|
|
rm -rf $BDIR/.src
|
|
|
|
rsync -aAru ${scripts_dir:-src}/ $BDIR/.src
|
|
|
|
ls -la $BDIR/.src
|
2023-01-17 11:53:24 -08:00
|
|
|
|
2023-03-22 09:10:54 -07:00
|
|
|
docker buildx --builder ${builder} bake ${nocache} ${target} 2>&1 | tee "$log_dir/${IMAGE_NAME//\//-}build.log"
|
|
|
|
[[ $? == 0 ]] && echo succcess building image $IMAGE_NAME || exit_abnormal 1
|
2023-01-17 11:53:24 -08:00
|
|
|
|
2023-03-22 09:10:54 -07:00
|
|
|
rm -rf $BDIR/.src
|
2023-01-17 11:53:24 -08:00
|
|
|
|
2023-03-22 09:10:54 -07:00
|
|
|
# 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
|
2022-10-20 18:48:17 -07:00
|
|
|
|
2023-03-22 09:10:54 -07:00
|
|
|
popd > /dev/null
|
2022-10-20 18:48:17 -07:00
|
|
|
|
2023-01-17 15:20:30 -08:00
|
|
|
if [[ ($try || $target == "dev") ]] && [[ ! $no_prompt ]]; then
|
|
|
|
echo trying newly built image in a container
|
2023-01-21 22:41:14 -08:00
|
|
|
try_container -m opt $([[ $target == "deploy" ]] && echo -p) $IMAGE_NAME
|
2023-01-17 15:20:30 -08:00
|
|
|
fi
|
2023-01-17 11:53:24 -08:00
|
|
|
|
2023-01-17 15:20:30 -08:00
|
|
|
#echo reset to calling directory $PWD
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
# if script was executed then call the function
|
|
|
|
(return 0 2>/dev/null) || docker_image_build $@
|