#!/bin/bash # metascript to include # # usual way if no parameters used by outer script : # # source $(dirname "$0")/metascript.sh # # defaultmetainit $@ # metascript_included=yes # assume all tools are in lib/ toolsdir=$(dirname $(readlink -f $0))/lib # all tools resources are relative to this directory # project directory # relative # toolsparentdir=$(realpath --relative-to "$(pwd)" $(readlink -f $0))/ # absolute toolsparentdir=$(realpath $(readlink -f $0))/ if [[ -z $log_functions ]] then log_functions=$toolsdir/log_functions.sh [[ -f $log_functions ]] || { echo "[FATAL] Missing $log_functions" >&2 ; exit 1 ;} source $log_functions fi metascript_usage() { cat <&2 metascript commands : help|usage help or usage of this {$0} tool dryrun|show|showdoc display what should/will be done defersource= script file defining defer() non sandard function defer= defer function to use, default is showdoc toolsresourcesdir= where to pick resource default to parent of script $toolsresourcesdir mostly used with dryrun apply default : will actual do work without defer EOF } usage() { echo "[WARNING} no specific usage function for {$0}, to improve by developer" >&2 echo >&2 metascript_usage } showinfo() { echo $@ } showdoc() { if [[ $1 =~ ^tools/ ]] then # assumes it handles ENV_METASCRIPT_DEFER $@ else echo '```' autoquoteargs $@ echo echo '```' fi } redirectto() { tofile=$1 if [[ -n $defer ]] then echo "Copy to $tofile" echo '```' cat echo '```' else cat > $tofile fi } execredirectfrom() { tofile=$1 shift if [[ -n $defer ]] then echo '```' autoquoteargs $@ echo ' < '"$tofile" echo '```' else $@ < $tofile fi } execredirectto() { tofile=$1 shift if [[ -n $defer ]] then echo '```' autoquoteargs $@ echo ' > '"$tofile" echo '```' else $@ > $tofile fi } pipeto() { if [[ -n $defer ]] then echo '```' echo -n 'cat << EOF| ' autoquoteargs $@ echo cat echo "EOF" echo '```' else cat | $@ fi } query_ext() { local prompt="$1" local var=$2 if [[ -n $defer ]] then # uppercase it eval $var=${var^^} $defer query $prompt "$(eval echo \$$var)" else echo -ne $prompt read $var fi } # two arguments first prompt, second name of var query_password() { local prompt="$1" local var=$2 if [[ -n $defer ]] then # uppercase it eval $var=${var^^} $defer query_password "\"$prompt\"" "$(eval echo \$$var)" else read -sp "$prompt" $var echo fi } # echo yes if reply match ^[Yy]([eE][sS]|)$ or no if does not match. query_yesno() { local prompt="$1" local yesno=no read -p "$prompt (Yes/No) " yesno if [[ $yesno =~ ^[Yy]([eE][sS]|)$ ]] then echo yes else echo no fi } # through hardcoded 'secret' variable create_secret() { # global secret # declare -g secret # export -n secret local -i length=$1 [[ -z $length ]] && length = 32 if (( length < 8 )) then log_warn "secret length $length < 8. very small" fi # secret=$(echo $RANDOM | md5sum | head -c $length) secret=$(tr -dc A-Za-z0-9 &2 from=${from//$s/\\$s} fi if [[ $from =~ \[ ]] then from=${from//\[/\\\[} fi if [[ $from =~ \* ]] then from=${from//\*/\\\*} fi if [[ $from =~ ^(.*)\$$ ]] then from=${BASH_REMATCH[1]}'\$' fi if [[ $from =~ ^\^(.*)$ ]] then from='\^'${BASH_REMATCH[1]} fi if [[ $to =~ [\\] ]] then # escape char \ should be doubled to=${to//\\/\\\\} fi if [[ $to =~ $s ]] then # echo "[ERROR] character $s is prohibited due to sed usage" >&2 # echo "This is a limitation of metascript.sh script, replaced by \$s" >&2 to=${to//$s/\\$s} fi if [[ $to =~ [\&] ]] then # echo "[ERROR] character & is prohibited due to sed usage" >&2 to=${to//\&/\\\&} fi # replace it globaly echo "s$s$from$s$to${s}g" } sedreplacefromto() { local from="$1" local to="$2" shift 2 local sedexpr="$1" execredirectto $to sed "$sedexpr" $from shift while [[ $# > 0 ]] do sedexpr="$1" $defer sed -i "$sedexpr" $to shift done } replacefromto() { local from="$1" local to="$2" shift 2 if [[ -n $defer ]] then $defer "replace $@ from '$from' into '$to'" else local sedexpr=$(sed_substitute_expr "$1" "$2") execredirectto $to sed "$sedexpr" $from shift 2 while [[ $# > 0 ]] do sedexpr=$(sed_substitute_expr "$1" "$2") $defer sed -i "$sedexpr" $to shift 2 done fi } sedreplacein() { local file=$1 shift while [[ $# > 0 ]] do $defer sed -i "$1" $file shift done } replacein() { local infile=$1 shift if [[ -n $defer ]] then $defer "replace $@ into '$infile'" else while [[ $# > 0 ]] do sedexpr=$(sed_substitute_expr "$1" "$2") $defer sed -i "$sedexpr" $infile shift 2 done fi } parsemetaarg() { case $1 in apply) defer= ;; defersource=*) defersource=${1/defersource=/} ;; defer=*) defer=${1/defer=/} ;; dryrun|show|showdoc) defer=showdoc ;; help|usage) usage ;; toolsresourcesdir=*) toolsresourcesdir=${1/toolsresourcesdir=/} ;; scl_enable=*) scl_args=(scl enable ${1/scl_enable=/} --) ;; *) log_error "unrecognized argument '$1'" usage exit 1 ;; esac } enforcearg() { local var="$1" local default="$2" eval value='$'"$var" if [[ -z $value ]] then log_error "{0} expect '$var' to be set ex $var=$default" usage exit 1 fi } enforcefile() { file="$1" constraint="$2" if [[ ! -f "$file" ]] then if [[ $constraint = exists ]] then log_error "[ERROR] Missing expected $file" [[ -n $defer ]] || exit 1 fi else if [[ $constraint = does_not_exists ]] then log_error "[ERROR] '$file' already exists. Move it away" [[ -n $defer ]] || exit 1 fi fi } enforcedir() { dir="$1" constraint="$2" if [[ $constraint = does_not_exist ]] then if [[ -e $dir ]] then log_error "'$dir' already exists. Move it away" [[ -n $defer ]] || exit 1 fi fi if [[ $constraint = exists ]] then if [[ ! -d "$dir" ]] then if [[ -e "$dir" ]] then log_error "'$dir' already exists but is not a directory as expected" [[ -n $defer ]] || exit 1 fi log_error "[ERROR] Missing expected directory '$dir'" [[ -n $defer ]] || exit 1 fi fi } applymetaargs() { if [[ -n $defer ]] then if [[ -n $defersource ]] then if [[ -f $defersource ]] then log_any "source $defersource" source $defersource else exit_fatal "defersource $defersource provided but not a file" fi fi # $showinfo "generated with $0 $allparms" export ENV_METASCRIPT_DEFER="$defer" export ENV_METASCRIPT_RESOURCESDIR="$toolsresourcesdir" fi } defaultmetainit() { while [[ $# > 0 ]] do parsemetaarg "$1" shift done applymetaargs } read_organisation() { organisation_file=$(find organisation -name '*.conf') if [[ -f $organisation_file ]] then while read line do case $line in name=*) organisation_name=${line/name=/} ;; domain=*) organisation_domain=${line/domain=/} ;; ldap_base=*) organisation_ldap_base=${line/ldap_base=/} ;; image_keyword=*) organisation_image_keyword=${line/image_keyword=/} ;; *) log_warn "'$line' not recognized as an organisation parameter" ;; esac done < $organisation_file fi } check_variable_match() { local var="$1" local match="$2" local default="$3" local value="" eval value='$'"$var" if [[ -z "$value" ]] then echo "set $var to default value $default" eval "$var=$default" eval value='$'"$var" fi if [[ ! $value =~ $match ]] then log_error "$var $value should match $match" exit 1 fi } check_variable_in() { local var="$1" local default="$2" shift 2 local value="" local values=$@ eval value='$'"$var" if [[ -z "$value" ]] then echo "set $var to default value $default" eval "$var=$default" eval value='$'"$var" fi while [[ $# > 0 ]] do if [[ "$value" = "$1" ]] then return fi shift done log_error "'$var' should be within $values it is '$value'" exit 1 } check_root() { if [[ -n $defer ]] then $defer "{$0} script to run run as root or with sudo" else [[ $EUID -eq 0 ]] || { log_error "{$0} You have to be root or use sudo to run this script" exit 1; } fi } get_timestamp_second() { echo "$(date +"%Y%m%d%H%M%S")" } if [[ -z $ENV_METASCRIPT_RESOURCESDIR ]] then toolsresourcesdir=$toolsparentdir else toolsresourcesdir=$ENV_METASCRIPT_RESOURCESDIR fi # quick way to give scl patches to fill scl_arg array if [[ -f $toolsparentdir/.scl_env ]] then source $toolsparentdir/.scl_env fi # empty defer means doit defer=$ENV_METASCRIPT_DEFER showinfo=showinfo allparms=$@ applymetaargs=applymetaargs