b88ea929b0
* fix image name generation * add logging directory and direct output to files there removed linked mount in try script as btrfs does not create volume directories (bind mount only now) move packages and init into separate directories to keep cache separate fix some minor bugs
275 lines
No EOL
6.9 KiB
Bash
Executable file
275 lines
No EOL
6.9 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
docker_image_build () {
|
|
|
|
local targets=(dev arm amd deploy private multi)
|
|
local verbose; local scripts_dir; local log_dir;
|
|
declare OPTION; declare OPTARG; declare OPTIND
|
|
|
|
SDIR=$(pwd)
|
|
BDIR=$(dirname "$(realpath "$BASH_SOURCE")")
|
|
export SDIR
|
|
export BDIR
|
|
pushd $BDIR > /dev/null
|
|
|
|
source $BDIR/lib/load.sh
|
|
|
|
case "$1" in
|
|
try)
|
|
shift 1
|
|
popd > /dev/null || return 2
|
|
try_container "$@"
|
|
return $?
|
|
;;
|
|
image_name)
|
|
shift 1
|
|
image_name "$@"
|
|
return $?
|
|
;;
|
|
tag)
|
|
shift 1
|
|
image_tag "$@"
|
|
return $?
|
|
;;
|
|
push)
|
|
shift 1
|
|
image_push "$@"
|
|
return $?
|
|
;;
|
|
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
|
|
|
|
exit_abnormal() { # Function: Exit with error.
|
|
usage
|
|
return ${1:-1}
|
|
}
|
|
|
|
scripts_dir=$SDIR/src
|
|
# TODO allow log directory option
|
|
log_dir=$SDIR/logs
|
|
mkdir -p $log_dir
|
|
[[ -z "$PS1" ]] || no_prompt=true
|
|
overwrite=true
|
|
target=dev
|
|
|
|
while getopts 'g:e:b:d:t:ncr:u:pxhs:w:akvoi' OPTION; do
|
|
# echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
|
|
case "$OPTION" in
|
|
e)
|
|
local efile=$SDIR/$OPTARG
|
|
if [[ -f $efile ]]; then
|
|
source "$efile"
|
|
[[ ! $? -eq 0 ]] && echo source of $efile failed, exiting && return 2
|
|
else
|
|
echo no environment file at $efile, exiting
|
|
return 2
|
|
fi
|
|
echo "----------"
|
|
echo loaded environment filen $efile
|
|
cat $efile
|
|
echo "----------"
|
|
;;
|
|
o)
|
|
unset overwrite
|
|
;;
|
|
v)
|
|
verbose=true
|
|
;;
|
|
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)
|
|
BUILD_DIR=$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)
|
|
target=$OPTARG
|
|
;;
|
|
g)
|
|
TAG=$OPTARG
|
|
;;
|
|
u)
|
|
RUSER=$OPTARG
|
|
;;
|
|
c)
|
|
try=true
|
|
;;
|
|
p)
|
|
push=true
|
|
;;
|
|
n)
|
|
nocache="--no-cache"
|
|
;;
|
|
r)
|
|
REPO=$OPTARG
|
|
;;
|
|
h)
|
|
exit_abnormal 0
|
|
return 0
|
|
;;
|
|
*)
|
|
echo "unknown $0 option -$OPTARG"
|
|
exit_abnormal 4
|
|
;;
|
|
esac
|
|
done
|
|
|
|
shift $((OPTIND - 1))
|
|
|
|
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
|
|
|
|
[[ ! "${targets[@]}" =~ $target ]] && echo $target is not a valid target && echo valid targets are: ${targets[@]} && exit 4
|
|
|
|
LINUX_DISTRO=${LINUX_DISTRO:-alpine}
|
|
|
|
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
|
|
|
|
name=$1
|
|
RUSER=${2:-$RUSER}
|
|
|
|
IMAGE_NAME=$([[ $RUSER ]] && echo ${RUSER}/)${name}$([[ ! $exclude_distro ]] && echo -${LINUX_DISTRO})
|
|
# TODO writing to existing tag untags existing image so write a new tag to that image then continue
|
|
|
|
# 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')
|
|
echo image exists retaging $(image_name $IMAGE_NAME) with tag :$newtag
|
|
image_tag $IMAGE_NAME $IMAGE_NAME:$newtag
|
|
image_tag -r $IMAGE_NAME
|
|
fi
|
|
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 BUILD_DIR
|
|
export KEEP
|
|
export SYSADMIN_PW
|
|
export BUST_INIT_CACHE
|
|
|
|
echo "******************************************"
|
|
echo "Building with base image: $BASE_IMAGE"
|
|
echo "Outputing to image name => $IMAGE_NAME<-arch>:${TAG:-latest}"
|
|
echo "Linux Distro: $LINUX_DISTRO"
|
|
echo "Using build target: $target"
|
|
echo "Build Command: docker buildx --builder ${builder} bake ${nocache} ${target}"
|
|
if [[ $verbose ]]; then
|
|
echo -e "\n---------------------------------"
|
|
docker buildx bake --print $target
|
|
echo -e "\n---------------------------------"
|
|
echo "build scripts at $scripts_dir to be copied to ${BUILD_DIR:-/build} in container ***** "
|
|
ls -la $scripts_dir
|
|
echo -e "\n----- base init script init.sh ------"
|
|
cat $scripts_dir/init.sh
|
|
echo -e "\n---------------------------------"
|
|
fi
|
|
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
|
|
|
|
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
|
|
|
|
# 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
|
|
|
|
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
|
|
|
|
rm -rf $BDIR/.src
|
|
|
|
# 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
|
|
|
|
popd > /dev/null
|
|
|
|
if [[ ($try || $target == "dev") ]] && [[ ! $no_prompt ]]; then
|
|
echo trying newly built image in a container
|
|
try_container -m opt $([[ $target == "deploy" ]] && echo -p) $IMAGE_NAME
|
|
fi
|
|
|
|
#echo reset to calling directory $PWD
|
|
|
|
}
|
|
|
|
# if script was executed then call the function
|
|
(return 0 2>/dev/null) || docker_image_build $@ |