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
master
David Kebler 2023-03-27 11:07:25 -07:00
parent 40a8dc2297
commit bc0d3a72a5
15 changed files with 249 additions and 437 deletions

View File

@ -1,7 +1,6 @@
# syntax=docker/dockerfile:latest # syntax=docker/dockerfile:latest
ARG BASE_IMAGE ARG BASE_IMAGE
FROM $BASE_IMAGE FROM $BASE_IMAGE
ARG PENV
ARG BASE_IMAGE ARG BASE_IMAGE
ARG KEEP ARG KEEP
ARG SYSADMIN_PW ARG SYSADMIN_PW
@ -12,7 +11,6 @@ WORKDIR $BUILD_DIR
COPY .src/packages ./packages COPY .src/packages ./packages
# PACKAGES # PACKAGES
RUN \ RUN \
# --mount=type=cache,target=/var/cache/apt \
echo -e "\n ************************************************* \n"\ echo -e "\n ************************************************* \n"\
echo "****** Building Image from Base: $BASE_IMAGE; : Distro: $LINUX_DISTRO; *****"; \ echo "****** Building Image from Base: $BASE_IMAGE; : Distro: $LINUX_DISTRO; *****"; \
echo " ---- running packages install script ---"; \ echo " ---- running packages install script ---"; \

147
build
View File

