#!/bin/sh set -ef [ $# -gt 0 ] || exit 1 set -a ANGIE_MODULES_DIR="${ANGIE_MODULES_DIR:-/usr/lib/angie/modules}" set +a unset NGX_DEBUG NGX_DEBUG=$(/usr/sbin/angie --build-env 2>&1 | mawk '$1=="DEBUG:" {print $2;exit;}') NGX_DEBUG="${NGX_DEBUG:-0}" case "${NGX_DEBUG}" in 0 | 1 ) ;; * ) NGX_DEBUG=1 ;; esac unset NGX_PRO NGX_PRO=$(/usr/sbin/angie -v 2>&1 | mawk 'NR==1 {print $4;exit;}' | tr '[:upper:]' '[:lower:]') NGX_PRO="${NGX_PRO:-0}" case "${NGX_PRO}" in '(pro)' ) NGX_PRO=1 ;; * ) NGX_PRO=0 ;; esac ## "fqpn" stands for "Full Qualified Package Name" ## Angie OSS: angie-module- ## Angie PRO: angie-pro-module- if [ ${NGX_PRO} = 1 ] ; then fqpn() { echo "angie-pro-module-$1" ; } else fqpn() { echo "angie-module-$1" ; } fi is_pkg_installed() { case "$(dpkg-query -W -f='${Status}' "$1" 2>/dev/null)" in "install ok installed" ) ## package is installed normally return 0 ;; "hold ok installed" ) ## package is installed and marked as "hold" return 0 ;; esac return 1 } is_mod_installed() { is_pkg_installed "$(fqpn "$1")" || return 1 } ## produce package list mods= for i ; do [ -n "$i" ] || continue printf '%s' "$i" | grep -zEq '^[a-z0-9.+-]+$' || { env printf 'package name %q is not legal, quitting!\n' "$i" >&2 exit 1 } if is_mod_installed "$i" ; then echo "package '$i' is already installed, skipping" >&2 continue fi mods="${mods}${mods:+ }$i" done [ -n "${mods}" ] || exit 0 list_have_item() { [ -n "$1" ] || return 1 [ -n "$2" ] || return 1 case " $1 " in *" $2 "* ) return 0 ;; esac return 1 } normalize_list() { [ -n "$1" ] || return 0 printf '%s' "$1" \ | sed -zE 's/[[:space:]]+/ /g;s/^ //;s/ $//' } sort_dedup_list() { [ -n "$1" ] || return 0 printf '%s' "$1" \ | tr -s '[:space:]' '\n' | sort -uV \ | sed -zE 's/[[:space:]]+/ /g;s/^ //;s/ $//' } mods=$(sort_dedup_list "${mods}") ## angie-module-lua: depends on angie-module-ndk ## angie-module-set-misc: depends on angie-module-ndk unset want_ndk ; want_ndk=0 if list_have_item "${mods}" lua ; then want_ndk=1 elif list_have_item "${mods}" set-misc ; then want_ndk=1 fi if [ ${want_ndk} = 1 ] ; then while : ; do if list_have_item "${mods}" ndk ; then break ; fi if is_mod_installed ndk ; then break ; fi mods="${mods} ndk" break ; done fi ## angie-module-wamr: depends on angie-module-wasm ## angie-module-wasmtime: depends on angie-module-wasm unset want_wasm ; want_wasm=0 if list_have_item "${mods}" wamr ; then want_wasm=1 elif list_have_item "${mods}" wasmtime ; then want_wasm=1 fi if [ ${want_wasm} = 1 ] ; then while : ; do if list_have_item "${mods}" wasm ; then break ; fi if is_mod_installed wasm ; then break ; fi mods="${mods} wasm" break ; done fi ## kind of quirk dirs='cache lib log' for n in ${dirs} ; do d="/run/ngx/$n" [ -d "$d" ] || install -d "$d" done pkgs= for m in ${mods} ; do pkgs="${pkgs}${pkgs:+ }$(fqpn "$m")" done apt-install.sh ${pkgs} ANGIE_DIST_MODCONF_DIR=/etc/angie.dist/mod ANGIE_MODCONF_DIR=/etc/angie/mod [ -d "${ANGIE_MODCONF_DIR}" ] || install -d "${ANGIE_MODCONF_DIR}" have_preseed() { if [ -e "${ANGIE_DIST_MODCONF_DIR}/.$1.preseed" ] ; then return 0 fi if [ -e "${ANGIE_MODCONF_DIR}/.$1.preseed" ] ; then return 0 fi return 1 } list_ngx_modules() { set +e dpkg-query -L "$1" \ | grep -F -e "${ANGIE_MODULES_DIR}/" \ | grep -E -e '/[^/]+_module(-debug)?\.so$' \ | sed -E '\,^(.+)-debug\.so$,{p;s//\1.so/;p;d}' \ | sort -uV \ | xargs -r ls -U1d 2>/dev/null set -e } is_same_file() { find -L "$1" -samefile "$2" -printf . -quit 2>/dev/null | grep -Fq . || return 1 } gen_mod_config() { if [ -s "$2" ] ; then printf '%s: configuration already exists: %s\n' "$1" "$2" >&2 return fi [ -n "$3" ] || return local __m for __m in $3 ; do echo "load_module ${__m};" done > "$2" } for m in ${mods} ; do [ -n "$m" ] || continue p=$(fqpn "$m") ## adjust modules: ## - remove debug module if not in debug image ## - move debug module to usual location otherwise while read -r fmod_debug ; do # [ -n "${fmod_debug}" ] || continue case "${fmod_debug}" in *-debug.so ) ;; * ) continue ;; esac fmod="${fmod_debug%-debug.so}.so" if [ "${NGX_DEBUG}" = 0 ] ; then if [ -f "${fmod}" ] ; then fmod_real=$(readlink -f "${fmod}") else env printf 'missing (non-debug) file: %q\n' "${fmod}" >&2 env printf 'falling back to (debug) file: %q\n' "${fmod_debug}" >&2 fmod_real=$(readlink -f "${fmod_debug}") fi else fmod_real=$(readlink -f "${fmod_debug}") fi [ -n "${fmod_real}" ] || exit 1 fmod_tmp=$(mktemp -u "${fmod}.XXXXXXXXXX") ln "${fmod_real}" "${fmod_tmp}" rm -f "${fmod}" "${fmod_debug}" mv -f "${fmod_tmp}" "${fmod}" apt-mark hold "$p" || : done <<-EOF $(list_ngx_modules "$p") EOF if have_preseed "$m" ; then printf '%s: skipping generation of module load config (preseed is in effect)\n' "$p" >&2 continue fi ## produce attachable module configs http_modules= ; mail_modules= ; stream_modules= while read -r fmod ; do [ -n "${fmod}" ] || continue fmod_short="modules/${fmod#"${ANGIE_MODULES_DIR}/"}" fname=${fmod##*/} case "${fname}" in ngx_http_* ) http_modules="${http_modules}${http_modules:+ }${fmod_short}" ;; ngx_mail_* ) mail_modules="${mail_modules}${mail_modules:+ }${fmod_short}" ;; ngx_stream_* ) stream_modules="${stream_modules}${stream_modules:+ }${fmod_short}" ;; ## damn NDK ndk_http_* ) http_modules="${http_modules}${http_modules:+ }${fmod_short}" ;; * ) env printf '%s: unable to determine module type for file (skipping): %q\n' "$p" "${fmod}" >&2 continue ;; esac done <<-EOF $(list_ngx_modules "$p") EOF [ -z "${http_modules}" ] || gen_mod_config "$p" "${ANGIE_MODCONF_DIR}/http-$m.conf" "${http_modules}" [ -z "${mail_modules}" ] || gen_mod_config "$p" "${ANGIE_MODCONF_DIR}/mail-$m.conf" "${mail_modules}" [ -z "${stream_modules}" ] || gen_mod_config "$p" "${ANGIE_MODCONF_DIR}/stream-$m.conf" "${stream_modules}" done echo "extra files/directories (if any):" >&2 find /run/ngx/cache/ /run/ngx/lib/ /run/ngx/log/ -mindepth 1 -exec ls -ld {} + >&2