594 lines
11 KiB
Bash
594 lines
11 KiB
Bash
#!/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 <<EOF >&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 </dev/urandom | head -c $length)
|
|
}
|
|
|
|
check_missing_dest_dir()
|
|
{
|
|
local dir=$1
|
|
if [[ -n $defer ]]
|
|
then
|
|
$defer "create $dir if it does not exist"
|
|
else
|
|
|
|
if [[ ! -d $dir ]]
|
|
then
|
|
echo "[ERROR] '$dir' does not exist please create it."
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
sed_substitute_expr()
|
|
{
|
|
local from="$1"
|
|
shift
|
|
local to="$1"
|
|
shift
|
|
local s='/'
|
|
if [[ $from =~ [\\] ]]
|
|
then
|
|
# escape char \ should be doubled
|
|
from=${from//\\/\\\\}
|
|
fi
|
|
if [[ $from =~ $s ]]
|
|
then
|
|
# echo "[ERROR] character $s is prohibited due to sed usage" >&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
|