2022-10-20 18:48:17 -07:00
|
|
|
#!/bin/bash
|
2023-01-17 15:20:30 -08:00
|
|
|
|
2023-04-14 21:27:40 -07:00
|
|
|
udbuild () {
|
2023-01-17 15:20:30 -08:00
|
|
|
|
2023-04-14 21:27:40 -07:00
|
|
|
local targets=(dev arm64 amd64 publish multi default)
|
2024-01-29 15:16:15 -08:00
|
|
|
local log_dir; local no_prompt; local packages; local befile
|
2023-04-22 08:19:45 -07:00
|
|
|
declare -A dimage; declare -A dinstall; declare -A dupdate
|
|
|
|
|
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 15:20:30 -08:00
|
|
|
BDIR=$(dirname "$(realpath "$BASH_SOURCE")")
|
2023-01-22 15:02:36 -08:00
|
|
|
export BDIR
|
2023-03-25 11:27:22 -07:00
|
|
|
# load script library
|
2023-01-17 15:20:30 -08:00
|
|
|
source $BDIR/lib/load.sh
|
2023-04-14 21:27:40 -07:00
|
|
|
BUILD_EFILE=""
|
2023-01-17 11:53:24 -08:00
|
|
|
|
2023-03-25 11:27:22 -07:00
|
|
|
# check for subcommands first
|
2023-01-17 15:20:30 -08:00
|
|
|
case "$1" in
|
2023-03-22 09:10:54 -07:00
|
|
|
try)
|
2023-04-14 21:27:40 -07:00
|
|
|
shift 1; try_container "$@"; return $? ;;
|
2024-01-29 15:16:15 -08:00
|
|
|
|
|
|
|
env_file)
|
|
|
|
shift 1
|
|
|
|
befile=$(echo -- "$@" | grep -oP -- '(?<=-e )[^ ]*')
|
|
|
|
env_file ${befile:-$BUILD_EFILE} ;
|
|
|
|
return $?
|
|
|
|
;;
|
|
|
|
|
|
|
|
lib)
|
|
|
|
shift 1
|
|
|
|
echo $BDIR/lib/build.lib
|
|
|
|
return 0
|
|
|
|
;;
|
|
|
|
|
|
|
|
build_src)
|
|
|
|
shift 1
|
|
|
|
befile=$(echo -- "$@" | grep -oP -- '(?<=-e )[^ ]*')
|
|
|
|
befile=${befile:-$BUILD_EFILE}
|
|
|
|
if befile=$(env_file $befile); then
|
|
|
|
[[ $befile ]] && source_env_file $befile
|
|
|
|
get_build_src
|
|
|
|
return $?
|
|
|
|
else
|
|
|
|
return 3
|
|
|
|
fi
|
2023-01-17 15:20:30 -08:00
|
|
|
;;
|
2023-04-14 21:27:40 -07:00
|
|
|
help)
|
|
|
|
;&
|
|
|
|
--help)
|
|
|
|
;&
|
|
|
|
-help) shift 1; usage "$@"; return $? ;;
|
|
|
|
source) type udbuild; return $? ;;
|
|
|
|
image)
|
2023-01-17 15:20:30 -08:00
|
|
|
shift 1
|
2023-04-14 21:27:40 -07:00
|
|
|
case "$1" in
|
|
|
|
name) shift 1; image_name "$@" ;;
|
|
|
|
tag) shift 1; image_tag "$@" ;;
|
|
|
|
push) shift 1; image_push "$@" ;;
|
|
|
|
delete) shift 1; image_delete "$@" ;;
|
2023-04-22 09:21:50 -07:00
|
|
|
exists) shift 1; image_exists "$@" ;;
|
2023-04-14 21:27:40 -07:00
|
|
|
info)
|
|
|
|
shift 1
|
|
|
|
case "$1" in
|
|
|
|
arch) shift 1; image_arch "$@" ;;
|
|
|
|
tags) shift 1; image_tags "$@" ;;
|
|
|
|
id) shift 1; image_id "$@" ;;
|
|
|
|
* ) image_info "$@"
|
|
|
|
esac
|
|
|
|
;;
|
|
|
|
*) echo no image subcommand $1 ;;
|
|
|
|
esac
|
|
|
|
return $?
|
2023-01-17 15:20:30 -08:00
|
|
|
;;
|
|
|
|
esac
|
2022-10-22 08:23:16 -07:00
|
|
|
|
2023-01-17 15:20:30 -08:00
|
|
|
[[ -z "$PS1" ]] || no_prompt=true
|
2023-01-22 15:02:36 -08:00
|
|
|
overwrite=true
|
2022-10-22 08:23:16 -07:00
|
|
|
|
2024-01-14 14:57:09 -08:00
|
|
|
while getopts 'ya:b:c:d:e:f:g:hi:lnopr:s:t:u:v:j:' OPTION; do
|
2022-10-22 08:23:16 -07:00
|
|
|
# echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
|
|
|
|
case "$OPTION" in
|
2023-04-22 08:19:45 -07:00
|
|
|
a)
|
|
|
|
APPEND_BUILD_ENV=$OPTARG
|
|
|
|
;;
|
|
|
|
b)
|
|
|
|
# CUSTOM BASE IMAGE
|
|
|
|
BASE_IMAGE=$OPTARG
|
|
|
|
;;
|
2024-01-14 14:57:09 -08:00
|
|
|
y)
|
|
|
|
# CUSTOM BASE IMAGE
|
|
|
|
BASE_IMAGE_COPY=true
|
|
|
|
;;
|
2023-04-22 08:19:45 -07:00
|
|
|
c)
|
|
|
|
TRY_CMD=$OPTARG
|
|
|
|
;;
|
|
|
|
d)
|
|
|
|
# LINUX_DISTRO=$OPTARG
|
|
|
|
LINUX_DISTRO=$OPTARG
|
|
|
|
;;
|
2023-03-27 11:07:25 -07:00
|
|
|
e)
|
2023-04-14 21:27:40 -07:00
|
|
|
BUILD_EFILE=$OPTARG
|
|
|
|
if ! source_env_file $BUILD_EFILE; then return 2; fi
|
2023-04-22 08:19:45 -07:00
|
|
|
;;
|
|
|
|
f)
|
|
|
|
REBUILD=$OPTARG
|
|
|
|
;;
|
|
|
|
g)
|
|
|
|
TAG=$OPTARG
|
|
|
|
;;
|
|
|
|
h)
|
|
|
|
usage
|
|
|
|
return 0
|
|
|
|
;;
|
|
|
|
i)
|
|
|
|
IMAGE_INFO=$OPTARG
|
|
|
|
;;
|
|
|
|
|
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)
|
2024-01-14 14:57:09 -08:00
|
|
|
VOLUME=$OPTARG
|
|
|
|
;;
|
|
|
|
j)
|
2023-04-22 08:19:45 -07:00
|
|
|
VERBOSE=$OPTARG
|
2023-04-14 21:27:40 -07:00
|
|
|
;;
|
2023-04-22 08:19:45 -07:00
|
|
|
l)
|
|
|
|
# append distro name to image name
|
|
|
|
APPEND_DISTRO=true
|
|
|
|
;;
|
|
|
|
n)
|
|
|
|
nocache="--no-cache"
|
|
|
|
;;
|
2023-04-14 21:27:40 -07:00
|
|
|
p)
|
|
|
|
echo "build script will be run WITHOUT user prompts (i.e. non-interactive)"
|
2023-01-17 11:53:24 -08:00
|
|
|
no_prompt=true
|
|
|
|
;;
|
2023-04-22 08:19:45 -07:00
|
|
|
r)
|
|
|
|
REPO=$OPTARG
|
|
|
|
;;
|
2023-01-17 11:53:24 -08:00
|
|
|
s)
|
2023-03-25 11:27:22 -07:00
|
|
|
# building source from which to bind into build, default is src/ in current directory
|
|
|
|
BUILD_SRC=$OPTARG
|
2023-01-17 11:53:24 -08:00
|
|
|
;;
|
2022-10-22 08:23:16 -07:00
|
|
|
t)
|
2023-03-27 11:07:25 -07:00
|
|
|
TARGET=$OPTARG
|
2023-01-22 15:02:36 -08:00
|
|
|
;;
|
2022-10-22 08:23:16 -07:00
|
|
|
u)
|
|
|
|
RUSER=$OPTARG
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "unknown $0 option -$OPTARG"
|
2023-04-22 08:19:45 -07:00
|
|
|
usage
|
|
|
|
return 1
|
2022-10-22 08:23:16 -07:00
|
|
|
;;
|
|
|
|
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-04-14 21:27:40 -07:00
|
|
|
[[ ! $BUILD_EFILE ]] && source_env_file
|
|
|
|
|
2024-09-15 18:47:22 -07:00
|
|
|
if ! validate_distro; then
|
|
|
|
>&2 echo "FATAL: unable to validate the BASE_IMAGE ($BASE_IMAGE) and it's LINUX_DISTRO ($LINUX_DISTRO), aborting build"
|
|
|
|
return 2
|
|
|
|
fi
|
|
|
|
|
2024-01-29 15:16:15 -08:00
|
|
|
if ! get_build_src > /dev/null ; then
|
2023-04-14 21:27:40 -07:00
|
|
|
if [[ $no_prompt ]] ; then
|
|
|
|
echo aborting the build...
|
2023-04-22 08:19:45 -07:00
|
|
|
echo -e "\e[1;31mNOTE: use '_core_' to explicitly build with only the UCI core repo\e[1;37m"
|
2023-04-14 21:27:40 -07:00
|
|
|
return 2
|
|
|
|
else
|
2023-04-22 08:19:45 -07:00
|
|
|
echo "Do you want to build with only the UCI core"
|
2023-04-14 21:27:40 -07:00
|
|
|
read -n 1 -p "instead? [y]=>" REPLY
|
|
|
|
[[ $REPLY != "y" ]] && echo -e "\n" && return 2
|
2023-04-22 08:19:45 -07:00
|
|
|
BUILD_SRC="_core_"
|
|
|
|
echo -e "\n\e[1;31mNOTE: use '_core_' to explicitly build with only the UCI core\e[1;37m"
|
2023-03-27 11:07:25 -07:00
|
|
|
fi
|
2023-04-14 21:27:40 -07:00
|
|
|
fi
|
2023-03-25 11:27:22 -07:00
|
|
|
|
2023-04-14 21:27:40 -07:00
|
|
|
TARGET=${TARGET:-default}
|
2023-03-27 11:07:25 -07:00
|
|
|
[[ ! "${targets[@]}" =~ $TARGET ]] && echo $TARGET is not a valid target && echo valid targets are: ${targets[@]} && exit 4
|
2023-01-22 15:02:36 -08:00
|
|
|
|
2023-04-03 14:14:17 -07:00
|
|
|
IMAGE_NAME=$(make_image_name $@)
|
2023-03-27 11:07:25 -07:00
|
|
|
|
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
|
|
|
|
|
2023-04-01 07:17:43 -07:00
|
|
|
ARCH=$(get_arch)
|
2023-04-14 21:27:40 -07:00
|
|
|
log_dir=$PWD/logs
|
|
|
|
mkdir -p $log_dir
|
|
|
|
[[ $TARGET == "dev" ]] && VERBOSE=true
|
2023-04-01 07:17:43 -07:00
|
|
|
|
2022-10-20 18:48:17 -07:00
|
|
|
export BASE_IMAGE
|
|
|
|
export TAG
|
|
|
|
export IMAGE_NAME
|
|
|
|
export LINUX_DISTRO
|
2023-04-03 14:14:17 -07:00
|
|
|
export BUILD_SRC
|
2023-04-01 07:17:43 -07:00
|
|
|
export ARCH
|
2023-04-14 21:27:40 -07:00
|
|
|
export VERBOSE
|
2023-04-22 08:19:45 -07:00
|
|
|
export REBUILD
|
2023-03-25 11:27:22 -07:00
|
|
|
|
2024-09-15 18:47:22 -07:00
|
|
|
if [[ $VERBOSE ]]; then
|
|
|
|
echo BASE_IMAGE=$BASE_IMAGE
|
|
|
|
echo TAG=$TAG
|
|
|
|
echo IMAGE_NAME=$IMAGE_NAME
|
|
|
|
echo LINUX_DISTRO=$LINUX_DISTRO
|
|
|
|
echo BUILD_SRC=$BUILD_SRC
|
|
|
|
echo ARCH=$ARCH
|
|
|
|
echo VERBOSE=$VERBOSE
|
|
|
|
echo REBUILD=$REBUILD
|
|
|
|
fi
|
|
|
|
|
2023-04-14 21:27:40 -07:00
|
|
|
build_info
|
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
|
2023-03-27 11:07:25 -07:00
|
|
|
[[ $REPLY != "y" ]] && echo -e "\n" && return 4
|
2024-09-15 18:47:22 -07:00
|
|
|
echo -e "********** starting build ****************\n"
|
2023-01-17 11:53:24 -08:00
|
|
|
fi
|
2022-10-20 18:48:17 -07:00
|
|
|
|
2024-01-14 14:57:09 -08:00
|
|
|
# cat $BDIR/Dockerfile | grep -b5 -a5 ENTRY
|
|
|
|
# return
|
2023-04-14 21:27:40 -07:00
|
|
|
|
2022-10-20 18:48:17 -07:00
|
|
|
builder=default
|
2023-04-14 21:27:40 -07:00
|
|
|
if [[ $TARGET == "publish" ]]; then
|
|
|
|
builder=publish
|
|
|
|
pushd "$BDIR" > /dev/null || return 3
|
|
|
|
if ! docker buildx ls | grep -q publish ; then
|
|
|
|
echo publish builder does not exist, creating with docker-container driver
|
|
|
|
docker buildx create --name publish --driver docker-container >/dev/null
|
|
|
|
docker buildx ls | grep publish
|
2022-10-20 18:48:17 -07:00
|
|
|
fi
|
2023-04-14 21:27:40 -07:00
|
|
|
popd > /dev/null || return 4
|
2022-10-20 18:48:17 -07:00
|
|
|
fi
|
|
|
|
|
2024-01-14 14:57:09 -08:00
|
|
|
# make a copy of build source locally in build directory
|
2023-04-22 08:19:45 -07:00
|
|
|
if [[ ! $BUILD_SRC = "_core_" ]]; then
|
|
|
|
# copy or bind build source directory to temporary .src/ subdirectory in build repo
|
|
|
|
[[ -d $BDIR/.src ]] && rm -rf $BDIR/.src
|
|
|
|
if [[ $(which rsync 2> /dev/null ) ]]; then
|
|
|
|
rsync -aAru ${BUILD_SRC:-src}/ $BDIR/.src
|
|
|
|
else
|
|
|
|
echo no rsync copying with cp
|
|
|
|
/bin/cp -a ${BUILD_SRC:-src}/. $BDIR/.src > /dev/null 2>&1
|
|
|
|
fi
|
2024-01-29 15:16:15 -08:00
|
|
|
ls -la $BDIR/.src/rootfs
|
2023-04-22 08:19:45 -07:00
|
|
|
fi
|
|
|
|
|
2024-10-17 16:17:59 -07:00
|
|
|
|
|
|
|
|
2024-01-14 14:57:09 -08:00
|
|
|
# create Dockerfile from template
|
|
|
|
if ! source $BDIR/Dockerfile.d/create; then
|
|
|
|
echo unable to create Dockerfile from template, aborting build
|
|
|
|
return 3
|
|
|
|
fi
|
|
|
|
|
2023-04-22 08:19:45 -07:00
|
|
|
if [[ -f $APPEND_BUILD_ENV ]]; then
|
2024-01-14 14:57:09 -08:00
|
|
|
if [[ ! $BUILD_SRC = "_core_" ]]; then
|
|
|
|
echo "------ Including custom build environment at $APPEND_BUILD_ENV -------"
|
|
|
|
cat $APPEND_BUILD_ENV
|
|
|
|
echo -e "\n--------------------"
|
|
|
|
echo | tee -a "$BDIR/.src/init/build.env" > /dev/null
|
|
|
|
tee -a "$BDIR/.src/init/build.env" > /dev/null < "$APPEND_BUILD_ENV"
|
|
|
|
fi
|
|
|
|
cat "$APPEND_BUILD_ENV" > "$BDIR/core/build.env"
|
2023-04-22 08:19:45 -07:00
|
|
|
# run in subshell to not affect $USER
|
|
|
|
/bin/bash <<"EOF"
|
|
|
|
unset USER
|
|
|
|
source "$BDIR/core/build.env"
|
|
|
|
[[ $USER_PW ]] && USER=${USER:-sysadmin}
|
|
|
|
if [[ $USER ]]; then
|
|
|
|
if [[ -f $PWD/$USER-permits ]]; then
|
|
|
|
echo sudo permits file: \'$USER-permits\' added to core build
|
|
|
|
/bin/cp -f $PWD/$USER-permits $BDIR/core
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
EOF
|
2023-04-14 21:27:40 -07:00
|
|
|
fi
|
|
|
|
|
2024-10-17 16:17:59 -07:00
|
|
|
if [[ -d $BDIR/.src/core ]]; then
|
|
|
|
[[ -d "$BDIR/core/custom" ]] && rm -rf "$BDIR/core/custom"
|
|
|
|
echo adding the custom core directory to /custom in the core directory
|
|
|
|
/bin/cp -a "$BDIR/.src/core/." "$BDIR/core/custom"
|
|
|
|
rm -rf "$BDIR/.src/core/"
|
|
|
|
ls -la $BDIR/core/custom
|
|
|
|
fi
|
2024-01-29 15:16:15 -08:00
|
|
|
|
2023-04-14 21:27:40 -07:00
|
|
|
pushd "$BDIR" > /dev/null || return 3
|
|
|
|
|
2024-01-14 14:57:09 -08:00
|
|
|
export BUILDING=true
|
|
|
|
|
2023-04-01 07:17:43 -07:00
|
|
|
echo running build command: docker buildx --builder ${builder} bake ${nocache} ${TARGET}
|
2023-04-22 08:19:45 -07:00
|
|
|
echo -e "#################################################################\e[1;37m"
|
2023-03-27 11:07:25 -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 5
|
2023-04-14 21:27:40 -07:00
|
|
|
popd > /dev/null || return 4
|
2023-01-17 11:53:24 -08:00
|
|
|
|
2023-04-22 08:19:45 -07:00
|
|
|
# cleanup
|
|
|
|
echo cleaning up..
|
2024-01-29 15:16:15 -08:00
|
|
|
rm -rf $BDIR/.src $BDIR/core/build.env $BDIR/core/custom-core.sh $BDIR/core/*-permits > /dev/null 2<&1
|
2023-04-22 08:19:45 -07:00
|
|
|
echo done cleaning
|
|
|
|
# try in container
|
2023-04-14 21:27:40 -07:00
|
|
|
if [[ ($TRY_CMD || $TARGET == "dev") ]]; then
|
2023-01-17 15:20:30 -08:00
|
|
|
echo trying newly built image in a container
|
2023-04-14 21:27:40 -07:00
|
|
|
echo name before try $IMAGE_NAME
|
|
|
|
try_container build -m opt $([[ $TARGET == "publish" ]] && echo -p) ${TRY_CMD:-shell}
|
2023-01-17 15:20:30 -08:00
|
|
|
fi
|
2023-01-17 11:53:24 -08:00
|
|
|
|
2023-04-01 07:17:43 -07:00
|
|
|
if [[ $TARGET == "private" ]]; then
|
2023-04-14 21:27:40 -07:00
|
|
|
echo pushing arm64 image $IMAGE_NAME to ${REPO:-docker hub}
|
2023-04-01 07:17:43 -07:00
|
|
|
image_push -a -r $REPO $IMAGE_NAME
|
2023-04-14 21:27:40 -07:00
|
|
|
echo pushing amd image $IMAGE_NAME to ${REPO:-docker hub}
|
2023-04-01 07:17:43 -07:00
|
|
|
image_push -r $REPO $IMAGE_NAME
|
|
|
|
fi
|
|
|
|
|
2024-10-17 16:17:59 -07:00
|
|
|
# cleanup
|
|
|
|
[[ -d "$BDIR/core/custom" ]] && rm -rf "$BDIR/core/custom"
|
|
|
|
|
2023-04-01 07:17:43 -07:00
|
|
|
}
|
2023-01-17 15:20:30 -08:00
|
|
|
|
|
|
|
# if script was executed then call the function
|
2023-04-14 21:27:40 -07:00
|
|
|
(return 0 2>/dev/null) || udbuild "$@"
|
2023-03-27 11:07:25 -07:00
|
|
|
|
|
|
|
|
|
|
|
|