@ -3,7 +3,8 @@
docker_image_build () { docker_image_build () {
local targets=(dev arm amd deploy private multi) 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 declare OPTION; declare OPTARG; declare OPTIND
BDIR=$(dirname "$(realpath "$BASH_SOURCE")") BDIR=$(dirname "$(realpath "$BASH_SOURCE")")
@ -51,26 +52,12 @@ exit_abnormal() { # Function: Exit with error.
[[ -z "$PS1" ]] || no_prompt=true [[ -z "$PS1" ]] || no_prompt=true
overwrite=true overwrite=true
target=dev
while getopts 'g:e:b:d:t:ncr:u:plhs:w:akvoi' OPTION; do while getopts 'g:e:b:d:t:ncr:u:plhs:w:akvoi' OPTION; do
# echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND} # echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
case "$OPTION" in case "$OPTION" in
e) e)
local efile if source_env_file $OPTARG; then efile=true; else return 2; fi
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
;; ;;
o) o)
unset overwrite unset overwrite
@ -107,7 +94,7 @@ while getopts 'g:e:b:d:t:ncr:u:plhs:w:akvoi' OPTION; do
append_distro=true append_distro=true
;; ;;
t) t)
target=$OPTARG TARGET=$OPTARG
;; ;;
g) g)
TAG=$OPTARG TAG=$OPTARG
@ -118,9 +105,10 @@ while getopts 'g:e:b:d:t:ncr:u:plhs:w:akvoi' OPTION; do
c) c)
try=true try=true
;; ;;
p) # TODO: push after build
push=true # p)
;; # push=true
# ;;
n) n)
nocache="--no-cache" nocache="--no-cache"
;; ;;
@ -133,14 +121,23 @@ while getopts 'g:e:b:d:t:ncr:u:plhs:w:akvoi' OPTION; do
;; ;;
*) *)
echo "unknown $0 option -$OPTARG" echo "unknown $0 option -$OPTARG"
exit_abnormal 4 exit_abnormal 1
;; ;;
esac esac
done done
shift $((OPTIND - 1)) 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 [[ ! $(isAbsPath $BUILD_SRC) ]] ; then
if [[ ${BUILD_SRC} == "_base_" ]]; then if [[ ${BUILD_SRC} == "_base_" ]]; then
@ -150,50 +147,68 @@ if [[ ! $(isAbsPath $BUILD_SRC) ]] ; then
fi fi
fi fi
log_dir=$PWD/logs if [[ ! ( -d $BUILD_SRC/packages && -d $BUILD_SRC/init ) ]]; then
mkdir -p $log_dir echo -e "\e[1;31minvalid build source directory"
echo $BUILD_SRC
if [[ ! -d $BUILD_SRC ]]; then echo -e "it does not contain packages and init subirectories\e[1;37m"
if [[ ! $(basename $BUILD_SRC) == "src" ]]; then
if $no_prompt ; then echo checking in src/ subdirectory for source
echo -e "\e[1;31mWARNING: no build source directory at $BUILD_SRC was not found" if [[ ( -d $BUILD_SRC/src/packages && -d $BUILD_SRC/src/init ) ]]; then
echo aborting... BUILD_SRC=$BUILD_SRC/src
echo -e "\e[1;31mNOTE: use '_base_' to explicitly use the in uci-docker-build repo\e[1;37m" echo found source in src/ subdirectory changing to source directory to
return 3 echo $BUILD_SRC
else
echo -e "\e[1;31mERROR: no build source directory at $BUILD_SRC</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 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 "Do you want to use the uci-docker-build repo source scripts"
echo "at $BDIR/src " echo "at $BDIR/src "
read -n 1 -p "instead? [y]=>" REPLY read -n 1 -p "instead? [y]=>" REPLY
[[ $REPLY != "y" ]] && echo -e "\n" && return 0 [[ $REPLY != "y" ]] && echo -e "\n" && return 2
BUILD_SRC=$BDIR/src BUILD_SRC=$BDIR/src
echo -e "\n\e[1;31mNOTE: use '_base_' to explicitly use the in uci-docker-build repo\e[1;37m" 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
fi fi
# done processing build source directory
pushd $BDIR || return 3 log_dir=$PWD/logs
mkdir -p $log_dir
[[ ! "${targets[@]}" =~ $target ]] && echo $target is not a valid target && echo valid targets are: ${targets[@]} && exit 4 pushd "$BDIR" > /dev/null || return 3
[[ ! "${targets[@]}" =~ $TARGET ]] && echo $TARGET is not a valid target && echo valid targets are: ${targets[@]} && exit 4
LINUX_DISTRO=${LINUX_DISTRO:-alpine} LINUX_DISTRO=${LINUX_DISTRO:-alpine}
if [[ $BASE_IMAGE ]]; then if [[ $BASE_IMAGE ]]; then
echo determining DISTRO of base image: $BASE_IMAGE echo determining DISTRO of base image: $BASE_IMAGE
LINUX_DISTRO=$(get_distro -d $BASE_IMAGE) LINUX_DISTRO=$(docker_image_distro $BASE_IMAGE)
[[ ! $LINUX_DISTRO ]] && echo "unable to get base image OS for: $BASE_IMAGE, aborting build" && exit 1 [[ ! $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 echo $BASE_IMAGE is built from distro $LINUX_DISTRO
else else
BASE_IMAGE=$LINUX_DISTRO BASE_IMAGE=$LINUX_DISTRO
fi fi
NAME=${NAME:-$1} if [[ $1 ]]; then
RUSER=${2:-$RUSER} [[ $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 if [[ $NAME ]]; then
[[ $add_distro ]] && NAME=$NAME-${LINUX_DISTRO} [[ $add_distro ]] && NAME=$NAME-${LINUX_DISTRO}
else else
echo no image name supplied using distro name $LINUX_DISTRO
NAME=${LINUX_DISTRO} NAME=${LINUX_DISTRO}
fi fi
IMAGE_NAME=$([[ $RUSER ]] && echo ${RUSER}/)${NAME} IMAGE_NAME=$([[ $RUSER ]] && echo ${RUSER}/)${NAME}
# TODO writing to existing tag untags existing image so write a new tag to that image then continue # 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 export SYSADMIN_PW
echo -e "\n******************************************" echo -e "\e[1;37m********************"
echo "Using scripts source directory at $BUILD_SRC" echo "Using scripts source directory at $BUILD_SRC"
echo "Building with base image: $BASE_IMAGE" echo "Building with base image: $BASE_IMAGE"
echo "Outputing to image name => $IMAGE_NAME<-arch>:${TAG:-latest}" echo "Outputing to image name => $IMAGE_NAME<-arch>:${TAG:-latest}"
echo "Linux Distro: $LINUX_DISTRO" echo "Linux Distro: $LINUX_DISTRO"
echo "Using build target: $target" echo "Using build target: $TARGET"
echo "Build Command: docker buildx --builder ${builder} bake ${nocache} ${target}" echo "Build Command: docker buildx --builder ${builder} bake ${nocache} ${TARGET}"
if [[ $verbose ]]; then if [[ $verbose ]]; then
echo -e "\n---------------------------------" echo -e "\n---------------------------------"
docker buildx bake --print $target docker buildx bake --print $TARGET
echo -e "\n---------------------------------" echo -e "\n---------------------------------"
echo "build scripts at $BUILD_SRC to be copied to ${BUILD_DIR:-/build} in container ***** " echo "build scripts at $BUILD_SRC to be copied to ${BUILD_DIR:-/build} in container ***** "
ls -la $BUILD_SRC ls -la $BUILD_SRC
@ -238,15 +253,15 @@ if [[ $verbose ]]; then
cat $BUILD_SRC/init.sh cat $BUILD_SRC/init.sh
echo -e "\n---------------------------------" echo -e "\n---------------------------------"
fi fi
echo -e "\n***************************************" echo -e "u********************\e[0;37m"
if [[ ! $no_prompt ]]; then if [[ ! $no_prompt ]]; then
read -n 1 -p "do you want to continue [y]=>" REPLY 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 fi
builder=default builder=default
if [ $target == "deploy" ]; then if [ $TARGET == "deploy" ]; then
builder=deploy builder=deploy
if ! docker buildx ls | grep -q deploy ; then if ! docker buildx ls | grep -q deploy ; then
echo multiarch deploy builder does not exist, creating with docker-container driver echo multiarch deploy builder does not exist, creating with docker-container driver
@ -255,7 +270,7 @@ if [ $target == "deploy" ]; then
fi fi
fi fi
[[ $target == "private" && ! $REPO ]] && echo "must use '-r <private repo>' if building to private repo" && exit 3 [[ $TARGET == "private" && ! $REPO ]] && echo "must use '-r <private repo>' if building to private repo" && exit 3
# copy source directory to temporary .src/ subdirectory # copy source directory to temporary .src/ subdirectory
# MUST either be readable by all or group readable by docker group # 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 rsync -aAru ${BUILD_SRC:-src}/ $BDIR/.src
ls -la $BDIR/.src ls -la $BDIR/.src
docker buildx --builder ${builder} bake ${nocache} ${target} 2>&1 | tee "$log_dir/${IMAGE_NAME//\//-}build.log" 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 [[ $? == 0 ]] && echo succcess building image $IMAGE_NAME || exit_abnormal 5
rm -rf $BDIR/.src 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 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 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 fi
#echo reset to calling directory $PWD
} }
# if script was executed then call the function # if script was executed then call the function
(return 0 2>/dev/null) || docker_image_build $@ (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

View File

@ -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

View File

@ -1 +1 @@
dbuild -e example-build.env "$@" dbuild -e example.env "$@"

29
examples/example.env Normal file
View File

@ -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

View File

@ -6,17 +6,22 @@ image_push () {
# if not reposity is given will use docker.io and push to hub.docker.com # if not reposity is given will use docker.io and push to hub.docker.com
# $1 name, $2 user(or repo), $3 repo # $1 name, $2 user(or repo), $3 repo
source=$$image_name
declare OPTION; declare OPTARG; declare OPTIND 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} # echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
case "$OPTION" in case "$OPTION" in
e) e) if ! source_env_file $OPTARG ; then return 2; fi
efile=$OPTARG
;; ;;
h) # pull image from dockerhub if not available t)
TAG=$OPTARG
;;
u)
RUSER=$OPTARG
;;
r)
REPO=$OPTARG
;;
d) # pull image from dockerhub if not available
hub=true hub=true
;; ;;
*) echo unknown run option -$OPTARG *) echo unknown run option -$OPTARG
@ -28,22 +33,8 @@ done
shift $((OPTIND - 1)) 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 # image tag
name=$1 name=${1:-$NAME}
user=${2:-$RUSER} user=${2:-$RUSER}
repo=${3:-$REPO} repo=${3:-$REPO}

View File

@ -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 <somefile> <anotherfile>
# ----------------------------------------------------------------------------------------------------------------------
# Prepend the contents of <somefile> [$1], to <anotherfile> [$2], leaving the result in <anotherfile> [$2].
# insert a newline at the end of <somefile> [$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]
}

104
lib/helpers.lib Executable file
View File

@ -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 $@

View File

@ -1,4 +1,9 @@
#!/bin/bash
declare libdir declare libdir
libdir=$(dirname "$(realpath "$BASH_SOURCE")") libdir=$(dirname "$(realpath "$BASH_SOURCE")")
source $libdir/file.mod source $libdir/helpers.lib
source_dir $libdir/src for f in $libdir/cmds/*; do
# echo sourcing: $f >&2
source "$f"
done

View File

@ -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
}