#!/bin/bash udbuild () { local targets=(dev arm64 amd64 publish multi default) local log_dir; local no_prompt local append_efile declare OPTION; declare OPTARG; declare OPTIND BDIR=$(dirname "$(realpath "$BASH_SOURCE")") export BDIR # load script library source $BDIR/lib/load.sh BUILD_EFILE="" # check for subcommands first case "$1" in try) shift 1; try_container "$@"; return $? ;; load_env_file) echo -e "@@@@@@ loading build environment file for external use @@@@@@" BUILD_EFILE=$(echo -- "$@" | grep -oP -- '(?<=-e )[^ ]*') source_env_file "$BUILD_EFILE" echo -e "@@@@@@@@@@@@@@@@@ returning to calling script @@@@@@@@@@@@@@@" return $? ;; build_src) shift 1; get_build_src "$@"; return $? ;; help) ;& --help) ;& -help) shift 1; usage "$@"; return $? ;; source) type udbuild; return $? ;; image) shift 1 case "$1" in name) shift 1; image_name "$@" ;; tag) shift 1; image_tag "$@" ;; push) shift 1; image_push "$@" ;; delete) shift 1; image_delete "$@" ;; info) shift 1 case "$1" in arch) shift 1; image_arch "$@" ;; exists) shift 1; image_exists "$@" ;; tags) shift 1; image_tags "$@" ;; id) shift 1; image_id "$@" ;; * ) image_info "$@" esac ;; *) echo no image subcommand $1 ;; esac return $? ;; esac exit_abnormal() { # Function: Exit with error. usage return ${1:-1} } [[ -z "$PS1" ]] || no_prompt=true overwrite=true while getopts 'fg:e:b:d:t:nc:r:u:lhs:a:voi:p' OPTION; do # echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND} case "$OPTION" in i) IMAGE_INFO=$OPTARG ;; e) BUILD_EFILE=$OPTARG if ! source_env_file $BUILD_EFILE; then return 2; fi ;; o) unset overwrite ;; v) VERBOSE=true ;; a) append_efile=$OPTARG ;; f) REBUILD=init ;; p) echo "build script will be run WITHOUT user prompts (i.e. non-interactive)" no_prompt=true ;; b) # CUSTOM BASE IMAGE BASE_IMAGE=$OPTARG ;; s) # building source from which to bind into build, default is src/ in current directory BUILD_SRC=$OPTARG ;; d) # LINUX_DISTRO=$OPTARG LINUX_DISTRO=$OPTARG ;; l) # append distro name to image name APPEND_DISTRO=true ;; t) TARGET=$OPTARG ;; g) TAG=$OPTARG ;; u) RUSER=$OPTARG ;; c) TRY_CMD=$OPTARG ;; n) nocache="--no-cache" ;; r) REPO=$OPTARG ;; h) exit_abnormal 0 return 0 ;; *) echo "unknown $0 option -$OPTARG" exit_abnormal 1 ;; esac done shift $((OPTIND - 1)) [[ ! $BUILD_EFILE ]] && source_env_file if ! get_build_src; then if [[ $no_prompt ]] ; then echo aborting the build... echo -e "\e[1;31mNOTE: use '_default_' to explicitly use build source in uci-docker-build repo\e[1;37m" return 2 else echo "Do you want to use the uci-docker-build default build source" echo "at $BDIR/src " read -n 1 -p "instead? [y]=>" REPLY [[ $REPLY != "y" ]] && echo -e "\n" && return 2 BUILD_SRC=$BDIR/src echo -e "\n\e[1;31mNOTE: use '_default_' to explicitly use build source in uci-docker-build repo\e[1;37m" fi fi TARGET=${TARGET:-default} [[ ! "${targets[@]}" =~ $TARGET ]] && echo $TARGET is not a valid target && echo valid targets are: ${targets[@]} && exit 4 get_distro IMAGE_NAME=$(make_image_name $@) # 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 ARCH=$(get_arch) log_dir=$PWD/logs mkdir -p $log_dir [[ $TARGET == "dev" ]] && VERBOSE=true export BASE_IMAGE export TAG export IMAGE_NAME export LINUX_DISTRO export BUILD_SRC export ARCH export VERBOSE build_info if [[ ! $no_prompt ]]; then read -n 1 -p "do you want to continue [y]=>" REPLY [[ $REPLY != "y" ]] && echo -e "\n" && return 4 fi if ! source $BDIR/Dockerfile.d/create; then echo unable to create Dockerfile from template, aborting build return 3 fi builder=default 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 fi popd > /dev/null || return 4 fi # 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 if [[ -f $append_efile ]]; then /bin/cp "$append_efile" "$BDIR/.src/init/env/_build.env_" echo 'source $ENV_DIR/_build.env_' >> $BDIR/.src/init/build.env fi pushd "$BDIR" > /dev/null || return 3 ######### RUNNING THE DOCKER BUILD COMMAND ###################### echo running build command: docker buildx --builder ${builder} bake ${nocache} ${TARGET} 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 popd > /dev/null || return 4 rm -rf $BDIR/.src if [[ ($TRY_CMD || $TARGET == "dev") ]]; then echo trying newly built image in a container echo name before try $IMAGE_NAME try_container build -m opt $([[ $TARGET == "publish" ]] && echo -p) ${TRY_CMD:-shell} fi if [[ $TARGET == "private" ]]; then echo pushing arm64 image $IMAGE_NAME to ${REPO:-docker hub} image_push -a -r $REPO $IMAGE_NAME echo pushing amd image $IMAGE_NAME to ${REPO:-docker hub} image_push -r $REPO $IMAGE_NAME fi } # if script was executed then call the function (return 0 2>/dev/null) || udbuild "$@"