From bc0d3a72a5325a2b445207130fd5a1647bda264c Mon Sep 17 00:00:00 2001 From: David Kebler Date: Mon, 27 Mar 2023 11:07:25 -0700 Subject: [PATCH] refactored and rearranging loading the library fix: build supports robust environment file loading allows override by options, etc. fix: improved looking for valid BUILD_SRC --- Dockerfile | 2 - build | 173 ++++++----- examples/example-build.env | 9 - examples/example.build | 2 +- examples/example.env | 29 ++ lib/{src/02-image-name => cmds/01-image-name} | 0 lib/{src => cmds}/image-info | 0 lib/{src => cmds}/image-push | 37 +-- lib/{src => cmds}/image-tag | 0 lib/{src => cmds}/try | 0 lib/{src => cmds}/usage | 0 lib/file.mod | 291 ------------------ lib/helpers.lib | 104 +++++++ lib/load.sh | 9 +- lib/src/01-helpers | 30 -- 15 files changed, 249 insertions(+), 437 deletions(-) delete mode 100644 examples/example-build.env create mode 100644 examples/example.env rename lib/{src/02-image-name => cmds/01-image-name} (100%) rename lib/{src => cmds}/image-info (100%) rename lib/{src => cmds}/image-push (79%) rename lib/{src => cmds}/image-tag (100%) rename lib/{src => cmds}/try (100%) rename lib/{src => cmds}/usage (100%) delete mode 100644 lib/file.mod create mode 100755 lib/helpers.lib delete mode 100755 lib/src/01-helpers diff --git a/Dockerfile b/Dockerfile index 7566710..375e348 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,6 @@ # syntax=docker/dockerfile:latest ARG BASE_IMAGE FROM $BASE_IMAGE -ARG PENV ARG BASE_IMAGE ARG KEEP ARG SYSADMIN_PW @@ -12,7 +11,6 @@ WORKDIR $BUILD_DIR COPY .src/packages ./packages # PACKAGES RUN \ - # --mount=type=cache,target=/var/cache/apt \ echo -e "\n ************************************************* \n"\ echo "****** Building Image from Base: $BASE_IMAGE; : Distro: $LINUX_DISTRO; *****"; \ echo " ---- running packages install script ---"; \ diff --git a/build b/build index 8934027..20c16b2 100755 --- a/build +++ b/build @@ -3,7 +3,8 @@ docker_image_build () { local targets=(dev arm amd deploy private multi) -local verbose; local BUILD_SRC; local log_dir; local no_prompt +local verbose; local log_dir; local no_prompt +local efile declare OPTION; declare OPTARG; declare OPTIND BDIR=$(dirname "$(realpath "$BASH_SOURCE")") @@ -51,27 +52,13 @@ exit_abnormal() { # Function: Exit with error. [[ -z "$PS1" ]] || no_prompt=true overwrite=true -target=dev while getopts 'g:e:b:d:t:ncr:u:plhs:w:akvoi' OPTION; do # echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND} case "$OPTION" in - e) - local efile - echo $PWD - [[ $(isAbsPath $OPTARG) ]] && efile=$OPTARG || efile=$(realpath $OPTARG) - if source "$efile"; then - echo "********************" - echo loaded build environment file at - echo $efile - echo "----------" - cat $efile - echo "*********************" - else - echo unable to source $efile, exiting && return 2 - return 2 - fi - ;; + e) + if source_env_file $OPTARG; then efile=true; else return 2; fi + ;; o) unset overwrite ;; @@ -107,7 +94,7 @@ while getopts 'g:e:b:d:t:ncr:u:plhs:w:akvoi' OPTION; do append_distro=true ;; t) - target=$OPTARG + TARGET=$OPTARG ;; g) TAG=$OPTARG @@ -118,9 +105,10 @@ while getopts 'g:e:b:d:t:ncr:u:plhs:w:akvoi' OPTION; do c) try=true ;; - p) - push=true - ;; + # TODO: push after build + # p) + # push=true + # ;; n) nocache="--no-cache" ;; @@ -133,67 +121,94 @@ while getopts 'g:e:b:d:t:ncr:u:plhs:w:akvoi' OPTION; do ;; *) echo "unknown $0 option -$OPTARG" - exit_abnormal 4 + exit_abnormal 1 ;; esac done shift $((OPTIND - 1)) -BUILD_SRC=${BUILD_SRC:-${PWD}/src} +[[ ! $efile ]] && source_env_file + +TARGET=${TARGET:-dev} + +# processing the build source directory +if [[ ! $BUILD_SRC ]]; then + echo no BUILD_SRC directory specified + echo using present directory $PWD + BUILD_SRC=$PWD +fi if [[ ! $(isAbsPath $BUILD_SRC) ]] ; then - if [[ ${BUILD_SRC} == "_base_" ]]; then - BUILD_SRC=${BDIR}/src + if [[ ${BUILD_SRC} == "_base_" ]]; then + BUILD_SRC=${BDIR}/src + else + BUILD_SRC=$(realpath ${BUILD_SRC}) + fi +fi + +if [[ ! ( -d $BUILD_SRC/packages && -d $BUILD_SRC/init ) ]]; then +echo -e "\e[1;31minvalid build source directory" + echo $BUILD_SRC + echo -e "it does not contain packages and init subirectories\e[1;37m" + if [[ ! $(basename $BUILD_SRC) == "src" ]]; then + echo checking in src/ subdirectory for source + if [[ ( -d $BUILD_SRC/src/packages && -d $BUILD_SRC/src/init ) ]]; then + BUILD_SRC=$BUILD_SRC/src + echo found source in src/ subdirectory changing to source directory to + echo $BUILD_SRC else - BUILD_SRC=$(realpath ${BUILD_SRC}) - fi -fi + echo -e "\e[1;31mERROR: no build source directory at $BUILD_SRC" + echo -e "with init/ and packages/ subdirectores was found\e[1;37m" + if [[ $no_prompt ]] ; then + echo aborting the build... + echo -e "\e[1;31mNOTE: use '_base_' 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 repo source scripts" + 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 '_base_' to explicitly use build source in uci-docker-build repo\e[1;37m" + fi + fi + fi +fi +# done processing build source directory log_dir=$PWD/logs mkdir -p $log_dir -if [[ ! -d $BUILD_SRC ]]; then + pushd "$BDIR" > /dev/null || return 3 - if $no_prompt ; then - echo -e "\e[1;31mWARNING: no build source directory at $BUILD_SRC was not found" - echo aborting... - echo -e "\e[1;31mNOTE: use '_base_' to explicitly use the in uci-docker-build repo\e[1;37m" - return 3 - else - echo -e "\e[1;31mWARNING: build scripts source directory at $BUILD_SRC does not exist.\e[1;37m" - echo "Do you want to use the uci-docker-build repo source scripts" - echo "at $BDIR/src " - read -n 1 -p "instead? [y]=>" REPLY - [[ $REPLY != "y" ]] && echo -e "\n" && return 0 - BUILD_SRC=$BDIR/src - echo -e "\n\e[1;31mNOTE: use '_base_' to explicitly use the in uci-docker-build repo\e[1;37m" - fi - -fi - -pushd $BDIR || return 3 - -[[ ! "${targets[@]}" =~ $target ]] && echo $target is not a valid target && echo valid targets are: ${targets[@]} && exit 4 +[[ ! "${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 +LINUX_DISTRO=$(docker_image_distro $BASE_IMAGE) + [[ ! $LINUX_DISTRO ]] && echo "unable to get base image OS for: $BASE_IMAGE, aborting build" && return 5 echo $BASE_IMAGE is built from distro $LINUX_DISTRO else BASE_IMAGE=$LINUX_DISTRO fi -NAME=${NAME:-$1} -RUSER=${2:-$RUSER} +if [[ $1 ]]; then +[[ $NAME ]] && echo changing image name from $NAME to $1 && NAME=$1 +fi +if [[ $2 ]]; then +[[ $RUSER ]] && echo changing image username from $RUSER to $2 && RUSER=$2 +fi if [[ $NAME ]]; then [[ $add_distro ]] && NAME=$NAME-${LINUX_DISTRO} else + echo no image name supplied using distro name $LINUX_DISTRO NAME=${LINUX_DISTRO} fi + + IMAGE_NAME=$([[ $RUSER ]] && echo ${RUSER}/)${NAME} # TODO writing to existing tag untags existing image so write a new tag to that image then continue @@ -221,16 +236,16 @@ export KEEP export SYSADMIN_PW -echo -e "\n******************************************" +echo -e "\e[1;37m********************" echo "Using scripts source directory at $BUILD_SRC" 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}" +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 + docker buildx bake --print $TARGET echo -e "\n---------------------------------" echo "build scripts at $BUILD_SRC to be copied to ${BUILD_DIR:-/build} in container ***** " ls -la $BUILD_SRC @@ -238,15 +253,15 @@ if [[ $verbose ]]; then cat $BUILD_SRC/init.sh echo -e "\n---------------------------------" fi -echo -e "\n***************************************" +echo -e "u********************\e[0;37m" if [[ ! $no_prompt ]]; then read -n 1 -p "do you want to continue [y]=>" REPLY - [[ $REPLY != "y" ]] && echo -e "\n" && exit 0 + [[ $REPLY != "y" ]] && echo -e "\n" && return 4 fi builder=default -if [ $target == "deploy" ]; then +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 @@ -255,7 +270,7 @@ if [ $target == "deploy" ]; then fi fi -[[ $target == "private" && ! $REPO ]] && echo "must use '-r ' if building to private repo" && exit 3 +[[ $TARGET == "private" && ! $REPO ]] && echo "must use '-r ' 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 @@ -263,31 +278,31 @@ rm -rf $BDIR/.src rsync -aAru ${BUILD_SRC:-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 +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 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 +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 + 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 $@ \ No newline at end of file +(return 0 2>/dev/null) || docker_image_build $@ + + + +# 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 \ No newline at end of file diff --git a/examples/example-build.env b/examples/example-build.env deleted file mode 100644 index 45be2c9..0000000 --- a/examples/example-build.env +++ /dev/null @@ -1,9 +0,0 @@ -# do not set LINUX_DISTRO if setting base image, it will be ignorned -LINUX_DISTRO=alpine -# BASE_IMAGE="dockerhubuser/mybase" -TAG=1.0.0 -RUSER=dockerhubuser -REPO=my.priviate.repo.net - - - diff --git a/examples/example.build b/examples/example.build index 5e1f1f0..f6ef0ba 100644 --- a/examples/example.build +++ b/examples/example.build @@ -1 +1 @@ -dbuild -e example-build.env "$@" +dbuild -e example.env "$@" diff --git a/examples/example.env b/examples/example.env new file mode 100644 index 0000000..7db779a --- /dev/null +++ b/examples/example.env @@ -0,0 +1,29 @@ +# using a filename of just .env will load it by default +# LINUX_DISTRO ignored if BASE_IMAGE is set +LINUX_DISTRO=alpine +# BASE_IMAGE="dockerhubuser/mybase" +# tag is 'latest' by default +# TAG=1.0.0 +# will be prepended to image name with /, used mostly for deploying +RUSER=dockerhubuser +# default is hub.docker.com +# REPO=my.priviate.repo.net +# if using base source this will set the pw for the sysadmin user in the image +SYSADMIN_PW=ucommandit +# default target is dev +# TARGET=deploy +BUILD_SRC=../src +# looks for /init and /packages in present directory by default +# also looks in src/ subdirectory +# relate paths work +# use '_base_' to force using the uci-docker-build build source +# BUILD_SRC=._base_ +# in the image where the build scripts are put /build by default +# BUILD_DIR=/opt/build +# keep the build scripts in the image. default is to remove them after build +# KEEP=true + + + + + diff --git a/lib/src/02-image-name b/lib/cmds/01-image-name similarity index 100% rename from lib/src/02-image-name rename to lib/cmds/01-image-name diff --git a/lib/src/image-info b/lib/cmds/image-info similarity index 100% rename from lib/src/image-info rename to lib/cmds/image-info diff --git a/lib/src/image-push b/lib/cmds/image-push similarity index 79% rename from lib/src/image-push rename to lib/cmds/image-push index 5d13026..003d792 100755 --- a/lib/src/image-push +++ b/lib/cmds/image-push @@ -6,17 +6,22 @@ image_push () { # if not reposity is given will use docker.io and push to hub.docker.com # $1 name, $2 user(or repo), $3 repo -source=$$image_name - - declare OPTION; declare OPTARG; declare OPTIND -while getopts 'e:aht:r:u:' OPTION; do +while getopts 'e:dt:r:u:' OPTION; do # echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND} case "$OPTION" in -e) - efile=$OPTARG - ;; -h) # pull image from dockerhub if not available +e) if ! source_env_file $OPTARG ; then return 2; fi + ;; +t) + TAG=$OPTARG + ;; +u) + RUSER=$OPTARG + ;; +r) + REPO=$OPTARG + ;; +d) # pull image from dockerhub if not available hub=true ;; *) echo unknown run option -$OPTARG @@ -28,22 +33,8 @@ done shift $((OPTIND - 1)) -SDIR=$1 -shift -[[ $efile ]] && efile = $SDIR/$efile -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 "----------" # image tag -name=$1 +name=${1:-$NAME} user=${2:-$RUSER} repo=${3:-$REPO} diff --git a/lib/src/image-tag b/lib/cmds/image-tag similarity index 100% rename from lib/src/image-tag rename to lib/cmds/image-tag diff --git a/lib/src/try b/lib/cmds/try similarity index 100% rename from lib/src/try rename to lib/cmds/try diff --git a/lib/src/usage b/lib/cmds/usage similarity index 100% rename from lib/src/usage rename to lib/cmds/usage diff --git a/lib/file.mod b/lib/file.mod deleted file mode 100644 index 26da0dd..0000000 --- a/lib/file.mod +++ /dev/null @@ -1,291 +0,0 @@ -#!/bin/bash -# TODO allow debug to have managment flags and levels -function debug () { -[[ $BASH_DEBUG ]] && echo -e "#### DEBUG ####\n $@ \n#####" >&2 -} - -# alias debug_on="sudo -i uncomment BASH_DEBUG /etc/bash.bashrc" -# alias debug_off="sudo -i comment BASH_DEBUG /etc/bash.bashrc" - - -# *************** DEBUGGING *********************** -# module_load debug -# if [[ $? -ne 0 ]]; then -# echo "unable to load a 'debug' module using a noop for debug function" -# # noop -# function debug () { -# : -# } -# fi - -# [[ ! $- == *i* ]] && exec >> ~/logs/load.log && exec 2>&1 -# export BASH_DEBUG=true - -# uncomment for debugging -# echo $USER running load script in $DIR -# echo callers -# caller -# echo $(ps -o comm= $PPID) -# echo ----- -# echo $BASH_SHELL_DIRS -# ******************END DEBUGGING ******************************* - -# ***************** LOGGING ***************** -# function nilog () { -# [[ ! $- == *i* ]] && echo -e "-----\n $USER $*" &>> ~/logs/load.log -# } - -# nilog "called load.sh $(date)" -# nilog caller: $(caller) -# nilog pid: $(ps -o comm= $PPID) - -# * -#!/bin/bash -iecho () { -[[ ! -z "$PS1" ]] && echo $1 -} - -# no way to tell if sourced vs subshell -# # [[ ! -z "$PS1" ]] && [[ $SHLVL -eq 1 ]] && echo $1 -# # echo [[ -z $PS1 ]] -# echo $SHLVL -# echo $$ -# echo $BASHPID -# if [[ -t 1 ]]; then -# echo "Terminal" -# else -# echo "Not-a-terminal" -# fi -#!/bin/bash - -# export BASH_DEBUG=true - -isFile() { - if [[ -f $1 ]] - then - echo "true" - return 0 - else - return 1 - fi -} - -build_file () { - # local file - # echo build file $1 $2 - # todo merge no cr - [[ $1 == "-f" ]] && file=true && shift 1 - [[ -f "$2" ]] || { iecho "output file $2 does not exist"; return 1; } - if [[ -f "$1" ]]; then - # echo adding file $1 to $2 - [[ $file ]] && echo -e "\n####### ADDED $1 ########" >> $2 - # remove comment lines, remove blank last line - cat "$1" | sed '/^\s*#/d' | sed '/^$/{:a;N;s/\n$//;ta}' >> $2 - [[ ! $file ]] && echo -e "\n" >> $2 - else iecho "no such file $1 to append to $2" - fi -} - -# TODO need to test -function lines_2_str () { - [[ ! -f "$1" ]] && return 1 - local str='' - # echo the lines: $lines >&2 - # lines="$(cat "$1")" - while read line; do - [[ "$line" =~ ^[[:space:]]*# ]] && continue - # echo line: "${line}" >&2 - str="$str ${line}" - # echo str: $str >&2 - done < $1 - # for line in $lines ; do - # str+='"'$line'" ' - # done - echo $str -} - -# find, superceeds find use `command find` to get the super -function _find () { -# USAGE -# all option arguments that contain globs/wildcards must be quoted to avoid expansion -# f sets path and file excludes from a supplied file path -# all lines ending in / will be treated as directory names to ignore, otherwise files -# p option explictly excludes paths(directories) -# d option sets the directory depth which is current directy by default, 0 is all -# x excitly excludes file globs as a string -# n inclucdes only file globs otherwise it's all except .files -# if no directory is given it will attempt to source the present working directory -# example: -# source_dir -p "archive" -x '"*.off" "*.md"' -d 0 # $DIR/$SUBDIR -local EXCLUDE_FILE -local PATHS -local NAMES -local ENAMES -local DEPTH=1 -local HIDDEN - -declare OPTION -declare OPTARG -declare OPTIND -while getopts 't:p:d:e:n:f:h' OPTION; do -case "$OPTION" in - t) - TYPE=$OPTARG - # echo "TYPE $TYPE" - ;; - f) - EXCLUDE_FILE=$OPTARG - # echo EXCLUDE FILE $EXCLUDE_FILE >&2 - ;; - p) - # PATHS=("$OPTARG") - IFS=',' read -r -a PATHS <<< "$OPTARG" - # echo EXCLUDING THESE PATHS ${PATHS[*]} - ;; - e) - IFS=',' read -r -a ENAMES <<< "${OPTARG}" - # echo EXCLUDING THESE FILE NAMES ${ENAMES[*]} - ;; - n) - # NAMES=("$OPTARG") - IFS=',' read -r -a NAMES <<< "${OPTARG}" - # NAMES=$OPTARG - ;; - d) - DEPTH=$OPTARG - # echo "SOURCING TO DEPTH (0=any)" "$DEPTH" - ;; - h) - HIDDEN=true - # echo "SOURCING TO DEPTH (0=any)" "$DEPTH" - ;; - *) - echo unknown option $OPTION - ;; -esac -done - -shift $(( OPTIND - 1 )) - -local DIR -DIR="$*" -if [ ! "$DIR" ]; then - if [ -v PS1 ]; then - echo no directory provided to search - echo searching present working directory $(pwd) - read -p "Do you want to continue? " -n 1 -r - [[ $REPLY =~ ^[Yy]$ ]] && DIR=$(pwd) || return 1 - else - return 1 - fi -fi - -[ ! -d "$DIR" ] && echo " directory $DIR does not exist, aborting" && return 1 - -# echo dir $DIR - -local FIND -FIND="command find $DIR" -FIND+=$([ ! $DEPTH == 0 ] && echo " -maxdepth $DEPTH ") -# FIND+=" -type $([ $TYPE ] && echo "$TYPE" || echo "f")" -TYPE=${TYPE:-f} -FIND+=" -type $TYPE " -# include HIDDEN files and directories IS FALSE BY DEFULT -[[ ! $HIDDEN ]] && FIND+="! -path \"*/.*/*\" ! -name \".*\" " - -local name -local path - -if [[ -f $EXCLUDE_FILE ]]; then - local ignores=$(lines_2_str "$EXCLUDE_FILE") - # echo ignores: $ignores >&2 - for exclude in $ignores ; do - # echo exclude: ${exclude} >&2 - [[ "$exclude" == */ ]] && PATHS+=("${exclude::-1}") || ENAMES+=("$exclude") - done -fi - -# echo paths ${PATHS[@]} >&2 -# echo exclude names ${ENAMES[@]} >&2 - -set -o noglob - -if [[ ${PATHS[0]} ]]; then - for path in ${PATHS[@]}; do - # echo excluding $path - FIND+=$(echo ' ! -path "*/'$path'/*"') - done -fi - -if [[ ${ENAMES[0]} ]]; then - for name in ${ENAMES[@]}; do - debug excluding name "$name" - FIND+=$(echo ' ! -name '$name'') - done -fi - -debug "INCLUDING ONLY THESE FILE NAMES ${NAMES[*]}" -if [[ ${NAMES[0]} ]]; then - for name in "${NAMES[@]}"; do - debug only finding $name - FIND+=$(echo " -name '${name}'") - done -fi - -# if [[ $NAMES ]]; then -# debug names for find command $NAMES -# for name in $NAMES; do -# debug "xxonly finding '$name'" -# FIND+=$(set -o noglob;echo " -name '${name}'") -# done -# fi - - -# echo -# echo find dir: $DIR >&2 -debug "find command: $FIND" -set +o noglob -local FILES -FILES=$(eval $FIND | sort) -[[ $FILES ]] && echo $FILES -return 0 -} - -source_dir () { - # echo passed: $* - debug function: source_dir - local FILES - FILES=$(_find "$@") # find function - # echo $FILES >&2 - [[ $? -ne 0 ]] && return 1 - for f in $FILES; do - # echo sourcing: $f >&2 - source "$f" - done - -} - -prepend_file () { -# ---------------------------------------------------------------------------------------------------------------------- -# usage prepend_file -# ---------------------------------------------------------------------------------------------------------------------- -# Prepend the contents of [$1], to [$2], leaving the result in [$2]. -# insert a newline at the end of [$1] if necessary -# ---------------------------------------------------------------------------------------------------------------------- - -# check # echo $1 $2 -[[ -f $1 ]] || return 1 -[[ -f $2 ]] || return 2 -# init -tmp_fn=$( mktemp -t TEMP_FILE_prepend.XXXXXXXX ) -chmod 600 "$tmp_fn" -\cp $1 $tmp_fn -sed -i '$a\' $tmp_fn -cat $2 >> $tmp_fn -\mv "$tmp_fn" "$2" -# cleanup -rm -f "$tmp_fn" -return 0 - -# [End] -} diff --git a/lib/helpers.lib b/lib/helpers.lib new file mode 100755 index 0000000..6586c1b --- /dev/null +++ b/lib/helpers.lib @@ -0,0 +1,104 @@ +#!/bin/bash + +isAbsPath() { + if [[ "${1:0:1}" == / || "${1:0:2}" == ~[/a-z] ]] + then + echo "true" + return 0 + else + return 1 + fi +} + +sed_ignore_comments () { + cmd="sed -r 'h;s/[^#]*//1;x;s/#.*//;${1};G;s/(.*)\n/\1/'" + if (( $# == 2 )) ; then + eval $cmd <<< "$2" + else + eval $cmd < /dev/stdin + fi +} + +clean_env_file () { + local compact + # -c will also remove comments and all empty lines + [[ $1 == "-c" ]] && compact=true && shift 1 + # + # remove trailing spaces | remove double quotes + # | remove blanks after equals and quote value | remove any spaces before afer = + # remove blank lines | remove comment lines if requested + cat $1 | sed_ignore_comments s/\\s*$//g | sed_ignore_comments s/\"//g \ + | sed_ignore_comments s/\(=[[:blank:]]*\)\(.*\)/\\1\"\\2\"/ \ + | sed_ignore_comments s/\\s*=\\s*/=/g \ + | sed -rz 's/^\n+//; s/\n+$/\n/g' | if [[ $compact ]]; then grep -v '^#' | grep -v "^$" ; else cat; fi +} + +env_file () { + env=${1:-.env} + [[ -f "${env}" ]] && { echo $env; return 0; } # || echo not $env + [[ -f "${env}.env" ]] && { echo "${env}.env"; return 0; } # || echo not ${env}.env + [[ -f "${env}/.env" ]] && { echo "${env}/.env"; return 0; } # || echo not ${env}/.env + return 1 +} + +read_env_file() { + while read line; do + evar=$(echo $line | cut -d '=' -f1) + if [[ ! ${!evar} ]]; then + # echo DECLARE $evar via $line + if declare -gx "$(echo "${line}" | sed 's/\"//g' )"; then + echo loaded: ${evar}=${!evar} + else + echo error setting $evar + return 1 + + fi + else + echo $evar already set to ${!evar} + fi + done < <(clean_env_file -c $1) +} + +source_env_file () { + local default + if efile=$(env_file $1); then + [[ $efile == ".env" ]] && default=true + [[ ! $(isAbsPath $efile) ]] && efile=$(realpath $efile) + echo -e "\e[1;37m********************\e[0;37m" + echo loading build environment with environment file + echo $efile + echo ---------------- + cat $efile + echo ---------------- + if read_env_file "$efile"; then + [[ $default ]] && echo -e "\e[1;31mNOTE: sourced default .env file in present directory\e[0;37m" + echo -e "\e[1;37m********************\e[0;37m" + else + echo error occured while loading environment file + echo $efile + echo exiting + echo -e "\e[1;37m********************\e[0;37m" + return 2 + fi + else + if [[ $efile ]]; then + echo unable to find an environment file with passed ${1} + else + echo unable to find default environment file .env + echo using passed and default build options + fi + return 2 + fi + +} + +docker_image_distro() { +local temp=/tmp/os-release.tmp +docker create --name dummy $1 > /dev/null +docker cp -L dummy:/etc/os-release $temp +docker rm -f dummy > /dev/null +echo $(cat $temp | tr [:upper:] [:lower:] | grep -Poi '(debian|ubuntu|red hat|centos|arch|alpine)' | uniq) +rm $temp +} + +(return 0 2>/dev/null) || docker_image_distro $@ \ No newline at end of file diff --git a/lib/load.sh b/lib/load.sh index 2f6bbb3..71296a6 100755 --- a/lib/load.sh +++ b/lib/load.sh @@ -1,4 +1,9 @@ +#!/bin/bash declare libdir libdir=$(dirname "$(realpath "$BASH_SOURCE")") -source $libdir/file.mod -source_dir $libdir/src \ No newline at end of file +source $libdir/helpers.lib +for f in $libdir/cmds/*; do + # echo sourcing: $f >&2 + source "$f" +done + diff --git a/lib/src/01-helpers b/lib/src/01-helpers deleted file mode 100755 index 763508c..0000000 --- a/lib/src/01-helpers +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -function get_distro() { -/bin/cp /etc/os-release /tmp/os-release.tmp -if [[ $1 == "-d" ]]; then -shift 1 -# docker run -it --name get_container_os --rm --entrypoint cat $1 /etc/os-release -docker create --name dummy $1 > /dev/null -docker cp -L dummy:/etc/os-release /tmp/os-release.tmp -docker rm -f dummy > /dev/null -# docker run -it --name get_container_os --rm --entrypoint cat $1 /etc/os-release > /tmp/container-os.tmp 2> /dev/null -shift 1 -fi -source /tmp/os-release.tmp -declare valid=${@:-"alpine debian ubuntu"} -# echo $ID $ID_LIKE -[[ "${valid}" =~ $ID ]] && echo $ID && return 0 -[[ "${valid}" =~ $ID_LIKE ]] && echo $ID_LIKE && return 0 -return 1 -} - -isAbsPath() { - if [[ "${1:0:1}" == / || "${1:0:2}" == ~[/a-z] ]] - then - echo "true" - return 0 - else - return 1 - fi -} \ No newline at end of file