2024-07-11 13:37:35 +03:00
|
|
|
#!/bin/sh
|
|
|
|
|
2024-07-15 16:15:47 +03:00
|
|
|
volume_root='/run/angie'
|
|
|
|
tmp_dir="${volume_root}/tmp"
|
|
|
|
merged_root="${volume_root}/merged"
|
|
|
|
target_root="${volume_root}"
|
|
|
|
|
2024-07-11 13:37:35 +03:00
|
|
|
have_envvar() {
|
|
|
|
[ -n "$1" ] || return 1
|
|
|
|
grep -Ezq "^$1=" /proc/self/environ || return
|
|
|
|
}
|
|
|
|
|
|
|
|
## unexporting variable in (POSIX) sh is PITA =/
|
|
|
|
unexport() {
|
|
|
|
unset ___k ___v
|
|
|
|
for ___k ; do
|
|
|
|
[ -n "${___k}" ] || continue
|
|
|
|
have_envvar "${___k}" || continue
|
|
|
|
|
|
|
|
___v=$(eval printf '%s' "\"\${${___k}}\"")
|
|
|
|
eval "unset ${___k}"
|
|
|
|
eval "${___k}=$(env printf '%s' \"\${___v}\")"
|
|
|
|
unset ___v
|
|
|
|
done
|
|
|
|
unset ___k
|
|
|
|
}
|
|
|
|
|
|
|
|
## likely the same as in https://pkg.go.dev/strconv#ParseBool
|
|
|
|
gobool_to_int() {
|
|
|
|
## local value=$1
|
|
|
|
## local default=$2
|
|
|
|
case "${1:-_}" in
|
|
|
|
1 | [Tt] | [Tt][Rr][Uu][Ee] ) echo 1 ;;
|
|
|
|
0 | [Ff] | [Ff][Aa][Ll][Ss][Ee] ) echo 0 ;;
|
|
|
|
* ) echo "${2:-error}" ;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
[ -n "${__IEP_SRC:-}" ] || __IEP_SRC="$0"
|
|
|
|
|
|
|
|
IEP_TRACE=$(gobool_to_int "${IEP_TRACE:-0}" 0)
|
|
|
|
export IEP_TRACE
|
|
|
|
if [ "${IEP_TRACE}" = 1 ] ; then
|
|
|
|
log_always() { echo "# $(date +'%Y-%m-%d %H:%M:%S.%03N %z'): ${__IEP_SRC}${*:+: $*}" >&2 ; }
|
|
|
|
else
|
|
|
|
log_always() { echo "# ${__IEP_SRC}${*:+: $*}" >&2 ; }
|
|
|
|
fi
|
|
|
|
|
|
|
|
IEP_VERBOSE=$(gobool_to_int "${IEP_VERBOSE:-${IEP_TRACE}}" "${IEP_TRACE}")
|
|
|
|
export IEP_VERBOSE
|
|
|
|
if [ "${IEP_VERBOSE}" = 1 ] ; then
|
|
|
|
log() { log_always "$@" ; }
|
|
|
|
else
|
|
|
|
log() { : ;}
|
|
|
|
fi
|
|
|
|
|
2024-07-15 16:15:47 +03:00
|
|
|
log_file() { sed -E '/^./s,^, ,' < "$1" >&2 ; }
|
|
|
|
|
2024-07-11 13:37:35 +03:00
|
|
|
if [ "${IEP_VERBOSE}" = 0 ] ; then
|
|
|
|
ln_s() { ln -s "$@" || return; }
|
2024-07-15 16:15:47 +03:00
|
|
|
cp_a() { cp -a "$@" || return; }
|
2024-07-11 13:37:35 +03:00
|
|
|
else
|
|
|
|
ln_s() { ln -sv "$@" || return; }
|
2024-07-15 16:15:47 +03:00
|
|
|
cp_a() { cp -av "$@" || return; }
|
2024-07-11 13:37:35 +03:00
|
|
|
fi
|
|
|
|
|
2024-07-15 16:15:47 +03:00
|
|
|
ln_cp() {
|
|
|
|
if [ -h "$1" ] ; then
|
|
|
|
ln_s "$(readlink -e "$1")" "$2"
|
|
|
|
else
|
|
|
|
cp_a "$1" "$2"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2024-07-11 13:37:35 +03:00
|
|
|
have_cmd() { command -v "$1" >/dev/null 2>&1 || return ; }
|
|
|
|
|
|
|
|
strip_suffix() { printf '%s' "${1%"$2"}" | tr -s '/' ; }
|
|
|
|
|
|
|
|
untemplate_path() {
|
|
|
|
case "$1" in
|
|
|
|
## inplace
|
2024-07-15 16:15:47 +03:00
|
|
|
"${volume_root}"/* | /etc/angie/run/* )
|
2024-07-11 13:37:35 +03:00
|
|
|
strip_suffix "$1" "$2"
|
|
|
|
;;
|
|
|
|
/etc/angie/conf.d/* | /etc/angie/mod.d/* | /etc/angie/modules.d/* | /etc/angie/njs.d/* | /etc/angie/site.d/* | /etc/angie/snip.d/* )
|
|
|
|
strip_suffix "$1" "$2"
|
|
|
|
;;
|
|
|
|
/etc/angie/static.d/* )
|
|
|
|
strip_suffix "$1" "$2"
|
|
|
|
;;
|
|
|
|
## set appropriate location
|
|
|
|
/etc/angie/* )
|
2024-07-15 16:15:47 +03:00
|
|
|
strip_suffix "${volume_root}${1#/etc/angie}" "$2"
|
2024-07-11 13:37:35 +03:00
|
|
|
;;
|
|
|
|
/tmp/* )
|
|
|
|
log_always "untemplate_path() shouldn't work with /tmp/: $1"
|
|
|
|
strip_suffix "$1" "$2"
|
|
|
|
;;
|
|
|
|
## last resort - STRONGLY AVOID
|
|
|
|
/* )
|
|
|
|
log_always "untemplate_path() does uncommon/last-resort mapping for: $1"
|
2024-07-15 16:15:47 +03:00
|
|
|
strip_suffix "${tmp_dir}$1" "$2"
|
2024-07-11 13:37:35 +03:00
|
|
|
;;
|
|
|
|
## misbehavior!
|
|
|
|
* )
|
|
|
|
log_always "untemplate_path() doesn't work with relative paths: $1"
|
|
|
|
return 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
install_userdir() {
|
|
|
|
if [ "${IEP_ROOT}" = 1 ] ; then
|
|
|
|
install -d -o "${NGX_USER}" -g "${NGX_GROUP}" "$@"
|
|
|
|
else
|
|
|
|
install -d "$@"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
untemplate_file_envsubst() {
|
|
|
|
[ -n "$1" ] || return
|
|
|
|
[ -f "$1" ] || { log_always "file not found: $1" ; return 1 ; }
|
|
|
|
|
|
|
|
[ -n "${NGX_ENVSUBST_SUFFIX:-}" ] || { log "NGX_ENVSUBST_SUFFIX is empty" ; return 1 ; }
|
|
|
|
|
|
|
|
__dest="$2"
|
|
|
|
[ -n "${__dest}" ] || __dest=$(untemplate_path "$1" "${NGX_ENVSUBST_SUFFIX}") || return
|
|
|
|
|
2024-07-15 16:15:47 +03:00
|
|
|
if [ -e "${__dest}" ] ; then
|
|
|
|
log "untemplate_file_envsubst: destination file already exists"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
2024-07-11 13:37:35 +03:00
|
|
|
[ -d "${__dest%/*}" ] || install_userdir "${__dest%/*}" || return
|
|
|
|
|
|
|
|
log "Running envsubst: $1 -> ${__dest}"
|
|
|
|
envsubst.sh < "$1" > "${__dest}" || return
|
|
|
|
}
|
|
|
|
|
|
|
|
## notes:
|
|
|
|
## - (OPTIONAL) place own wrapper script as "/usr/local/sbin/jinja.py"
|
|
|
|
## in order to perform different template processing
|
|
|
|
untemplate_file_jinja() {
|
|
|
|
[ -n "$1" ] || return
|
|
|
|
[ -f "$1" ] || { log_always "file not found: $1" ; return 1 ; }
|
|
|
|
|
|
|
|
[ -n "${NGX_JINJA_SUFFIX:-}" ] || { log "NGX_JINJA_SUFFIX is empty" ; return 1 ; }
|
|
|
|
|
|
|
|
__dest="$2"
|
|
|
|
[ -n "${__dest}" ] || __dest=$(untemplate_path "$1" "${NGX_JINJA_SUFFIX}") || return
|
|
|
|
|
2024-07-15 16:15:47 +03:00
|
|
|
if [ -e "${__dest}" ] ; then
|
|
|
|
log "untemplate_file_jinja: destination file already exists"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
2024-07-11 13:37:35 +03:00
|
|
|
[ -d "${__dest%/*}" ] || install_userdir "${__dest%/*}" || return
|
|
|
|
|
|
|
|
log "Running jinja.py: $1 -> ${__dest}"
|
|
|
|
jinja.py "$1" "${__dest}" || return
|
|
|
|
}
|
|
|
|
|
|
|
|
untemplate_dir_envsubst() {
|
|
|
|
[ -n "${NGX_ENVSUBST_SUFFIX:-}" ] || { log "NGX_ENVSUBST_SUFFIX is empty" ; return 1 ; }
|
|
|
|
|
|
|
|
__template_list=$(mktemp) || return
|
|
|
|
|
|
|
|
find "$@" -follow -type f -name "*${NGX_ENVSUBST_SUFFIX}" \
|
|
|
|
| sort -uV > "${__template_list}"
|
|
|
|
|
|
|
|
__have_args="${ENVSUBST_ARGS:+1}"
|
|
|
|
if [ -z "${__have_args}" ] ; then
|
|
|
|
## optimize envsubst.sh invocation by caching argument list
|
|
|
|
## ref: envsubst.sh
|
|
|
|
ENVSUBST_ARGS=$(mktemp) || return
|
|
|
|
envsubst-args.sh > "${ENVSUBST_ARGS}"
|
|
|
|
export ENVSUBST_ARGS
|
|
|
|
fi
|
|
|
|
|
2024-07-15 16:15:47 +03:00
|
|
|
while read -r __orig_file ; do
|
|
|
|
[ -n "${__orig_file}" ] || continue
|
|
|
|
untemplate_file_envsubst "${__orig_file}"
|
2024-07-11 13:37:35 +03:00
|
|
|
done < "${__template_list}"
|
2024-07-15 16:15:47 +03:00
|
|
|
unset __orig_file
|
2024-07-11 13:37:35 +03:00
|
|
|
|
|
|
|
if [ -z "${__have_args}" ] ; then
|
|
|
|
rm -f "${ENVSUBST_ARGS}" ; unset ENVSUBST_ARGS
|
|
|
|
fi
|
|
|
|
unset __have_args
|
|
|
|
|
|
|
|
rm -f "${__template_list}" ; unset __template_list
|
|
|
|
}
|
|
|
|
|
|
|
|
untemplate_dir_jinja() {
|
|
|
|
[ -n "${NGX_JINJA_SUFFIX:-}" ] || { log "NGX_JINJA_SUFFIX is empty" ; return 1 ; }
|
|
|
|
|
|
|
|
__template_list=$(mktemp) || return
|
|
|
|
|
|
|
|
find "$@" -follow -type f -name "*${NGX_JINJA_SUFFIX}" \
|
|
|
|
| sort -uV > "${__template_list}"
|
|
|
|
|
2024-07-15 16:15:47 +03:00
|
|
|
while read -r __orig_file ; do
|
|
|
|
[ -n "${__orig_file}" ] || continue
|
|
|
|
untemplate_file_jinja "${__orig_file}"
|
2024-07-11 13:37:35 +03:00
|
|
|
done < "${__template_list}"
|
2024-07-15 16:15:47 +03:00
|
|
|
unset __orig_file
|
2024-07-11 13:37:35 +03:00
|
|
|
|
|
|
|
rm -f "${__template_list}" ; unset __template_list
|
|
|
|
}
|
|
|
|
|
|
|
|
remap_path() {
|
|
|
|
[ -n "$1" ] || return
|
|
|
|
|
|
|
|
case "$1" in
|
|
|
|
## conf
|
|
|
|
/etc/angie/conf.dist/* ) echo "${2:-/etc/angie/conf.d}${1#/etc/angie/conf.dist}" ;;
|
|
|
|
/etc/angie/conf/* ) echo "${2:-/etc/angie/conf.d}${1#/etc/angie/conf}" ;;
|
|
|
|
/angie/conf/* ) echo "${2:-/etc/angie/conf.d}${1#/angie/conf}" ;;
|
|
|
|
## mod
|
|
|
|
/etc/angie/mod.dist/* ) echo "${2:-/etc/angie/mod.d}${1#/etc/angie/mod.dist}" ;;
|
|
|
|
/etc/angie/mod/* ) echo "${2:-/etc/angie/mod.d}${1#/etc/angie/mod}" ;;
|
|
|
|
/angie/mod/* ) echo "${2:-/etc/angie/mod.d}${1#/angie/mod}" ;;
|
|
|
|
## modules
|
|
|
|
/etc/angie/modules.dist/* ) echo "${2:-/etc/angie/modules.d}${1#/etc/angie/modules.dist}" ;;
|
|
|
|
/etc/angie/modules/* ) echo "${2:-/etc/angie/modules.d}${1#/etc/angie/modules}" ;;
|
|
|
|
/angie/modules/* ) echo "${2:-/etc/angie/modules.d}${1#/angie/modules}" ;;
|
|
|
|
## njs
|
|
|
|
/etc/angie/njs.dist/* ) echo "${2:-/etc/angie/njs.d}${1#/etc/angie/njs.dist}" ;;
|
|
|
|
/etc/angie/njs/* ) echo "${2:-/etc/angie/njs.d}${1#/etc/angie/njs}" ;;
|
|
|
|
/angie/njs/* ) echo "${2:-/etc/angie/njs.d}${1#/angie/njs}" ;;
|
|
|
|
## site
|
|
|
|
/etc/angie/site.dist/* ) echo "${2:-/etc/angie/site.d}${1#/etc/angie/site.dist}" ;;
|
|
|
|
/etc/angie/site/* ) echo "${2:-/etc/angie/site.d}${1#/etc/angie/site}" ;;
|
|
|
|
/angie/site/* ) echo "${2:-/etc/angie/site.d}${1#/angie/site}" ;;
|
|
|
|
## snip
|
|
|
|
/etc/angie/snip.dist/* ) echo "${2:-/etc/angie/snip.d}${1#/etc/angie/snip.dist}" ;;
|
|
|
|
/etc/angie/snip/* ) echo "${2:-/etc/angie/snip.d}${1#/etc/angie/snip}" ;;
|
|
|
|
/angie/snip/* ) echo "${2:-/etc/angie/snip.d}${1#/angie/snip}" ;;
|
|
|
|
|
|
|
|
## static
|
|
|
|
/etc/angie/static.dist/* ) echo "${2:-/etc/angie/static.d}${1#/etc/angie/static.dist}" ;;
|
|
|
|
/etc/angie/static/* ) echo "${2:-/etc/angie/static.d}${1#/etc/angie/static}" ;;
|
|
|
|
/angie/static/* ) echo "${2:-/etc/angie/static.d}${1#/angie/static}" ;;
|
|
|
|
|
|
|
|
## log
|
|
|
|
/etc/angie/log.dist/* ) echo "${2:-/etc/angie/log.d}${1#/etc/angie/log.dist}" ;;
|
|
|
|
/angie/log/* ) echo "${2:-/etc/angie/log.d}${1#/angie/log}" ;;
|
|
|
|
|
|
|
|
## misbehavior!
|
|
|
|
* )
|
|
|
|
log_always "remap_path() doesn't know how to handle this path: $1"
|
|
|
|
return 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
combine_remap_path() {
|
|
|
|
[ -n "$1" ] || return
|
|
|
|
|
|
|
|
case "$1" in
|
2024-07-15 16:15:47 +03:00
|
|
|
"${merged_root}"/* ) echo "${2:-${target_root}}${1#"${merged_root}"}" ;;
|
2024-07-11 13:37:35 +03:00
|
|
|
## misbehavior!
|
|
|
|
* )
|
|
|
|
log_always "combine_remap_path() doesn't know how to handle this path: $1"
|
|
|
|
return 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
2024-07-15 16:15:47 +03:00
|
|
|
|
|
|
|
is_builtin_module() {
|
|
|
|
[ -n "${1:-}" ] || return 1
|
|
|
|
[ -n "${2:-}" ] || return 1
|
|
|
|
|
|
|
|
[ -f "/etc/angie/builtin.$1" ] || return 1
|
|
|
|
[ -s "/etc/angie/builtin.$1" ] || return 1
|
|
|
|
|
|
|
|
grep -Fxq -e "$2" "/etc/angie/builtin.$1" || return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
sort_dedup_list() {
|
|
|
|
[ -n "$1" ] || return 0
|
|
|
|
|
|
|
|
printf '%s' "$1" \
|
|
|
|
| tr -s '[:space:]' '\n' | sort -uV | paste -sd ' ' \
|
|
|
|
| sed -zE 's/^\s+//;s/\s+$//'
|
|
|
|
}
|