refactor environment handling
also: - drop "njs" directories (not actually used nor useful) - rework jinja filters: more functions, shorter names, etc.
This commit is contained in:
parent
1dda7066c9
commit
a0a4531501
@ -37,7 +37,7 @@ RUN python3 -m compileall -q -j 2 /usr/local/lib/j2cfg/
|
|||||||
RUN libpython="${PYTHON_SITE_PACKAGES%/*}" ; \
|
RUN libpython="${PYTHON_SITE_PACKAGES%/*}" ; \
|
||||||
find "${libpython}/" -mindepth 1 -maxdepth 1 -printf '%P\0' \
|
find "${libpython}/" -mindepth 1 -maxdepth 1 -printf '%P\0' \
|
||||||
| sed -zEn \
|
| sed -zEn \
|
||||||
-e '/^(asyncio|collections|concurrent|encodings|html|importlib|json|logging|multiprocessing|re|urllib|xml)$/p' \
|
-e '/^(collections|importlib|json|re)$/p' \
|
||||||
| sort -zV \
|
| sort -zV \
|
||||||
| env -C "${libpython}" xargs -0r \
|
| env -C "${libpython}" xargs -0r \
|
||||||
python3 -m compileall -q -j 2 ; \
|
python3 -m compileall -q -j 2 ; \
|
||||||
@ -141,7 +141,7 @@ RUN install -d -o angie -g angie -m 03777 /angie /run/angie ; \
|
|||||||
ln -sv /run/angie/lock lock.d ; \
|
ln -sv /run/angie/lock lock.d ; \
|
||||||
ln -sv ${ANGIE_MODULES_DIR} modules.dist ; \
|
ln -sv ${ANGIE_MODULES_DIR} modules.dist ; \
|
||||||
## hyper-modular paths:
|
## hyper-modular paths:
|
||||||
data='conf j2cfg mod modules njs site snip static' ; \
|
data='conf j2cfg mod modules site snip static' ; \
|
||||||
vardata='cache lib log' ; \
|
vardata='cache lib log' ; \
|
||||||
for n in ${data} ; do \
|
for n in ${data} ; do \
|
||||||
for d in "$n" "$n.dist" ; do \
|
for d in "$n" "$n.dist" ; do \
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
{#- prologue -#}
|
|
||||||
{%- set preserve_env = ( j2cfg.core_preserve_environment or [] )|env_any_to_str_list -%}
|
|
||||||
{%- set have_tz = preserve_env|is_str_list_re_match('TZ(=|$)') -%}
|
|
||||||
{%- set have_malloc_arena = preserve_env|is_str_list_re_match('MALLOC_ARENA_MAX(=|$)') -%}
|
|
||||||
{#- main part -#}
|
|
||||||
{%- if not have_tz -%}
|
|
||||||
env TZ;
|
|
||||||
{% endif %}
|
|
||||||
{%- if not have_malloc_arena -%}
|
|
||||||
env MALLOC_ARENA_MAX;
|
|
||||||
{% endif %}
|
|
||||||
{%- for v in preserve_env -%}
|
|
||||||
{%- if re.search("(\"|'|\\s)", v) %}
|
|
||||||
{#- TODO: investigate corrent escape behavior for Angie/nginx -#}
|
|
||||||
env {{ v.__repr__() }};
|
|
||||||
{%- else %}
|
|
||||||
env {{ v }};
|
|
||||||
{%- endif %}
|
|
||||||
{%- endfor -%}
|
|
28
angie/conf.dist/core-worker-env.conf.j2
Normal file
28
angie/conf.dist/core-worker-env.conf.j2
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{#- prologue -#}
|
||||||
|
{#- NB: "TZ" is always provided by Angie itself -#}
|
||||||
|
{%- set s_vars = ['MALLOC_ARENA_MAX', 'GLIBC_TUNABLES', 'MALLOC_CONF'] -%}
|
||||||
|
{%- set c_env = ( j2cfg.core_worker_env or [] ) | any_to_env_dict -%}
|
||||||
|
{%- set c_vars = c_env | dict_keys -%}
|
||||||
|
{%- set c_vars_preserve = c_env | dict_empty_keys -%}
|
||||||
|
{%- set c_vars_override = c_env | dict_non_empty_keys -%}
|
||||||
|
{%- set vars_preserve = ( c_vars_preserve + ( s_vars | list_diff(c_vars) )) | sort -%}
|
||||||
|
{#- main part -#}
|
||||||
|
{%- if vars_preserve %}
|
||||||
|
## preserve
|
||||||
|
{%- for k in vars_preserve %}
|
||||||
|
env {{ k }};
|
||||||
|
{%- endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{%- if c_vars_override %}
|
||||||
|
## WARNING!
|
||||||
|
## explicit environment variables are NOT implemented
|
||||||
|
## reason: envs are supported only for http_perl but not for http_js/stream_js
|
||||||
|
## solution: provide environment variables explicitly
|
||||||
|
## and then list them in "core_worker_env" key in config
|
||||||
|
{%- for k in c_vars_override %}
|
||||||
|
{%- set v = c_env[k] -%}
|
||||||
|
# env {{ k }}={{ v.__repr__() }};
|
||||||
|
{%- endif %}
|
||||||
|
{%- endfor %}
|
||||||
|
{% endif %}
|
@ -1,7 +0,0 @@
|
|||||||
{#- prologue -#}
|
|
||||||
{%- set preserve_env = ( j2cfg.core_preserve_environment or [] )|env_any_to_str_list -%}
|
|
||||||
{%- set preserve_vars = preserve_env|str_list_re_fullmatch('[^=]+') -%}
|
|
||||||
{#- main part -#}
|
|
||||||
{% for v in preserve_vars -%}
|
|
||||||
{{ v }}
|
|
||||||
{% endfor -%}
|
|
10
angie/j2cfg.dist/core-worker-env.txt.j2
Normal file
10
angie/j2cfg.dist/core-worker-env.txt.j2
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{#- prologue -#}
|
||||||
|
{%- set s_vars = ['MALLOC_ARENA_MAX', 'GLIBC_TUNABLES', 'MALLOC_CONF'] -%}
|
||||||
|
{%- set c_env = ( j2cfg.core_worker_env or [] ) | any_to_env_dict -%}
|
||||||
|
{%- set c_vars = c_env | dict_keys -%}
|
||||||
|
{%- set c_vars_preserve = c_env | dict_empty_keys -%}
|
||||||
|
{%- set vars_preserve = ( c_vars_preserve + ( s_vars | list_diff(c_vars) )) | sort -%}
|
||||||
|
{#- main part -#}
|
||||||
|
{%- for k in vars_preserve -%}
|
||||||
|
{{ k }}
|
||||||
|
{% endfor -%}
|
@ -12,7 +12,7 @@ have_envvar() {
|
|||||||
|
|
||||||
## unexporting variable in (POSIX) sh is PITA =/
|
## unexporting variable in (POSIX) sh is PITA =/
|
||||||
unexport() {
|
unexport() {
|
||||||
unset ___k ___v
|
local ___k ___v
|
||||||
for ___k ; do
|
for ___k ; do
|
||||||
[ -n "${___k}" ] || continue
|
[ -n "${___k}" ] || continue
|
||||||
have_envvar "${___k}" || continue
|
have_envvar "${___k}" || continue
|
||||||
@ -20,9 +20,7 @@ unexport() {
|
|||||||
___v=$(eval printf '%s' "\"\${${___k}}\"")
|
___v=$(eval printf '%s' "\"\${${___k}}\"")
|
||||||
eval "unset ${___k}"
|
eval "unset ${___k}"
|
||||||
eval "${___k}=$(env printf '%s' \"\${___v}\")"
|
eval "${___k}=$(env printf '%s' \"\${___v}\")"
|
||||||
unset ___v
|
|
||||||
done
|
done
|
||||||
unset ___k
|
|
||||||
}
|
}
|
||||||
|
|
||||||
## likely the same as in https://pkg.go.dev/strconv#ParseBool
|
## likely the same as in https://pkg.go.dev/strconv#ParseBool
|
||||||
@ -38,31 +36,33 @@ gobool_to_int() {
|
|||||||
|
|
||||||
[ -n "${__IEP_SRC:-}" ] || __IEP_SRC="$0"
|
[ -n "${__IEP_SRC:-}" ] || __IEP_SRC="$0"
|
||||||
|
|
||||||
IEP_TRACE=$(gobool_to_int "${IEP_TRACE:-0}" 0)
|
|
||||||
export IEP_TRACE
|
|
||||||
log_always() {
|
log_always() {
|
||||||
if [ "${IEP_TRACE}" = 1 ] ; then
|
if [ "${IEP_DEBUG}" = 1 ] ; then
|
||||||
echo "# $(date +'%Y-%m-%d %H:%M:%S.%03N %z'): ${__IEP_SRC}${*:+: $*}"
|
echo "# $(date +'%Y-%m-%d %H:%M:%S.%03N %z'): ${__IEP_SRC}${*:+: $*}"
|
||||||
else
|
else
|
||||||
echo "# ${__IEP_SRC}${*:+: $*}"
|
echo "# ${__IEP_SRC}${*:+: $*}"
|
||||||
fi >&2
|
fi >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
IEP_VERBOSE=$(gobool_to_int "${IEP_VERBOSE:-${IEP_TRACE}}" "${IEP_TRACE}")
|
|
||||||
export IEP_VERBOSE
|
|
||||||
log() {
|
log() {
|
||||||
[ "${IEP_VERBOSE}" = 0 ] || log_always "$@"
|
[ "${IEP_VERBOSE}" = 0 ] || log_always "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
log_file() { sed -E '/^./s,^, ,' < "$1" >&2 ; }
|
log_file() { sed -E '/^./s,^, ,' < "$1" >&2 ; }
|
||||||
|
|
||||||
|
ln_s() {
|
||||||
if [ "${IEP_VERBOSE}" = 0 ] ; then
|
if [ "${IEP_VERBOSE}" = 0 ] ; then
|
||||||
ln_s() { ln -s "$@" || return; }
|
ln -s "$@" || return
|
||||||
cp_a() { cp -a "$@" || return; }
|
|
||||||
else
|
else
|
||||||
ln_s() { ln -sv "$@" || return; }
|
ln -sv "$@" || return
|
||||||
cp_a() { cp -av "$@" || return; }
|
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
cp_a() {
|
||||||
|
if [ "${IEP_VERBOSE}" = 0 ] ; then
|
||||||
|
cp -a "$@" || return
|
||||||
|
else
|
||||||
|
cp -av "$@" || return
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
ln_cp() {
|
ln_cp() {
|
||||||
if [ -h "$1" ] ; then
|
if [ -h "$1" ] ; then
|
||||||
@ -82,7 +82,7 @@ untemplate_path() {
|
|||||||
"${volume_root}"/* | /etc/angie/run/* )
|
"${volume_root}"/* | /etc/angie/run/* )
|
||||||
strip_suffix "$1" "$2"
|
strip_suffix "$1" "$2"
|
||||||
;;
|
;;
|
||||||
/etc/angie/conf.d/* | /etc/angie/j2cfg.d/* | /etc/angie/mod.d/* | /etc/angie/modules.d/* | /etc/angie/njs.d/* | /etc/angie/site.d/* | /etc/angie/snip.d/* )
|
/etc/angie/conf.d/* | /etc/angie/j2cfg.d/* | /etc/angie/mod.d/* | /etc/angie/modules.d/* | /etc/angie/site.d/* | /etc/angie/snip.d/* )
|
||||||
strip_suffix "$1" "$2"
|
strip_suffix "$1" "$2"
|
||||||
;;
|
;;
|
||||||
/etc/angie/static.d/* )
|
/etc/angie/static.d/* )
|
||||||
@ -118,12 +118,14 @@ install_userdir() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expand_file_envsubst() {
|
expand_file_envsubst() {
|
||||||
__r=0
|
local __ret __src __dst
|
||||||
|
|
||||||
|
__ret=0
|
||||||
for __src ; do
|
for __src ; do
|
||||||
[ -n "${__src}" ] || continue
|
[ -n "${__src}" ] || continue
|
||||||
|
|
||||||
if ! [ -f "${__src}" ] ; then
|
if ! [ -f "${__src}" ] ; then
|
||||||
__r=1
|
__ret=1
|
||||||
log_always "file not found: ${__src}"
|
log_always "file not found: ${__src}"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
@ -131,24 +133,23 @@ expand_file_envsubst() {
|
|||||||
case "${__src}" in
|
case "${__src}" in
|
||||||
*.in ) ;;
|
*.in ) ;;
|
||||||
* )
|
* )
|
||||||
__r=1
|
__ret=1
|
||||||
log "expand_file_envsubst: file name extension mismatch: ${__src}"
|
log "expand_file_envsubst: file name extension mismatch: ${__src}"
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
__dest=$(strip_suffix "${__src}" '.in')
|
__dst=$(strip_suffix "${__src}" '.in')
|
||||||
if [ -e "${__dest}" ] ; then
|
if [ -e "${__dst}" ] ; then
|
||||||
__r=1
|
__ret=1
|
||||||
log "expand_file_envsubst: destination file already exists: ${__dest}"
|
log "expand_file_envsubst: destination file already exists: ${__dst}"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "Running envsubst: ${__src} -> ${__dest}"
|
log "Running envsubst: ${__src} -> ${__dst}"
|
||||||
envsubst.sh < "${__src}" > "${__dest}" || __r=1
|
envsubst.sh < "${__src}" > "${__dst}" || __ret=1
|
||||||
done
|
done
|
||||||
unset __src __dest
|
return ${__ret}
|
||||||
return ${__r}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expand_file_j2cfg() {
|
expand_file_j2cfg() {
|
||||||
@ -156,6 +157,8 @@ expand_file_j2cfg() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expand_dir_envsubst() {
|
expand_dir_envsubst() {
|
||||||
|
local __template_list __have_args __ret __orig_file
|
||||||
|
|
||||||
__template_list=$(mktemp) || return
|
__template_list=$(mktemp) || return
|
||||||
|
|
||||||
find "$@" -follow -type f -name '*.in' \
|
find "$@" -follow -type f -name '*.in' \
|
||||||
@ -175,7 +178,6 @@ expand_dir_envsubst() {
|
|||||||
[ -n "${__orig_file}" ] || continue
|
[ -n "${__orig_file}" ] || continue
|
||||||
expand_file_envsubst "${__orig_file}" || __ret=1
|
expand_file_envsubst "${__orig_file}" || __ret=1
|
||||||
done < "${__template_list}"
|
done < "${__template_list}"
|
||||||
unset __orig_file
|
|
||||||
|
|
||||||
if [ -z "${__have_args}" ] ; then
|
if [ -z "${__have_args}" ] ; then
|
||||||
rm -f "${ENVSUBST_ARGS}" ; unset ENVSUBST_ARGS
|
rm -f "${ENVSUBST_ARGS}" ; unset ENVSUBST_ARGS
|
||||||
@ -188,6 +190,8 @@ expand_dir_envsubst() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expand_dir_j2cfg() {
|
expand_dir_j2cfg() {
|
||||||
|
local __template_list __ret
|
||||||
|
|
||||||
__template_list=$(mktemp) || return
|
__template_list=$(mktemp) || return
|
||||||
|
|
||||||
find "$@" -follow -type f -name '*.j2' -printf '%p\0' \
|
find "$@" -follow -type f -name '*.j2' -printf '%p\0' \
|
||||||
@ -224,10 +228,6 @@ remap_path() {
|
|||||||
/etc/angie/modules.dist/* ) echo "${2:-/etc/angie/modules.d}${1#/etc/angie/modules.dist}" ;;
|
/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}" ;;
|
/etc/angie/modules/* ) echo "${2:-/etc/angie/modules.d}${1#/etc/angie/modules}" ;;
|
||||||
/angie/modules/* ) echo "${2:-/etc/angie/modules.d}${1#/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
|
## site
|
||||||
/etc/angie/site.dist/* ) echo "${2:-/etc/angie/site.d}${1#/etc/angie/site.dist}" ;;
|
/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}" ;;
|
/etc/angie/site/* ) echo "${2:-/etc/angie/site.d}${1#/etc/angie/site}" ;;
|
||||||
|
@ -19,7 +19,7 @@ if [ "${NGX_HTTP}${NGX_MAIL}${NGX_STREAM}" = '000' ] ; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
unset default_dirs_merge default_dirs_link
|
unset default_dirs_merge default_dirs_link
|
||||||
default_dirs_merge='conf j2cfg mod modules njs site snip'
|
default_dirs_merge='conf j2cfg mod modules site snip'
|
||||||
default_dirs_link=''
|
default_dirs_link=''
|
||||||
|
|
||||||
if [ "${NGX_PROCESS_STATIC}" = 1 ] ; then
|
if [ "${NGX_PROCESS_STATIC}" = 1 ] ; then
|
||||||
|
25
image-entry.d/04-detect-local-ip-addresses.envsh
Executable file
25
image-entry.d/04-detect-local-ip-addresses.envsh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
## allow these addresses to be provided in case of:
|
||||||
|
## - local development/testing
|
||||||
|
## - `hostname -I' random failures or misbehavior
|
||||||
|
if [ -z "${NGX_IP_ADDRESSES:-}" ] ; then
|
||||||
|
NGX_IP_ADDRESSES=$(hostname -I)
|
||||||
|
fi
|
||||||
|
NGX_IP_ADDRESSES=$(printf '%s' "${NGX_IP_ADDRESSES}" | sed -zE 's/^\s+//;s/\s+$//;s/\s+/ /g')
|
||||||
|
export NGX_IP_ADDRESSES
|
||||||
|
|
||||||
|
unset NGX_IPV4_ADDRESSES NGX_IPV6_ADDRESSES
|
||||||
|
for i in ${NGX_IP_ADDRESSES} ; do
|
||||||
|
case "$i" in
|
||||||
|
*:* )
|
||||||
|
NGX_IPV6_ADDRESSES="${NGX_IPV6_ADDRESSES:-}${NGX_IPV6_ADDRESSES:+ }$i"
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
NGX_IPV4_ADDRESSES="${NGX_IPV4_ADDRESSES:-}${NGX_IPV4_ADDRESSES:+ }$i"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
unset i
|
||||||
|
|
||||||
|
export NGX_IPV4_ADDRESSES NGX_IPV6_ADDRESSES
|
@ -10,9 +10,16 @@ _NGX_WORKER_CONNECTIONS=4096
|
|||||||
[ -n "${NGX_WORKER_PROCESSES:-}" ] || NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}
|
[ -n "${NGX_WORKER_PROCESSES:-}" ] || NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}
|
||||||
case "${NGX_WORKER_PROCESSES}" in
|
case "${NGX_WORKER_PROCESSES}" in
|
||||||
"${_NGX_WORKER_PROCESSES}" ) ;;
|
"${_NGX_WORKER_PROCESSES}" ) ;;
|
||||||
[1-9] | [1-9][0-9] ) ;;
|
## allow values within [1;999]
|
||||||
0 | [Aa][Uu][Tt][Oo] )
|
[1-9] | [1-9][0-9] | [1-9][0-9][0-9] ) ;;
|
||||||
log_always "NGX_WORKER_PROCESSES=${NGX_WORKER_PROCESSES} isn't supported yet"
|
[Aa][Uu][Tt][Oo] )
|
||||||
|
## adjust
|
||||||
|
NGX_WORKER_PROCESSES=auto
|
||||||
|
log_always "NGX_WORKER_PROCESSES: \"auto\" isn't supported by container yet"
|
||||||
|
log_always "offloading decision to Angie (this could be a problem!)"
|
||||||
|
;;
|
||||||
|
0 )
|
||||||
|
log_always "NGX_WORKER_PROCESSES: \"0\" isn't supported by container yet"
|
||||||
log_always "setting NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}"
|
log_always "setting NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}"
|
||||||
NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}
|
NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}
|
||||||
;;
|
;;
|
||||||
@ -28,6 +35,11 @@ case "${NGX_WORKER_PRIORITY}" in
|
|||||||
"${_NGX_WORKER_PRIORITY}" ) ;;
|
"${_NGX_WORKER_PRIORITY}" ) ;;
|
||||||
-[1-9] | -1[0-9] | -20 ) ;;
|
-[1-9] | -1[0-9] | -20 ) ;;
|
||||||
[0-9] | 1[0-9] | 20 ) ;;
|
[0-9] | 1[0-9] | 20 ) ;;
|
||||||
|
-0 )
|
||||||
|
log_always "NGX_WORKER_PRIORITY: likely an error: '-0'"
|
||||||
|
log_always "adjusting NGX_WORKER_PRIORITY=0"
|
||||||
|
NGX_WORKER_PRIORITY=0
|
||||||
|
;;
|
||||||
* )
|
* )
|
||||||
log_always "NGX_WORKER_PRIORITY: unrecognized value: ${NGX_WORKER_PRIORITY}"
|
log_always "NGX_WORKER_PRIORITY: unrecognized value: ${NGX_WORKER_PRIORITY}"
|
||||||
log_always "setting NGX_WORKER_PRIORITY=${_NGX_WORKER_PRIORITY}"
|
log_always "setting NGX_WORKER_PRIORITY=${_NGX_WORKER_PRIORITY}"
|
||||||
@ -38,7 +50,7 @@ esac
|
|||||||
[ -n "${NGX_WORKER_RLIMIT_NOFILE:-}" ] || NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}
|
[ -n "${NGX_WORKER_RLIMIT_NOFILE:-}" ] || NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}
|
||||||
case "${NGX_WORKER_RLIMIT_NOFILE}" in
|
case "${NGX_WORKER_RLIMIT_NOFILE}" in
|
||||||
"${_NGX_WORKER_RLIMIT_NOFILE}" ) ;;
|
"${_NGX_WORKER_RLIMIT_NOFILE}" ) ;;
|
||||||
[1-9] | [1-9][0-9] )
|
[0-9] | [1-9][0-9] )
|
||||||
log_always "NGX_WORKER_RLIMIT_NOFILE: too low: ${NGX_WORKER_RLIMIT_NOFILE}"
|
log_always "NGX_WORKER_RLIMIT_NOFILE: too low: ${NGX_WORKER_RLIMIT_NOFILE}"
|
||||||
log_always "setting NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}"
|
log_always "setting NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}"
|
||||||
NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}
|
NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}
|
||||||
@ -59,7 +71,7 @@ esac
|
|||||||
[ -n "${NGX_WORKER_CONNECTIONS:-}" ] || NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}
|
[ -n "${NGX_WORKER_CONNECTIONS:-}" ] || NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}
|
||||||
case "${NGX_WORKER_CONNECTIONS}" in
|
case "${NGX_WORKER_CONNECTIONS}" in
|
||||||
"${_NGX_WORKER_CONNECTIONS}" ) ;;
|
"${_NGX_WORKER_CONNECTIONS}" ) ;;
|
||||||
[1-9] | [1-9][0-9] )
|
[0-9] | [1-9][0-9] )
|
||||||
log_always "NGX_WORKER_CONNECTIONS: too low: ${NGX_WORKER_CONNECTIONS}"
|
log_always "NGX_WORKER_CONNECTIONS: too low: ${NGX_WORKER_CONNECTIONS}"
|
||||||
log_always "setting NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}"
|
log_always "setting NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}"
|
||||||
NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}
|
NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}
|
||||||
@ -82,7 +94,7 @@ nofile_hard=$(ulimit -Hn)
|
|||||||
|
|
||||||
if [ "${nofile_hard}" = unlimited ] ; then
|
if [ "${nofile_hard}" = unlimited ] ; then
|
||||||
## minor hack (if applicable) :)
|
## minor hack (if applicable) :)
|
||||||
nofile_hard=${NGX_WORKER_RLIMIT_NOFILE}
|
nofile_hard=$((NGX_WORKER_RLIMIT_NOFILE * 2))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
nofile_ok=0
|
nofile_ok=0
|
||||||
@ -104,7 +116,7 @@ if [ ${nofile_ok} = 0 ] ; then
|
|||||||
nofile_hard=$(ulimit -Hn)
|
nofile_hard=$(ulimit -Hn)
|
||||||
fi
|
fi
|
||||||
if [ ${nofile_hard} -lt ${NGX_WORKER_RLIMIT_NOFILE} ] ; then
|
if [ ${nofile_hard} -lt ${NGX_WORKER_RLIMIT_NOFILE} ] ; then
|
||||||
log_always "lowering NGX_WORKER_RLIMIT_NOFILE to ${nofile_hard}"
|
log_always "lowering NGX_WORKER_RLIMIT_NOFILE to ${nofile_hard} due to hard limit"
|
||||||
NGX_WORKER_RLIMIT_NOFILE=${nofile_hard}
|
NGX_WORKER_RLIMIT_NOFILE=${nofile_hard}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -120,3 +132,15 @@ unset nofile_soft nofile_hard nofile_ok
|
|||||||
export NGX_WORKER_PROCESSES NGX_WORKER_PRIORITY NGX_WORKER_RLIMIT_NOFILE NGX_WORKER_CONNECTIONS
|
export NGX_WORKER_PROCESSES NGX_WORKER_PRIORITY NGX_WORKER_RLIMIT_NOFILE NGX_WORKER_CONNECTIONS
|
||||||
|
|
||||||
unset _NGX_WORKER_PROCESSES _NGX_WORKER_PRIORITY _NGX_WORKER_RLIMIT_NOFILE _NGX_WORKER_CONNECTIONS
|
unset _NGX_WORKER_PROCESSES _NGX_WORKER_PRIORITY _NGX_WORKER_RLIMIT_NOFILE _NGX_WORKER_CONNECTIONS
|
||||||
|
|
||||||
|
if [ ${NGX_WORKER_RLIMIT_NOFILE} -lt ${NGX_WORKER_CONNECTIONS} ] ; then
|
||||||
|
log_always "WARNING: NGX_WORKER_RLIMIT_NOFILE is less than NGX_WORKER_CONNECTIONS (${NGX_WORKER_RLIMIT_NOFILE} < ${NGX_WORKER_CONNECTIONS})"
|
||||||
|
else
|
||||||
|
ratio=$(mawk -v "a=${NGX_WORKER_RLIMIT_NOFILE}" -v "b=${NGX_WORKER_CONNECTIONS}" 'BEGIN{print a/b;exit;}' </dev/null)
|
||||||
|
case "${ratio}" in
|
||||||
|
1 | 1.* )
|
||||||
|
log_always "WARNING: \"NGX_WORKER_RLIMIT_NOFILE/NGX_WORKER_CONNECTIONS\" ratio is too low (=${ratio})"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
unset ratio
|
||||||
|
fi
|
||||||
|
@ -10,9 +10,10 @@ else
|
|||||||
[ -n "${NGX_HTTP_MAX_RANGES:-}" ] || NGX_HTTP_MAX_RANGES=${_NGX_HTTP_MAX_RANGES}
|
[ -n "${NGX_HTTP_MAX_RANGES:-}" ] || NGX_HTTP_MAX_RANGES=${_NGX_HTTP_MAX_RANGES}
|
||||||
case "${NGX_HTTP_MAX_RANGES}" in
|
case "${NGX_HTTP_MAX_RANGES}" in
|
||||||
"${_NGX_HTTP_MAX_RANGES}" ) ;;
|
"${_NGX_HTTP_MAX_RANGES}" ) ;;
|
||||||
|
## allow values within [1;999]
|
||||||
[1-9] | [1-9][0-9] | [1-9][0-9][0-9] ) ;;
|
[1-9] | [1-9][0-9] | [1-9][0-9][0-9] ) ;;
|
||||||
0 )
|
0 )
|
||||||
log "HTTP: Range/If-Range/Accept-Ranges support is disabled"
|
log_always "HTTP: Range/If-Range/Accept-Ranges support is disabled by NGX_HTTP_MAX_RANGES=0"
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
log_always "NGX_HTTP_MAX_RANGES: unrecognized value: ${NGX_HTTP_MAX_RANGES}"
|
log_always "NGX_HTTP_MAX_RANGES: unrecognized value: ${NGX_HTTP_MAX_RANGES}"
|
||||||
|
@ -3,12 +3,15 @@ set -f
|
|||||||
|
|
||||||
. /image-entry.d/00-common.envsh
|
. /image-entry.d/00-common.envsh
|
||||||
|
|
||||||
|
## Angie: unset core variable
|
||||||
|
unset ANGIE ANGIE_BPF_MAPS
|
||||||
|
|
||||||
[ "${NGX_STRICT_LOAD}" = 0 ] || set -e
|
[ "${NGX_STRICT_LOAD}" = 0 ] || set -e
|
||||||
|
|
||||||
cd "${merged_root}/"
|
cd "${merged_root}/"
|
||||||
|
|
||||||
expand_error_delim() {
|
expand_error_delim() {
|
||||||
IEP_TRACE=0 log_always ' ----------------------------------- '
|
IEP_DEBUG=0 log_always ' ----------------------------------- '
|
||||||
}
|
}
|
||||||
expand_error() {
|
expand_error() {
|
||||||
[ "${expand_error_seen:-}" != 1 ] || return
|
[ "${expand_error_seen:-}" != 1 ] || return
|
||||||
|
@ -22,7 +22,7 @@ rm -f "$t" ; unset t
|
|||||||
[ "${NGX_STRICT_LOAD}" = 0 ] || set -e
|
[ "${NGX_STRICT_LOAD}" = 0 ] || set -e
|
||||||
|
|
||||||
load_error_delim() {
|
load_error_delim() {
|
||||||
IEP_TRACE=0 log_always ' ----------------------------------- '
|
IEP_DEBUG=0 log_always ' ----------------------------------- '
|
||||||
}
|
}
|
||||||
load_error() {
|
load_error() {
|
||||||
[ "${load_error_seen:-}" != 1 ] || return
|
[ "${load_error_seen:-}" != 1 ] || return
|
||||||
|
@ -3,7 +3,7 @@ set -f
|
|||||||
|
|
||||||
. /image-entry.d/00-common.envsh
|
. /image-entry.d/00-common.envsh
|
||||||
|
|
||||||
if [ "${IEP_TRACE}" = 1 ] ; then
|
if [ "${IEP_RETAIN_MERGED_TREE}" = 1 ] ; then
|
||||||
log_always "NOT removing merged tree: ${merged_root}/"
|
log_always "NOT removing merged tree: ${merged_root}/"
|
||||||
else
|
else
|
||||||
log "removing merged tree: ${merged_root}/"
|
log "removing merged tree: ${merged_root}/"
|
||||||
|
@ -3,6 +3,9 @@ set -f
|
|||||||
|
|
||||||
. /image-entry.d/00-common.envsh
|
. /image-entry.d/00-common.envsh
|
||||||
|
|
||||||
|
## Angie: unset core variable
|
||||||
|
unset ANGIE ANGIE_BPF_MAPS
|
||||||
|
|
||||||
## merely debug test
|
## merely debug test
|
||||||
log_always 'test Angie configuration:'
|
log_always 'test Angie configuration:'
|
||||||
log_always '========================='
|
log_always '========================='
|
||||||
|
@ -1,41 +1,64 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
## Angie: unset core variable
|
||||||
|
unset ANGIE ANGIE_BPF_MAPS
|
||||||
|
|
||||||
|
if [ "${IEP_RETAIN_ENV}" = 1 ] ; then
|
||||||
|
log_always "NOT removing following variables:"
|
||||||
|
sed -E '/^./s,^, ,' >&2
|
||||||
|
echo >&2
|
||||||
|
else
|
||||||
__set="$-"
|
__set="$-"
|
||||||
set +e
|
set +e
|
||||||
if [ "${IEP_TRACE}" = 1 ] ; then
|
|
||||||
log_always "NOT going to unset following variables:"
|
unset __env __env_print
|
||||||
sed -E '/^./s,^,- ,' >&2
|
|
||||||
else
|
|
||||||
unset __env
|
|
||||||
while read -r __env ; do
|
while read -r __env ; do
|
||||||
[ -n "${__env}" ] || continue
|
[ -n "${__env}" ] || continue
|
||||||
|
|
||||||
case "${__env}" in
|
case "${__env}" in
|
||||||
*\'* )
|
\'* | \"* )
|
||||||
log "skipping variable (malformed): ${__env}" >&2
|
log "skipping variable (malformed): ${__env}" >&2
|
||||||
continue
|
continue
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
if [ "${IEP_DEBUG}" = 1 ] ; then
|
||||||
|
__env_print="${__env}="$(printenv "${__env}")
|
||||||
|
__env_print=$(env printf '%q' "${__env_print}")
|
||||||
|
log_always "unsetting variable: ${__env_print}"
|
||||||
|
else
|
||||||
log "unsetting variable: ${__env}"
|
log "unsetting variable: ${__env}"
|
||||||
|
fi
|
||||||
|
|
||||||
unset "${__env}"
|
unset "${__env}"
|
||||||
done
|
done
|
||||||
unset __env
|
unset __env __env_print
|
||||||
|
|
||||||
|
[ -z "${__set}" ] || set -"${__set}"
|
||||||
|
unset __set
|
||||||
fi <<-EOF
|
fi <<-EOF
|
||||||
$(
|
$(
|
||||||
|
set +e
|
||||||
cat /proc/self/environ \
|
cat /proc/self/environ \
|
||||||
| sed -zEn '/^([^=]+).*$/s//\1/p' \
|
| sed -zEn '/^([^=]+).*$/s//\1/p' \
|
||||||
| xargs -0r printf '%q\n' \
|
| xargs -0r printf '%q\n' \
|
||||||
| {
|
| {
|
||||||
f="${target_root}/j2cfg/core-preserve-environment.txt"
|
## retain variables defined in ".core_worker_env" configuration key
|
||||||
|
## (if it was specified somewhere in dictionaries - either yaml or json)
|
||||||
|
f="${target_root}/j2cfg/core-worker-env.txt"
|
||||||
[ -s "$f" ] || exec cat
|
[ -s "$f" ] || exec cat
|
||||||
grep -Fxv -f "$f"
|
grep -Fxv -f "$f"
|
||||||
} \
|
} \
|
||||||
| grep -E \
|
| {
|
||||||
-e '^(NGX|PYTHON)' \
|
## remove environment variables:
|
||||||
|
## 1. variables starting with "NGX" as they are used by configuration templates
|
||||||
|
## 2. variables containing "_SERVICE" or "_PORT" as they are came from
|
||||||
|
## container orchestration
|
||||||
|
grep -E \
|
||||||
|
-e '^NGX' \
|
||||||
|
-e '_(SERVICE|PORT)' \
|
||||||
|
|
||||||
|
} \
|
||||||
| sort -uV
|
| sort -uV
|
||||||
)
|
)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
[ -z "${__set}" ] || set -"${__set}"
|
|
||||||
unset __set
|
|
||||||
|
119
image-entry.sh
119
image-entry.sh
@ -1,35 +1,77 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -f
|
set -f
|
||||||
|
|
||||||
|
[ -n "${IEP_TRACE}" ] || IEP_TRACE=0
|
||||||
|
[ "${IEP_TRACE}" = 1 ] || IEP_TRACE=0
|
||||||
|
[ "${IEP_TRACE}" = 0 ] || echo "# trace: $(date +'%Y-%m-%d %H:%M:%S.%03N %z'): start" >&2
|
||||||
|
|
||||||
iep_preserve_env() {
|
iep_preserve_env() {
|
||||||
## preserve LD_PRELOAD
|
## preserve LD_PRELOAD
|
||||||
unset __IEP_LD_PRELOAD
|
unset __IEP_LD_PRELOAD
|
||||||
__IEP_LD_PRELOAD="${LD_PRELOAD:-}"
|
__IEP_LD_PRELOAD="${LD_PRELOAD:-}"
|
||||||
unset LD_PRELOAD
|
unset LD_PRELOAD
|
||||||
|
|
||||||
|
## glibc: preserve GLIBC_TUNABLES
|
||||||
|
unset __IEP_GLIBC_TUNABLES
|
||||||
|
__IEP_GLIBC_TUNABLES="${GLIBC_TUNABLES:-}"
|
||||||
|
unset GLIBC_TUNABLES
|
||||||
|
|
||||||
## glibc: preserve MALLOC_ARENA_MAX
|
## glibc: preserve MALLOC_ARENA_MAX
|
||||||
unset __IEP_MALLOC_ARENA_MAX
|
unset __IEP_MALLOC_ARENA_MAX
|
||||||
__IEP_MALLOC_ARENA_MAX=${MALLOC_ARENA_MAX:-2}
|
__IEP_MALLOC_ARENA_MAX="${MALLOC_ARENA_MAX:-2}"
|
||||||
export MALLOC_ARENA_MAX=2
|
export MALLOC_ARENA_MAX=2
|
||||||
|
|
||||||
|
## jemalloc: preserve MALLOC_CONF
|
||||||
|
unset __IEP_MALLOC_CONF
|
||||||
|
__IEP_MALLOC_CONF="${MALLOC_CONF:-}"
|
||||||
|
unset MALLOC_CONF
|
||||||
|
}
|
||||||
|
|
||||||
|
iep_prepare_env() {
|
||||||
|
## Angie: unset core variable
|
||||||
|
unset ANGIE ANGIE_BPF_MAPS
|
||||||
|
|
||||||
|
## dumb-init: preserve args
|
||||||
|
unset IEP_DUMB_INIT_ARGS
|
||||||
|
IEP_DUMB_INIT_ARGS="${DUMB_INIT_ARGS:-}"
|
||||||
|
unset DUMB_INIT_ARGS
|
||||||
|
if [ "${DUMB_INIT_SETSID:-}" = 0 ] ; then
|
||||||
|
IEP_DUMB_INIT_ARGS="-c${IEP_DUMB_INIT_ARGS:+ }${IEP_DUMB_INIT_ARGS}"
|
||||||
|
fi
|
||||||
|
unset DUMB_INIT_SETSID
|
||||||
}
|
}
|
||||||
|
|
||||||
iep_restore_env() {
|
iep_restore_env() {
|
||||||
unset IEP_VERBOSE IEP_TRACE IEP_ROOT IEP_LOCAL_OVERRIDE
|
unset IEP_DEBUG IEP_VERBOSE IEP_TRACE IEP_ROOT
|
||||||
|
unset IEP_LOCAL_OVERRIDE IEP_RETAIN_MERGED_TREE IEP_RETAIN_ENV
|
||||||
|
|
||||||
## restore LD_PRELOAD
|
## restore LD_PRELOAD
|
||||||
if [ -n "${__IEP_LD_PRELOAD}" ] ; then
|
if [ -n "${__IEP_LD_PRELOAD:-}" ] ; then
|
||||||
export LD_PRELOAD="${__IEP_LD_PRELOAD}"
|
export LD_PRELOAD="${__IEP_LD_PRELOAD}"
|
||||||
fi
|
fi
|
||||||
unset __IEP_LD_PRELOAD
|
unset __IEP_LD_PRELOAD
|
||||||
|
|
||||||
|
## glibc: restore GLIBC_TUNABLES
|
||||||
|
if [ -n "${__IEP_GLIBC_TUNABLES:-}" ] ; then
|
||||||
|
export GLIBC_TUNABLES="${__IEP_GLIBC_TUNABLES}"
|
||||||
|
fi
|
||||||
|
unset __IEP_GLIBC_TUNABLES
|
||||||
|
|
||||||
## glibc: restore MALLOC_ARENA_MAX
|
## glibc: restore MALLOC_ARENA_MAX
|
||||||
if [ "${MALLOC_ARENA_MAX}" = 2 ] ; then
|
if [ -n "${__IEP_MALLOC_ARENA_MAX:-}" ] ; then
|
||||||
export MALLOC_ARENA_MAX="${__IEP_MALLOC_ARENA_MAX}"
|
export MALLOC_ARENA_MAX="${__IEP_MALLOC_ARENA_MAX}"
|
||||||
fi
|
fi
|
||||||
unset __IEP_MALLOC_ARENA_MAX
|
unset __IEP_MALLOC_ARENA_MAX
|
||||||
|
|
||||||
|
## jemalloc: restore MALLOC_CONF
|
||||||
|
if [ -n "${__IEP_MALLOC_CONF:-}" ] ; then
|
||||||
|
export MALLOC_CONF="${__IEP_MALLOC_CONF}"
|
||||||
|
fi
|
||||||
|
unset __IEP_MALLOC_CONF
|
||||||
}
|
}
|
||||||
|
|
||||||
iep_preserve_env
|
iep_preserve_env
|
||||||
|
iep_prepare_env
|
||||||
|
|
||||||
## early setup TMPDIR (affects "mktemp")
|
## early setup TMPDIR (affects "mktemp")
|
||||||
export TMPDIR=/run/angie/tmp
|
export TMPDIR=/run/angie/tmp
|
||||||
@ -39,7 +81,6 @@ export TMPDIR=/run/angie/tmp
|
|||||||
# case "$1" in
|
# case "$1" in
|
||||||
# angie | */angie ) ;;
|
# angie | */angie ) ;;
|
||||||
# * )
|
# * )
|
||||||
# unset IEP_INIT DUMB_INIT_ARGS
|
|
||||||
# iep_restore_env
|
# iep_restore_env
|
||||||
# exec "$@"
|
# exec "$@"
|
||||||
# ;;
|
# ;;
|
||||||
@ -48,31 +89,46 @@ export TMPDIR=/run/angie/tmp
|
|||||||
unset __IEP_SRC ; __IEP_SRC="${0##*/}"
|
unset __IEP_SRC ; __IEP_SRC="${0##*/}"
|
||||||
. /image-entry.d/00-common.envsh
|
. /image-entry.d/00-common.envsh
|
||||||
|
|
||||||
unexport IEP_INIT DUMB_INIT_ARGS
|
IEP_INIT=$(gobool_to_int "${IEP_INIT:-0}" 0)
|
||||||
|
# unexport IEP_INIT
|
||||||
|
unset x ; x="${IEP_INIT}" ; unset IEP_INIT ; IEP_INIT="$x" ; unset x
|
||||||
|
|
||||||
|
IEP_RETAIN_MERGED_TREE=$(gobool_to_int "${IEP_RETAIN_MERGED_TREE:-0}" 0)
|
||||||
|
IEP_RETAIN_ENV=$(gobool_to_int "${IEP_RETAIN_ENV:-0}" 0)
|
||||||
|
export IEP_RETAIN_MERGED_TREE IEP_RETAIN_ENV
|
||||||
|
|
||||||
|
# IEP_TRACE=$(gobool_to_int "${IEP_TRACE:-0}" 0)
|
||||||
|
IEP_DEBUG=$(gobool_to_int "${IEP_DEBUG:-0}" 0)
|
||||||
|
IEP_VERBOSE=$(gobool_to_int "${IEP_VERBOSE:-${IEP_DEBUG}}" "${IEP_DEBUG}")
|
||||||
|
export IEP_TRACE IEP_DEBUG IEP_VERBOSE
|
||||||
|
|
||||||
## run parts (if any)
|
## run parts (if any)
|
||||||
while read -r f ; do
|
unset __IEP_SCRIPT
|
||||||
[ -n "$f" ] || continue
|
while read -r __IEP_SCRIPT ; do
|
||||||
[ -f "$f" ] || continue
|
[ -n "${__IEP_SCRIPT}" ] || continue
|
||||||
|
[ -f "${__IEP_SCRIPT}" ] || continue
|
||||||
|
|
||||||
case "$f" in
|
|
||||||
|
case "${__IEP_SCRIPT}" in
|
||||||
*.envsh )
|
*.envsh )
|
||||||
if ! [ -x "$f" ] ; then
|
if ! [ -x "${__IEP_SCRIPT}" ] ; then
|
||||||
log "NOT sourcing $f - not executable"
|
log "NOT sourcing ${__IEP_SCRIPT} - not executable"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
log_always "sourcing $f"
|
[ "${IEP_TRACE}" = 0 ] || echo "# trace: $(date +'%Y-%m-%d %H:%M:%S.%03N %z'): source ${__IEP_SCRIPT}" >&2
|
||||||
__IEP_SRC="$f"
|
log "sourcing ${__IEP_SCRIPT}"
|
||||||
. "$f"
|
__IEP_SRC="${__IEP_SCRIPT}"
|
||||||
|
. "${__IEP_SCRIPT}"
|
||||||
__IEP_SRC="${0##*/}"
|
__IEP_SRC="${0##*/}"
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
if ! [ -x "$f" ] ; then
|
if ! [ -x "${__IEP_SCRIPT}" ] ; then
|
||||||
log "NOT running $f - not executable"
|
log "NOT running ${__IEP_SCRIPT} - not executable"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
log_always "running $f"
|
[ "${IEP_TRACE}" = 0 ] || echo "# trace: $(date +'%Y-%m-%d %H:%M:%S.%03N %z'): run ${__IEP_SCRIPT}" >&2
|
||||||
"$f"
|
log "running ${__IEP_SCRIPT}"
|
||||||
|
"${__IEP_SCRIPT}"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done <<EOF
|
done <<EOF
|
||||||
@ -85,11 +141,30 @@ $(
|
|||||||
)
|
)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
[ "${IEP_TRACE}" = 0 ] || echo "# trace: $(date +'%Y-%m-%d %H:%M:%S.%03N %z'): end" >&2
|
||||||
|
|
||||||
|
if [ "${IEP_DEBUG}" = 1 ] ; then
|
||||||
|
log_always "ready to run application: $*"
|
||||||
|
else
|
||||||
|
log_always "ready to run application"
|
||||||
|
fi
|
||||||
|
echo >&2
|
||||||
|
|
||||||
iep_restore_env
|
iep_restore_env
|
||||||
|
|
||||||
IEP_INIT=$(gobool_to_int "${IEP_INIT:-0}" 0)
|
## variables that are not so easily unsettable
|
||||||
|
unset __IEP_ENV
|
||||||
|
for i in '_' 'SHLVL' ; do
|
||||||
|
__IEP_ENV="${__IEP_ENV:-}${__IEP_ENV:+ }-u $i"
|
||||||
|
done
|
||||||
|
|
||||||
if [ "${IEP_INIT}" = 0 ] ; then
|
if [ "${IEP_INIT}" = 0 ] ; then
|
||||||
exec "$@"
|
exec \
|
||||||
|
${__IEP_ENV:+ env ${__IEP_ENV} } \
|
||||||
|
"$@"
|
||||||
else
|
else
|
||||||
exec dumb-init ${DUMB_INIT_ARGS} "$@"
|
exec \
|
||||||
|
${__IEP_ENV:+ env ${__IEP_ENV} } \
|
||||||
|
dumb-init ${IEP_DUMB_INIT_ARGS} \
|
||||||
|
"$@"
|
||||||
fi
|
fi
|
||||||
|
@ -5,31 +5,7 @@ import re
|
|||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
|
from .settings import is_env_banned
|
||||||
def uniq_list(a: list) -> list:
|
|
||||||
return list(dict.fromkeys(a))
|
|
||||||
|
|
||||||
|
|
||||||
def list_remove_non_str(a: list) -> list:
|
|
||||||
return list(itertools.filterfalse(
|
|
||||||
lambda x: not isinstance(x, str), a
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
def list_remove_empty_str(a: list) -> list:
|
|
||||||
return list(itertools.filterfalse(
|
|
||||||
lambda x: len(x) == 0, a
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
def uniq_str_list(a: list) -> list:
|
|
||||||
return uniq_list(list_remove_empty_str(a))
|
|
||||||
|
|
||||||
|
|
||||||
def str_split_to_list(s: str, sep=r'\s+') -> list:
|
|
||||||
return list_remove_empty_str(
|
|
||||||
re.split(sep, s)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def is_sequence(x) -> bool:
|
def is_sequence(x) -> bool:
|
||||||
@ -40,33 +16,74 @@ def is_mapping(x) -> bool:
|
|||||||
return isinstance(x, collections.abc.Mapping)
|
return isinstance(x, collections.abc.Mapping)
|
||||||
|
|
||||||
|
|
||||||
def any_to_str_list(k) -> list:
|
def uniq(a: (list, set)) -> list:
|
||||||
if isinstance(k, str):
|
return list(dict.fromkeys(a))
|
||||||
return [k]
|
|
||||||
|
|
||||||
if is_sequence(k):
|
|
||||||
return [str(e) for e in k]
|
|
||||||
|
|
||||||
return [str(k)]
|
|
||||||
|
|
||||||
|
|
||||||
def is_str_list_re_match(a: list, pattern, flags=0) -> bool:
|
def remove_non_str(a: (list, set)) -> list:
|
||||||
|
return list(filter(lambda x: isinstance(x, str), a))
|
||||||
|
|
||||||
|
|
||||||
|
def remove_empty_str(a: (list, set)) -> list:
|
||||||
|
return list(filter(None, a))
|
||||||
|
|
||||||
|
|
||||||
|
def uniq_str_list(a: (list, set)) -> (list, set):
|
||||||
|
return remove_empty_str(uniq(a))
|
||||||
|
|
||||||
|
|
||||||
|
def str_split_to_list(s: str, sep=r'\s+') -> list:
|
||||||
|
return remove_empty_str(re.split(sep, s))
|
||||||
|
|
||||||
|
|
||||||
|
def dict_to_env_str_list(x: dict) -> list:
|
||||||
|
r = []
|
||||||
|
for k in sorted(x.keys()):
|
||||||
|
if x[k] is None:
|
||||||
|
r.append(f'{k}')
|
||||||
|
else:
|
||||||
|
r.append(f'{k}={str(x[k])}')
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def any_to_str_list(x) -> list:
|
||||||
|
if isinstance(x, str):
|
||||||
|
return [x]
|
||||||
|
|
||||||
|
if is_sequence(x):
|
||||||
|
return [str(e) for e in x]
|
||||||
|
|
||||||
|
if is_mapping(x):
|
||||||
|
return dict_to_env_str_list(x)
|
||||||
|
|
||||||
|
return [str(x)]
|
||||||
|
|
||||||
|
|
||||||
|
def is_re_match(a: (list, set), pattern, flags=0) -> bool:
|
||||||
return any(re.match(pattern, x, flags) for x in a)
|
return any(re.match(pattern, x, flags) for x in a)
|
||||||
|
|
||||||
|
|
||||||
def is_str_list_re_fullmatch(a: list, pattern, flags=0) -> bool:
|
def is_re_fullmatch(a: (list, set), pattern, flags=0) -> bool:
|
||||||
return any(re.fullmatch(pattern, x, flags) for x in a)
|
return any(re.fullmatch(pattern, x, flags) for x in a)
|
||||||
|
|
||||||
|
|
||||||
def str_list_re_match(a: list, pattern, flags=0) -> list:
|
def re_match(a: (list, set), pattern, flags=0) -> list:
|
||||||
return [x for x in a if re.match(pattern, x, flags)]
|
return [x for x in a if re.match(pattern, x, flags)]
|
||||||
|
|
||||||
|
|
||||||
def str_list_re_fullmatch(a: list, pattern, flags=0) -> list:
|
def re_fullmatch(a: (list, set), pattern, flags=0) -> list:
|
||||||
return [x for x in a if re.fullmatch(pattern, x, flags)]
|
return [x for x in a if re.fullmatch(pattern, x, flags)]
|
||||||
|
|
||||||
|
|
||||||
def str_list_re_sub(a: list, pattern, repl, count=0, flags=0) -> list:
|
def re_match_negate(a: (list, set), pattern, flags=0) -> list:
|
||||||
|
return [x for x in a if not re.match(pattern, x, flags)]
|
||||||
|
|
||||||
|
|
||||||
|
def re_fullmatch_negate(a: (list, set), pattern, flags=0) -> list:
|
||||||
|
return [x for x in a if not re.fullmatch(pattern, x, flags)]
|
||||||
|
|
||||||
|
|
||||||
|
def re_sub(a: (list, set), pattern, repl, count=0, flags=0) -> list:
|
||||||
return [re.sub(pattern, repl, x, count, flags) for x in a]
|
return [re.sub(pattern, repl, x, count, flags) for x in a]
|
||||||
|
|
||||||
|
|
||||||
@ -84,9 +101,10 @@ def as_cgi_header(s: str) -> str:
|
|||||||
return 'HTTP_' + re.sub('[^A-Z0-9]+', '_', s.upper()).strip('_')
|
return 'HTTP_' + re.sub('[^A-Z0-9]+', '_', s.upper()).strip('_')
|
||||||
|
|
||||||
|
|
||||||
def env_any_to_str_list(x) -> list:
|
def any_to_env_dict(x) -> dict:
|
||||||
if x is None:
|
if x is None:
|
||||||
return []
|
return {}
|
||||||
|
|
||||||
h = {}
|
h = {}
|
||||||
|
|
||||||
def feed(k, v=None):
|
def feed(k, v=None):
|
||||||
@ -96,16 +114,13 @@ def env_any_to_str_list(x) -> list:
|
|||||||
if m == '=':
|
if m == '=':
|
||||||
k = k2
|
k = k2
|
||||||
v = v2
|
v = v2
|
||||||
if len(k) == 0:
|
|
||||||
return
|
|
||||||
if not re.fullmatch(r'[a-zA-Z_][a-zA-Z0-9_]*', k):
|
if not re.fullmatch(r'[a-zA-Z_][a-zA-Z0-9_]*', k):
|
||||||
return
|
return
|
||||||
|
if is_env_banned(k):
|
||||||
|
return
|
||||||
if k in h:
|
if k in h:
|
||||||
return
|
return
|
||||||
if v is None:
|
h[k] = v if v is None else str(v)
|
||||||
h[k] = v
|
|
||||||
else:
|
|
||||||
h[k] = str(v)
|
|
||||||
|
|
||||||
if isinstance(x, str):
|
if isinstance(x, str):
|
||||||
feed(x)
|
feed(x)
|
||||||
@ -113,35 +128,57 @@ def env_any_to_str_list(x) -> list:
|
|||||||
for e in x:
|
for e in x:
|
||||||
feed(e)
|
feed(e)
|
||||||
elif is_mapping(x):
|
elif is_mapping(x):
|
||||||
for k, v in x.items():
|
for k in x:
|
||||||
feed(k, v)
|
feed(k, x[k])
|
||||||
else:
|
else:
|
||||||
return []
|
return {}
|
||||||
|
|
||||||
r = []
|
return h
|
||||||
for k in sorted(h.keys()):
|
|
||||||
if h[k] is None:
|
|
||||||
r.append(k)
|
def dict_keys(x: dict) -> list:
|
||||||
else:
|
return sorted([k for k in x.keys()])
|
||||||
r.append(f'{k}={h[k]}')
|
|
||||||
return r
|
|
||||||
|
def dict_empty_keys(x: dict) -> list:
|
||||||
|
return sorted([k for k in x.keys() if x[k] is None])
|
||||||
|
|
||||||
|
|
||||||
|
def dict_non_empty_keys(x: dict) -> list:
|
||||||
|
return sorted([k for k in x.keys() if x[k] is not None])
|
||||||
|
|
||||||
|
|
||||||
|
def list_diff(a: (list, set), b: (list, set)) -> list:
|
||||||
|
return list(set(a) - set(b))
|
||||||
|
|
||||||
|
|
||||||
|
def list_intersect(a: (list, set), b: (list, set)) -> list:
|
||||||
|
return list(set(a) & set(b))
|
||||||
|
|
||||||
|
|
||||||
J2CFG_FILTERS = [
|
J2CFG_FILTERS = [
|
||||||
|
any_to_env_dict,
|
||||||
any_to_str_list,
|
any_to_str_list,
|
||||||
as_cgi_header,
|
as_cgi_header,
|
||||||
env_any_to_str_list,
|
dict_empty_keys,
|
||||||
|
dict_keys,
|
||||||
|
dict_non_empty_keys,
|
||||||
|
dict_to_env_str_list,
|
||||||
is_mapping,
|
is_mapping,
|
||||||
|
is_re_fullmatch,
|
||||||
|
is_re_match,
|
||||||
is_sequence,
|
is_sequence,
|
||||||
is_str_list_re_fullmatch,
|
list_diff,
|
||||||
is_str_list_re_match,
|
list_intersect,
|
||||||
list_remove_empty_str,
|
re_fullmatch,
|
||||||
list_remove_non_str,
|
re_fullmatch_negate,
|
||||||
|
re_match,
|
||||||
|
re_match_negate,
|
||||||
|
re_sub,
|
||||||
|
remove_empty_str,
|
||||||
|
remove_non_str,
|
||||||
sh_like_file_to_list,
|
sh_like_file_to_list,
|
||||||
str_list_re_fullmatch,
|
|
||||||
str_list_re_match,
|
|
||||||
str_list_re_sub,
|
|
||||||
str_split_to_list,
|
str_split_to_list,
|
||||||
uniq_list,
|
uniq,
|
||||||
uniq_str_list,
|
uniq_str_list,
|
||||||
]
|
]
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
J2CFG_TEMPLATE_EXT = '.j2'
|
J2CFG_TEMPLATE_EXT = '.j2'
|
||||||
|
|
||||||
J2CFG_PATH = [
|
J2CFG_PATH = [
|
||||||
@ -24,3 +27,15 @@ J2CFG_JINJA_EXTENSIONS = [
|
|||||||
'jinja2.ext.do',
|
'jinja2.ext.do',
|
||||||
'jinja2.ext.loopcontrols',
|
'jinja2.ext.loopcontrols',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
J2CFG_BANNED_ENVS = [
|
||||||
|
r'ANGIE(=|$)',
|
||||||
|
r'ANGIE_BPF_MAPS(=|$)'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def is_env_banned(k: str) -> bool:
|
||||||
|
for r in J2CFG_BANNED_ENVS:
|
||||||
|
if re.match(r, k):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
139
j2cfg/test.j2
139
j2cfg/test.j2
@ -1,20 +1,40 @@
|
|||||||
j2cfg:
|
j2cfg:
|
||||||
{{ j2cfg }}
|
{{ j2cfg }}
|
||||||
|
|
||||||
|
{% set x = [1,2,3,4] %}
|
||||||
|
x = {{ x }}
|
||||||
|
is_sequence:
|
||||||
|
{{ x | is_sequence }}
|
||||||
|
|
||||||
|
{% set x = {1:2,3:4} %}
|
||||||
|
x = {{ x }}
|
||||||
|
is_sequence:
|
||||||
|
{{ x | is_sequence }}
|
||||||
|
|
||||||
|
{% set x = [1,2,3,4] %}
|
||||||
|
x = {{ x }}
|
||||||
|
is_mapping:
|
||||||
|
{{ x | is_mapping }}
|
||||||
|
|
||||||
|
{% set x = {1:2,3:4} %}
|
||||||
|
x = {{ x }}
|
||||||
|
is_mapping:
|
||||||
|
{{ x | is_mapping }}
|
||||||
|
|
||||||
{% set x = [2,3,1,2] %}
|
{% set x = [2,3,1,2] %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
uniq_list:
|
uniq:
|
||||||
{{ x | uniq_list }}
|
{{ x | uniq }}
|
||||||
|
|
||||||
{% set x = ['2',3,'1','2'] %}
|
{% set x = ['2',3,'1','2'] %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
list_remove_non_str:
|
remove_non_str:
|
||||||
{{ x | list_remove_non_str }}
|
{{ x | remove_non_str }}
|
||||||
|
|
||||||
{% set x = ['2','','1','2'] %}
|
{% set x = ['2','','1','2'] %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
list_remove_empty_str:
|
remove_empty_str:
|
||||||
{{ x | list_remove_empty_str }}
|
{{ x | remove_empty_str }}
|
||||||
|
|
||||||
{% set x = ['2','3','1','2'] %}
|
{% set x = ['2','3','1','2'] %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
@ -31,25 +51,10 @@ str_split_to_list:
|
|||||||
str_split_to_list(':'):
|
str_split_to_list(':'):
|
||||||
{{ x | str_split_to_list(':') }}
|
{{ x | str_split_to_list(':') }}
|
||||||
|
|
||||||
{% set x = [1,2,3,4] %}
|
{% set x = { 'VAR1': 'Etc/UTC', 'VAR2': '', 'VAR3': None, '4VAR4': 'yeah', 'VAR5=not': 'yeah', 'VAR5=real yeah': None, 'VAR6': {'pi': 3.1415926}, 'VAR7': ['pi', 3.1415926] } %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
is_sequence:
|
dict_to_env_str_list:
|
||||||
{{ x | is_sequence }}
|
{{ x | dict_to_env_str_list }}
|
||||||
|
|
||||||
{% set x = {1:2,3:4} %}
|
|
||||||
x = {{ x }}
|
|
||||||
is_sequence:
|
|
||||||
{{ x | is_sequence }}
|
|
||||||
|
|
||||||
{% set x = [1,2,3,4] %}
|
|
||||||
x = {{ x }}
|
|
||||||
is_mapping:
|
|
||||||
{{ x | is_mapping }}
|
|
||||||
|
|
||||||
{% set x = {1:2,3:4} %}
|
|
||||||
x = {{ x }}
|
|
||||||
is_mapping:
|
|
||||||
{{ x | is_mapping }}
|
|
||||||
|
|
||||||
{% set x = '1 2 3 4' %}
|
{% set x = '1 2 3 4' %}
|
||||||
"x = {{ x }}"
|
"x = {{ x }}"
|
||||||
@ -68,38 +73,52 @@ any_to_str_list:
|
|||||||
|
|
||||||
{% set x = ['a2','b3','c1','d2'] %}
|
{% set x = ['a2','b3','c1','d2'] %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
is_str_list_re_match('[ab]'):
|
is_re_match('[ab]'):
|
||||||
{{ x | is_str_list_re_match('[ab]') }}
|
{{ x | is_re_match('[ab]') }}
|
||||||
is_str_list_re_match('[mn]'):
|
is_re_match('[mn]'):
|
||||||
{{ x | is_str_list_re_match('[mn]') }}
|
{{ x | is_re_match('[mn]') }}
|
||||||
|
|
||||||
{% set x = ['a2','b3','c1','d2'] %}
|
{% set x = ['a2','b3','c1','d2'] %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
is_str_list_re_fullmatch('[ab]'):
|
is_re_fullmatch('[ab]'):
|
||||||
{{ x | is_str_list_re_fullmatch('[ab]') }}
|
{{ x | is_re_fullmatch('[ab]') }}
|
||||||
is_str_list_re_fullmatch('[ab][12]'):
|
is_re_fullmatch('[ab][12]'):
|
||||||
{{ x | is_str_list_re_fullmatch('[ab][12]') }}
|
{{ x | is_re_fullmatch('[ab][12]') }}
|
||||||
|
|
||||||
{% set x = ['a2','b3','c1','d2'] %}
|
{% set x = ['a2','b3','c1','d2'] %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
str_list_re_match('[ab]'):
|
re_match('[ab]'):
|
||||||
{{ x | str_list_re_match('[ab]') }}
|
{{ x | re_match('[ab]') }}
|
||||||
str_list_re_match('[mn]'):
|
re_match('[mn]'):
|
||||||
{{ x | str_list_re_match('[mn]') }}
|
{{ x | re_match('[mn]') }}
|
||||||
|
|
||||||
{% set x = ['a2','b3','c1','d2'] %}
|
{% set x = ['a2','b3','c1','d2'] %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
str_list_re_fullmatch('[ab]'):
|
re_fullmatch('[ab]'):
|
||||||
{{ x | str_list_re_fullmatch('[ab]') }}
|
{{ x | re_fullmatch('[ab]') }}
|
||||||
str_list_re_fullmatch('[ab][12]'):
|
re_fullmatch('[ab][12]'):
|
||||||
{{ x | str_list_re_fullmatch('[ab][12]') }}
|
{{ x | re_fullmatch('[ab][12]') }}
|
||||||
|
|
||||||
|
{% set x = ['a2','b3','c1','d2'] %}
|
||||||
|
x = {{ x }}
|
||||||
|
re_match_negate('[ab]'):
|
||||||
|
{{ x | re_match_negate('[ab]') }}
|
||||||
|
re_match_negate('[mn]'):
|
||||||
|
{{ x | re_match_negate('[mn]') }}
|
||||||
|
|
||||||
|
{% set x = ['a2','b3','c1','d2'] %}
|
||||||
|
x = {{ x }}
|
||||||
|
re_fullmatch_negate('[ab]'):
|
||||||
|
{{ x | re_fullmatch_negate('[ab]') }}
|
||||||
|
re_fullmatch_negate('[ab][12]'):
|
||||||
|
{{ x | re_fullmatch_negate('[ab][12]') }}
|
||||||
|
|
||||||
{% set x = ['a2b','b3b','c1f','d2g'] %}
|
{% set x = ['a2b','b3b','c1f','d2g'] %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
str_list_re_sub('[ab]', '_'):
|
re_sub('[ab]', '_'):
|
||||||
{{ x | str_list_re_sub('[ab]', '_') }}
|
{{ x | re_sub('[ab]', '_') }}
|
||||||
str_list_re_sub('[mn]', '_'):
|
re_sub('[mn]', '_'):
|
||||||
{{ x | str_list_re_sub('[mn]', '_') }}
|
{{ x | re_sub('[mn]', '_') }}
|
||||||
|
|
||||||
{% set x = 'j2cfg-multi.py' %}
|
{% set x = 'j2cfg-multi.py' %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
@ -118,15 +137,35 @@ as_cgi_header:
|
|||||||
|
|
||||||
{% set x = 'VAR1=Etc/UTC' %}
|
{% set x = 'VAR1=Etc/UTC' %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
env_any_to_str_list:
|
any_to_env_dict:
|
||||||
{{ x | env_any_to_str_list }}
|
{{ x | any_to_env_dict }}
|
||||||
|
|
||||||
{% set x = ['VAR1=Etc/UTC', 'VAR2=', 'VAR3', '4VAR4=yeah', 'VAR5=yeah', 'VAR5=not-yeah'] %}
|
{% set x = ['VAR1=Etc/UTC', 'VAR2=', 'VAR3', '4VAR4=yeah', 'VAR5=yeah', 'VAR5=not-yeah'] %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
env_any_to_str_list:
|
any_to_env_dict:
|
||||||
{{ x | env_any_to_str_list }}
|
{{ x | any_to_env_dict }}
|
||||||
|
|
||||||
{% set x = { 'VAR1': 'Etc/UTC', 'VAR2': '', 'VAR3': None, '4VAR4': 'yeah', 'VAR5=not': 'yeah', 'VAR5=real yeah': None, 'VAR6': {'pi': 3.1415926}, 'VAR7': ['pi', 3.1415926] } %}
|
{% set x = { 'VAR1': 'Etc/UTC', 'VAR2': '', 'VAR3': None, '4VAR4': 'yeah', 'VAR5=not': 'yeah', 'VAR5=real yeah': None, 'VAR6': {'pi': 3.1415926}, 'VAR7': ['pi', 3.1415926] } %}
|
||||||
x = {{ x }}
|
x = {{ x }}
|
||||||
env_any_to_str_list:
|
any_to_env_dict:
|
||||||
{{ x | env_any_to_str_list }}
|
{{ x | any_to_env_dict }}
|
||||||
|
|
||||||
|
{% set x = { 'VAR1': 'Etc/UTC', 'VAR2': '', 'VAR3': None, '4VAR4': 'yeah', 'VAR5=not': 'yeah', 'VAR5=real yeah': None, 'VAR6': {'pi': 3.1415926}, 'VAR7': ['pi', 3.1415926] } %}
|
||||||
|
x = {{ x }}
|
||||||
|
dict_keys:
|
||||||
|
{{ x | dict_keys }}
|
||||||
|
dict_empty_keys:
|
||||||
|
{{ x | dict_empty_keys }}
|
||||||
|
dict_non_empty_keys:
|
||||||
|
{{ x | dict_non_empty_keys }}
|
||||||
|
|
||||||
|
{% set x = [1,2,3,4] %}
|
||||||
|
{% set y = [3,4,5,6] %}
|
||||||
|
list_diff(x, y):
|
||||||
|
{{ x | list_diff(y) }}
|
||||||
|
list_diff(y, x):
|
||||||
|
{{ y | list_diff(x) }}
|
||||||
|
list_intersect(x, y):
|
||||||
|
{{ x | list_intersect(y) }}
|
||||||
|
list_intersect(y, x):
|
||||||
|
{{ y | list_intersect(x) }}
|
||||||
|
@ -4,7 +4,7 @@ set -f
|
|||||||
sed -znE '/^([^=]+)=.*$/s,,\1,p' /proc/self/environ \
|
sed -znE '/^([^=]+)=.*$/s,,\1,p' /proc/self/environ \
|
||||||
| sed -zE \
|
| sed -zE \
|
||||||
-e '/^_$/d;/^ENVSUBST_/d;' \
|
-e '/^_$/d;/^ENVSUBST_/d;' \
|
||||||
-e '/^__IEP/d;/^IEP_(INIT|VERBOSE|TRACE)$/d' \
|
-e '/^__IEP_/d;/^IEP_$/d' \
|
||||||
| {
|
| {
|
||||||
if [ -n "${ENVSUBST_EXCLUDE_REGEX:-}" ] ; then
|
if [ -n "${ENVSUBST_EXCLUDE_REGEX:-}" ] ; then
|
||||||
grep -zEv -e "${ENVSUBST_EXCLUDE_REGEX}"
|
grep -zEv -e "${ENVSUBST_EXCLUDE_REGEX}"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
[ "${IEP_VERBOSE}" = 0 ] || {
|
[ "${IEP_VERBOSE:-}" = 0 ] || {
|
||||||
pfx=
|
pfx=
|
||||||
[ "${IEP_TRACE}" = 0 ] || pfx="$(date +'%Y-%m-%d %H:%M:%S.%03N %z'): "
|
[ "${IEP_DEBUG:-}" = 0 ] || pfx="$(date +'%Y-%m-%d %H:%M:%S.%03N %z'): "
|
||||||
echo "# ${pfx}${0##*/}:" >&2
|
echo "# ${pfx}${0##*/}:" >&2
|
||||||
printf ' - %s\n' "$@" >&2
|
printf ' - %s\n' "$@" >&2
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
[ "${IEP_VERBOSE}" = 0 ] || {
|
[ "${IEP_VERBOSE:-}" = 0 ] || {
|
||||||
pfx=
|
pfx=
|
||||||
[ "${IEP_TRACE}" = 0 ] || pfx="$(date +'%Y-%m-%d %H:%M:%S.%03N %z'): "
|
[ "${IEP_DEBUG:-}" = 0 ] || pfx="$(date +'%Y-%m-%d %H:%M:%S.%03N %z'): "
|
||||||
echo "# ${pfx}${0##*/}:${*:+ $*}" >&2
|
echo "# ${pfx}${0##*/}:${*:+ $*}" >&2
|
||||||
}
|
}
|
||||||
exec python3 "/usr/local/lib/j2cfg/${0##*/}.py" "$@"
|
exec python3 "/usr/local/lib/j2cfg/${0##*/}.py" "$@"
|
Loading…
Reference in New Issue
Block a user