diff --git a/Dockerfile b/Dockerfile index ca4f779..f09a331 100644 --- a/Dockerfile +++ b/Dockerfile @@ -153,6 +153,11 @@ COPY /angie/ /etc/angie/ RUN find /etc/angie/ -name .gitkeep -delete ; \ find /etc/angie/ ! -type l -exec chmod go-w {} + +## preseed builtin modules list +RUN x='angie-builtin-modules.sh' ; \ + "$x" ; \ + chmod a-x $(which "$x") + ## misc tools RUN apt-install.sh \ brotli \ @@ -195,4 +200,4 @@ ENV DUMB_INIT_SETSID=0 \ STOPSIGNAL SIGQUIT ENTRYPOINT [ "image-entry.sh" ] -CMD [ "angie", "-g", "daemon off;" ] +CMD [ "angie" ] diff --git a/angie/.none.conf b/angie/.none.conf new file mode 100644 index 0000000..c337864 --- /dev/null +++ b/angie/.none.conf @@ -0,0 +1,3 @@ +daemon off; +master_process off; +events {} diff --git a/angie/angie.conf b/angie/angie.conf index ba02fb9..7122434 100644 --- a/angie/angie.conf +++ b/angie/angie.conf @@ -1,8 +1,9 @@ +daemon off; pid run/angie.pid; lock_file lock.d/angie.lock; ## almost useless -include mod.d/core-*.conf; +include mod.d/core-*.load; # mod-http.conf.in # mod-mail.conf.in @@ -11,10 +12,10 @@ include run/mod-*.conf; events { include conf.d/core_ev-*.conf; - include snip.d/core_ev-*.conf; + include snip.d/core_ev-*.load; } include conf.d/core-*.conf; -include snip.d/core-*.conf; +include snip.d/core-*.load; # ctx-http.conf.in # ctx-mail.conf.in diff --git a/angie/conf.dist/http-buffers.conf b/angie/conf.dist/http-buffers.conf new file mode 100644 index 0000000..4603ec6 --- /dev/null +++ b/angie/conf.dist/http-buffers.conf @@ -0,0 +1,7 @@ +subrequest_output_buffer_size 16k; +client_body_buffer_size 16k; +client_header_buffer_size 4k; +large_client_header_buffers 8 16k; + +## lowering from 16k to 4k to improve time-to-first-byte +ssl_buffer_size 4k; diff --git a/angie/ctx-http.conf b/angie/ctx-http.conf index cc64391..aea7f06 100644 --- a/angie/ctx-http.conf +++ b/angie/ctx-http.conf @@ -1,5 +1,5 @@ http { include conf.d/http-*.conf; - include snip.d/http-*.conf; + include snip.d/http-*.load; include site.d/http-*.conf; } \ No newline at end of file diff --git a/angie/ctx-mail.conf b/angie/ctx-mail.conf index 0780fca..49903a7 100644 --- a/angie/ctx-mail.conf +++ b/angie/ctx-mail.conf @@ -1,5 +1,5 @@ mail { include conf.d/mail-*.conf; - include snip.d/mail-*.conf; + include snip.d/mail-*.load; include site.d/mail-*.conf; } \ No newline at end of file diff --git a/angie/ctx-stream.conf b/angie/ctx-stream.conf index 1bf0cf5..324b691 100644 --- a/angie/ctx-stream.conf +++ b/angie/ctx-stream.conf @@ -1,5 +1,5 @@ stream { include conf.d/stream-*.conf; - include snip.d/stream-*.conf; + include snip.d/stream-*.load; include site.d/stream-*.conf; } \ No newline at end of file diff --git a/angie/mod-http.conf b/angie/mod-http.conf index 4164f42..d18a01d 100644 --- a/angie/mod-http.conf +++ b/angie/mod-http.conf @@ -1 +1 @@ -include mod.d/http-*.conf; \ No newline at end of file +include mod.d/http-*.load; \ No newline at end of file diff --git a/angie/mod-mail.conf b/angie/mod-mail.conf index 752474e..015317b 100644 --- a/angie/mod-mail.conf +++ b/angie/mod-mail.conf @@ -1 +1 @@ -include mod.d/mail-*.conf; \ No newline at end of file +include mod.d/mail-*.load; \ No newline at end of file diff --git a/angie/mod-stream.conf b/angie/mod-stream.conf index bafd341..2eba682 100644 --- a/angie/mod-stream.conf +++ b/angie/mod-stream.conf @@ -1 +1 @@ -include mod.d/stream-*.conf; \ No newline at end of file +include mod.d/stream-*.load; \ No newline at end of file diff --git a/angie/mod.dist/http-brotli-filter.conf b/angie/mod.dist/http-brotli-filter.conf deleted file mode 100644 index 2acbe61..0000000 --- a/angie/mod.dist/http-brotli-filter.conf +++ /dev/null @@ -1 +0,0 @@ -load_module modules.d/ngx_http_brotli_filter_module.so; \ No newline at end of file diff --git a/angie/mod.dist/http-brotli.conf b/angie/mod.dist/http-brotli.conf index c365782..2acbe61 100644 --- a/angie/mod.dist/http-brotli.conf +++ b/angie/mod.dist/http-brotli.conf @@ -1,2 +1 @@ -load_module modules.d/ngx_http_brotli_filter_module.so; -load_module modules.d/ngx_http_brotli_static_module.so; \ No newline at end of file +load_module modules.d/ngx_http_brotli_filter_module.so; \ No newline at end of file diff --git a/angie/mod.dist/http-zstd-filter.conf b/angie/mod.dist/http-zstd-filter.conf deleted file mode 100644 index cb586bc..0000000 --- a/angie/mod.dist/http-zstd-filter.conf +++ /dev/null @@ -1 +0,0 @@ -load_module modules.d/ngx_http_zstd_filter_module.so; \ No newline at end of file diff --git a/angie/mod.dist/http-zstd.conf b/angie/mod.dist/http-zstd.conf index 591f74b..cb586bc 100644 --- a/angie/mod.dist/http-zstd.conf +++ b/angie/mod.dist/http-zstd.conf @@ -1,2 +1 @@ -load_module modules.d/ngx_http_zstd_filter_module.so; -load_module modules.d/ngx_http_zstd_static_module.so; \ No newline at end of file +load_module modules.d/ngx_http_zstd_filter_module.so; \ No newline at end of file diff --git a/angie/snip.dist/http-brotli-static.conf b/angie/snip.dist/http-brotli-static.conf new file mode 100644 index 0000000..0b7c7d9 --- /dev/null +++ b/angie/snip.dist/http-brotli-static.conf @@ -0,0 +1,2 @@ +## no extra configuration is present at this time +## ref: https://github.com/google/ngx_brotli/ diff --git a/angie/snip.dist/http-brotli.conf b/angie/snip.dist/http-brotli.conf new file mode 100644 index 0000000..ff5bfde --- /dev/null +++ b/angie/snip.dist/http-brotli.conf @@ -0,0 +1,24 @@ +## default is 6 +brotli_comp_level 5; +## default is 512k +brotli_window 64k; + +brotli_min_length 1024; +brotli_buffers 32 16k; + +brotli_types + application/atom+xml + application/javascript + application/json + application/vnd.api+json + application/rss+xml + application/x-javascript + application/xhtml+xml + application/xml + image/svg+xml + image/x-icon + text/css + text/javascript + text/plain + text/xml +; diff --git a/angie/snip.dist/http-gunzip.conf b/angie/snip.dist/http-gunzip.conf new file mode 100644 index 0000000..19dd7da --- /dev/null +++ b/angie/snip.dist/http-gunzip.conf @@ -0,0 +1 @@ +gunzip_buffers 16 16k; \ No newline at end of file diff --git a/angie/snip.dist/http-gzip-static.conf b/angie/snip.dist/http-gzip-static.conf new file mode 100644 index 0000000..5f33c12 --- /dev/null +++ b/angie/snip.dist/http-gzip-static.conf @@ -0,0 +1,2 @@ +## no extra configuration is present at this time +## ref: https://angie.software/en/configuration/modules/http_gzip_static/ diff --git a/angie/snip.dist/http-gzip.conf b/angie/snip.dist/http-gzip.conf new file mode 100644 index 0000000..2e3f830 --- /dev/null +++ b/angie/snip.dist/http-gzip.conf @@ -0,0 +1,25 @@ +## default is 1 +gzip_comp_level 2; + +gzip_min_length 1024; +gzip_buffers 32 16k; + +gzip_vary on; +gzip_proxied any; + +gzip_types + application/atom+xml + application/javascript + application/json + application/vnd.api+json + application/rss+xml + application/x-javascript + application/xhtml+xml + application/xml + image/svg+xml + image/x-icon + text/css + text/javascript + text/plain + text/xml +; diff --git a/angie/snip.dist/http-zstd-static.conf b/angie/snip.dist/http-zstd-static.conf new file mode 100644 index 0000000..730b785 --- /dev/null +++ b/angie/snip.dist/http-zstd-static.conf @@ -0,0 +1,2 @@ +## no extra configuration is present at this time +## ref: https://github.com/tokers/zstd-nginx-module/ diff --git a/angie/snip.dist/http-zstd.conf b/angie/snip.dist/http-zstd.conf new file mode 100644 index 0000000..9720f81 --- /dev/null +++ b/angie/snip.dist/http-zstd.conf @@ -0,0 +1,22 @@ +## default is 1 +zstd_comp_level 2; + +zstd_min_length 1024; +zstd_buffers 32 16k; + +zstd_types + application/atom+xml + application/javascript + application/json + application/vnd.api+json + application/rss+xml + application/x-javascript + application/xhtml+xml + application/xml + image/svg+xml + image/x-icon + text/css + text/javascript + text/plain + text/xml +; diff --git a/image-entry.d/00-common.envsh b/image-entry.d/00-common.envsh index 5843bcf..64ba8e9 100644 --- a/image-entry.d/00-common.envsh +++ b/image-entry.d/00-common.envsh @@ -1,5 +1,10 @@ #!/bin/sh +volume_root='/run/angie' +tmp_dir="${volume_root}/tmp" +merged_root="${volume_root}/merged" +target_root="${volume_root}" + have_envvar() { [ -n "$1" ] || return 1 grep -Ezq "^$1=" /proc/self/environ || return @@ -45,18 +50,28 @@ IEP_VERBOSE=$(gobool_to_int "${IEP_VERBOSE:-${IEP_TRACE}}" "${IEP_TRACE}") export IEP_VERBOSE if [ "${IEP_VERBOSE}" = 1 ] ; then log() { log_always "$@" ; } - log_file() { sed -E '/^./s,^, ,' < "$1" >&2 ; } else log() { : ;} - log_file() { :; } fi +log_file() { sed -E '/^./s,^, ,' < "$1" >&2 ; } + if [ "${IEP_VERBOSE}" = 0 ] ; then ln_s() { ln -s "$@" || return; } + cp_a() { cp -a "$@" || return; } else ln_s() { ln -sv "$@" || return; } + cp_a() { cp -av "$@" || return; } fi +ln_cp() { + if [ -h "$1" ] ; then + ln_s "$(readlink -e "$1")" "$2" + else + cp_a "$1" "$2" + fi +} + have_cmd() { command -v "$1" >/dev/null 2>&1 || return ; } strip_suffix() { printf '%s' "${1%"$2"}" | tr -s '/' ; } @@ -64,7 +79,7 @@ strip_suffix() { printf '%s' "${1%"$2"}" | tr -s '/' ; } untemplate_path() { case "$1" in ## inplace - /run/angie/* | /etc/angie/run/* ) + "${volume_root}"/* | /etc/angie/run/* ) 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/* ) @@ -75,7 +90,7 @@ untemplate_path() { ;; ## set appropriate location /etc/angie/* ) - strip_suffix "/run/angie${1#/etc/angie}" "$2" + strip_suffix "${volume_root}${1#/etc/angie}" "$2" ;; /tmp/* ) log_always "untemplate_path() shouldn't work with /tmp/: $1" @@ -84,7 +99,7 @@ untemplate_path() { ## last resort - STRONGLY AVOID /* ) log_always "untemplate_path() does uncommon/last-resort mapping for: $1" - strip_suffix "/run/angie/tmp$1" "$2" + strip_suffix "${tmp_dir}$1" "$2" ;; ## misbehavior! * ) @@ -111,6 +126,11 @@ untemplate_file_envsubst() { __dest="$2" [ -n "${__dest}" ] || __dest=$(untemplate_path "$1" "${NGX_ENVSUBST_SUFFIX}") || return + if [ -e "${__dest}" ] ; then + log "untemplate_file_envsubst: destination file already exists" + return + fi + [ -d "${__dest%/*}" ] || install_userdir "${__dest%/*}" || return log "Running envsubst: $1 -> ${__dest}" @@ -129,6 +149,11 @@ untemplate_file_jinja() { __dest="$2" [ -n "${__dest}" ] || __dest=$(untemplate_path "$1" "${NGX_JINJA_SUFFIX}") || return + if [ -e "${__dest}" ] ; then + log "untemplate_file_jinja: destination file already exists" + return + fi + [ -d "${__dest%/*}" ] || install_userdir "${__dest%/*}" || return log "Running jinja.py: $1 -> ${__dest}" @@ -152,10 +177,11 @@ untemplate_dir_envsubst() { export ENVSUBST_ARGS fi - while read -r _orig_file ; do - [ -n "${_orig_file}" ] || continue - untemplate_file_envsubst "${_orig_file}" + while read -r __orig_file ; do + [ -n "${__orig_file}" ] || continue + untemplate_file_envsubst "${__orig_file}" done < "${__template_list}" + unset __orig_file if [ -z "${__have_args}" ] ; then rm -f "${ENVSUBST_ARGS}" ; unset ENVSUBST_ARGS @@ -173,10 +199,11 @@ untemplate_dir_jinja() { find "$@" -follow -type f -name "*${NGX_JINJA_SUFFIX}" \ | sort -uV > "${__template_list}" - while read -r _orig_file ; do - [ -n "${_orig_file}" ] || continue - untemplate_file_jinja "${_orig_file}" + while read -r __orig_file ; do + [ -n "${__orig_file}" ] || continue + untemplate_file_jinja "${__orig_file}" done < "${__template_list}" + unset __orig_file rm -f "${__template_list}" ; unset __template_list } @@ -227,12 +254,11 @@ remap_path() { esac } -merged_root='/run/angie/merged' combine_remap_path() { [ -n "$1" ] || return case "$1" in - "${merged_root}"/* ) echo "${2:-/run/angie}${1#"${merged_root}"}" ;; + "${merged_root}"/* ) echo "${2:-${target_root}}${1#"${merged_root}"}" ;; ## misbehavior! * ) log_always "combine_remap_path() doesn't know how to handle this path: $1" @@ -240,3 +266,21 @@ combine_remap_path() { ;; esac } + +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+$//' +} diff --git a/image-entry.d/10-core-modules.envsh b/image-entry.d/10-core-modules.envsh new file mode 100755 index 0000000..ad083fa --- /dev/null +++ b/image-entry.d/10-core-modules.envsh @@ -0,0 +1,38 @@ +#!/bin/sh + +unset core_modules core_snippets +core_modules= +core_snippets="${NGX_CORE_SNIPPETS:-}" + +## filter out builtin core modules +unset i +for i in ${NGX_CORE_MODULES:-} ; do + [ -n "$i" ] || continue + + if is_builtin_module core "$i" ; then + log "$i is builtin module, moving to snippets" + core_snippets="${core_snippets}${core_snippets:+ }$i" + continue + fi + + ## naive deduplication + case " ${core_modules} " in + *" $i "* ) + log "$i is already specified" + continue + ;; + esac + + core_modules="${core_modules}${core_modules:+ }$i" +done +unset i + +## sort and remove duplicates +core_snippets=$(sort_dedup_list "${core_snippets}") + +set -a +NGX_CORE_MODULES="${core_modules}" +NGX_CORE_SNIPPETS="${core_snippets}" +set +a + +unset core_modules core_snippets diff --git a/image-entry.d/10-core-user.envsh b/image-entry.d/11-core-user.envsh similarity index 100% rename from image-entry.d/10-core-user.envsh rename to image-entry.d/11-core-user.envsh diff --git a/image-entry.d/11-core-env.envsh b/image-entry.d/12-core-env.envsh similarity index 100% rename from image-entry.d/11-core-env.envsh rename to image-entry.d/12-core-env.envsh diff --git a/image-entry.d/12-core-worker-defaults.envsh b/image-entry.d/13-core-worker-defaults.envsh similarity index 100% rename from image-entry.d/12-core-worker-defaults.envsh rename to image-entry.d/13-core-worker-defaults.envsh diff --git a/image-entry.d/21-http-modules.envsh b/image-entry.d/21-http-modules.envsh new file mode 100755 index 0000000..6854fb0 --- /dev/null +++ b/image-entry.d/21-http-modules.envsh @@ -0,0 +1,39 @@ +#!/bin/sh + +if [ "${NGX_HTTP}" = 1 ] ; then + unset http_modules http_snippets + http_modules= + http_snippets="${NGX_HTTP_SNIPPETS:-}" + + ## filter out builtin http modules + unset i + for i in ${NGX_HTTP_MODULES:-} ; do + [ -n "$i" ] || continue + + if is_builtin_module http "$i" ; then + log "$i is builtin module, moving to snippets" + http_snippets="${http_snippets}${http_snippets:+ }$i" + continue + fi + + ## naive deduplication + case " ${http_modules} " in + *" $i "* ) + log "$i is already specified" + continue + ;; + esac + + http_modules="${http_modules}${http_modules:+ }$i" + done + unset i + + http_snippets=$(sort_dedup_list "${http_snippets}") + + set -a + NGX_HTTP_MODULES="${http_modules}" + NGX_HTTP_SNIPPETS="${http_snippets}" + set +a + + unset http_modules http_snippets +fi diff --git a/image-entry.d/21-http-max-ranges.envsh b/image-entry.d/22-http-max-ranges.envsh similarity index 100% rename from image-entry.d/21-http-max-ranges.envsh rename to image-entry.d/22-http-max-ranges.envsh diff --git a/image-entry.d/31-mail-modules.envsh b/image-entry.d/31-mail-modules.envsh new file mode 100755 index 0000000..ca554e6 --- /dev/null +++ b/image-entry.d/31-mail-modules.envsh @@ -0,0 +1,39 @@ +#!/bin/sh + +if [ "${NGX_MAIL}" = 1 ] ; then + unset mail_modules mail_snippets + mail_modules= + mail_snippets="${NGX_MAIL_SNIPPETS:-}" + + ## filter out builtin mail modules + unset i + for i in ${NGX_MAIL_MODULES:-} ; do + [ -n "$i" ] || continue + + if is_builtin_module mail "$i" ; then + log "$i is builtin module, moving to snippets" + mail_snippets="${mail_snippets}${mail_snippets:+ }$i" + continue + fi + + ## naive deduplication + case " ${mail_modules} " in + *" $i "* ) + log "$i is already specified" + continue + ;; + esac + + mail_modules="${mail_modules}${mail_modules:+ }$i" + done + unset i + + mail_snippets=$(sort_dedup_list "${mail_snippets}") + + set -a + NGX_MAIL_MODULES="${mail_modules}" + NGX_MAIL_SNIPPETS="${mail_snippets}" + set +a + + unset mail_modules mail_snippets +fi diff --git a/image-entry.d/41-stream-modules.envsh b/image-entry.d/41-stream-modules.envsh new file mode 100755 index 0000000..bebd540 --- /dev/null +++ b/image-entry.d/41-stream-modules.envsh @@ -0,0 +1,39 @@ +#!/bin/sh + +if [ "${NGX_STREAM}" = 1 ] ; then + unset stream_modules stream_snippets + stream_modules= + stream_snippets="${NGX_STREAM_SNIPPETS:-}" + + ## filter out builtin stream modules + unset i + for i in ${NGX_STREAM_MODULES:-} ; do + [ -n "$i" ] || continue + + if is_builtin_module stream "$i" ; then + log "$i is builtin module, moving to snippets" + stream_snippets="${stream_snippets}${stream_snippets:+ }$i" + continue + fi + + ## naive deduplication + case " ${stream_modules} " in + *" $i "* ) + log "$i is already specified" + continue + ;; + esac + + stream_modules="${stream_modules}${stream_modules:+ }$i" + done + unset i + + stream_snippets=$(sort_dedup_list "${stream_snippets}") + + set -a + NGX_STREAM_MODULES="${stream_modules}" + NGX_STREAM_SNIPPETS="${stream_snippets}" + set +a + + unset stream_modules stream_snippets +fi diff --git a/image-entry.d/50-flush-run-volume.sh b/image-entry.d/50-flush-run-volume.sh index be6f192..b4cf016 100755 --- a/image-entry.d/50-flush-run-volume.sh +++ b/image-entry.d/50-flush-run-volume.sh @@ -3,9 +3,9 @@ set -f . /image-entry.d/00-common.envsh -find /run/angie/ -mindepth 1 -exec rm -rf {} + +find "${volume_root}/" -mindepth 1 -exec rm -rf {} + -[ -d /run/angie/tmp ] || install -d -m 03777 /run/angie/tmp -[ -d /run/angie/lock ] || install_userdir /run/angie/lock +[ -d "${tmp_dir}" ] || install -d -m 03777 "${tmp_dir}" +[ -d "${volume_root}/lock" ] || install_userdir "${volume_root}/lock" exit 0 diff --git a/image-entry.d/51-topmost-configs.sh b/image-entry.d/51-topmost-configs.sh index f929ffa..cd71f89 100755 --- a/image-entry.d/51-topmost-configs.sh +++ b/image-entry.d/51-topmost-configs.sh @@ -4,7 +4,7 @@ set -f . /image-entry.d/00-common.envsh s=/etc/angie -d=/run/angie +d=${target_root} comps='' [ "${NGX_HTTP}" = 0 ] || comps="${comps} http" diff --git a/image-entry.d/54-combine-tree.sh b/image-entry.d/54-combine-tree.sh index 25d8724..26829d1 100755 --- a/image-entry.d/54-combine-tree.sh +++ b/image-entry.d/54-combine-tree.sh @@ -3,6 +3,22 @@ set -f . /image-entry.d/00-common.envsh +## sanity check +t=$(mktemp) || exit 1 + +for n in mod snip ; do + [ -d "${merged_root}/$n" ] || continue + find "${merged_root}/$n/" ! -type d +done \ +| grep -E "^${merged_root}/(mod|snip)/.+\.load\$" \ +| sort -V > "$t" + +if [ -s "$t" ] ; then + log_always 'these files will be EXPLICITLY skipped:' + log_file "$t" +fi +rm -f "$t" ; unset t + [ "${NGX_STRICT_LOAD}" = 0 ] || set -e load_error() { @@ -16,15 +32,26 @@ load_error() { fi } -smart_ln() { - if [ -h "$1" ] ; then - ln_s "$(readlink -e "$1")" "$2" - else - cp "$1" "$2" - fi -} +dirs='cache lib log' +for n in ${dirs} ; do + s="/angie/$n" + d="${target_root}/$n" -dirs='conf modules njs site' + if [ -d "$s" ] ; then + ln_s "$s" "$d" + else + [ -d "$d" ] || install_userdir "$d" + fi +done + +## provide same symlinks as upstream (both Angie and nginx) docker images do +d="${target_root}/log" +[ -e "$d/access.log" ] || ln_s /dev/stdout "$d/access.log" +[ -e "$d/error.log" ] || ln_s /dev/stderr "$d/error.log" + +## NB: if any error occurs above then configuration is merely empty and/or broken + +dirs='conf mod modules njs site snip' [ "${NGX_PROCESS_STATIC}" = 0 ] || dirs="${dirs} static" while read -r old_path ; do [ -n "${old_path}" ] || continue @@ -35,68 +62,91 @@ while read -r old_path ; do new_dir="${new_path%/*}" [ -d "${new_dir}" ] || mkdir -p "${new_dir}" - smart_ln "${old_path}" "${new_path}" + ln_cp "${old_path}" "${new_path}" done <<-EOF $( + set +e for n in ${dirs} ; do [ -d "${merged_root}/$n" ] || continue find "${merged_root}/$n/" ! -type d - done | sort -V + done \ + | grep -Ev \ + -e "^${merged_root}/(mod|snip)/.+\.load\$" \ + -e "^${merged_root}/mod/[^/]+\.preseed\$" \ + | sort -V + set -e ) EOF if [ "${NGX_PROCESS_STATIC}" = 0 ] ; then for d in /angie/static /etc/angie/static /etc/angie/static.dist ; do [ -d "$d" ] || continue - ln_s "$d" /run/angie/static + ln_s "$d" "${target_root}/static" break done fi -dirs='cache lib log' -for n in ${dirs} ; do - s="/angie/$n" - d="/run/angie/$n" - - if [ -d "$s" ] ; then - ln_s "$s" "$d" - else - [ -d "$d" ] || install_userdir "$d" - fi -done - -## provide same symlinks as upstream (both Angie and nginx) docker images do -d=/run/angie/log -[ -e "$d/access.log" ] || ln_s /dev/stdout "$d/access.log" -[ -e "$d/error.log" ] || ln_s /dev/stderr "$d/error.log" - ## Angie modules are loaded in [strict] order! combine_modules() { [ -n "$1" ] || return 1 n="$1" ; shift + [ $# -ne 0 ] || return 0 + + old_dir="${merged_root}/mod" + new_dir="${target_root}/mod" + i=0 for m ; do [ -n "$m" ] || continue - old_name="mod/$n-$m.conf" - - old_path="${merged_root}/${old_name}" + old_name="$n-$m.conf" + old_path="${old_dir}/${old_name}" if ! [ -f "${old_path}" ] ; then - log_always "file ${old_name} is not found" + log_always "file ${old_name} is not found in ${old_dir}/" load_error log "file ${old_name} is skipped" continue fi - new_path=$(printf "/run/angie/mod/$n-%02d-%s.conf" "$i" "$m") - new_dir="${new_path%/*}" - [ -d "${new_dir}" ] || mkdir -p "${new_dir}" + new_name=$(printf "%s-%02d-%s.load" "$n" "$i" "$m") + new_path="${new_dir}/${new_name}" - smart_ln "${old_path}" "${new_path}" + ln_cp "${old_path}" "${new_path}" i=$((i+1)) - done + done ; unset m +} + +combine_snippets() { + [ -n "$1" ] || return 1 + n="$1" ; shift + + [ $# -ne 0 ] || return 0 + + old_dir="${merged_root}/snip" + new_dir="${target_root}/snip" + + for s ; do + [ -n "$s" ] || continue + + new_path="${new_dir}/$n-$s.load" + if [ -e "${new_path}" ] ; then + log "${new_path} already exists, skipping" + continue + fi + + old_name="$n-$s.conf" + old_path="${old_dir}/${old_name}" + if ! [ -f "${old_path}" ] ; then + log_always "file ${old_name} is not found in ${old_dir}/" + load_error + log "file ${old_name} is skipped" + continue + fi + + ln_cp "${old_path}" "${new_path}" + done ; unset s } combine_modules core ${NGX_CORE_MODULES:-} @@ -104,82 +154,15 @@ combine_modules http ${NGX_HTTP_MODULES:-} combine_modules mail ${NGX_MAIL_MODULES:-} combine_modules stream ${NGX_STREAM_MODULES:-} -combine_snippets() { - [ -n "$1" ] || return 1 - n="$1" ; shift - - for s ; do - [ -n "$s" ] || continue - - old_name="snip/$n-$s.conf" - - old_path="${merged_root}/${old_name}" - if ! [ -f "${old_path}" ] ; then - log_always "file ${old_name} is not found" - load_error - log "file ${old_name} is skipped" - continue - fi - - new_path="/run/angie/${old_name}" - new_dir="${new_path%/*}" - [ -d "${new_dir}" ] || mkdir -p "${new_dir}" - - smart_ln "${old_path}" "${new_path}" - done -} - combine_snippets core ${NGX_CORE_SNIPPETS:-} combine_snippets core_ev ${NGX_CORE_EVENTS_SNIPPETS:-} combine_snippets http ${NGX_HTTP_SNIPPETS:-} combine_snippets mail ${NGX_MAIL_SNIPPETS:-} combine_snippets stream ${NGX_STREAM_SNIPPETS:-} -combine_module_snippets() { - [ -n "$1" ] || return 1 - n="$1" ; shift - - for s ; do - [ -n "$s" ] || continue - - old_name="snip/$n-$s.conf" - - old_path="${merged_root}/${old_name}" - if ! [ -f "${old_path}" ] ; then - log "file ${old_name} is not found, skipping" - continue - fi - - new_path="/run/angie/${old_name}" - new_dir="${new_path%/*}" - [ -d "${new_dir}" ] || mkdir -p "${new_dir}" - - smart_ln "${old_path}" "${new_path}" - done -} - -combine_module_snippets core ${NGX_CORE_MODULES:-} -combine_module_snippets http ${NGX_HTTP_MODULES:-} -combine_module_snippets mail ${NGX_MAIL_MODULES:-} -combine_module_snippets stream ${NGX_STREAM_MODULES:-} - -## merge remaining snippets -while read -r old_path ; do - [ -n "${old_path}" ] || continue - - new_path=$(combine_remap_path "${old_path}") - [ -n "${new_path}" ] || exit 1 - - new_dir="${new_path%/*}" - [ -d "${new_dir}" ] || mkdir -p "${new_dir}" - - smart_ln "${old_path}" "${new_path}" -done <<-EOF -$( - find "${merged_root}/snip/" ! -type d \ - | grep -Ev -e "^${merged_root}/snip/(core|core_ev|http|mail|stream)-[^/]*\.conf\$" \ - | sort -V -) -EOF +combine_snippets core ${NGX_CORE_MODULES:-} +combine_snippets http ${NGX_HTTP_MODULES:-} +combine_snippets mail ${NGX_MAIL_MODULES:-} +combine_snippets stream ${NGX_STREAM_MODULES:-} exit 0 diff --git a/image-entry.d/90-angie-config-test.sh b/image-entry.d/90-angie-config-test.sh index 07117b6..6ccc90d 100755 --- a/image-entry.d/90-angie-config-test.sh +++ b/image-entry.d/90-angie-config-test.sh @@ -11,7 +11,7 @@ r=$? log_always '=========================' ## cleanup after test -rm -f /run/angie/angie.pid +rm -f "${volume_root}/angie.pid" if [ $r = 0 ] ; then log_always 'ready to run Angie' diff --git a/scripts/angie-builtin-modules.sh b/scripts/angie-builtin-modules.sh new file mode 100755 index 0000000..7857d87 --- /dev/null +++ b/scripts/angie-builtin-modules.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -f + +conf_dir='/etc/angie' +conf_file="${conf_dir}/.none.conf" +pid_file='/run/angie/none.pid' + +angie -g "error_log /dev/stderr warn; pid ${pid_file};" -c "${conf_file}" -t +r=$? +rm -f "${pid_file}" +[ $r -eq 0 ] || exit $r + +t=$(mktemp) || exit $? + +angie -c "${conf_file}" -m 2>&1 | tee "$t" >/dev/null + +sed -En '/^ngx_(http|mail|stream)/d;/^ngx_(.+)_module$/{s//\1/;s/_filter$//;s/_/-/g;p}' < "$t" \ +| sort -uV > "${conf_dir}/builtin.core" + +for m in http mail stream ; do + sed -En '/^ngx_'"${m}"'_(.+)_module$/{s//\1/;s/_filter$//;s/_/-/g;p}' < "$t" \ + | sort -uV > "${conf_dir}/builtin.$m" +done + +rm -f "$t" ; unset t + +for m in core http mail stream ; do + echo "${conf_dir}/builtin.$m" +done \ +| xargs -r ls -ld